Skip to content

feat(pipeline-cli): intake-compose verb for the format-2 sub-issue body — one composer, not N re-derivations (#3688)#3703

Merged
usirin merged 1 commit into
mainfrom
usirin/3688-intake-compose-verb-96F9E5D0
Jul 20, 2026
Merged

feat(pipeline-cli): intake-compose verb for the format-2 sub-issue body — one composer, not N re-derivations (#3688)#3703
usirin merged 1 commit into
mainfrom
usirin/3688-intake-compose-verb-96F9E5D0

Conversation

@usirin

@usirin usirin commented Jul 19, 2026

Copy link
Copy Markdown
Member

Fixes #3688

What

Adds pipeline-cli intake-compose sub-issue — one tested composer that emits the format-2 sub-issue body of the gh-issue-intake-formats.md prose contract (§2) from a structured spec JSON, so a filer cites the verb instead of re-deriving the format by hand (#3254 / epic #3258).

How

Out of scope (per the issue): changing the prose contract's format itself, or the §CP path regex.

Acceptance criteria

  • A pipeline-cli intake-composer verb emits a format-2 body from structured inputs, with a pure unit-tested core.
  • The consumers that re-derive the format cite the verb; adoption-lint passes (full-corpus green test).
  • The composer's body handoff cannot reintroduce the -f body=@file leak (stdout-only, no --out; a command test covers the safe path).

Note

This is a §CP change (packages/pipeline-cli + the intake-format contract's consumer) — it banks for human approval, it does not auto-merge. The §CP path regex (CONTROL_PLANE_RE) and the format contract's meaning are unchanged; this is an extract-and-adopt only.

Guards run locally

pnpm typecheck (pipeline-cli, incl. new test files) clean · pnpm lint:worktree clean · pipeline-cli tests green (intake-compose 16, adoption-lint full-corpus 15, router/commands 13) · leak-guard scan clean on the diff · pre-commit + pre-push hooks passed.

🤖 Generated with Claude Code

@usirin

usirin commented Jul 19, 2026

Copy link
Copy Markdown
Member Author

review-code: advisory — blocking-set PR (manual merge)

§CP PR (packages/pipeline-cli/** + plan-epic/SKILL.md match CONTROL_PLANE_RE, resolved live from main), so this verdict authorizes nothing on its first line (ADR 0053/0111/0151). Re-review at the new head after the conflict-resolving rebase over #3695 / #3696 / #3697 — the prior verdicts at 48b4795d are superseded.

Reviewed-head: @ abf132d

Acceptance criteria (issue #3688)

  • [PASS] A pipeline-cli intake-composer verb emits a format-2 intake body from structured inputs, with a pure unit-tested core. compose.ts is IO-free (composeSubIssueBody + validateSubIssueSpec), covered by compose.unit.test.ts. Exercised behaviorally at head, not just read: a spec of {stories, tdd, whatToBuild, acceptanceCriteria[2]} emits the exact format-2 shape — **Stories:** / **TDD:** header, ### What to build, ### Acceptance criteria with - [ ] bullets.
  • [PASS] The consumers that re-derive the format cite the verb; adoption-lint passes. plan-epic now calls and cites pipeline-cli intake-compose sub-issue. adoption-lint run exactly as CI invokes it (62-file corpus, 7 declared decisions, plan-epic in scope): clean, exit 0. Verified non-vacuous by falsification — stripping the citation from a scratch copy of plan-epic/SKILL.md makes the new signature fire with the expected finding, so the green is earned rather than a signature that never matches.
  • [PASS] The composer's body handoff cannot reintroduce the -f body=@file leak. stdout-only by construction: there is no --out flag anywhere in the tool (the only two --out occurrences are prose explaining its deliberate absence), so there is no file to @-reference. command.test.ts covers the safe path.

Rebase-integrity checks (silent-revert class, #3678)

  • [PASS] adoption-lint/manifest.ts carries both epic-splice apply (feat(pipeline-cli): extract plan-epic epic-body splice into an epic-splice verb (#3689) #3697) and the new intake-compose sub-issue entries.
  • [PASS] registry.ts has epicSpliceCommand, orphanHealCommand, and intakeComposeCommand all both imported and registered — no import-without-registration half-revert.
  • [PASS] plan-epic/SKILL.md retains all 7 epic-splice citations (identical count to main) at lines 757–910, disjoint from this PR's intake-compose citations at lines 472/500.
  • [PASS] git diff origin/main...HEAD is exactly the 7 intended files (+473/−20); no landed sibling work reverted.

Gates at this head

  • [PASS] Full pipeline-cli suite: 115 files / 1622 tests green (intake-compose 16).
  • [PASS] pnpm typecheck clean.
  • [PASS] Format-2 hard floor enforced behaviorally: a zero-acceptance-criteria spec is rejected with the contract-§2 violation message and exit 2.
  • [PASS] No machine-local / absolute / home paths in the diff.

Observation (non-blocking)

The issue framed the migration as "~4 skills that re-derive the format (report / triage / plan-epic / …)"; this PR migrates one. That narrowing is correct, not a shortfall: the manifest signature discriminates a real format-2 filer by the co-occurrence of both section headings and a bare POST /issues create. Checked independently — report composes format-1 and already delegates to tracker create-issue; triage only mutates /issues/<N>; write-code reads format-2 but creates PRs, not issues. plan-epic is the only true filer, so the consumer set is genuinely 1.

Verdict: PASS on substance — recorded as advisory; a @kamp-us/control-plane approval at this head gates the merge.

@usirin

usirin commented Jul 19, 2026

Copy link
Copy Markdown
Member Author

review-skill: advisory — blocking-set PR (manual merge)

§CP PR (plan-epic/SKILL.md is a gate-skill path under CONTROL_PLANE_RE), so this verdict authorizes nothing on its first line (ADR 0053/0073 §5/0111/0151). Re-review at the new head after the conflict-resolving rebase over #3695 / #3696 / #3697 — the prior verdict at 48b4795d is superseded.

Reviewed-head: @ abf132d

Behavioral-artifact review — claude-plugins/kampus-pipeline/skills/plan-epic/SKILL.md

  • [PASS] The instruction change is coherent and executable. The child-creation step now composes the body via BODY="$(pipeline-cli intake-compose sub-issue --spec "$CHILD_SPEC_FILE")" and posts it with -f body="$BODY". I ran that exact command shape at head against a representative spec: it emits a well-formed format-2 body, so the documented invocation actually works rather than describing an aspirational verb.
  • [PASS] Cite-the-verb rule (Investigation: the adoption seam — what forces a skill to consume the CLI verb that owns its step? #3254) satisfied. The hand-re-derived ### What to build / ### Acceptance criteria heredoc is gone and replaced by a citation of the owning verb; the spec JSON the skill shows matches the tool's decoded schema field-for-field (stories / tdd / whatToBuild / acceptanceCriteria), so a reader following the skill literally produces a spec the verb accepts.
  • [PASS] The plan-epic cross-epic body bleed: parallel runs cross-contaminate child bodies (structural floor misses it) #754 /tmp collision guard survives the rewrite. The per-run mktemp /tmp/plan-epic-<EPIC>-child.XXXXXX is preserved — it now scopes the spec file rather than the body file — and the cross-epic body-bleed rationale is carried forward intact, not dropped along with the heredoc.
  • [PASS] Leak-class reasoning is accurate. The skill's claim that a stdout-only verb makes the gh api -f body=@<path> leak unreachable is verified against the tool: no --out flag exists, so the claim is grounded rather than asserted.
  • [PASS] No machine-local / absolute / home paths introduced in the prose or examples.

Rebase-integrity checks (silent-revert class, #3678)

Skill hygiene

Verdict: PASS on substance — recorded as advisory; a @kamp-us/control-plane approval at this head gates the merge.

@usirin

usirin commented Jul 19, 2026

Copy link
Copy Markdown
Member Author

§CP bank — reviewed-ready, awaiting control-plane approval.

Both gates PASS (advisory) at head 48b4795d:

  • review-code — #issuecomment-5017849663
  • review-skill — #issuecomment-5017851699

CI green. Per ADR 0135 this control-plane PR needs a non-author @kamp-us/control-plane approval at the current head before the approval-aware shipper may enqueue. Assigned to @cansirin + @notusirin.

notusirin
notusirin previously approved these changes Jul 20, 2026
…dy — one composer, not N re-derivations (#3688)

Add `pipeline-cli intake-compose sub-issue`: one tested composer that emits the
format-2 sub-issue body of the gh-issue-intake-formats.md prose contract (§2) from
a structured spec JSON, so a filer cites the verb instead of re-deriving the format
by hand (#3254 / epic #3258).

- Pure, unit-tested core (`compose.ts`): `composeSubIssueBody` emits the body
  deterministically; `validateSubIssueSpec` enforces the format-2 invariants (the
  ≥1-acceptance-criterion hard floor).
- The verb emits the body BY VALUE to stdout only (no `--out` file), so the caller
  captures it into `$BODY` and posts `-f body="$BODY"` — the `gh api -f body=@<path>`
  machine-local-path leak (#2002 / #754 / PR #1567) is structurally unreachable. A
  command test covers the safe path.
- Adopt same-commit: migrate plan-epic's child-body composition to call the verb and
  cite it; add the `intake-compose sub-issue` decision to the adoption-lint manifest
  (its signature isolates a real format-2 filer via the bare POST-/issues create tell,
  keeping the contract file and format-readers out of scope).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@usirin

usirin commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

Repair: rebased onto origin/main — merge conflict resolved

Was mergeable_state=dirty. Three siblings landed after this branch was cut: #3695, #3697 (epic-splice), #3696 (orphan-heal). Rebased onto origin/main; now mergeable=true, single commit, linear.

New head: abf132d7a43151247fcd058e601c18e99f787e68

Conflict surface. Only packages/pipeline-cli/src/tools/adoption-lint/manifest.ts conflicted — a purely additive collision where #3697's epic-splice apply entry and this PR's intake-compose sub-issue entry were appended at the same array slot. Resolved by keeping both. registry.ts and plan-epic/SKILL.md auto-merged; the plan-epic regions are disjoint as the prior review found (child-creation ~L468–500 here, epic-body splice ~L757+ from #3697).

No sibling entry was lost — verified post-rebase:

  • manifest.ts: both verb: "epic-splice apply" and verb: "intake-compose sub-issue" present.
  • registry.ts: all three of epicSpliceCommand, orphanHealCommand, intakeComposeCommand imported and registered in the command list.
  • plan-epic/SKILL.md: epic-splice apply citations at L757/792/799/839/850/854/910 intact alongside intake-compose sub-issue at L472/500.
  • Zero conflict markers repo-wide; PR touches exactly its own 7 files.

Guards re-run on the rebased head

  • pnpm typecheck — 33/33 tasks pass.
  • pnpm lint — 9 warnings, all pre-existing on main, none in any file this PR touches.
  • pipeline-cli adoption-lint checkclean on the full CI corpus (the workflow's own find selection, not a subset). Clearance is genuine, not a substring false-clear: stripping the pipeline-cli intake-compose citation from plan-epic/SKILL.md re-flags it with this entry's exact reason string, so the rule has teeth on a real consumer.
  • Tests — 115 files / 1622 tests pass; intake-compose alone 2 files / 16 tests.

The rebase moved the head, so the prior approval and verdicts are dismissed. Re-review needed.

@usirin

usirin commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

§CP re-bank — reviewed-ready at the NEW head, awaiting fresh control-plane approval.

This PR was rebased to resolve a conflict with landed #3697/#3696, which moved the head to abf132d7 and dismissed the prior approval + verdicts (ADR 0058).

Fresh gates both PASS (advisory) at abf132d7:

  • review-code — #issuecomment-5017849663
  • review-skill — #issuecomment-5017851699

Silent-revert scrutiny clean: registry.ts has epicSpliceCommand + orphanHealCommand + intakeComposeCommand all imported AND registered; manifest.ts carries both epic-splice and intake-compose decisions; plan-epic retains all 7 epic-splice citations.

Per ADR 0135 this needs a fresh non-author @kamp-us/control-plane approval at abf132d7 before the shipper may enqueue. @cansirin @notusirin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Intake composer verb for the gh-issue-intake-formats.md prose contract — one composer, not 4 re-derivations

3 participants