fix(ship): Step 18 marks the document-release subagent spawned — env prefix + auto-choose prompt (#2733)

The dispatch prompt now (1) frames the run as a SPAWNED subagent whose
LAST line is machine-parsed, (2) instructs prefixing the preamble's
gstack-skill-start invocation with GSTACK_SESSION_KIND=spawned on the
same command line (template bash blocks don't share exports), and
(3) resolves every AUQ gate to auto-choosing the recommended option,
conservative on no-recommendation, never destructive. The JSON contract
gains a required "decisions" array (auto-chosen gates, printed to the
ship console — never embedded in the public PR body) and a placement
clause so the skill's own doc-health summary stops competing with the
LAST-line JSON. Tripwire pins added; codex/factory goldens refreshed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-08-30 23:46:44 +00:00
co-authored by Claude Fable 5
parent 9c7b0a2c95
commit 791eb870c2
5 changed files with 54 additions and 20 deletions
@@ -69,6 +69,20 @@ describe('/ship Step 18 dispatches /document-release (carve visibility)', () =>
expect(content).toContain('.claude/skills/gstack/document-release/SKILL.md');
expect(content).toContain('## Step 19: Create PR/MR');
expect(content).toContain('Parent processing:');
// #2733: the dispatch marks the subagent spawned so document-release's
// AUQ gates auto-choose instead of prose-stopping (which breaks the
// parent's LAST-line JSON parse). Three layers pinned: the env marker
// prefix, the behavioral instruction, and the framing sentence.
expect(content).toContain('GSTACK_SESSION_KIND=spawned');
expect(content).toContain('auto-choose the RECOMMENDED option');
expect(content).toContain('as a SPAWNED subagent');
// Auto-chosen gate decisions ride the JSON contract (console-printed by
// the parent), never the public PR body.
expect(content).toContain('"decisions"');
const docHeading = content.indexOf('\n## Documentation\n');
expect(docHeading, 'PR-body template must carry the ## Documentation heading').toBeGreaterThan(0);
const docSection = content.slice(docHeading, content.indexOf('\n## Test plan\n'));
expect(docSection, 'decisions must never leak into the PR-body Documentation embed').not.toContain('decisions');
}
});