bubbles-status-transition
Transition a Bubbles spec/scope/bug status safely through the framework's gate checks. Use when changing state.json status (`in_progress` → `done`, `done_with_concerns`, `blocked`, `specs_hardened`, etc.), promoting an artifact, or running pre-push checks. Covers the mechanical transition guard and the grandfather clause for historical done specs.
- License 许可
- MIT
- 最近更新
- 2026-11-07
- Stars
- ★ 1
- Forks
- 0
01 前言 Front Matter
- name
- bubbles-status-transition
- description
- Transition a Bubbles spec/scope/bug status safely through the framework's gate checks. Use when changing state.json status (`in_progress` → `done`, `done_with_concerns`, `blocked`, `specs_hardened`, etc.), promoting an artifact, or running pre-push checks. Covers the mechanical transition guard and the grandfather clause for historical done specs.
03 SKILL.md 正文
Bubbles Status Transition
Goal
Move a spec or scope through its lifecycle without violating the framework's transition gates, and understand exactly when historical done specs are re-evaluated vs. grandfathered.
When to use
- About to edit
state.jsonstatus field - About to set a scope's
Status:line in scopes.md orscopes/*/scope.md - Before staging a commit that includes status changes
- Investigating why
state-transition-guard.shrejected a transition
Status ceiling per workflow mode
Each workflow mode in bubbles/workflows/modes.yaml declares a statusCeiling. The spec cannot transition to a status above this ceiling. Common ceilings:
v4.1.0: the new delivered_pending_activation ceiling sits between validated and done for work that ships implementation + tests + audit + docs but defers live-runtime evidence to an external actor (operator commit, third-party approval, cutover window, regulator review). Modes targeting it: adapter-readiness-to-packet, dark-launch-shipped, migration-shipped-pending-cutover. See docs/v4.1.0-delivered-pending-activation.md for the full opt-in surface (deliverableFiles[] manifest, phaseStubs{}, lockdown tags, evidence-by-reference).
| Mode family | Ceiling | Meaning |
|---|---|---|
brainstorm |
specs_scoped |
Planning only; no implementation |
plan-only |
specs_scoped |
Same as brainstorm |
spec-scope-hardening |
specs_hardened |
Specs and design hardened; no code |
docs-only |
docs_updated |
Managed docs may change; no source code |
validate-only |
validated |
Certification check only |
audit-only |
validated |
Audit-owned findings only |
full-delivery, feature, bugfix-fastlane, etc. |
done |
Full implementation permitted |
If the ceiling is below done, the agent MUST refuse to mark the spec done even if the work feels complete. Set the ceiling status instead and emit a route_required packet for the next-stage workflow.
Ceiling status is terminal-for-mode (not a backlog item)
When a workflow mode has statusCeiling other than done (e.g., validate-to-doc → validated, docs-only → docs_updated, adapter-readiness-to-packet → delivered_pending_activation), the ceiling status IS the completion signal for that mode. Each such mode also declares terminalAliases: [<ceiling>] so that portfolio tooling can treat it as terminal.
- Terminal-for-mode means:
status == "done"ORstatus == mode.statusCeilingORstatus ∈ mode.terminalAliases. - Use the helper
bash bubbles/scripts/is-terminal-for-mode.sh <status> <mode>(exit 0 = terminal) instead of comparing to the literal string"done". - Promotion past the ceiling is forbidden by
state-transition-guard.sh. Re-orchestrating a ceiling-bound spec/bug throughbugfix-fastlaneto forcedoneis fake make-work — the actual work already shipped. - Portfolio sweeps (
spec-dashboard.sh,bubbles.status,bubbles.recap, retro tooling) MUST useis-terminal-for-mode.shso ceiling-bound packets are counted as completed work, not as open items.
Done is sequential
- A spec cannot be
doneuntil ALL scopes showStatus: Done(Gate G024). - A scope cannot be
Doneuntil ALL DoD items are[x]with inline raw-output evidence (Gate G025). - A DoD item cannot be
[x]until executed in the current session (anti-fabrication).
Mechanical guard (must pass before push)
bash bubbles/scripts/state-transition-guard.sh specs/<NNN-feature>
Returns exit 0 only when every relevant check passes.
The guard does not run itself. It runs where a repository wires it. Measured across the six consumer repos on 2026-08-12: five carry a pre-push hook, exactly ONE of those invokes any Bubbles guard, and one carries no hook at all. So on five of six repos the guard was reachable only when someone remembered to type it — which, from the outside, is indistinguishable from having no gate.
Wire it, or it is not enforcing anything:
# in .git/hooks/pre-push, or the repo's own pre-push runner
bash .github/bubbles/scripts/verify-changed-specs.sh --base-ref origin/main
verify-changed-specs is the generic entry point: it discovers the specs a diff
touched AND the certified scenarios a SOURCE-only diff invalidated, then runs the
gates on each. The guard itself has no bypass flag; what varies between repos is
whether it is invoked at all.
Grandfather clause for historical done specs (PRESERVED)
This is the most important rule for framework upgrades:
done-spec-audit.shdefault profile isadvisory— read-only historical report, exits 0 even if older specs would fail current policy.- Pre-push uses
--profile changed— only re-evaluates specs whosestate.jsonactually changed in the diff. Spec 042 that's beendonesince v2.x stays green when v4.0 ships, unless someone edits itsstate.jsonin the same commit. - Recertification is opt-in only — requires
--profile recertification --all --reopen-failing. There is no implicit recertification. - The deprecated
--fixflag is blocked without an explicit recertification command.
When a historical done spec is reopened (because the work needs to be revisited), the agent MUST apply current-version policy from that point forward. The grandfather only applies while the spec stays untouched.
Pre-completion mechanical pipeline
Run all of these and capture raw output into report.md before flipping any status to done:
bash bubbles/scripts/state-transition-guard.sh specs/<NNN-feature>
bash bubbles/scripts/artifact-lint.sh specs/<NNN-feature>
bash bubbles/scripts/cli.sh framework-validate # in source repo
bash .github/bubbles/scripts/cli.sh framework-validate # in downstream repo
Status is two mirrors — never write one alone
state.json records the lifecycle status twice: top-level status and certification.status. They are one fact in two places. transition-contract-resolver.sh refuses any spec whose mirrors disagree.
The refusal is E009-STATUS-MIRROR at exit 69. It fires BEFORE the mode registry is read, so the guard then reports workflowMode, auditProfile and targetStatus as UNRESOLVED. Those UNRESOLVED values are a symptom of the early exit. They are NOT evidence that a status ceiling is unsupported.
certification.* is bubbles.validate-owned, so every other agent has exactly one legal move:
- Do NOT advance
statusalone. A half-write leaves the spec unresolvable and every later guard run fails. - Do NOT hand-edit
certification.statusto match. That forges a certification record. - DO emit
route_requiredtobubbles.validatenaming the observed divergence.
This applies in both directions. A status that lags the spec's own scopes and execution record is still a bookkeeping defect that only bubbles.validate may correct.
route_required
target: bubbles.validate
reason: status-mirror divergence
feature: specs/<NNN-feature>
observed: status=<top-level value> certification.status=<mirror value>
evidence: <verbatim resolver or guard output showing the disagreement>
request: certify the transition the guard already passes, or restate status to match the evidence
What bubbles.validate does with that packet
bubbles.validate owns the repair and runs it through
state-certification-reconcile.sh,
which is dry-run by default:
bash bubbles/scripts/state-certification-reconcile.sh specs/<NNN-feature>
BUBBLES_AGENT_NAME=bubbles.validate bash bubbles/scripts/state-certification-reconcile.sh specs/<NNN-feature> --apply
The tool does not edit the mirror on request. It re-runs the transition guard
against a candidate in which the mirrors already agree, and writes
certification.status only on a PASS verdict. Exit 3 means the guard refused,
so the status is genuinely ahead of its evidence and the spec needs the work
finished or the status restated. The tool never invents certifiedAt and never
lowers top-level status.
Failure recovery
If any guard exits non-zero:
- Read the failing check label and the suggested remediation.
- Fix the underlying gap in the spec/artifact/code.
- Re-run the guard.
- Do NOT lower the status target. Do NOT add a bypass flag.
On E009-STATUS-MIRROR, read the detail line before diagnosing. It names both mirror values and the owning agent, and a contract-resolution refusal is never a defect in the framework's ceiling handling.
Authoritative modules
agents/bubbles_shared/state-gates.md— state-claim integrityagents/bubbles_shared/completion-governance.md— sequential completion, deferral blockingagents/bubbles_shared/scope-workflow.md— status ceiling enforcementbubbles/workflows/modes.yaml— per-modestatusCeilingdefinitionsbubbles/scripts/state-transition-guard.sh— mechanical guardbubbles/scripts/done-spec-audit.sh— historical grandfather + recertification
04 同仓库更多 Skills
smackerel-trace-capture
Wire Smackerel's concrete validate-plane stack into the framework trace-driven defect-discovery method. Use when running live-category tests (integration/e2e/e2e-ui/stress) against the ephemeral test stack; capturing SLO or trace evidence; hunting latency/error/perf bugs from spans; querying the test-stack Jaeger or Prometheus; or touching `.specify/runtime/observability`. Concrete smackerel endpoints + the exact `capture-slo.sh` command; do NOT duplicate `bubbles-observability-adapter` — this only adds the wiring.
smackerel-no-defaults
Enforce Smackerel's NO-DEFAULTS / fail-loud SST policy. Use when editing config, Docker Compose, deploy adapters, docs, instructions, skills, env handling, host bind addresses, or any runtime value that could be hidden by fallback syntax.
bubbles-workflow-mode-resolution
Resolve a Bubbles workflow mode against `bubbles/workflows.yaml`, including template inheritance, status ceilings, gate wiring, and decision policy. Use when picking a mode for a request, when a guard reports a mode-related failure, or when extending workflows.yaml with a new mode or template. Covers natural-language intent routing and the workflow registry consistency rules.
bubbles-workflow-execution-loops
Run per-round synchronous workflow execution loops correctly. Use when orchestrating a multi-round workflow, dispatching specialist subagents, handling round-based remediation, or interpreting a workflow mode's execution policy. Covers authorized direct execution, dispatch-and-wait, batch-then-summarize prohibition, and mapped-mode execution.
bubbles-vscode-agent-constraints
Design agents that fit the VS Code Copilot Chat runtime instead of fighting it. Use when authoring or editing any `*.agent.md`; when adding `tools:`, `agents:`, `handoffs:`, `model:`, `user-invocable:`, or `disable-model-invocation:` frontmatter; when designing an orchestrator that dispatches specialists; when a design implies agent-calls-agent-calls-agent chaining; when a subagent dispatch silently no-ops or an agent cannot be selected in the dropdown; or when writing a governance rule about delegation that the runtime cannot actually enforce. Prevents multi-level-subagent designs, prose-only dispatch laws, and frontmatter/body contradictions.
bubbles-upkeep-cadence
How to schedule, dispatch, and record recurring operational upkeep tasks (backup, restore-drill, BCDR-drill, patch-cycle, secret-rotation, flag-cleanup, compliance-sweep). Use when authoring or modifying `config/upkeep-calendar.yaml`, when investigating a missed task, when reading the upkeep ledger, or when adding a new task type.