| name | gsom-shell-promotion |
| description | Use when promoting a GSOM Research shell issue (parent contract defined, children undefined) into fully-specified Research child issues via a question-list-driven mapping. Generates §8.5-compliant child contracts with Evidence Bridge subsections and optionally materializes them via br create + br dep add. |
gsom-shell-promotion
Promotes a Governance-mode "shell" issue into one or more
§8.5-compliant Research children. The canonical source of truth for the
schema is the design note at
docs/superpowers/specs/2026-04-05-gsom-shell-promotion-skill-design.md
— this skill file is the deployment manifest, not a design document.
Status
Library-mode only. Direct CLI execution via npx tsx or bun run
is currently stubbed — running this file directly will print a usage
message and exit 1. The supported invocation surface is programmatic:
import and call the exported main() function with an injected
BrClient.
CLI wiring (real ChildProcessBrClient, direct execution path,
br update --notes, br sync post-create) is tracked as bd-1g33g.3
(blocked by this issue). This banner will be removed when bd-1g33g.3
closes.
When to use
Invoke this skill when you have:
- A Governance-mode shell issue whose description contains a
fully-specified parent contract (Purpose, Bucket, Doc Refs, Decision
Owner, Acceptance Criteria, Scope Out, Stop-the-Line Triggers) but
has no materialized children yet.
- A list of Research questions that each map one-to-one onto a
future child hypothesis. The Nth question pairs with the Nth
Acceptance Criteria item as the child's
evidence_class_expectation.
- Intent to create the children atomically, with each child
inheriting the shell's Bucket / Doc Refs / Decision Owner / Scope
Out, and each child wired back to the shell via a
blocked-by edge.
Do not use this skill to:
- Edit existing children (use
br update directly)
- Promote across epic boundaries (the shell's parent epic is authoritative)
- Reassign Decision Owner (inherited verbatim — override in the shell first)
Invocation
⚠️ CLI surface is stubbed. The shipped entry point today is
main() with an injected BrClient. Running the file directly via
npx tsx or bun run currently exits 1 without doing useful work.
See the §Status section above and bd-1g33g.3 for the plan.
CLI Invocation (pending bd-1g33g.3)
The CLI surface described here is the target shape for bd-1g33g.3.
It is not currently wired — direct execution is stubbed. This
subsection documents the eventual shape so callers can plan integration.
npx tsx apps/amnesia/tools/gsom-shell-promotion.ts \
--shell-id <bd-id> \
--questions "q1,q2,q3" \
[--dry-run]
Required flags:
| Flag | Meaning |
|---|
--shell-id <bd-id> | Dotted ID of the Governance shell issue (e.g., bd-1lghe.7). |
--questions "q1,q2,..." | Comma-separated list of Research questions. Each becomes a child hypothesis. Whitespace around commas is trimmed. |
Optional flags:
| Flag | Default | Meaning |
|---|
--dry-run | off | Print the generated child contracts to stdout without calling br create or br dep add. Safe to run repeatedly. |
Library Invocation (current)
The supported programmatic surface. Import main and a BrClient
implementation, then invoke with the same argv shape described above.
import { main, type BrClient } from 'apps/amnesia/tools/gsom-shell-promotion'
const brClient: BrClient = {
show: async (id) => { },
create: async (contract) => { },
depAdd: async (from, to) => { },
}
const result = await main({
argv: ['--shell-id', 'bd-xxxxx', '--questions', 'q1,q2', '--dry-run'],
env: process.env,
cwd: process.cwd(),
brClient,
})
process.exit(result.exitCode)
The flag semantics (--shell-id, --questions, --dry-run) are
identical to the CLI surface above — only the entry point differs.
Tests invoke main() directly with a stub BrClient; see
apps/amnesia/tools/__tests__/gsom-shell-promotion.test.ts for the
full injection pattern.
Behavior
Happy path (non-dry-run)
- Fetch the shell via
br show <shell-id>.
- Parse the shell description into structured fields (Purpose, Bucket,
Doc Refs, Decision Owner, Acceptance Criteria, Scope Out,
Stop-the-Line Triggers).
- Validate that the shell's Bucket is Research-eligible
(Observability / Research / Correctness / Performance / Architecture).
- For each question, generate a child contract via the source → target
mapping in design note §3, then validate it against the inlined
§8.5 validator.
- If all contracts validate, call
br create once per contract, then
br dep add <child-id> "blocked-by:<shell-id>" for each child.
- Print the promoted child IDs to stdout and exit 0.
Dry-run
--dry-run prints the full generated contracts — hypothesis, parent_id,
bucket, decision_owner, and the Evidence Bridge subsection — to stdout,
then exits 0 without calling br create or br dep add. Always run
with --dry-run first and review the plan before the real invocation.
Failure modes
| Mode | Trigger | Remediation |
|---|
shell_not_found | br show <shell-id> returned null. | Confirm the shell ID exists; run br show <id> manually to verify. |
wrong_parent_mode | Shell Bucket is not Research-eligible. | Update the shell to use a Research-eligible Bucket, or pick a different shell. |
shell_contract_incomplete | Shell is missing required fields (Purpose / Bucket / Doc Refs / Decision Owner / Acceptance Criteria). | Populate the missing fields on the shell via br update, then retry. The error message lists the specific missing fields. |
child_hypothesis_malformed | A question is empty after trimming, or the generated child fails §8.5 validation. | Check the --questions argument; ensure each comma-separated entry has non-whitespace content. |
br_unavailable | br show, br create, or br dep add threw. | Verify br is on PATH and the beads database is healthy. Check br sync --status for dirty state. |
All failure modes exit non-zero with a message prefixed by the mode name
on stderr. Exit codes are all 1 in the current release; richer
discrimination via distinct exit codes is a future enhancement.
Output
Non-dry-run (happy path) — stdout:
gsom-shell-promotion: promoted bd-1lghe.7 into 3 child(ren): bd-1lghe.7.1, bd-1lghe.7.2, bd-1lghe.7.3
The children are materialized in SQLite. Run br sync --flush-only -v
afterward to flush to JSONL per the standard post-mutation workflow.
Dry-run — stdout:
gsom-shell-promotion: dry-run plan for bd-1lghe.7
3 child contract(s) would be created:
[1] hypothesis: Does X converge under Y?
parent_id: bd-1lghe
bucket: Observability
decision_owner: amnesia-platform
evidence_bridge.motivation: Validate that X behaves under Y conditions
evidence_bridge.evidence_class_expectation: Decisive evidence artefact at apps/amnesia/docs/...
[2] ...
Example
Note: The CLI invocation shown in this example is the target
shape post-bd-1g33g.3. Today the same behavior is reached by calling
main() programmatically with an injected BrClient (see
§Invocation → Library Invocation above). The field mapping, dry-run
output, and failure-mode behavior are identical across both surfaces.
Given a shell bd-1lghe.7 with this description:
Purpose: Validate that tile-store convergence holds under H-scroll bursts.
Bucket: Observability
Doc Refs Read:
- docs/architecture/gold-standard-v2/ADR-005.md
Decision Owner: amnesia-platform
Acceptance Criteria:
1. Decisive evidence bundle at apps/amnesia/docs/perf-evidence/h-scroll-convergence/
2. Invariant INV-13 roster entry updated with status
Scope Out:
- No changes to canvas-state-machine.ts outside SET_ZOOM handler
Stop-the-Line Triggers:
- S2: any test produces a false PASS on convergence
Invoke:
npx tsx apps/amnesia/tools/gsom-shell-promotion.ts \
--shell-id bd-1lghe.7 \
--questions "Does H-scroll 8x converge within 5s?,Does post-pan dispatch reach idle?" \
--dry-run
You'll see two generated child contracts, each inheriting Bucket /
Doc Refs / Decision Owner / Scope Out from the shell, and each with an
Evidence Bridge subsection whose motivation quotes the shell's Purpose
and whose evidence_class_expectation quotes the shell's Acceptance
Criterion item 1 and 2 respectively. Review the plan, then re-run
without --dry-run to materialize.
Error handling
Each failure mode surfaces a message on stderr prefixed by the mode
name. Recovery steps by mode are listed in the table under "Behavior →
Failure modes" above. All modes are non-destructive in the shell: no
partial children are created and no shell state is mutated on failure.
For br_unavailable specifically, the CLI does not retry — the caller
should resolve the underlying br issue (PATH, database health, dirty
state) before re-invoking.
Authority and references
- GSOM-001 §6 — Work modes and mode-override rules
- GSOM-001 §8.5 — Research child contract schema
- Design note —
docs/superpowers/specs/2026-04-05-gsom-shell-promotion-skill-design.md (source of truth for field mappings)
- Implementation issue —
bd-1lghe.14
- CLI wiring follow-up —
bd-1g33g.3 (real ChildProcessBrClient, direct execution path, br update --notes, br sync finalization; blocked by bd-1lghe.14)