Imported from databricks-solutions/vibe-coding-workshop-template (
skills/vibecoding-state/SKILL.md). Install upstream withnpx skills add databricks-solutions/vibe-coding-workshop-template --skill vibecoding-state. Copyright stays with the author.
name: vibecoding-state
description: >
Owns the end-to-end state, gating, pathway-applicability, and retrospective
contract for the Instructions.md / example/<use_case>/WALKTHROUGH.md
vibecoding workshops. Every workshop prompt invokes this skill at the top
(enter) and bottom (exit) so the state file is read, gates are enforced,
non-applicable steps are skipped, and the per-step log is appended — without
each prompt repeating the contract as prose. Also owns the bootstrap
initializer, the bootstrap → canonical migrate_canonical move, and the
async retrospective.per_prompt / retrospective.rollup passes. Invoke
BEFORE acting on any workshop prompt.
license: Apache-2.0
compatibility: "Works with any workshop that follows the vibecoding state schema in references/state-template.md. Pathways A, B, C write the AppKit state to <app_root>/.vibecoding-state.md (= <artifact_root>/<app_name>/.vibecoding-state.md, the top-level app dir); the Track A custom-agent app (Pathways C/D) writes to <agent_app_root>/.vibecoding-state.md (= <artifact_root>/<agent_app_name>/.vibecoding-state.md, the top-level agent app dir)."
clients: [ide_cli, genie_code]
bundle_resource: none
deploy_verb: none
deploy_note: "Runtime state/gating/retrospective contract — not a deployable skill; no bundle resource and no deploy verb. It is the resolver: at enter (and, pre-bootstrap, via the lightweight resolve_root op) it resolves the active client and writes the client_context capability set (cli_channel, bundle_deploy.verb, page_context_required, state_file_root, artifact_root, skills_install_root, skill_ref_root, dp_bundle_root) that every downstream prompt and skill consumes, so it is client-agnostic by construction. On Genie Code the state file and artifacts live under the USER PROJECT root (state_file_root = artifact_root = /Workspace/Users/<email>/<repo>), which is a git clone of the workshop repo (a git working tree, so generated bundles are recognized); the skill tree is copied from there to skills_install_root (= /Workspace/Users/<email>/.assistant/skills/<repo>, the discovery + readSkillFile anchor, no git required); relative artifact paths resolve as <ARTIFACT_ROOT>/<relpath>, repo-relative skill paths load via readSkillFile under skill_ref_root (= skills/<clone-folder> = "skills/" + basename(skills_install_root)), the data-product bundle is authored under dp_bundle_root (= <artifact_root>/{user_schema_prefix}_<use_case_slug>_dab, the bundle deploy page-context root), and the AppKit app is authored under app_root (= <artifact_root>/<app_name>, the top-level app dir — same shape on both clients). See skills/genie-code-environment §8 for the resolved per-client deploy verbs, the artifact_root rule, the skill-load rule, and the dp_bundle_root rule."
coverage: full
metadata:
last_verified: "2026-04-30"
volatility: low
upstream_sources: []
author: "prashanth-subrahmanyam"
version: "2.1.0"
domain: "genai-agents"
role: "runtime-contract"
operations: "bootstrap, resolve_root, resolve_spec, enter, migrate_canonical, exit, retrospective.per_prompt, retrospective.rollup, state_contract_audit, endpoint_guardrail_audit, llm_role_endpoint_probe, audit_debts, skill_helper_resolution"
produces: "live_state_file, bootstrap_preflight, state_file_set, canonical_names, state_overrides, deferred_actions, mlflow_eval_known_quality_issues, gate_load_bearing_checks, productized_debts, preflight_check_registry, evaluation_runs_preflight, system_prompt_review, skill_helper_resolutions, resolved_variant, resolved_resources, resolved_ui, resolved_agent, resolved_governance, per_step_log_section, retrospective_entry"
consumes: "Workshop Choices (PRD), PRD document at prd_path, Pathway Applicability Matrix, prior prompt gate"
references:
- "references/state-template.md"
- "references/retrospective-template.md"
- "references/spec-schema.md"
- "references/resolver-prompt.md"
Vibecoding State — Workshop Runtime Contract
This skill is the single source of truth for how every prompt in the repo-root Instructions.md workshop and its worked instantiations (e.g. example/skyloyalty/WALKTHROUGH.md) interacts with the shared per-user state file and the async per-prompt retrospective file.
Prompts do not re-state the "Vibecoding state contract / Preamble / Postamble / Pathway Applicability guard / Retrospective contract" prose. They invoke this skill with typed parameters and this skill owns the behavior.
When to Use
Invoke this skill — always — when executing any vibecoding workshop prompt. Specifically:
- Every prompt in
Instructions.md(Prompt 0.1 through 8.24). - Every prompt in
example/<use_case>/WALKTHROUGH.md(e.g. SkyLoyalty's 22 prompts). - Every post-workshop per-prompt retro + the single session rollup.
Do not invoke for: one-off terminal commands, ad-hoc debugging, or anything outside the workshop flow.
Candidate future skills that this skill deliberately does not absorb (they stay inline in prompts for now): workspace-preflight (databricks compute-policies list, databricks current-user me), llm-endpoint-health (databricks serving-endpoints get <endpoint>), bundle-deploy (databricks bundle validate/deploy/run), derive-app-name (email + use_case_slug → APP_NAME), prd-reader. If you end up duplicating any of those across prompts, extract them next.
Operations
All thirteen operations take a typed parameter bag. The prompt invokes the operation by name (e.g. vibecoding-state.enter) and passes only the dynamic values. Everything else (file paths, log schema, gate rules, pathway matrix, resolved spec) is owned by this skill.
Operation: bootstrap
When: Once per workshop run, at Prompt 0.1 (Instructions.md) or Prompt 1 (WALKTHROUGH.md). Only runs if no live state file exists.
Inputs:
| Param | Type | Required | Description |
|---|---|---|---|
use_case_slug |
string | required | Short hyphenated lowercase slug, ≤ 26 chars. Drives the bootstrap path. |
workspace_url |
string | required | The only value the operator provides by hand. Every subsequent prompt reads it from state. |
pathway |
A | B | C | D |
required | |
track |
A | B | C | n/a |
required | n/a for pathways A, B. |
prd_path |
string | required | e.g. example/<use_case_slug>/docs/design_prd.md. |
llm_endpoint |
string | required | e.g. databricks-claude-sonnet-4-6. |
dabs_bundle_path |
string | n/a |
required |
Behavior:
- Detect environment & write the
## Environment Capabilitiesblock (RULE_0 / RULE_1 enabling). Before any other step, resolve the active coding client and write the capability block (schema inreferences/state-template.md§ Environment Capabilities) as section 0 of the state file. This is the block every prompt and theenter/exitoperations read to resolve the deploy verb, CLI channel, and state-file root — so no skill or prompt body assumes a local IDE. Detection signal [inference — pending the live Genie Code probe]: if a Databricks-managed CLI channel is present in-session (therunDatabricksClitool / Genie serverless markers), setclient_context: genie_code,cli_channel: runDatabricksCli,bundle_deploy.page_context_required: true, bothstate_file_rootandartifact_rootto the user project workspace path (/Workspace/Users/<email>/<repo>— a git clone of the workshop repo, so it is a git working tree and generated bundles are recognized), andskills_install_rootto the skills copy path (/Workspace/Users/<email>/.assistant/skills/<repo>, a copy of the tree for discovery, no git required); otherwise setclient_context: ide_cli,cli_channel: local_shell,bundle_deploy.page_context_required: false, andstate_file_root,artifact_root, andskills_install_rootall to the local repo path. Ensureartifact_root(and thusstate_file_root, which equals it) is a git-backed working tree — the kickstartgit clones the workshop repo into it; if<artifact_root>/.gitis absent,git clone <workshop remote>into it before writing the## Environment Capabilitiesblock (a baremkdirleaves generated bundles unrecognized — TESTED; a Repos-managed Git folder is the documented fallback). Ongenie_codeoperate via the workspace path /executeCode, mindful of the FUSE create-then-validate gap (clone, then confirmos.path.exists(<artifact_root>/.git)before writing); a non-PRD-first flow may reachbootstrapbefore the clone exists. (artifact_rootdefaults equal tostate_file_root; it is where relative artifact paths resolve as<ARTIFACT_ROOT>/<relpath>— seeskills/genie-code-environment§8.skills_install_rootis the read-side anchor: a copy of the clone ongenie_code, the same repo onide_cli.) Also setskill_ref_root— the prefix that makes a repo-relative skill path loadable: ongenie_codeit is thereadSkillFileprefix"skills/" + basename(skills_install_root)(e.g.skills/vibe-coding-workshop, because the skills copy lives under.assistant/skills/<repo>and any file there loads asskills/{path-after-.assistant/skills/}); onide_cliit is empty (repo-relative skill paths /@-mentions resolve as-is). Seeskills/genie-code-environment§8 for how prompts use it. Also setdp_bundle_root=<artifact_root>/{user_schema_prefix}_<use_case_slug>_dab(theuse_case_slugbootstrap param is available here;{user_schema_prefix}is the SAME username-derived prefix used for the{user_schema_prefix}_bronze/_silver/_goldschemas — companion app ongenie_code, authenticated-user derivation onide_cli, e.g.jane_d) — the self-contained Databricks Asset Bundle project directory the whole data-product pipeline (bronze→silver→gold→semantic) writes itsdatabricks.yml/src//resources/into, and thebundle deploypage-context root ongenie_code. The username prefix disambiguates concurrent users in a shared workspace; the bundlename:insidedatabricks.ymlMUST match this prefixed folder name (bundle: { name: {user_schema_prefix}_<use_case_slug>_dab }). It is the same shape on both clients (a dedicated subdir of the repo/clone root, NOT the bare root and NOT inside a read-only framework dir); seeskills/genie-code-environment§8. Also setapp_root=<artifact_root>/<app_name>— the AppKit application track's analog ofdp_bundle_root: a TOP-LEVEL sibling of<use_case_slug>_dab(NOT nested underapps_lakebase/) that holds the scaffolded app (app.yaml/databricks.yml/server//client/+<app_root>/.vibecoding-state.md) on BOTH clients, so the app's root folder has parity regardless of client. It is theapps init --output-dirtarget ongenie_code, deploys viaapps deploy(nobundlepage-context pin), and is<pending>untilAPP_NAMEis resolved (Module 1 / prompt 04);n/afor Pathway D. Also setagent_app_root=<artifact_root>/<agent_app_name>— the Track A custom-agent track's analog ofapp_root: a TOP-LEVEL sibling of<app_name>and<use_case_slug>_dab(NOT nested underapps_lakebase/) that holds the cloned agent framework (app.yaml/pyproject.toml/databricks.yml/server/+<agent_app_root>/.vibecoding-state.md) on BOTH clients, so the agent app's root folder has parity regardless of client. Ongenie_codeit is theapps init --output-dirtarget and theuv/FastAPI server builds server-side viaapps deploy(mode=SNAPSHOT) — there is no localuv run devloop. It is<pending>untilAGENT_APP_NAMEis resolved (Track A clone / prompt 43);n/afor Pathways A/B. The remaining fields are client-invariant:bundle_deploy.verbis alwaysbundle deploy --target dev,app_deployis always{ verb: "apps deploy", gated: true }, anddestructive_opsis alwaysconfirm_required. Also seedgenie_code_manifest_loaded(G3):n/aonide_cli(the check is inert there),falseongenie_code— on Genie Code the first deploy/divergent prompt'senterhalts until theskills/genie-code-environmentmanifest is read in-thread and flips ittrue(seereferences/spec-schema.md§ Genie Code manifest-load gate). Record the detection signal that fired in a trailing# detected_via:comment so a later live probe can confirm or correct it. For how the detectedgenie_codeclient actually behaves — therunDatabricksCliallow-list tiers, the bundle-deploy CWD pin and FUSE create-then-validate gap, the App-scaffold output-dir rule, and the deployed-app OAuth session pattern — see thegenie-code-environmentskill (this skill detects the client; that skill explains it). - Workspace URL normalization & placeholder refusal. Trim any trailing slash from
workspace_urland normalize the scheme tohttps://. Refuse any literal placeholder —<your-workspace-url>, the empty string, orhttps://<...>— by halting with a remediation hint pointing the operator at Workshop Choices. Record the normalized value inbootstrap_preflight.workspace_url_normalizedand the placeholder check inworkspace_url_was_placeholder. - Profile selection & host match. Run
databricks auth profilesand select the profile whose host equals the normalized workspace host. Store it inbootstrap_preflight.workspace_profile. If no profile matches, setworkspace_host_auth_status: wrong_hostand halt; if the matching profile failsdatabricks current-user me, setunauthenticatedand halt; on success setauthenticated. - CLI version preflight (client-branched — Gap-1). On
ide_cli: capturedatabricks --versionintobootstrap_preflight.databricks_cli_version, compare againstbootstrap_preflight.databricks_cli_min_version(default0.295.0, may be raised by workshop config), and halt with an upgrade hint if the installed version is older. Ongenie_code:databricks --versionis hard-blocked (no local CLI binary — the managedrunDatabricksClichannel does not expose a version string; CONFIRMED P1), so setbootstrap_preflight.databricks_cli_version: unknown_on_genie_codeand skip the numeric comparison and the version halt entirely. Any later decision that would have keyed off the numeric version (thedatabricks_cli_min_versionregistry check, andskill_helper_resolution's CLI-version gate) falls back to the behavior probe —databricks bundle validateaccepting the field/deploy without stripping — instead of a version number. The managed channel always tracks a current CLI, so the only real risk a version gate guards against (a stale local install) cannot occur on Genie Code. - Apps quota preflight. Before any
databricks apps createhappens (Pathways A/B/C), rundatabricks apps list --output jsonand recordcurrent_count,max_count, andfree_slotsinbootstrap_preflight.apps_quota. Iffree_slots < 1, halt with a clean-up hint listing the apps the operator can delete. - First state file path. Write the bootstrap live file to
example/<use_case_slug>/.vibecoding-state.md(used in this repo'sexample/examples) orworkshops/<use_case_slug>/.vibecoding-state.md(used by external adopters that follow theworkshops/convention). Whichever path is chosen, record it verbatim inbootstrap_preflight.first_state_file_pathsomigrate_canonicalknows exactly which file to move once$APP_NAMEis resolved. Setbootstrap_preflight.app_name_known_at_bootstrap = false—$APP_NAMEis resolved later by Module 1 / Prompt 2. - Copy the template. Copy
references/state-template.mdtobootstrap_preflight.first_state_file_path. - Replace
<USE_CASE_SLUG>in the title and both<ISO timestamp>placeholders with the current ISO timestamp. - Write all
Workshop Choicesfrom the params above. - Run
databricks auth profiles+databricks current-user meto capturePROFILE,Workspace host,User emailintoGlobal Variables. (PROFILEis the same value already stored asbootstrap_preflight.workspace_profile.) - Run the serverless-only preflight (
databricks compute-policies list) and setworkspace_serverless_only. - DAB dev-mode schema-prefix detection. If
dabs_bundle_pathis a real path (notn/a), shell out todatabricks bundle validate --target dev --output jsonfrom that path and inspect every UC schema resource. If any resource has dev-mode prefixing applied (a name shaped likedev_${user}_<schema>instead of the unprefixed<schema>), setbootstrap_preflight.bundle_dev_mode_schema_prefix_detected = true. Every downstream prompt that passesagent_schema,ops_schema, oruc_schemainto a job/notebook MUST read the resolved (prefixed) schema name from state — never the unprefixed variable name. - Verify-job summary semantics. Set
bootstrap_preflight.verify_summary_semanticsfrom the merged workshop config. Defaultpass_field/warn_field/fail_fieldare"pass","warn","fail"(matching05_verify_infrastructure.py'snotebook.exitpayload).warning_policydefaults toallow_with_notes; set toblock_if_load_bearingfor use cases whose verify-job emits warnings that must block the gate. Whenwarning_policy == block_if_load_bearing, any warning whose name matches an entry in the workshop'sgate_load_bearing_checks[]list blocks the first verify gate (PASS only whenfail == 0AND no load-bearing warning is present). - Derive
variant_idfrompathway+trackusing the deterministic derivation table inreferences/resolver-prompt.md§ Variant-ID Derivation Table. - Invoke
resolve_spec(see below) to parse the PRD atprd_pathand populate the six spec sections (## Variant,## Resources,## UI,## Agent,## Governance,## Spec Provenance). This is a hard step: ifresolve_spechalts,bootstraphalts.
Outputs: Path of the bootstrap state file (also stored as bootstrap_preflight.first_state_file_path), populated with ## Environment Capabilities (section 0), ## Bootstrap Preflight, Workshop Choices, Global Variables (partial), and fully resolved Variant / Resources / UI / Agent / Governance / Provenance spec sections (schema v2.0). The workshop continues with this path until migrate_canonical runs.
Errors: If the bootstrap path already exists, abort — do not overwrite. The operator must remove or migrate the stale file. Any of the four halt rules in references/spec-schema.md § Bootstrap Preflight (steps 1–4 above) abort before the template is copied. If resolve_spec fails validation twice, abort and surface the validation errors; the operator must fix the PRD before re-running.
DAB dev-mode schema-prefix rule (consumer-side). If Databricks Asset Bundle dev mode prefixes UC schema resource names, notebook/job parameters must receive the resolved prefixed schema name, not the unprefixed variable. Bootstrap captures bundle_dev_mode_schema_prefix_detected; any prompt that passes agent_schema, ops_schema, or uc_schema to a job reads the resolved value from state.
Operation: resolve_root
When: Any prompt that writes an artifact before bootstrap has run (e.g. the PRD-generation prompt produces docs/design_prd.md before the PRD exists to bootstrap from). It is the minimal, gate-free way to learn where relative artifact paths must land so a bare docs/… does not resolve against a page-dependent CWD on Genie Code. Idempotent — safe to call repeatedly; a later bootstrap supersedes it as the persistence owner.
Inputs: none required. (Optional state_file_path — if the caller already knows where a state file lives.)
Behavior:
- Read-if-present. If a state file with a
## Environment Capabilitiesblock (section 0) already exists (the live file, or the bootstrap pathexample/<use_case_slug>/.vibecoding-state.md/workshops/<use_case_slug>/.vibecoding-state.md), readclient_context,artifact_root,skills_install_root, andskill_ref_rootfrom it and return them. Do not re-detect or rewrite. - Else detect fresh (bootstrap step-0 detection ONLY). Run just the client/root detection from
bootstrapstep 0 — no URL/profile/CLI/quota preflights, no template copy, noresolve_spec, no gates: if a Databricks-managed CLI channel is present (runDatabricksCli/ Genie serverless markers) ⇒client_context: genie_code,artifact_root= the user project workspace path (e.g./Workspace/Users/<email>/<repo>, a git clone of the workshop repo),skills_install_root= the skills copy path (e.g./Workspace/Users/<email>/.assistant/skills/<repo>, a copy for discovery),skill_ref_root="skills/" + basename(skills_install_root)(e.g.skills/vibe-coding-workshop); otherwise ⇒client_context: ide_cli,artifact_root=skills_install_root= the local repo root,skill_ref_root= empty. - Ensure
artifact_rootis a git-backed working tree. The kickstartgit clones the workshop repo intoartifact_root; if<artifact_root>/.gitis missing,git clone <workshop remote>into it so the caller's first relative write (e.g. the PRD at<ARTIFACT_ROOT>/docs/design_prd.md, produced beforebootstrap) lands in a real, git-backed directory where generated bundles are recognized (a baremkdirleaves them unrecognized — TESTED; a Repos-managed Git folder is the documented fallback). Ongenie_codeoperate via the workspace path /executeCode, mindful of the FUSE create-then-validate gap (clone, then confirm withos.path.exists(<artifact_root>/.git)before writing). This clone/check is the only filesystem side effect ofresolve_root. - Echo, do not persist. Return
client_context+artifact_root+skills_install_root+skill_ref_rootfor the caller to use immediately and to echo the project-root + skill-load rules to the operator. No state file is written —bootstrapstep 0 remains the sole writer of section 0, so there is no "abort if path exists" conflict and no half-initialized state file.
Outputs: { client_context, artifact_root, skills_install_root, skill_ref_root } (ephemeral). The calling prompt resolves its relative artifact path as <ARTIFACT_ROOT>/<relpath>, loads any repo-relative skill path X/Y/SKILL.md as <skill_ref_root>/X/Y/SKILL.md via readSkillFile (§8), and echoes: "artifacts resolve under the workshop project root (artifact_root, the git-cloned user project on Genie Code — not the skills copy) and skills load under skill_ref_root (= skills/<clone-folder> = skills/ + basename of skills_install_root on Genie Code), never the page CWD."
Errors: None that halt — resolve_root is fail-soft. If detection is ambiguous, default to ide_cli / repo-root and note the assumption; the later bootstrap step 0 is authoritative.
Operation: resolve_spec
When: Called automatically as the final step of bootstrap. May also be re-invoked manually if the PRD changes mid-workshop (rare; prefer restarting from bootstrap).
Inputs:
| Param | Type | Required | Description |
|---|---|---|---|
prd_path |
string | required | Path to the PRD. Read from Workshop Choices.prd_path if omitted. |
llm_endpoint |
string | required | LLM endpoint used to synthesize the spec. Read from Workshop Choices.llm_endpoint if omitted. Must be a Databricks Model Serving endpoint reachable from the workspace. |
Behavior:
- Read the PRD contents from
prd_pathand computeprd_sha256. - Load the schema from
references/spec-schema.mdand the prompt fromreferences/resolver-prompt.md. - Derive
variant_iddeterministically from Workshop Choices (pathway,track) per the resolver prompt's Variant-ID Derivation Table. Inject it into the user prompt. - Call
llm_endpointwith the system + user prompts. Expect a single YAML document with exactly six top-level keys:variant_id,resources,ui,agent,governance,spec_provenance. - Run the deterministic guards listed in the resolver prompt's "Post-resolution Guards" section:
- YAML parses cleanly into a dict with the expected top-level keys.
- Every validation rule in
references/spec-schema.md§"Validation Rules" passes. - Consumer cross-check: each
agent.tools[].nameofkind: functionwithlanguage: pythonreconciles with the PRD Tools Table. - Placeholder guard: no resource-ID-shaped strings leaked through.
- Variant-ID echo check: emitted
variant_idequals the one passed in. - MCP ref resolution: every
agent.tools[].mcp_server_ref(kind=mcp) maps to anagent.mcp_servers[].name.
- If any guard fails, retry once with the validation errors appended to the user prompt. Second failure halts bootstrap.
- Split the validated YAML by top-level key and write each block into its matching state-file section (
## Variant,## Resources,## UI,## Agent,## Governance,## Spec Provenance), replacing the<pending>placeholder body with a fenced ```yaml block containing the resolved content. - Stamp
## Spec Provenancewithresolved_at,resolver_version: "2.0",schema_version: "2.0",prd_sha256, andllm_endpoint.
Outputs: No return value; mutates the live state file.
Errors: Validation failure (after one retry), missing PRD file, unreachable llm_endpoint, or any LLM response that is not parseable YAML with the six expected keys — all halt bootstrap.
Downstream contract: Every consuming skill declares which fields it reads via a machine-parseable fields_read: YAML list in its frontmatter (see § Field Consumer Contract below and references/spec-schema.md §"Field Consumer Contract"). Prompts in Instructions.md and WALKTHROUGH.md reference resolved content by dotted path (e.g. ui.user_journeys, agent.tools, governance.scorer_suite.guidelines) instead of inlining domain-specific content. This is what makes the workshops use-case-agnostic.
Operation: hydrate_from_files
When: Called once per workshop, before any prompt that reads state://AgentSpec, state://AppSpec, or state://DataSpec. The Agents Accelerator visible path calls it from prompt uc_resources_foundation (input_id 200, order 40), right after op enter succeeds and before any UC schema/volume creation.
Purpose: The Agents Accelerator design pair (docs/agent_spec.yaml from prompt 38, docs/agent_tool_plan.yaml from prompt 39) becomes the source of truth for the agent's intent. hydrate_from_files lifts those file values into the live state file so every downstream consumer (Track A build prompts, MLflow SDLC suite at prompts 50-56) keeps reading from state://AgentSpec, state://AppSpec, and state://Spec Provenance without an additional visible-path step. This is additive to resolve_spec: PRD-only LLM-driven workflows that never produce the docs/*.yaml files continue to work unchanged.
Inputs:
| Param | Type | Required | Description |
|---|---|---|---|
agent_spec_yaml |
string | required | Path to the docs/agent_spec.yaml produced by prompt 38 (agent_spec_design). |
agent_tool_plan_yaml |
string | required | Path to the docs/agent_tool_plan.yaml produced by prompt 39 (agent_tool_selection). |
ui_design_md |
string | required | Path to the docs/ui_design.md produced by prompt 04 (cursor_copilot_ui_design). |
prd_path |
string | required | Path to docs/design_prd.md from prompt 03 (prd_generation); used for source_prd provenance. |
state_path |
string | required | Path to the live state file (Pathways A/B/C: apps_lakebase/$APP_NAME/.vibecoding-state.md; Pathway D: agents/$AGENT_NAME/.vibecoding-state.md). |
Behavior:
-
Read
agent_spec_yaml. Copy scalar/listagent.*fields directly into the state file's## Agentsection as a fencedyamlblock:model,capabilities,personas,system_prompt,benchmark_seeds,must_do,must_not_do. File values override any priorresolve_specLLM output silently; the file is the source of truth.Tool projection rule (preserves the v2.0
fields_read: agent.toolscontract without rewriting any consumer). The Agent Spec produced by step 38 follows the 00b schema (tool_recommendations, NOTagent.tools). Hydration MUST project tools intostate://AgentSpec.agent.tools[]using these three sub-rules:a. Seed
state://AgentSpec.agent.tools[]fromdocs/agent_spec.yaml.tool_recommendations.managed_databricks[]plustool_recommendations.external[]. Map each entry to the v2.0 tool discriminated-union shape: populatekind(hosted|function|mcp),name,surface,io_contract,readonly, plus the kind-specific fields (hosted_type+resource_ref, orlanguage, ormcp_server_ref). Carryselected_by_defaultforward to pre-mark entries. b. Overlaydocs/agent_tool_plan.yaml.selected_tools[]on top. Any Tool Plan entry with the samenameREPLACES the spec recommendation — binding selection wins over loose recommendation. Tool Plan entries with no matching spec recommendation are appended. c. Tool families absent from BOTH the spec and the Tool Plan are NOT written intoagent.tools[]. Skipped families are recorded as skipped, not failed (consistent with step 44 semantics).The projection is the only legitimate way
state://AgentSpec.agent.tools[]becomes populated on the Agents Accelerator visible path. Step 38 does NOT and MUST NOT writeagent.tools[]directly intodocs/agent_spec.yaml; downstream prompts that still citeagent.tools[](e.g. step 44's prerequisite block before Pass 3.5) MUST be updated to readtool_recommendations(loose) plusselected_tools(binding) instead. -
Read
agent_tool_plan_yaml. Mergeselected_tools[],selected_mcp_servers[],runtime_config.llm, andresource_grantsinto## Agentunder new keysselected_tools,selected_mcp_servers,runtime_config, andresource_grants. Tools selected by the user in the Tool Plan win over the Agent Spec's recommendations. -
Read
ui_design_md. Parse loose markdown headings into## UI(pages[],personas[],user_journeys[]) on a best-effort basis. If the document is structured differently or only contains free-form prose, write the verbatim markdown into## UI.raw_markdownand emit a non-fatal warning so downstream SDLC prompts can still find personas/journeys textually. -
Stamp
## Spec Provenance. Computeprd_sha256fromprd_pathand writeresolved_at(current UTC ISO timestamp),resolver_version: "3.0"(new tag distinguishing file-based hydration from LLMresolve_spec's"2.0"),schema_version: "2.0",prd_sha256, andhydrated_from_files: true. -
Optional
## Resources(DataSpec). If the PRD declares a Lakehouse/Resources section (Bronze tables, Genie Spaces, Vector Search indexes, etc.) and## Resourcesis already populated by an earlierresolve_specrun, leave it untouched. Otherwise write## Resourcesasoptional: truewithtables: [],mark_skipped: "no Lakehouse track", signalling downstream prompts thatstate://DataSpec.*lookups should fall back gracefully (e.g. KA branch C in prompt 42 reads fromdocs/design_prd.md+docs/agent_spec.yaml.agent.capabilitiesinstead ofstate://DataSpec.glossary). -
Idempotency. Re-running with the same inputs is a no-op: each section is regenerated from the file values, sha256 is stable, and the state file ends in the same byte sequence (modulo the
resolved_attimestamp, which is allowed to drift). Re-running with newerdocs/*.yamlfiles overwrites cleanly.
Outputs: { hydrated: true, sections_written: ["## Agent", "## UI", "## Resources", "## Spec Provenance"] }. The Agents Accelerator step 40 records hydrated_from_files: true and resolver_version: "3.0" in its op exit captured map.
Errors:
- Missing required input file → halt with an explicit pointer to the producing prompt:
agent_spec_yaml→ 38,agent_tool_plan_yaml→ 39,ui_design_md→ 04,prd_path→ 03,state_path→ bootstrap. agent_spec.yamlmissingagent.model→ halt with a pointer to prompt 38's model selection rule (Pass 1 / Pass 2 of the Agents Accelerator cleanup).agent_tool_plan.yaml.runtime_config.llm.endpointequals the literal YAML-path stringdocs/agent_spec.yaml.agent.model→ halt with the Pass 2 placeholder rule citation. This is defense-in-depth; prompt 39's generated prompt already forbids this.- Any value at a documented Agent Spec / Tool Plan path is still wrapped in
{...}(e.g.{agent_sql_catalog}) → halt with the Pass 2 placeholder-handling rule. The user must rerun prompt 39 with real values.
Downstream contract: After hydrate_from_files runs, every prompt that consumes state://AgentSpec.agent.*, state://AppSpec.ui.*, or state://Spec Provenance.* sees the file-derived values. state://DataSpec.* is <pending> or optional: true unless the Lakehouse track produced one. SDLC prompts (50-56) MUST handle the optional/pending DataSpec case gracefully — they already do (the Agents Accelerator visible path no longer requires Lakehouse outputs), but the optional: true flag makes the contract explicit.
LLM driver prompt: See references/hydrator-prompt.md for the actual prompt that an LLM-driven implementation runs to execute this operation. That file is to hydrate_from_files what references/resolver-prompt.md is to resolve_spec.
Operation: enter
When: At the top of every workshop prompt, before any domain skill or command runs.
Inputs:
| Param | Type | Required | Description |
|---|---|---|---|
prompt_id |
string | required | e.g. 0.1, 3.2, 5.A4, 7.22.5, or 20c. Matches the heading the prompt will log under. |
require_prior_gate |
{prompt_id: string, gate: string} |
optional | Assert the listed prompt's Gate equals the listed string. If it does not match, enter stops the workshop and surfaces the mismatch. |
Behavior:
-
Locate the live state file:
- First, resolve
state_file_rootfrom the## Environment Capabilitiesblock (section 0). Every path below is relative to it — the local repo root forclient_context: ide_cli, the git-folder workspace path forgenie_code. On a pre-capability state file (no section 0), defaultstate_file_rootto the repo root and proceed without assuming a deploy channel. - If
$APP_NAMEis known (Pathways A/B/C), use<app_root>/.vibecoding-state.md(=<state_file_root>/<app_name>/.vibecoding-state.md, the TOP-LEVEL app dir — NOTapps_lakebase/<app_name>/). - Else if
$AGENT_APP_NAMEis known (Track A agent app, Pathways C/D), use<agent_app_root>/.vibecoding-state.md(=<state_file_root>/<agent_app_name>/.vibecoding-state.md, the TOP-LEVEL agent app dir — NOTapps_lakebase/<agent_app_name>/). - Else if
dp_bundle_rootis resolved (a data-product / lakehouse run with no app or agent app — e.g. the Gold-design→Bronze→Silver→Gold→semantic pipeline), use<dp_bundle_root>/.vibecoding-state.md(=<state_file_root>/{user_schema_prefix}_<use_case_slug>_dab/.vibecoding-state.md). This is the canonical DP-track live file — the data-product analog of<app_root>/<agent_app_root>. The FIRST data-product prompt to run (Gold design, step 09 — or Bronze, step 10, if design was skipped) bootstrap-creates it fromreferences/state-template.mdif absent (a real create, copying the template + filling Workshop Choices from the priorexample/bootstrap file if present — not justresolve_root); every later DP step appends to it. Do NOT leave data-product state in the temporaryexample/bootstrap path — that path carries no durable record and was the root cause of "state survived only in chat summary." - Else fall back to the bootstrap path
<state_file_root>/example/<use_case_slug>/.vibecoding-state.md(pre-bootstrap only — oncedp_bundle_root/app_root/agent_app_rootis known, migrate/bootstrap-create the canonical file above). - If none of these exists yet: for the
dp_bundle_root/app_root/agent_app_rootcanonical paths, bootstrap-create the file from the template (this is the first prompt of that track); only stop and tell the operator to runbootstrapfirst if evenuse_case_slug/Workshop Choices are unknown.
- First, resolve
-
Schema v2.0 gate (hard fail). Parse the
## Spec ProvenanceYAML block. Ifschema_version != "2.0", halt with:State file uses schema v<X> — this repo is strictly v2.0. Run: python scripts/migrate-spec-v1-to-v2.py <path-to-state-file> Then re-run this prompt.No best-effort reads against older shapes.
-
Read end-to-end. Treat
Workshop Choices,Global Variables, andCaptured Resource IDsas authoritative. Never ask the operator for a value that already exists in state. -
Multi-file resolution via
state_file_set. Parse the## State File Setblock.- If
state_file_set.secondary.pathis<pending>or null, treat the located file as the only source — done. - If
secondaryis declared andprompt_idis insecondary.required_for_prompts, read the secondary file too. Halt if it does not exist (remediation: runbootstrapfor the missing side or correctsecondary.path). - Walk both files following
lookup_order(e.g.["primary", "secondary"]). For each canonical field requested by the prompt, the first hit wins. - For any canonical field present in both files with different values: halt unless
conflict_policy: primary_winsis set explicitly. Withprimary_wins, use the primary value and append the conflict to## State Contract Audit(fields_read_but_never_produced/captured_fields_with_no_consumerare unaffected; conflicts get their own audit row).
- If
-
Apply
canonical_namesaliasing on read. Parse the## Canonical Namesblock. Whenever the prompt reads an env var, HTTP header, jq path, or state field listed as a legacy/incorrect spelling on the left of acanonical_namesmap, resolve to the canonical name on the right. If the map's value isnull(e.g.http_headers.x-forwarded-user-info: null), the name does not exist; halt and surface a hint pointing at the canonical alternatives.state_contract_auditperforms the same checks at audit time. -
Enforce the prior gate if
require_prior_gateis set. On mismatch, halt unless a matching entry exists instate_overrides[](see step 7). Mismatches that are NOT covered by an override stop the workshop. -
Apply
state_overrides[](fail-closed escape hatch). Parse## State Overrides. An override entry covers a failing gate when ALL of the following hold:prompt_idmatches the current prompt;gate_typematches the failing gate (require_prior_gatefor step 6,hard_assert/preflight_checkfor step 9 below,pathway_applicabilityfor step 8); andexpires_atis in the future relative to the current ISO timestamp. A covered failure is treated as satisfied and the override is logged in the prompt'sResolved issues / workaroundsPer-Step Log entry. Expired or missing entries DO NOT cover the failure —enterhalts. Cross-session continuity (e.g. resuming from a previous run's state file) is recorded as astate_overridewhosereasoncites the earlier run's evidence; it is NOT a prose exception. -
Consult the Pathway Applicability Matrix (below). If the prompt does not apply for this
pathway/trackand nostate_overridewithgate_type: pathway_applicabilitycovers it, synthesize a## Prompt <prompt_id> — Skipped (N/A for pathway <X>)section withGate: Skipped — N/A for pathway <X>, append it, and return askipped: truesignal so the prompt body short-circuits. With a covering override, proceed (the overridereasonis logged in the prompt's Per-Step Log entry). -
Enforce
deferred_actions[]. Parse## Deferred Actions. Halt if the current prompt's role is in any opendeferred_action'starget_prompt_roles[]and itsdivergence_checkevaluates to false (or fails to parse under the divergence-check grammar inreferences/spec-schema.md§ Deferred Actions). Halt is suppressed only when astate_overridewithgate_type: hard_assert(orpreflight_check) on the currentprompt_idexists AND itsreferences[]contains"deferred_action:<id>"matching the action'sid. Ifdivergence_checkreturns true, flipstatustoresolvedand proceed. Entries withstatus: waivedare skipped without evaluation. -
Enforce
mlflow_eval_known_quality_issues[]. Parse## MLflow Eval Known Quality Issues. If the current prompt's role appears in any open issue'starget_prompt_roles_blocked[], halt with a remediation hint citingid,source_prompt_role, anderror_signature— unless astate_overrideexists on the currentprompt_idwhosereferences[]contains"known_issue:<id>"matching the issue'sid. The issue'serror_signatureSHOULD be a name fromgate_load_bearing_checks[]so audits and verify summaries align, butenterhalts purely ontarget_prompt_roles_blocked[]membership andstatus: open— it does NOT consultgate_load_bearing_checks[]directly (that list drivesstate_contract_auditand the verify-jobwarning_policy: block_if_load_bearingrule per § Gate Load Bearing Checks inreferences/spec-schema.md). -
Enforce
preflight_check_registry. Parse## Preflight Check Registry. For each registry entry, if the current prompt's role appears inblocks_prompt_roles[], evaluate the matching state field per the State-field mapping table inreferences/spec-schema.md§ Preflight Check Registry. If the pass condition is not met (the field is<pending>, missing, or fails the predicate), halt with a remediation hint pointing atowner. The halt is suppressed only when a matchingstate_overridewithgate_type: preflight_checkexists on the currentprompt_idwhoseaffected_state_fieldmatches the check's state field. Forreflection_lm_large_context_probe, the check is treated as passing only when a synchronous ≥80000-character probe has been run against the currently boundllm_role_endpoints.reflection_lm.endpointandendpoint_guardrail_audit[<reflection_lm.endpoint>].long_context_ok == trueANDaccepted_min_context_chars >= 80000— the generic bootstrap endpoint guardrail pass is NOT sufficient on its own. The owning skill (instruction_iteration) MUST invoke the probe synchronously before any 08b diff-summary helper or iteration helper call. Forgenie_code_manifest_loaded(G3, the one client-conditional check), evaluate it only whenenvironment_capabilities.client_context == 'genie_code'— it is inert onide_cli— and on Genie Code halt the deploy roles untilenvironment_capabilities.genie_code_manifest_loaded == true(the agent has readskills/genie-code-environmentin-thread); seereferences/spec-schema.md§ Genie Code manifest-load gate. -
Resolve variables. Return the subset of state the prompt body needs (it is declared in the prompt's
enterinvocation — e.g.APP_NAME,PROFILE,warehouse_id). Always also return the environment-capability set so any deploy/run instruction the prompt emits uses the resolved verb + channel instead of assuming a local IDE:bundle_deploy.verb(alwaysbundle deploy --target dev),app_deploy.verb(apps deploy),cli_channel(local_shellforide_cli,runDatabricksCliforgenie_code),artifact_root+skill_ref_root, and — for data-product prompts —dp_bundle_root(so the bundle is written and deployed under<artifact_root>/{user_schema_prefix}_<use_case_slug>_dab, not the bare clone root), and — for AppKit app-track prompts —app_root(so the app is scaffolded, wired, and deployed under<artifact_root>/<app_name>, the top-level app dir, on both clients), and — for Track A custom-agent prompts —agent_app_root(so the agent app is cloned, wired, and deployed under<artifact_root>/<agent_app_name>, the top-level agent app dir, on both clients). Whenbundle_deploy.page_context_required: true, also return the page-context note (Genie Code must run the deploy from thedp_bundle_rootpage). The body never hardcodes a bare-shelldatabrickscall.
Recovery reconcile (on resume / after a context reset — do BEFORE re-authoring anything). When enter runs in a thread that did not author the work itself (a resumed or compacted session), the live state file — not the chat summary — is the source of truth. (a) For any prompt whose Per-Step Log entry shows Gate: …PASSED (or the prompt's success gate), treat that step as DONE: do NOT re-run it or overwrite its files, regardless of what a summary says ("NOT DONE"/"IN PROGRESS" in a stale summary is the known drift failure). (b) Before writing files for an in-flight step, reconcile what is already on disk: list the target dirs with os.listdir(...) (NOT listFiles, which lags FUSE writes — see genie-code-environment §10) and compare against the paths the state file captured, so you resume the partial step instead of recreating files that already exist.
Outputs: {skipped: bool, resolved: {<key>: <value>}, capabilities: {client_context, cli_channel, bundle_deploy, app_deploy, state_file_root}}.
Errors:
- step 6 — prior-gate mismatch with no covering override.
- step 7 — invalid override (expired / missing fields / fails any of the four override-coverage clauses).
- step 8 — pathway-applicability mismatch with no
pathway_applicabilityoverride. - step 9 — open
deferred_actionwhosedivergence_checkevaluates to false (or fails to parse) and nostate_overridereferences it. - step 10 — open
mlflow_eval_known_quality_issuewhosetarget_prompt_roles_blocked[]includes the current prompt and nostate_overridereferences it. - step 11 —
preflight_check_registryentry whoseblocks_prompt_roles[]includes the current prompt's role and whose state-field pass condition is not met (and nostate_overridewithgate_type: preflight_checkcovers it). Forreflection_lm_large_context_probe, the synchronous large-context probe MUST have been run against the currently bound reflection-LM endpoint withaccepted_min_context_chars >= 80000. - step 7 corollary — expired
state_overrides[]entries do NOT cover failures.
Other halt conditions (not numbered above): missing state file, unresolved <pending> value the prompt requires, missing required secondary state file when prompt_id is in state_file_set.secondary.required_for_prompts, conflicting canonical fields across primary/secondary without conflict_policy: primary_wins, and read on a header/env-var/jq-path/state-field whose canonical_names entry is null.
Operation: migrate_canonical
When: Exactly once, at the prompt that first resolves $APP_NAME (Pathways A/B/C, usually Prompt 1.1 / Prompt 2 of the walkthrough) or $AGENT_NAME (Pathway D, usually Prompt 4.0).
Inputs:
| Param | Type | Required | Description |
|---|---|---|---|
app_name |
string | required for A/B/C | Mutually exclusive with agent_name. |
agent_name |
string | required for D | Mutually exclusive with app_name. |
Behavior:
- Move
example/<use_case_slug>/.vibecoding-state.mdto<app_root>/.vibecoding-state.md(=<artifact_root>/<app_name>/.vibecoding-state.md, A/B/C) or<agent_app_root>/.vibecoding-state.md(=<artifact_root>/<agent_app_name>/.vibecoding-state.md, Track A agent app for C/D). - Update
Global Variables.APP_NAME(orAGENT_NAME). - Pin MLflow experiment paths to the user-and-use-case identity. At the same prompt that first resolves
$APP_NAME/$AGENT_NAME, also resolve any<pending>MLflow experiment paths inCaptured Resource IDsso downstream skills (F2, SDLC 04c, 08-appkit-feedback) consume the value from state instead of constructing their own — generic leaves likeTracing,traces, ormy-app-feedbackare forbidden:mlflow_experiment_path→/Users/<user_email>/mlflow/<APP_NAME>-agent(Pathway C) or/Users/<user_email>/mlflow/<AGENT_NAME>-agent(Pathway D).n/afor Pathways A and B.mlflow_feedback_experiment_path→/Users/<user_email>/mlflow/<APP_NAME>-feedback(Pathway C only).n/afor A, B, D.- The leaf MUST carry the same
${FIRSTNAME}-${LASTINITIAL}-${use_case_slug}shape that backsAPP_NAMEso concurrent workshop attendees on a shared workspace cannot collide on a single MLflow experiment.
- All subsequent
entercalls resolve to the canonical path automatically.
Outputs: Path of the canonical state file.
Errors: If the canonical path already exists, abort — the operator has collided with an earlier run.
Operation: exit
When: At the bottom of every workshop prompt, after all verification checks have passed.
Inputs:
| Param | Type | Required | Description |
|---|---|---|---|
prompt_id |
string | required | Must match the enter call. |
title |
string | required | Human-readable title (e.g. Deploy to Databricks Apps). |
gate |
string | required | The Gate line. For build/modify prompts this MUST be Local testing passed. For infra/deploy/eval prompts it is the prompt's success criterion (e.g. Deployment RUNNING, Eval thresholds met, Signoff APPROVED). For skipped steps: Skipped — N/A for pathway <X>. |
captured |
{key: value, ...} |
optional | Newly resolved Captured Resource IDs (e.g. {app_url: "https://..."}). The skill writes these into the top-of-file list, replacing the matching <pending> entries. |
skills_invoked |
[string, ...] |
optional | Paths of domain skills that ran between enter and exit. Written into the Per-Step Log. |
resolved_issues |
[string, ...] |
optional | One bullet per issue hit and its fix. Defaults to none. |
verification |
[string, ...] |
optional | One bullet per objective check that passed. |
Behavior:
- Run the prompt's verification checks (caller supplies
verificationif declared). When a check involves a deploy/run, use the verb + CLI channel resolved byenterfrom## Environment Capabilities(never a bare-shelldatabrickscall). - Write the
## Prompt <prompt_id> — <title>section to the live state file (located underenvironment_capabilities.state_file_root, same resolution asenterstep 1) using the Per-Step Log template inreferences/state-template.md. Idempotent byprompt_id(hard): first scan the file for an existing## Prompt <prompt_id> — …heading. If one exists, replace that section in place (update its Gate, captured vars, and bullets); only append a NEW section when no entry for thisprompt_idis present. Never append a second section for aprompt_idthat is already logged — a re-run after a retry or context reset must update the existing entry, not create a duplicate (duplicatesilver_layer_sdpentries were a live regression). - Update
Captured Resource IDsat the top — replace<pending>entries for every key incaptured. Mark pathway-irrelevant IDs<n/a>. - Bump
Last updatedin the header. - Gate rule (hard): if the prompt is a build/modify prompt,
gateMUST beLocal testing passed. If it is anything else,exitstops and the next deployment-oriented prompt'senterwill reject on the prior-gate check. - Verify the write (load-bearing — not advisory): after appending, re-read the live state file and confirm the new
## Prompt <prompt_id>section, the updatedCaptured Resource IDs, and the bumpedLast updatedare actually present. If the re-read does not show the appended section, theexitdid NOT persist — retry the write (on Genie Code, fall back toexecuteCodeopen(path,"a")whenworkspaceUpdateFilesilently no-ops on an existing file). The prompt is NOT complete until this re-read confirms the write. The chat summary is NOT the state store. - Print a 3-line summary to chat: what was created, what values were captured, what the next prompt will consume.
Handoff invariant (every summary / context-compaction / thread handoff): carry state_file_path, last_completed_prompt, last_gate, environment_capabilities, and state file updated: yes/no verbatim (see references/retrospective-template.md § Handoff invariant). A handoff that omits these is non-conformant; the next thread must re-open the live file rather than trust the prose. Generate the summary FROM the live state file's Per-Step Log — never from in-memory recollection — and the state file always supersedes the summary: if the summary and the state file disagree about whether a step is done, the state file wins (a step logged with its gate PASSED is DONE even if the summary says "NOT DONE" / "IN PROGRESS"; a summary mid-execution snapshot must NOT trigger re-running a completed, gated step).
Outputs: The new log section's path inside the state file.
Errors: Verification check failure, gate-rule violation — halt without marking complete.
Operation: retrospective.per_prompt
When: Async, after the whole workshop completes. Run once per executed prompt. Do not interleave with active prompts.
Inputs:
| Param | Type | Required | Description |
|---|---|---|---|
prompt_id |
string | required | The prompt being retro'd. |
title |
string | required | Same title logged in the Per-Step Log. |
transcript |
string | null |
optional | Raw agent transcript. If null, reconstruct from the state file's Resolved issues + Verification bullets. |
Behavior:
- Load
references/retrospective-template.md. - Fill in the per-prompt block exactly as specified (fixed headings, no additions or renames).
- Append to
example/<use_case_slug>/retrospective.md. - Print back to chat: Friction score, Outcome, Pathway/track applicability verdict, Top 3 improvements. Nothing else.
Errors: If the state file has no matching ## Prompt <prompt_id> section, halt — there is nothing to retro.
Operation: retrospective.rollup
When: After every per-prompt retro is in retrospective.md. Run exactly once.
Inputs: None.
Behavior: Follow the Session Rollup Prompt in references/retrospective-template.md. Produce example/<use_case_slug>/retrospective-rollup.md with the seven fixed sections (Instructions.md edits, Skill edits, State-file schema edits, Pathway Applicability Matrix edits, Top disambiguation gaps, Gate violations, Spec drift).
Before producing the backlog, run the Spec Drift checks from the rollup template in this order:
- PRD drift. Compute
sha256of the file at## Workshop Choices → prd_pathand compare with## Spec Provenance → prd_sha256. Mismatch → halt with a hard error instructing the operator to re-runresolve_spec(or accept drift by updatingprd_sha256explicitly). - Schema drift. Read
## Spec Provenance → schema_version. If it differs from theSchema Versioninreferences/spec-schema.md(currently"2.0"), halt with a hard error: either run the migrator for that schema bump or re-runresolve_specon the current schema. - Producer-consumer contract (fields_read: drift check). Load every known consumer skill's frontmatter and parse its
fields_read:YAML list. Parse the live state file's## Resources,## UI,## Agent,## GovernanceYAML blocks and enumerate every dotted-path leaf. Computeconsumed = union(fields_read:)(expand parent paths likeui.*to their leaves). Computeproduced = leaves_of(state file). Halt with a hard error if:produced − consumed ≠ ∅→ resolver emitted a field nothing reads (stale or missing consumer).consumed − produced ≠ ∅→ consumer declares a read on a field the resolver did not emit (schema drift or typo).
Only if all three pass does the rollup proceed to enumerate the four non-blocking sub-checks (unused resolved fields, hardcoded leaks), merge them into the backlog as section 7 (Spec drift), and write the rollup file.
Surface state_contract_audit.productized_debts_status in the rollup as a one-line debt-lift summary (e.g. "Productized debts: 5 total / 1 lifted / 0 parse errors").
Outputs: Path of the rollup file. On halt, path of a short error report at example/<use_case_slug>/retrospective-rollup.ERROR.md explaining which check failed and how to recover.
Operation: state_contract_audit
When: Run before retrospective.rollup, before any workshop release, and after modifying prompt/skill state fields.
Inputs:
| Param | Type | Required | Description |
|---|---|---|---|
prompt_registry_ref |
string | required | Path or SQL seed ref containing prompt captured fields. |
skill_root |
string | optional | Default: genai-agents. |
state_template_path |
string | optional | Default: skills/vibecoding-state/references/state-template.md. |
mode |
enum | optional | warn for local authoring, fail before release. Default: fail. |
Behavior:
- Parse every prompt's declared
capturedfields fromdocs/02_seed_section_input_prompts.sql. - Parse every skill frontmatter
fields_read:andproduces:list. - Parse
references/spec-schema.mdandreferences/state-template.md. - Emit four lists:
fields_read_but_never_producedfields_produced_but_not_in_schemaschema_fields_missing_from_templatecaptured_fields_with_no_consumer
- Canonical-names extension. Parse the live state file's
## Canonical Namesblock and grep prompt sources + skill bodies for legacy/incorrect spellings of env vars, HTTP headers, jq paths, MLflow Prompt Registry URI schemes, and eval-dataset column names. Add any non-canonical reads tofields_read_but_never_produced(with the legacy name as the field) so the same fail-list flushes them. Reads onnull-valued canonical entries (e.g.x-forwarded-user-info) are always reported regardless of mode. - Preflight-registry extension. Parse the live state file's
## Preflight Check Registryblock. For each entry, verify (a)ownerresolves to either a real skill path underskill_rootor a known prompt id in the workshop's prompt registry, and (b) every check name referenced from a prompt body or skillfields_read:list exists as a key in the registry. Unresolved owners and unknown referenced check names are added tofields_read_but_never_producedso the same fail-list flushes them. Until forward-referenced owners (Phase 2.2'sinstruction_iteration, Phase 4.4'slakebase_memory, etc.) land, those entries
Truncated - read the full file at https://github.com/databricks-solutions/vibe-coding-workshop-template/blob/9b4eb111831fbcad37f883859a715ff81bbc6b0e/skills/vibecoding-state/SKILL.md.