Skip to content

docs(data-app): point at the official dataapp-developer skill - #637

Merged
padak merged 1 commit into
mainfrom
docs/point-at-dataapp-developer-skill
Aug 22, 2026
Merged

docs(data-app): point at the official dataapp-developer skill#637
padak merged 1 commit into
mainfrom
docs/point-at-dataapp-developer-skill

Conversation

@padak

@padak padak commented Aug 22, 2026

Copy link
Copy Markdown
Member

Why

references/data-app-workflow.md documents the lifecycle — what kbagent data-app does to an app: create, deploy, secrets, credentials, rollback. It never said what the git repo must contain.

That is a separate contract, owned by the base image and documented in Keboola's own dataapp-developer skill in keboola/ai-kit. Our file already mentioned that skill twice in passing (the DuckDB-cache template, its default dashboard pattern) without ever saying where it lives or what it covers.

So an agent authoring a repo from our docs alone is working from the half of the picture we happen to own.

Why it matters more than a usual doc gap

The repo-side rules are not discoverable by trying. A container that never becomes ready produces no container logs at alldata-app logs answers App is not running, and the deploy just dies as StartupDeadlineExceeded after ten minutes. There is nothing to grep and nothing to iterate against.

The new section names the three that bite hardest, all sourced from references/python-js-apps.md:

  • nginx must listen 8888 — hardcoded by the platform
  • never declare [program:nginx] — the base image manages nginx
  • the health check polls GET /, not /health — blocking work there stalls startup

It also states the limit of our own tool

kbagent data-app validate-repo checks a SUBSET of that contract — notably it does not inspect the nginx listen port, so 0 BLOCKING is not a promise that the app will start.

Not hypothetical. A repo built as an E2E fixture reported 0 BLOCKING, 6 OK and failed to start twice. A validator that is trusted beyond what it checks is worse than one that is understood, so the boundary is now written down next to the recommendation to use it.

(Making validate-repo actually check listen 8888 is the real fix and is not in this PR — happy to open it separately. The rule is stated in the skill in exactly the form a check could implement: "at least one nginx server block listening on 8888".)

Scope

  • references/data-app-workflow.md — new section, placed before "Storage access" because it is what you need before authoring anything.
  • agents/keboola-expert.md — the same warning inline in the data-app row, since an agent consults the tool matrix before it opens any workflow file. Prompt is now 48828 bytes against the 70000 budget (test_agent_prompt.py passes).

Every referenced ai-kit path was verified to exist via the GitHub API. Docs only, no source changes, no version bump.


Open in Devin Review

data-app-workflow.md documents the LIFECYCLE -- what `kbagent data-app`
does to an app. It never said what the git repo must contain, which is a
separate contract owned by the base image and documented in Keboola's own
`dataapp-developer` skill (keboola/ai-kit). The file already referenced that
skill twice in passing without ever saying where it lives.

An agent authoring a repo from this file alone hits rules it cannot discover
by trying, because a container that never becomes ready produces no logs at
all -- the deploy just dies as StartupDeadlineExceeded after ten minutes. The
new section names the three that bite hardest (nginx must listen on 8888, no
[program:nginx], the health check polls GET /) and points at the templates,
which are a faster correct start than assembling keboola-config/ by hand.

It also states the limit of our own tool: `validate-repo` checks a subset of
that contract and does not inspect the nginx listen port, so 0 BLOCKING is
not a promise that the app starts. That is not hypothetical -- a repo built
for the E2E fixtures reported 0 BLOCKING, 6 OK and failed to start twice.

keboola-expert.md gets the same warning inline, since an agent consults the
tool matrix before it opens any workflow file. Prompt is 48828 bytes against
the 70000 budget.

Every referenced ai-kit path was verified to exist.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@padak
padak merged commit 9d49927 into main Aug 22, 2026
5 checks passed
@padak
padak deleted the docs/point-at-dataapp-developer-skill branch August 22, 2026 13:48
padak added a commit that referenced this pull request Aug 22, 2026
…rade to

`upgrade_command` in `kbagent version --json` is documented as a string a
consumer may shell out to verbatim, but `get_kbagent_version_info()` built
it unconditionally. Both non-False states of `up_to_date` therefore handed
out an actively wrong command:

* `true` (local >= latest). A caller on a pre-release compares ahead of the
  stable release a non-`--beta` fetch returns (`0.44.0b1` >= `0.43.3`), so it
  read `up_to_date: true` beside a `--force --reinstall` command pinned to the
  OLDER stable wheel. Running it is a silent downgrade off the beta -- the
  exact foot-gun the beta channel's three gates exist to prevent.
* `null` (release feed unreachable). `resolve_kbagent_wheel_url(None)` yields
  no asset, so it fell through to the unpinned `git+` source install, resolving
  whatever the default branch happens to be -- on the one code path reached
  precisely because kbagent could not establish what the current release is.

`prepare_kbagent_update_plan()` already gated on `up_to_date is False`, so
`kbagent update` itself was never affected; only the reported string was. The
frozen (PyInstaller) channel branch is untouched -- `brew upgrade` and friends
are no-ops when current, not downgrades, and `install_channel` consumers rely
on that shape.

Two tests added; both fail on the parent commit.

Also in this commit, for the 0.88.0 release span:

- changelog: `(#issue)` decorations on all 24 bullets. The `SDK:` prefix is not
  in `_PREFIX_RE`, so that bullet rendered uncoloured -- it becomes `New (#622):`
  with the SDK context kept in the sentence.
- changelog: entries for #636 and #637, which carried no version bump and so
  arrived with no changelog at all.
- four first sentences shortened under the 160-char headline budget that
  `test_changelog_render.py` enforces -- two of them were pushed over by the
  decorations added here.
padak added a commit that referenced this pull request Aug 22, 2026
…rade to

`upgrade_command` in `kbagent version --json` is documented as a string a
consumer may shell out to verbatim, but `get_kbagent_version_info()` built
it unconditionally. Both non-False states of `up_to_date` therefore handed
out an actively wrong command:

* `true` (local >= latest). A caller on a pre-release compares ahead of the
  stable release a non-`--beta` fetch returns (`0.44.0b1` >= `0.43.3`), so it
  read `up_to_date: true` beside a `--force --reinstall` command pinned to the
  OLDER stable wheel. Running it is a silent downgrade off the beta -- the
  exact foot-gun the beta channel's three gates exist to prevent.
* `null` (release feed unreachable). `resolve_kbagent_wheel_url(None)` yields
  no asset, so it fell through to the unpinned `git+` source install, resolving
  whatever the default branch happens to be -- on the one code path reached
  precisely because kbagent could not establish what the current release is.

`prepare_kbagent_update_plan()` already gated on `up_to_date is False`, so
`kbagent update` itself was never affected; only the reported string was. The
frozen (PyInstaller) channel branch is untouched -- `brew upgrade` and friends
are no-ops when current, not downgrades, and `install_channel` consumers rely
on that shape.

Two tests added; both fail on the parent commit.

Also in this commit, for the 0.88.0 release span:

- changelog: `(#issue)` decorations on all 24 bullets. The `SDK:` prefix is not
  in `_PREFIX_RE`, so that bullet rendered uncoloured -- it becomes `New (#622):`
  with the SDK context kept in the sentence.
- changelog: entries for #636 and #637, which carried no version bump and so
  arrived with no changelog at all.
- four first sentences shortened under the 160-char headline budget that
  `test_changelog_render.py` enforces -- two of them were pushed over by the
  decorations added here.
padak added a commit that referenced this pull request Aug 22, 2026
…rade to

`upgrade_command` in `kbagent version --json` is documented as a string a
consumer may shell out to verbatim, but `get_kbagent_version_info()` built
it unconditionally. Both non-False states of `up_to_date` therefore handed
out an actively wrong command:

* `true` (local >= latest). A caller on a pre-release compares ahead of the
  stable release a non-`--beta` fetch returns (`0.44.0b1` >= `0.43.3`), so it
  read `up_to_date: true` beside a `--force --reinstall` command pinned to the
  OLDER stable wheel. Running it is a silent downgrade off the beta -- the
  exact foot-gun the beta channel's three gates exist to prevent.
* `null` (release feed unreachable). `resolve_kbagent_wheel_url(None)` yields
  no asset, so it fell through to the unpinned `git+` source install, resolving
  whatever the default branch happens to be -- on the one code path reached
  precisely because kbagent could not establish what the current release is.

`prepare_kbagent_update_plan()` already gated on `up_to_date is False`, so
`kbagent update` itself was never affected; only the reported string was. The
frozen (PyInstaller) channel branch is untouched -- `brew upgrade` and friends
are no-ops when current, not downgrades, and `install_channel` consumers rely
on that shape.

Two tests added; both fail on the parent commit.

Also in this commit, for the 0.88.0 release span:

- changelog: `(#issue)` decorations on all 24 bullets. The `SDK:` prefix is not
  in `_PREFIX_RE`, so that bullet rendered uncoloured -- it becomes `New (#622):`
  with the SDK context kept in the sentence.
- changelog: entries for #636 and #637, which carried no version bump and so
  arrived with no changelog at all.
- four first sentences shortened under the 160-char headline budget that
  `test_changelog_render.py` enforces -- two of them were pushed over by the
  decorations added here.
padak added a commit that referenced this pull request Aug 22, 2026
…eport fix (#638)

Nothing between v0.87.0 and today had been published: #629 bumped pyproject to
0.88.0, #633 bumped it again to 0.89.0, and both changelog blocks sat unreleased.
Ship the whole span as one release instead of publishing two versions
retroactively.

- changelog: merge the 0.89.0 bullets into 0.88.0, reordered so the #624
  column-description fix leads -- the first bullet is what `kbagent changelog`
  renders as the one-line summary. Add (#issue) decorations to all 24 bullets;
  the `SDK:` prefix is not in \_PREFIX_RE so that bullet rendered uncoloured and
  becomes `New (#622):`. Add entries for #636 and #637, which carried no version
  bump and so arrived with no changelog at all.
- pyproject 0.89.0 -> 0.88.0, propagated to plugin.json, marketplace.json and
  uv.lock via `make version-sync`.
- rewrite every `0.89.0+` / `(since v0.89.0)` version gate across CLAUDE.md, the
  keboola-expert prompt, commands-reference.md, gotchas.md, context.py,
  docs/sdk.md and two test comments. A stale gate makes the agent refuse flags
  that do exist on the user's installed version.
- fix: `kbagent version --json` no longer advertises an `upgrade_command` when
  there is nothing to upgrade to. It was built unconditionally, so a caller on a
  pre-release read `up_to_date: true` beside a `--force --reinstall` command
  pinned to the OLDER stable wheel (a silent downgrade), and an unreachable
  release feed produced an unpinned `git+` default-branch install. `kbagent
  update` itself was never affected. Two tests added; both fail on the parent.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant