From 57096ba559383997a0f207ce3c7ff8c934fc111d Mon Sep 17 00:00:00 2001 From: Petr Date: Sat, 22 Aug 2026 15:39:45 +0200 Subject: [PATCH] docs(data-app): point at the official dataapp-developer skill 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. --- plugins/kbagent/agents/keboola-expert.md | 2 +- .../kbagent/references/data-app-workflow.md | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/plugins/kbagent/agents/keboola-expert.md b/plugins/kbagent/agents/keboola-expert.md index e9214386..ac87432d 100644 --- a/plugins/kbagent/agents/keboola-expert.md +++ b/plugins/kbagent/agents/keboola-expert.md @@ -134,7 +134,7 @@ been retired, so its absence is NOT a promise (see ยง1 Rule 6). | Read or write a config's runtime state | `kbagent config state-get` / `config state-set --state JSON` (0.84.2+) -- the dedicated state endpoint | -- | `config update --set 'state...'` (hard error since 0.84.2; before that it silently wrote `configuration.state.*` and left runtime state untouched) | | Get OAuth authorization URL | `kbagent config oauth-url --project P --component-id C --config-id K` | -- | raw `GET .../oauth/authorize` | | Inventory data apps | `kbagent data-app list --project P` | `kbagent config list --component-id keboola.data-apps` (Storage view only -- no state/URL/configVersion) | hand-joining Storage configs to Data Science per project | -| Bring a new data app online | `kbagent data-app create --project P --name N --slug S --git-repo URL [--git-pat-env VAR \| --git-public]` -- Storage access is ON by default on 0.87.0+ (`--no-workspace` opts out; on <= 0.86.0 patch `runtime.workspace.enabled` after create or it reads NOTHING) -- or `--use-managed-git-repo` for an empty Keboola-hosted repo (mutually exclusive; forces `--no-deploy`; then `git-credentials-create` + push + `deploy`). See [data-app-workflow.md](../skills/kbagent/references/data-app-workflow.md) | `config new --component-id keboola.data-apps` + `encrypt values` + raw `POST /apps`, only for custom shapes | `PATCH desiredState=running` without `configVersion` + `restartIfRunning` (pins to the v2 empty shell; errors `dataApp.git.repository is required`) | +| Bring a new data app online | `kbagent data-app create --project P --name N --slug S --git-repo URL [--git-pat-env VAR \| --git-public]` -- Storage access is ON by default on 0.87.0+ (`--no-workspace` opts out; on <= 0.86.0 patch `runtime.workspace.enabled` after create or it reads NOTHING) -- or `--use-managed-git-repo` for an empty Keboola-hosted repo (mutually exclusive; forces `--no-deploy`; then `git-credentials-create` + push + `deploy`). See [data-app-workflow.md](../skills/kbagent/references/data-app-workflow.md). **Authoring the repo itself is a different contract** (nginx `listen 8888`, no `[program:nginx]`, health check polls `GET /`) owned by Keboola's `dataapp-developer` skill in `keboola/ai-kit` -- read it before writing `keboola-config/`; `validate-repo` checks only a subset, so 0 BLOCKING does not promise the app starts | `config new --component-id keboola.data-apps` + `encrypt values` + raw `POST /apps`, only for custom shapes | `PATCH desiredState=running` without `configVersion` + `restartIfRunning` (pins to the v2 empty shell; errors `dataApp.git.repository is required`) | | Roll out / wake / pause / tear down a data app | `data-app deploy --wait` after ANY config change (sends the `{desiredState, configVersion, restartIfRunning}` trio); `data-app start` wakes a parked app without bumping the version; `data-app stop` pauses; `data-app delete` is irreversible and cascades to the Storage config | -- | `config update` then `job run` (data apps are not jobs); deleting the `keboola.data-apps` config by hand (orphans the deployment record) | | Debug a data app (failed deploy or runtime crash) | `kbagent data-app runs --app-id N` FIRST -- lists deploy attempts with `failure_reason` + `startup_logs`, and works on failed/never-started apps where `data-app logs` 400s | `kbagent data-app logs --app-id N [--lines N \| --since ISO8601]` for a running container's tail (may echo runtime secrets) | opening the UI "Terminal Log" tab; concluding anything from an empty log grep | | Read the data-app simpleAuth password | `kbagent data-app password --project P --app-id N` -- needs a Manage API token (interactive prompt; `--allow-env-manage-token` for CI) | -- | trying to "rotate" it (unsupported -- delete + recreate) | diff --git a/plugins/kbagent/skills/kbagent/references/data-app-workflow.md b/plugins/kbagent/skills/kbagent/references/data-app-workflow.md index 95607151..d7cf6bef 100644 --- a/plugins/kbagent/skills/kbagent/references/data-app-workflow.md +++ b/plugins/kbagent/skills/kbagent/references/data-app-workflow.md @@ -12,6 +12,44 @@ that auto-suspends after idle. Two API surfaces own them: git PATs. The CLI encapsulates the documented footguns so callers cannot hit them; see "Gotchas encoded" below. +## What goes IN the repo: the `dataapp-developer` skill (read before authoring) + +This file covers the **lifecycle** -- create, deploy, secrets, credentials, +rollback -- i.e. what `kbagent data-app` does to an app. It does NOT specify +what the git repo must contain. That is the base image's contract, and it is +owned by Keboola's official skill: + + keboola/ai-kit -> plugins/dataapp-developer/skills/dataapp-development/ + SKILL.md + references/python-js-apps.md <- the /app contract, nginx, supervisord + references/storage-access.md + references/troubleshooting.md + templates/{python-app,nodejs-app,python-node-app}/ + +Read `references/python-js-apps.md` before authoring or reviewing a repo. The +rules that bite hardest are not discoverable from a failed deploy, because a +container that never becomes ready produces **no logs at all** -- the deploy +just dies as `StartupDeadlineExceeded` after ten minutes: + +- **nginx must `listen 8888`.** Hardcoded by the platform; the proxy routes + external traffic there and nowhere else. Only ports >= 1024 work at all + (the container does not run as root). +- **Never declare `[program:nginx]`** in `keboola-config/supervisord/`. The + base image manages nginx; declaring it too makes one of the two fail to + start. +- **The health check polls `GET /`**, not `/health`. Blocking work on that + path stalls it and the container never reports ready. +- Required paths are fixed: `keboola-config/nginx/sites/*.conf` and + `keboola-config/supervisord/services/*.conf`. The repo is cloned to `/app`. + +`kbagent data-app validate-repo` checks a SUBSET of that contract (see +"Pre-flight repo validation" below) -- notably it does not inspect the nginx +`listen` port, so **0 BLOCKING is not a promise that the app will start**. +Treat the skill as the specification and validate-repo as a cheap first pass. + +The templates under `templates/` are the fastest correct starting point: copy +one rather than assembling `keboola-config/` by hand. + ## Storage access: `runtime.workspace.enabled` (read this first) Any data app that reads Storage needs `runtime.workspace.enabled: true` in