Skip to content

docs(dataapp-developer): document Storage Access enablement and fix stale claims - #98

Open
MiroCillik wants to merge 1 commit into
mainfrom
miro-AI-3754
Open

docs(dataapp-developer): document Storage Access enablement and fix stale claims#98
MiroCillik wants to merge 1 commit into
mainfrom
miro-AI-3754

Conversation

@MiroCillik

@MiroCillik MiroCillik commented Aug 18, 2026

Copy link
Copy Markdown
Member

Fixes documentation in the dataapp-development skill that was wrong or missing, found by building and deploying a real Python/JS data app end-to-end. Everything here was verified against a live app (project 40, connection.eu-central-1.keboola.com) — no inferred behavior.

Refs AI-3753, AI-3751, CFTL-716.

Scope reduced. This PR originally added a drafts/previews recipe. Removed in ee78053 per @davidesner's review — the drafts & deployments API is under active development (AJDA-3034, AJDA-3140), and documenting today's manual mechanism would entrench a pattern that keeps main writeable and decouples app deployment from branch merge. What remains is unrelated to drafts.

storage-access.md — new §Enabling Storage Access

runtime.workspace.enabled: true is what makes the platform provision the app's ephemeral workspace and inject WORKSPACE_ID / QUERY_SERVICE_URL / KBC_WORKSPACE_MANIFEST_PATH. It appeared nowhere in the skill, yet every storage pattern the skill documents depends on it — including DuckDB-cached RO, which duckdb-caching.md presents as the default for read-only dashboards.

The failure mode is the expensive kind: the app builds, deploys, reports state=running, passes its health probe — and reads zero rows. Confirmed in both directions on a live app: absent → Missing env vars: WORKSPACE_ID while every platform signal stayed green; present → full cache load. kbagent data-app create does not set it.

troubleshooting.md

  • The existing Storage Access env-var entry gave a UI-only fix and conflated enabling access with adding writable tables (unload_strategy: "direct-grant"), which a read-only app doesn't need. Rewritten for the read-only case with the kbagent command, and it now states that the app still reports healthy while broken.
  • New entry: config change has no effect after redeploy (CFTL-716), with the config_version_storage vs config_version_deployed diagnostic. Hit this live — a config change silently didn't deploy across a warm redeploy and a cold stop→deploy; only an explicit --config-version applied it.
  • §Reading logs: kbagent data-app logs has shipped (verified on 0.84.2) — the skill still described it as an unshipped follow-up. Now documented, along with the rough edges found in use: 400 ... is not running on a stopped app, the manage-token requirement on some subcommands, and the 20-line MCP tail cap.

python-js-apps.md — §Deployment from Keboola-managed git

Replaces the Deployment via MCP — PLACEHOLDER section, which claimed customer-provided git was "the only supported path". Managed Forgejo repos work today via --use-managed-git-repo; documented with pointers to the keboola-git skill for the repo plumbing. Branch previews are explicitly marked as intentionally undocumented pending the new API, so agents don't reinvent the workaround.

TODO.md

  • AJDA-2924 (workspace.enabled=true by default) was re-filed as AJDA-2924 and canceled 2026-08-11 — so the flag is a permanent explicit step, not pending work.
  • Dropped a stale claim that a "flip workspace on first" caveat lives in SKILL.md and deployment-paths.md. It is in neither (grep → 0 hits); it was planned and never landed.
  • data-app logs marked shipped; kbagent gaps found during this work recorded.

Release Notes

  • Justification
    • Agents building Keboola data apps were being misled by the skill's own docs. The one config flag that makes Storage reads work was never named, so an app would deploy green and silently serve no data — the most expensive kind of wrong, because every signal reports success. A stale claim also told agents a shipped command didn't exist.
    • For a non-technical consumer: the guide Claude follows when building a Keboola data app now explains how to give an app access to project data, and how to tell when a change didn't actually deploy.
  • Plans for Customer Communication
    • None needed — documentation only, no product surface change. Worth mentioning to anyone who has hit "my data app runs but shows no data", which now has a documented cause and fix.
  • Impact Analysis
    • Docs-only change to one plugin's skill content. No code, no runtime, no single-tenant impact. Not behind a feature flag; applies to everyone who installs the plugin.
    • Risk is limited to the guidance itself being wrong. Each claim was verified against a live app rather than inferred, and the two platform bugs referenced (CFTL-716, AJDA-2924) are linked so the text can be revisited when they change.
  • Deployment Plan
    • Continuous — merge to main and it ships with the next plugin version bump. Not critical.
  • Rollback Plan
    • Fully reversible: revert the commit. No state, no migration, two-way door.
  • Post-Release Support Plan
    • No support burden. Two sections will need revisiting when upstream work lands: the redeploy entry once CFTL-716 is fixed, and the managed-git section once the drafts & deployments API ships.
    • Support team does not need notifying.

Verification

  • runtime.workspace.enabled cause and effect confirmed both directions on a live app; data path proven from container logs (cached 2412 beers), not from state=running.
  • CFTL-716 reproduced: warm redeploy and cold stop→deploy both left the deployment pinned to the stale version; explicit --config-version applied it. Reported on that issue.
  • kbagent data-app logs exercised throughout.
  • Also verified config update --merge preserves parameters.dataApp.git — which cleared config update of suspicion for an earlier breakage; the real cause is create --use-managed-git-repo not persisting dataApp.git, recorded in TODO.md.
  • All internal markdown links in changed files resolve; trigger-evals.json parses.

Review

Copilot raised 5 comments; 4 applied, 1 rejected with evidence (it flagged kbagent data-app logs as unavailable, citing the skill's own stale text — the command exists, so the stale text was fixed instead). Replies are in the threads.

🤖 Generated with Claude Code

@linear-code

linear-code Bot commented Aug 18, 2026

Copy link
Copy Markdown

AI-3754

AI-3753

@MiroCillik
MiroCillik requested review from davidesner and jordanrburger and a lite review from Copilot and removed request for Copilot, davidesner and jordanrburger August 18, 2026 14:49
@MiroCillik

Copy link
Copy Markdown
Member Author

Note: This is for the current drafts implementation - NOT for the NEW ONE - which is under development.
But this is a pain for some important clients who rely heavily on local/MCP apps development.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the dataapp-development skill documentation to accurately reflect (1) how branch-based previews/drafts work for Python/JS data apps and (2) how to explicitly enable Storage Access via runtime.workspace.enabled: true, including its otherwise-silent failure mode.

Changes:

  • Added a new reference describing draft/preview deployments as separate app configurations linked via isDraft + parentConfigurationId.
  • Updated existing references to document Storage Access enablement and the config-version pinning behavior required for changes to take effect.
  • Routed the skill entry points and trigger evals to ensure the new preview/draft guidance is discoverable.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
plugins/dataapp-developer/skills/dataapp-development/TODO.md Updates tracked gaps/issues and reflects new “drafts/previews” + Storage Access findings.
plugins/dataapp-developer/skills/dataapp-development/SKILL.md Adds routing entries so preview/draft guidance is reachable from the skill.
plugins/dataapp-developer/skills/dataapp-development/references/troubleshooting.md Improves Storage Access troubleshooting and adds “stale config after redeploy” guidance.
plugins/dataapp-developer/skills/dataapp-development/references/storage-access.md Documents runtime.workspace.enabled: true as required for any workspace query.
plugins/dataapp-developer/skills/dataapp-development/references/python-js-apps.md Replaces the MCP placeholder with managed-git + drafts/previews deployment guidance.
plugins/dataapp-developer/skills/dataapp-development/references/drafts-and-previews.md New end-to-end recipe for preview deployments/drafts including safety/verification steps.
plugins/dataapp-developer/evals/dataapp-development/trigger-evals.json Adds trigger queries for preview/draft requests.
Suppressed comments (2)

plugins/dataapp-developer/skills/dataapp-development/references/drafts-and-previews.md:275

  • Same issue here: sed "s/${SECRET}/…/g" treats the secret as a regex, so redaction can fail and leak the push credential into the transcript. Prefer a literal replacement (e.g., via Python) so redaction is robust regardless of token contents.
git checkout main && git merge --no-ff "$BRANCH"
SECRET=$(mint_secret)
git push "https://kai:${SECRET}@git.${STACK}/keboola/app-${PROD_APP_ID}.git" main:main 2>&1 \
  | sed "s/${SECRET}/<redacted>/g"
unset SECRET

plugins/dataapp-developer/skills/dataapp-development/references/drafts-and-previews.md:284

  • This production-verification step also relies on kbagent data-app logs, which the troubleshooting reference describes as a follow-up command (not guaranteed to exist). Add the UI Terminal Log fallback here as well so the publish checklist remains executable.
# 3. verify production from its logs BEFORE touching the draft
kbagent data-app logs --project "$PROJECT" --app-id "$PROD_APP_ID" --lines 200

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread plugins/dataapp-developer/skills/dataapp-development/references/storage-access.md Outdated
Comment thread plugins/dataapp-developer/skills/dataapp-development/TODO.md Outdated

@keboola-pr-reviewer-bot keboola-pr-reviewer-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.

Verdict: needs_human (risk 2/5) · profile _default

Docs-only change to agent-instruction (skill) files, which policy says never to auto-approve; content looks safe but a human should confirm.

Impact flags: possible rollback re-introduction — see Check Run summary.

Concerns:

  • plugins/dataapp-developer/skills/dataapp-development/references/drafts-and-previews.md: New agent instructions direct irreversible cascade data-app delete and merge-to-main on live projects
  • plugins/dataapp-developer/skills/dataapp-development/references/python-js-apps.md: Documented kbagent CLI behavior (flags, version pin) unverifiable from diff
  • .claude-plugin/marketplace.json: Skill content changed but plugin/marketplace version not bumped per CLAUDE.md

MiroCillik added a commit that referenced this pull request Aug 20, 2026
…claim

Copilot review on #98. Four accepted, one rejected with evidence.

- credentials: stop embedding the secret in the push URL. git echoes the remote
  URL in its own error output, so a failed push leaked it; sed-scrubbing was the
  wrong layer (it treats the secret as a regex, so a token containing . * [ \ or
  / would break the substitution and leak what it was hiding). Replaced with a
  credential helper so the URL carries no secret at all -- verified by
  ls-remote/push against the live managed repo. Observed tokens are 40 chars of
  [a-z0-9], but that is not a documented guarantee.
- replace the <latest> --config-version placeholders in storage-access.md and
  troubleshooting.md with the capture idiom already used in drafts-and-previews.md
- TODO.md: fix the cross-reference to the python-js-apps.md section this PR renamed
- REJECTED, and fixed the opposite way: review flagged `kbagent data-app logs` as
  unavailable, citing troubleshooting.md. The command exists and works (verified
  on kbagent 0.84.2, used throughout this work); the SKILL was stale. Updated
  troubleshooting.md and TODO.md, and documented the rough edges found in use --
  400 on a stopped app, manage-token requirement, 20-line MCP cap.
- add §Faster iteration: hot-reload the preview. Discovered that Kai Agent pushed
  dev-mode configs onto a draft branch; KBC_APP_MODE=dev turns a preview into a
  real edit loop. Documented with the correction that supervisord-dev must carry
  the hot-reload flag (node --watch) -- Kai's copy was byte-identical to the prod
  config, so the watcher would pull commits while the process served stale code.

Refs: AI-3754, AI-3753, CFTL-716
@davidesner

Copy link
Copy Markdown
Contributor

@MiroCillik I thought we would wait for the new API. Isn't it available already? So things like

Kai's "Publish to Production" is: merge the branch into main, redeploy production, then remove the draft.`

are not necessary. Leaving the main writeable and the deploy mechanism decoupled between app deployment and branch merge doesn't seem like a good pattern to me.

@MiroCillik

Copy link
Copy Markdown
Member Author

Yeah, I guess it's better to wait for the new API regarding drafts.. But there are also other improvements/fixes in this PR, I will remove the "drafts" part from it.

@MiroCillik MiroCillik changed the title docs(dataapp-developer): document drafts/previews and Storage Access enablement docs(dataapp-developer): document Storage Access enablement and fix stale claims Aug 20, 2026
@MiroCillik

Copy link
Copy Markdown
Member Author

Agreed with @davidesner — dropped the drafts/previews part in ee78053. The objection is the right one: a merge-to-main-then-redeploy publish step keeps main writeable and decouples app deployment from branch merge, and writing that into the skill would have entrenched exactly the pattern the new drafts & deployments API (AJDA-3034, AJDA-3140) is replacing. Better an empty section than a blessed workaround.

Removed

  • references/drafts-and-previews.md (whole file)
  • both SKILL.md router entries and the two preview/draft trigger evals
  • the preview recipe in python-js-apps.md — now a short note stating it is intentionally absent, why, and pointing at the UI flow (Kai's draft + "Publish to Production") meanwhile
  • the TODO.md draft-command gaps, reframed as "waiting on the new API, not on kbagent" so nobody picks up a data-app draft CLI task that the new API supersedes

Kept — none of this is draft-related:

Change Why
storage-access.md §Enabling Storage Access runtime.workspace.enabled appeared nowhere in the skill, yet every workspace query needs it. Without it an app deploys, reports state=running, passes its health probe, and reads zero rows (AI-3753)
troubleshooting.md read-only Storage Access fix (the old entry gave a UI-only, read-write direct-grant answer); new stale-config-after-redeploy entry (CFTL-716); corrected §Reading logs
python-js-apps.md §Deployment from Keboola-managed git replaces a PLACEHOLDER that wrongly said customer-provided git was "the only supported path" (AI-3751)
TODO.md AI-3218 was canceled as AJDA-2924, so the workspace flag is permanent rather than pending; dropped a stale claim about a caveat that exists in neither SKILL.md nor deployment-paths.md; marked data-app logs shipped

Diff is now 4 files, +104/−16, no new files. Retitled the PR to match.

The Copilot fixes from the previous round survive where they applied to kept files — the <latest> → captured-config_version_storage change in storage-access.md and troubleshooting.md, and the dangling TODO.md cross-reference. The credential-redaction fix went away with the file it was in.

One consequence worth naming: AI-3754 asked for a kbagent data-app draft command group. If the new API is the path, that ask is superseded and the issue should probably be reduced to the two findings that outlive it — --use-managed-git-repo can't target an existing app's repo, and data-app create --use-managed-git-repo doesn't persist parameters.dataApp.git. Happy to rewrite it that way; also happy to leave it for whoever owns the new API to fold in.

Comment thread plugins/dataapp-developer/skills/dataapp-development/references/python-js-apps.md Outdated
Comment thread plugins/dataapp-developer/skills/dataapp-development/references/python-js-apps.md Outdated
- `branch_id` — the numeric ID to paste into `.env.local`.
- `is_development_branch` — confirms which branch the MCP session is currently scoped to. **Must be `false`** before relying on `branch_id`. If `true`, the MCP is in a dev-branch context — switch to the production branch in your MCP setup and re-run, otherwise you'll paste a dev-branch ID into `.env.local` and the app will read dev-branch tables locally.

## Enabling Storage Access (required for ANY workspace query)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@MiroCillik

I think this **kbagent data-app create does not set this flag**, and neither does the UI's app-creation flow in every case. Check it before the first deploy. should be changed and this option exposed via flag explicitly, rather than adding it directly like this (more prone to error) + this functionality should work with CLI alone. The same goes for https://github.com/keboola/mcp-server/blob/main/src/keboola_mcp_server/tools/data_apps.py#L1298 MCP tool. I leave up to you whether this should be a followup action or whether it should supersede this.

To be fair since every pattern listed requires this (i.e. every data app that requires access to storage) the ideal state would be that CLI and MCP tools created it by default with this flag by default. (I know you said it is a security risk https://linear.app/keboola/issue/AJDA-2924/dataapps-workspaceenabledtrue-by-default-for-every-new-app). Then this entire section could be reduced to a statement that when the app doesn't require storage access, the workspace access should be explicitly disabled.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I agree, this should be a default in CLI and MCP and not need a special config update call -> will create follow up issues

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Reworked, and treating the tooling change as follow-up rather than superseding this — but your comment turned up more than the framing being wrong, so worth spelling out what I found in data_apps.py:

  • MCP already sets the flag. Line 1242: runtime=(CodeDataAppConfig.Runtime(workspace=…Workspace(enabled=True)) if has_storage_workspace else None).
  • It is gated on a project feature I did not know existed — line 154, DATA_APPS_STORAGE_WORKSPACE_FEATURE = 'data-apps-storage-workspace'.
  • There is a fallback when the feature is off — line 1113 injects WORKSPACE_ID through parameters.dataApp.secrets instead.

So my text was wrong about MCP and silent on both the feature gate and the fallback. It now states plainly who sets the flag (MCP yes, kbagent data-app create no, UI via Advanced Settings) and mentions the feature gate, instead of teaching a hand-edit as the normal path. Kept the silent-failure warning, because that is the part that actually costs people time — the app builds, reports state=running, passes its health probe, and reads zero rows.

On follow-up vs supersede: follow-up. The gap is real for anyone on the CLI today, so leaving it undocumented while the flag ships did not seem right. AI-3753 already asks for exactly the --workspace/--no-workspace affordance you describe; I have added the MCP-parity note there. If you would rather this section wait for the flag, I will pull it.

On defaulting it: agreed that would collapse this section to "disable it when the app does not need storage" — that is the better end state, and AJDA-2924 is where that argument belongs rather than here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Let's wait until the AI-3753 lands and we can simplify this section

Comment thread plugins/dataapp-developer/skills/dataapp-development/references/storage-access.md Outdated
…e MCP claims

Rebased onto main after #99. Addresses @davidesner's review; drafts content is
gone entirely (previous round) and no longer referenced.

- storage-access.md: new §Enabling Storage Access. runtime.workspace.enabled is
  what makes the platform provision the app workspace and inject WORKSPACE_ID /
  QUERY_SERVICE_URL; it appeared nowhere in the skill. Now states who sets it:
  MCP modify_python_js_data_app does (gated on the data-apps-storage-workspace
  project feature, falling back to injecting WORKSPACE_ID via dataApp.secrets),
  kbagent data-app create does not. Drops the earlier "set it by hand" framing
  per review; exposing it as a CLI/MCP flag is tracked as follow-up (AI-3753).
  The failure mode is silent -- app builds, reports running, passes its health
  probe, reads zero rows -- so that is called out explicitly.
- python-js-apps.md: replace §Deployment via MCP -- PLACEHOLDER, which claimed
  customer-provided git was "the only supported path". Documents managed-git
  provisioning via both modify_python_js_data_app and kbagent. Per review, the
  branch-preview note is dropped and MCP is described accurately -- Python/JS is
  supported, it just uses a different tool than Streamlit.
- deployment-paths.md: three more instances of the same wrong claim ("No
  Python/JS type via MCP today", "MCP doesn't yet support Python/JS app
  deployment", "Path C until MCP gains support"), one of which also dangled at
  the renamed section.
- troubleshooting.md: rewrite the Storage Access env-var entry for the read-only
  case (it gave a UI-only, read-write direct-grant answer); add "config change
  has no effect after redeploy" with the config_version_storage vs _deployed
  diagnostic; §Reading logs now documents kbagent data-app logs, which has
  shipped, plus the rough edges found using it.
- TODO.md: AI-3218 was canceled as AJDA-2924, so the flag is permanent; drop a
  stale claim about a caveat present in neither SKILL.md nor deployment-paths.md;
  mark data-app logs shipped and the MCP Python/JS gap outdated; record the
  kbagent gaps found.
- No Linear links in reference files, per review. TODO.md keeps them, matching
  the convention already there.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants