Skip to content

feat(work-items): add mini-SDLC pipeline-shape SSOT + wire work Step 5 to it - #861

Merged
kyle-sexton merged 3 commits into
mainfrom
feat/613-mini-sdlc-pipeline-ssot
Jul 21, 2026
Merged

feat(work-items): add mini-SDLC pipeline-shape SSOT + wire work Step 5 to it#861
kyle-sexton merged 3 commits into
mainfrom
feat/613-mini-sdlc-pipeline-ssot

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Stage 1 of the mini-SDLC umbrella (#513). The /work-items:work lane had no durable definition of the shape of the pipeline it runs per item — the lane catalog, the implementer ≠ reviewer ≠ verifier invariant, and the depth tiers lived only as evolving skill prose and per-issue plans, so the shape drifted and could not be scaled or reviewed in one place.

This PR adds the single source of truth for that stable policy and points the work skill at it:

Scope and honesty about current runtime

This stage lands the shape + wire-in only. The depth-scaling dispatcher and the separated-reviewer/verifier runtime are later #513 stages. The SSOT is written in normative (target-shape) voice and makes no claim that the work lane already depth-scales lanes or already fully separates the three roles today; rollout state is a single pointer to #513 rather than an inline stage-status section that would drift.

Nothing is locked: form, location, and name are a reversible reference-doc STOPGAP (OPERATOR DECISION 1 on #513, promotable to a skill later — naming-collision with session-flow:orchestrate / implementation:implement-dispatch flagged for that time), and the depth-tier names are placeholders (OPERATOR DECISION 2).

Fresh-docs verification

Per the repo fresh-docs mandate, confirmed this session from current official docs:

  • A plugin's reference/*.md supporting files are auto-discovered and referenced by relative path from SKILL.md — no manifest registration needed. https://code.claude.com/docs/en/plugins-reference (Skills: "automatically discovered", "supporting files alongside SKILL.md"; "The manifest is optional... auto-discovers components"), https://code.claude.com/docs/en/skills ("detailed reference documentation... Reference these files from your SKILL.md").
  • plugin.json version is an optional semver string; bump MINOR for new features and document in CHANGELOG.md. https://code.claude.com/docs/en/plugins-reference (version field; Version management). marketplace.json pins no version for work-items, so only plugin.json is bumped: 0.18.2 → 0.19.0 (rebased over a concurrent 0.18.2 patch that landed on the same plugin during review; reconciled so the 0.19.0 entry sits above 0.18.2 in the CHANGELOG and the minor bump stays the highest version).

Verification (local gates)

  • check-changelog-parity.sh --check-bump origin/main — PASS (0.19.0 entry present)
  • check-skill-portability.sh origin/main — PASS (no unexcused coupling tokens)
  • check-changed-skills.sh origin/main — PASS (0 errors; 1 pre-existing no-Gotchas warning)
  • validate-plugins.sh — PASS (all manifests + catalog)
  • markdownlint-cli2 + typos on changed files — clean
  • Independent fresh-context code review (producer ≠ reviewer) — changes-needed (minor) folded in: reworded four target-state-vs-present-tense spots so the SSOT defines the shape without claiming the runtime already depth-scales or fully separates roles, converted issue refs to the repo's #nnn code-span house style, fixed a re-anchor link text/target mismatch, and cited the settled sizing heuristic.

Closes #613

Related

🤖 Generated with Claude Code

…5 to it

Stage 1 of the mini-SDLC umbrella (#513): the work lane had no durable
definition of the *shape* of the pipeline it runs per item. The lane
catalog, the implementer != reviewer != verifier invariant, and the depth
tiers lived only as evolving prose and per-issue plans, so the shape
drifted and could not be scaled or reviewed in one place.

Add reference/pipeline-shape.md as the single source of truth for that
stable policy — the fixed lane set (explore -> research -> plan ->
devil's-advocate -> implement -> test -> review -> verify, re-anchor slot
reserved), the "variation in depth, never in shape" principle, the
role-separation invariant, and placeholder depth tiers carried as a plan
field. It points at the return-payload contract (#496) and convention-gap
protocol (#554) rather than restating them.

Wire work/SKILL.md Step 5 to dispatch against the SSOT for lane shape,
additively: the existing instruction to follow the consuming project's own
development workflow and domain rules is retained; the chain runs the shape
within the consumer's workflow, never in place of it.

Reversible reference-doc STOPGAP — form/location/name left to the operator
per #513 (OPERATOR DECISION 1). This stage lands the shape + wire-in only;
the depth-scaling dispatcher and separated-reviewer/verifier runtime are
later #513 stages, so the doc defines the target shape and claims nothing
about what the runtime already depth-scales or separates today.

Per-plugin bump 0.18.1 -> 0.19.0 (minor, new feature) + CHANGELOG entry.

Closes #613

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 2m 35s —— View job


PR Review: feat(work-items): add mini-SDLC pipeline-shape SSOT + wire work Step 5 to it

  • Gather context and classify request
  • Read changed files
  • Review pipeline-shape.md (new reference doc)
  • Review work/SKILL.md (step 5 wire-in)
  • Review plugin.json (version bump)
  • Review CHANGELOG.md (new entry)
  • Post findings

Summary

Clean, minimal Stage 1 of #513. No blockers. Two minor observations worth flagging for awareness, neither requiring changes before merge.


work/SKILL.md — Step 5 wire-in

The actual diff confirms the change is purely additive: one sentence inserted between dispatch is only *how* that workflow is carried out. and the #572 deferral note. No prior constraint language was removed. The ${CLAUDE_PLUGIN_ROOT} path reference is correct for plugin-form safety. ✅

The consumer-workflow primacy ("the dispatched chain runs that shape within the consumer's workflow and rules, never in place of them") lands cleanly alongside the existing MUST instruction. ✅


reference/pipeline-shape.md — new SSOT

What works well:

  • Target-state voice is consistently maintained throughout ("is being built to run", "the runtime already…makes no claim"). The doc defines policy without overstating runtime behavior. ✅
  • STOPGAP status, operator decision markers (1, 2), and the reversibility note are prominent and correctly placed. ✅
  • Issue refs all use the `#NNN` code-span house style. ✅
  • "Variation in depth, never in shape" principle + separation invariant are clearly owned here and nowhere else. ✅
  • Placeholder depth tier names in angle brackets signal their provisional status unambiguously. ✅
  • The "Contracts this shape composes" section correctly points at #496 and #554 rather than restating them. ✅

Observation 1 — Lane catalog references uninstalled skill names (expected, but worth recording)

The table at line 34–43 cites skill compositions including review:code-reviewer, review:quality-gate, verification:*, re-anchor:*, and tdd:principles that may not exist in this marketplace yet. The doc calls this out correctly ("the skills named are the intended realization of each lane, not a re-specification of their contracts"), so this is intentional — but it means a reader following these names today may find dead ends. Suggest adding a sentence to the lane catalog intro along the lines of "Not all named skills are installed in this marketplace today; the catalog defines intended realization, and #513 stages track their rollout." Or leave it to the STOPGAP/#513 pointer already present — either is defensible.

Observation 2 — Sizing heuristic cross-reference is opaque to future readers

Line 69: "matching the sizing heuristic settled in the #513 ACCEPTED decision brief" gives readers no inline anchor for what the heuristic actually is. This is a deliberate "point, don't restate" tradeoff (noted in the PR description), but if the heuristic can be named in a few words (e.g., "complexity × blast radius tiers") it would make this sentence navigable without opening #513. Not required — the pointer is sufficient given the explicit STOPGAP form.


plugin.json — version bump

0.18.2 → 0.19.0: correct MINOR bump for new feature (new reference file + SKILL.md pointer). ✅

Side note: the commit message body reads "Per-plugin bump 0.18.1 -> 0.19.0" — the from-version is stale (actual prior version was 0.18.2, per the CHANGELOG and the diff). The files are correct; the commit message line is cosmetically off. The PR description acknowledged this reconciliation explicitly, so it's recorded. Not a merge blocker.


CHANGELOG.md

The 0.19.0 entry is well-structured: Added + Changed sections, scope note at the end of the Added bullet, consistent format with prior entries. The scope note ("this stage lands the shape and the wire-in only…") correctly sets expectations without burying the lede. ✅


CLAUDE.md / design-rule alignment

Rule Status
Repo-agnostic (no hardcoded paths)
${CLAUDE_PLUGIN_ROOT} for within-plugin refs
Configurable without editing the plugin ✅ (reference doc, no new userConfig needed)
Plugin-form-safe (no ../ reach-outs)
No PII / secrets
Versioned with explicit semver
Security review (no code execution, no egress, no remote MCP)

No blockers. The two observations are informational; Observation 1 could optionally be addressed before merge but is not required.

@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 52s —— View job


Security Review

  • Gather PR diff and changed files
  • Review plugin.json changes
  • Review pipeline-shape.md (new reference doc)
  • Review SKILL.md change
  • Review CHANGELOG.md
  • Assess for injection surfaces, secrets exposure, and dangerous patterns
  • Post security findings

No security issues found.

All four changed files are documentation and policy content. Here is what was checked:

plugin.json (+1/-1) — a semver version bump from 0.18.20.19.0. No new permissions, no new userConfig keys, no new MCP server references, no egress changes. Existing userConfig entries (work_dispatch_concurrency_cap, work_cycle_batch_cap) are unchanged.

reference/pipeline-shape.md (+80/-0) — a new normative reference document describing the desired pipeline lane catalog and role-separation invariant. It contains no shell expansions, no templated variable substitutions, no command execution, and no external URLs. Issue references (#496, #513, #513, #554) are inert GitHub fragment links. No injection surface and no credential or secret exposure.

skills/work/SKILL.md (+1/-1) — one sentence added to Step 5 pointing ${CLAUDE_PLUGIN_ROOT}/reference/pipeline-shape.md as the lane-shape authority. The ${CLAUDE_PLUGIN_ROOT} interpolation is the plugin's standard read-only path variable already used throughout this file; no new expansion or execution path is introduced. The change is purely additive prose.

CHANGELOG.md (+26/-0) — changelog entries only. No security relevance.

No code execution paths, secrets handling, permission changes, dangerous GitHub Actions patterns, injection surfaces, or supply-chain risk were introduced by this PR.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6886035f8a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/work-items/reference/pipeline-shape.md Outdated
…hape SSOT

Address a review finding on #613: the SSOT names sibling-plugin skills
(discovery/planning/testing/review/verification) as each lane's realization
and states every lane always runs, but work-items installs standalone and
declares no dependency on those plugins. Clarify that the named skills are
each lane's *reference* realization and that where a lane's skill is not
installed the lane degrades to the consumer's own workflow for that stage
(the Step 5 anchor) rather than dead-ending — kept in target-shape voice,
consistent with the doc's no-current-runtime-claim disclaimer. No hard
dependency is declared: that is a later #513/dispatcher concern, not a
stage-1 STOPGAP decision.

Refs #613

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 1m 45s —— View job


PR Review: feat(work-items): add mini-SDLC pipeline-shape SSOT + wire work Step 5 to it

  • Gather context and classify request
  • Read git diff and changed files
  • Review latest commit (standalone-install lane fallback)
  • Review pipeline-shape.md
  • Review work/SKILL.md
  • Review plugin.json and CHANGELOG.md
  • Post findings

Summary

Two commits. The original feature (6886035) was reviewed comprehensively in the prior pass — no new concerns there. This review focuses on the synchronize trigger commit (91c0f89) and confirms the full PR is clean.


Latest commit — 91c0f89: standalone-install lane fallback

This commit addresses the Codex P1 finding ("Add fallbacks for independently installed plugins"). Two targeted edits to pipeline-shape.md:

Principle section (lines 24–27)
The realization collapse spectrum extends from two levels to three, adding "the consumer's own workflow step for that stage when no lane skill is installed" as the bottom rung. This is well-placed — it sits inside the existing parenthetical that already described collapse levels, so the structure is preserved. ✅

Lane catalog intro (lines 31–35)
Explicitly states work-items installs standalone, hard-depends on none of the named skills, and specifies the fallback: "degrade to the consumer's own workflow for that stage (the Step 5 anchor) rather than dead-end." Directly answers the dead-end concern. ✅

Scope check:

  • Target-state voice maintained throughout: "is to degrade" (not "degrades"). ✅
  • No hard dependency declared — correctly deferred to #513/dispatcher stage. ✅
  • The "Step 5 anchor" cross-reference is effective: SKILL.md Step 5 already mandates following the consumer's development workflow, so this ties the policy doc back to the existing runtime anchor without restating it. ✅
  • The Codex concern asked for per-lane conditionality or dependency declarations. The fallback is stated uniformly (applies to all lanes) rather than per-row in the table — that's correct, since the fallback mechanism is identical for every lane. A per-row repetition would add noise without clarity. ✅

One minor observation: The second commit touches only pipeline-shape.md; the 0.19.0 CHANGELOG entry is not updated to mention the fallback clarification. This is defensible — the fallback is a within-release refinement of the existing 0.19.0 feature, not a new addition. The entry's summary still accurately describes what shipped. Not a blocker.


plugin.json — version

0.19.0: correct MINOR bump for a new reference file + SKILL.md pointer. No new permissions, MCP servers, or userConfig keys. ✅


CLAUDE.md design-rule alignment

Rule Status
Repo-agnostic (no hardcoded paths)
${CLAUDE_PLUGIN_ROOT} for within-plugin refs
Configurable without editing the plugin
Plugin-form-safe (no ../ reach-outs)
No PII / secrets
Versioned with explicit semver
Security (no code execution, no egress, no remote MCP)

No blockers. The Codex P1 finding is adequately addressed. Ready to merge.

@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 59s —— View job


Security Review — PR #861

  • Gather context and load tools
  • Fetch PR diff
  • Review changed files for security issues
  • Post findings

No security issues found.

All four changed files are documentation and configuration metadata. Here is what was examined:

reference/pipeline-shape.md (+84/-0 / +12 in HEAD commit)
A new normative reference document. Contains no shell expansions, no template variable substitutions, no command execution, and no external URLs. The #NNN issue references are inert fragment anchors. No injection surface, no credential exposure, no PII.

skills/work/SKILL.md (+1/-1)
One sentence inserted in Step 5 pointing ${CLAUDE_PLUGIN_ROOT}/reference/pipeline-shape.md as the lane-shape authority — see permalink. ${CLAUDE_PLUGIN_ROOT} is the plugin's standard read-only path variable, already used throughout the file and system-controlled (not user-supplied). No path traversal risk, no new expansion or execution path, no new trust delegation.

plugin.json (+1/-1)
Semver version bump 0.18.2 → 0.19.0 only. No new permissions, no new userConfig keys, no new MCP server references, no egress changes, no supply-chain modifications.

CHANGELOG.md (+26/-0)
Changelog entries only. No security relevance.

No code execution paths, secrets handling, permission changes, dangerous GitHub Actions patterns, injection surfaces, or supply-chain risk introduced by this PR.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 91c0f89a81

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/work-items/reference/pipeline-shape.md
kyle-sexton added a commit that referenced this pull request Jul 21, 2026
Re-syncs onto main after #860 (fleet-wide `shell: bash` declaration sweep)
merged, which bumped source-control to 0.15.9, claude-ops to 0.17.2, and
repo-hygiene to 0.4.5. Resolved conflicts on those three plugins' plugin.json
and CHANGELOG.md; re-derived each held version against the new main plus a
fresh live-open-PR check rather than assuming the prior numbers still held:

- source-control 0.15.10: still one past main's 0.15.9 and #840's live 0.15.9
  claim.
- claude-ops 0.17.3: still one past main's 0.17.2 and #844's live 0.17.2
  claim.
- repo-hygiene 0.4.6: still one past main's new 0.4.5 (#860, now merged); no
  open-PR collision remains for this plugin.
- work-items 0.19.1 and guardrails 0.9.6 were untouched by this merge (no
  conflict) and remain correct against #857/#861 (both still 0.19.0, open)
  and no open collision, respectively.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1V3gkrfSf75isB8MiDy3o
kyle-sexton added a commit that referenced this pull request Jul 21, 2026
#857 (Jira Cloud adapter) merged into main since this branch's last rebase,
bumping work-items to 0.19.0. Resolved the resulting conflict, keeping this
branch's 0.19.1 (already one past both the new main and #861's still-open
0.19.0 claim, so no further bump needed). Re-verified all 5 plugins fresh
against current main and every live open PR (#840 0.15.10, #844 0.17.2, #861
0.19.0): source-control 0.15.11, claude-ops 0.17.3, repo-hygiene 0.4.6, and
guardrails 0.9.6 all remain correct with no change required.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1V3gkrfSf75isB8MiDy3o
kyle-sexton added a commit that referenced this pull request Jul 21, 2026
An unrelated claude-ops docs PR (#877, closing #864) merged since this
branch's last rebase and landed at exactly 0.17.3 — the same version this
branch was claiming. Re-bumped claude-ops to 0.17.4 to clear the exact
collision (plugin.json auto-merged to an identical-looking "0.17.3" string
without flagging a conflict, since both sides happened to write the same
literal text for unrelated reasons; caught by diffing main's version history
directly, not by trusting a clean auto-merge). CHANGELOG.md split into two
sections (0.17.3 for #877's actual change, 0.17.4 for this PR's).

Also swept for new open PRs against all 5 plugins post-merge: #870
(feat/800-audit-instructions) newly touches repo-hygiene (claims 0.4.5) and
claude-ops (claims 0.17.2) — both below this branch's current claims
(0.4.6 / 0.17.4), no collision. source-control (0.15.11), work-items
(0.19.1), and guardrails (0.9.6) re-confirmed against current main and every
live open PR (#840 0.15.10, #844 0.17.2, #861 0.19.0) — unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1V3gkrfSf75isB8MiDy3o
Resolve the work-items version/CHANGELOG collision with #857 (Jira adapter),
which took work-items to 0.19.0 after this branch also claimed 0.19.0. Stack
this branch's pipeline-shape SSOT bump to 0.20.0 with its own CHANGELOG
section above #857's 0.19.0 (Jira adapter) entry; both entries preserved.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 1m 45s —— View job


PR Review: feat(work-items): add mini-SDLC pipeline-shape SSOT + wire work Step 5 to it

  • Gather context and classify request
  • Read changed files at HEAD (ea33ac2)
  • Review merge commit — confirm no conflicts or regressions introduced
  • Review pipeline-shape.md at current HEAD
  • Review work/SKILL.md at current HEAD
  • Review plugin.json and CHANGELOG.md
  • Post findings

Summary

Three commits on this branch (6886035, 91c0f89, ea33ac2). The first two were reviewed comprehensively in prior passes — no new concerns there. This review focuses on the merge-from-main commit (ea33ac2) and confirms the full PR is clean at the current HEAD.


Merge commit — ea33ac2: Merge origin/main into feat/613-mini-sdlc-pipeline-ssot

The merge pulled in 19 commits from main. The only conflict surface was the work-items plugin version — the Jira adapter (#379) had landed on main as 0.19.0 while this branch was targeting the same version number.

Version reconciliation:

File main (0.19.0) Branch HEAD (0.20.0) Verdict
plugin.json "version": "0.19.0" "version": "0.20.0" ✅ Correct MINOR bump
CHANGELOG.md ## [0.19.0] (Jira adapter) at top ## [0.20.0] (pipeline-shape) above ## [0.19.0] ✅ Correct ordering

The bump is semantically correct: 0.20.0 is a MINOR release (new feature: new reference file + SKILL.md pointer) sitting above the Jira adapter's 0.19.0. No changelog entry is missing or misplaced. ✅

Observation — PR description version references are now stale. The description reads "0.18.2 → 0.19.0" throughout, reflecting the pre-merge intent. The actual bump landed as 0.19.0 → 0.20.0. This is cosmetic only — the committed files are correct — but a reader comparing the description to plugin.json will see a discrepancy. Not a merge blocker.


pipeline-shape.md at HEAD

ea33ac2 — 84 lines, unchanged from 91c0f89.

All findings from prior passes carry forward:

  • Target-state voice maintained throughout. ✅
  • Standalone-install fallback added in 91c0f89 addresses the Codex P1 finding. ✅
  • STOPGAP status, OPERATOR DECISION markers, and placeholder tier names are prominent. ✅
  • ${CLAUDE_PLUGIN_ROOT} path reference in work/SKILL.md is correct. ✅
  • Plan-lane approval-gate tension noted in Codex P2 is correctly deferred to #513/#715 (dispatcher stage). ✅

work/SKILL.md at HEAD

ea33ac2 — one sentence inserted in Step 5, purely additive. No merge conflict; the sentence sits cleanly alongside the existing instruction chain. ✅


CLAUDE.md design-rule alignment

Rule Status
Repo-agnostic (no hardcoded paths)
${CLAUDE_PLUGIN_ROOT} for within-plugin refs
Configurable without editing the plugin
Plugin-form-safe (no ../ reach-outs)
No PII / secrets
Versioned with explicit semver ✅ (0.20.0)
Security (no code execution, no egress, no remote MCP)

No blockers. The merge commit cleanly reconciled the version collision with the Jira adapter. The one observation (stale version reference in the PR description) is cosmetic and does not affect the committed files. Ready to merge.

@claude

claude Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 1m 14s —— View job


Security Review — PR #861

  • Gather context and classify request
  • Fetch PR diff
  • Review changed files for security issues
  • Post findings

No security issues found.

All four changed files are documentation and policy content. Here is what was checked:

plugin.json (+1/-1) — version bump 0.19.0 → 0.20.0 only. No new permissions, no new userConfig keys, no new MCP server references, no egress changes. Existing userConfig entries (work_dispatch_concurrency_cap, work_cycle_batch_cap) are unchanged.

reference/pipeline-shape.md (+84/-0) — new normative reference document defining the per-item pipeline lane catalog and role-separation invariant (permalink). Contains no shell expansions, no template variable substitutions, no command execution, and no external URLs. The #NNN issue references are inert GitHub fragment anchors. No injection surface, no credential exposure, no PII. The file will be read as instruction content by the Claude Code runtime — this is the intended use case; the content is normative policy text with no user-controlled interpolation or adversarial prompt patterns.

skills/work/SKILL.md (+1/-1) — one sentence added to Step 5 pointing ${CLAUDE_PLUGIN_ROOT}/reference/pipeline-shape.md as the lane-shape authority (permalink). ${CLAUDE_PLUGIN_ROOT} is a system-controlled read-only path variable already used throughout this file — not user-supplied and not externally injectable. The path is a static within-plugin reference with no ../ traversal. No new trust delegation, no new execution path.

CHANGELOG.md (+26/-0) — changelog entries only. No security relevance.

No code execution paths, secrets handling, permission changes, dangerous GitHub Actions patterns, injection surfaces, or supply-chain risk introduced by this PR.

kyle-sexton added a commit that referenced this pull request Jul 21, 2026
claude-ops: #844 rebased and re-derived its claim from 0.17.2 to 0.17.4,
colliding exactly with this branch's prior 0.17.4. Bump to 0.17.5.

source-control: a new PR, #882 (fix/511-babysit-self-identity-decouple),
claims 0.16.0 — a minor bump above this branch's prior 0.15.11 and above
#840's 0.15.10. Bump to 0.16.1 to stay ahead of both.

repo-hygiene (0.4.6), guardrails (0.9.6), and work-items (0.19.1) were
re-verified fresh against current main and every live open PR
(main: repo-hygiene 0.4.5, guardrails 0.9.5, work-items 0.19.0; #861 0.19.0)
and remain correct, no change needed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1V3gkrfSf75isB8MiDy3o
kyle-sexton added a commit that referenced this pull request Jul 21, 2026
#844 (claude-ops) merged into main at exactly 0.17.4, which this branch's
prior 0.17.5 was already one past — kept as-is, no re-bump needed for the
number itself, just resolved the resulting plugin.json/CHANGELOG.md conflict.

Full fresh collision sweep after the merge found claude-ops now has NO open-PR
collision at all. It also found #861 (work-items) re-derived its own claim
from 0.19.0 to 0.20.0 since the last check (following #857's Jira-adapter
minor bump into main) — colliding with this branch's prior 0.19.1. Re-bumped
work-items to 0.20.1.

source-control (0.16.1, held behind #882's 0.16.0 and #840's 0.15.10),
repo-hygiene (0.4.6, no collision), and guardrails (0.9.6, no collision)
re-verified against current main and all live open PRs — unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1V3gkrfSf75isB8MiDy3o
@kyle-sexton

Copy link
Copy Markdown
Contributor Author

This was generated by AI (decide lane — decision-brief pass; parked PR-thread decision surfaced via periodic scan).

Decision brief — Plan lane vs. autonomous execution. Parking a decision surfaced in review thread discussion_r3624454271 (Codex P1 "Preserve autonomous execution when plan approval is unavailable"). The author verified the tension as VALID and left the thread open, deferring to the #513/#715 dispatcher stage without marking a remedy RECOMMENDED. This brief rules the constraint now and scopes the mechanism to #715.

Problem

The shape's mandatory Plan lane routes every autonomous /work-items:work item through /planning:plan, whose Step 5 is a human-approval gate. If the future dispatcher runs that lane at full realization, an unattended run parks the moment it finishes planning and never reaches implementation — silently, after already claiming the item and holding a lease.

Today

  • Plan lane = /planning:plan. pipeline-shape.md:41 names it the lane's realization; pipeline-shape.md:24 — "A lane is never skipped," so every autonomous item hits this lane.
  • The gate is human-specific and terminal. planning/skills/plan/SKILL.md:210 "the user approves, modifies, or rejects it before execution begins"; :206 "the user is the terminal gate (deterministic check → human)"; :341 "the approval gate is the point — it's where human judgment enters the loop." The gate's designed purpose is injecting human judgment, not merely a second pair of eyes.
  • /work-items:work claims then dispatches autonomously. work/skills/work/SKILL.md:181 — orchestrator claims + dispatches after acquiring the lease; there is no approval handoff or autonomous planning path. The autonomous frontier filter list-frontier --autonomous (:130) only excludes the needs-human role label — it does not mean "this plan is pre-approved."
  • Nothing reads the shape yet. The dispatcher that would route the lane is #715 (Stage 2), unbuilt (pipeline-shape.md:74); pipeline-shape.md makes no claim about runtime today. So the conflict is latent, not live.

Blocked or ruleable?

Split. The constraint is ruleable now; the mechanism is blocked on #715 — and blocked by a real design dependency, not just ownership. pipeline-shape.md:25-27 says a lane's realization collapses (fresh-context subagent → inline lightweight check → consumer's own workflow step). A shallow-tier Plan lane may be a gateless inline check that never invokes /planning:plan Step 5 at all. So whether the gate even fires depends on how #715 specifies the shallow-Plan collapse. Codex's "parks immediately" is therefore conditional — it assumes the collapsed Plan lane still routes through full /planning:plan. The mechanism can't be correctly chosen until #715 settles that collapse spec.

Options

➡️ RECOMMENDED — Record the binding constraint now; defer the mechanism to #715/#572.
Rule as policy, in #715's frame: an autonomous run must never silently park at a human-judgment gate, and whichever mechanism #715 picks must preserve independent human judgment over the plan (producer ≠ approver — the plan's author cannot self-approve). This is the tie-breaker across the three remedies below and subsumes the author's "defer" disposition while making it actionable — #715 inherits a constraint, not an open question. Reversibility: high (a recorded constraint, no runtime committed). If autonomous dispatch (#572) ships before #715, adopt Option 2 as the interim posture in the meantime.

Option 1 — Autonomous-safe planning variant (gateless Plan lane). Changes the skill the lane uses. Rejected as a standalone. planning/skills/plan/SKILL.md:341/:206 make the gate specifically a human-judgment injection; a gateless variant doesn't just let the producer self-approve — it deletes the human judgment the gate exists for, violating the invariant this whole PR holds (implementer ≠ reviewer ≠ verifier, extended to producer ≠ approver). Viable only if it substitutes an independent approver — which is Option 3, not a bare gate removal. Reversibility: medium (new skill surface to unwind).

Option 2 — Stop-before-claim (interim posture). Don't claim work that would stall at the gate. Caveat, not a free reuse: since the Plan lane is never skipped (:24), "skip items needing planning" would starve the lane of everything. It only works as a policy extension — move the human's approval to triage-time eligibility (an item is marked autonomous-eligible only once its plan/approach is pre-approved), pre-satisfying the plan gate for eligible items. Today's needs-human is a role label, not "this plan needs approval," so this extends the triage state machine, it does not merely reuse the existing filter. Reversibility: high (label/selection policy, no new mechanism). Best interim answer if dispatch ships before #715.

Option 3 — Approval-handoff mechanism. The autonomous run parks the plan to an async approval surface (human, or a designated distinct approver) and resumes on approval — never discarding the work. Preserves producer ≠ approver and keeps the work alive; it is the richest durable answer, and the natural home for #715/#572 to build. Reversibility: low (a new mechanism + lifecycle state). Do not build ahead of #715's collapse spec.

Cross-links

  • #513 / #715 — mini-SDLC umbrella / Stage-2 Opus complexity-dispatcher; owns lane routing and the shallow-Plan collapse spec this decision depends on.
  • #572 — autonomous orchestrator-dispatch lifecycle (branch/worktree provisioning, PR-creation ownership); the approval-handoff / stop-before-claim seam lives on this same autonomous lifecycle surface.
  • #304 — fresh-eyes / producer ≠ reviewer checkpoint; the same-context-bias principle that grounds "producer ≠ approver" here.

kyle-sexton added a commit that referenced this pull request Jul 21, 2026
#882 (source-control) merged into main at 0.16.0, which this branch's prior
0.16.1 was already one past — resolved the resulting plugin.json/CHANGELOG.md
conflict, kept as-is.

Full fresh collision sweep after the merge found source-control now carries
TWO additional open PRs beyond #840: #895 (fix/548-babysit-worktree-head-safety,
claims 0.15.10) and #898 (feat/399-shared-worktree-helper, claims 0.17.0 — a
minor bump above this branch's prior 0.16.1). Re-bumped source-control to
0.17.1 to stay ahead of all three (#898's 0.17.0, #895's and #840's 0.15.10).

claude-ops (0.17.5, no collision), work-items (0.20.1, held behind #861's
0.20.0), repo-hygiene (0.4.6, no collision), and guardrails (0.9.6, no
collision) re-verified against current main and all live open PRs — unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1V3gkrfSf75isB8MiDy3o
@kyle-sexton

Copy link
Copy Markdown
Contributor Author

Tower merge (delegation, veto window open): CLEAN, all checks green, 0 unresolved threads (all rounds classified + resolved), version restacked to 0.20.0 post-collision. Closes #613 — mini-SDLC stage 1 SSOT lands. This was generated by AI (control tower, session 6).

@kyle-sexton
kyle-sexton merged commit b447754 into main Jul 21, 2026
23 checks passed
@kyle-sexton
kyle-sexton deleted the feat/613-mini-sdlc-pipeline-ssot branch July 21, 2026 23:25
kyle-sexton added a commit that referenced this pull request Jul 25, 2026
… as deliberate (#853)

## Summary

Closes the design fork raised in #820: whether the shell assert-helper
duplicated across
5 plugins (and the divergent per-script exit-code taxonomies alongside
it) should be
consolidated into a shared mechanism, or documented as deliberate. This
PR documents.

## Fix

- Adds `docs/conventions/shell-test-helpers/README.md` as the owner doc
explaining why the
duplication and divergence stay as-is, and registers it in
`docs/PLUGIN-PHILOSOPHY.md`'s
  convention registry table.
- Adds a one-line pointer comment at each copy site back to the owner
doc:
`guardrails/hooks/guardrails-test-helpers.sh`,
`claude-ops/hooks/claude-ops-test-helpers.sh`,
`source-control/scripts/test-helpers.sh`,
`repo-hygiene/skills/clean/scripts/lib/test-helpers.sh`,
  `work-items/tools/work-item-tracker/tests/lib.sh`.
- Adds the same kind of pointer to
`scripts/check-skill-portability.test.sh`, which opted out
for an unrelated reason (it's repo tooling, not a plugin, so no plugin
assertion library
applies) — noted so the fork's second observation isn't left
unexplained.
- Bumps `plugin.json` + adds a `CHANGELOG.md` entry for every plugin
whose helper file gained
the pointer comment. Each has been re-derived from current `main` many
times as sibling PRs
  merged or rebased mid-flight (see Related for the current picture):
  - `repo-hygiene`: 0.4.4→0.4.6
  - `source-control`: 0.15.7→0.16.1
  - `claude-ops`: 0.17.1→0.17.5
  - `work-items`: 0.18.1→0.20.1
  - `guardrails`: 0.9.5→0.9.6 (no open-PR collision at any point so far)

No behavior change anywhere — comments and docs only.

## Decision

**Chose Option B: document the per-plugin duplication and exit-code
divergence as deliberate.
No shared helper introduced.**

Investigation before deciding:

- This repo already has one sanctioned cross-plugin shared-source
mechanism: a canonical file
under `lib/` (e.g. `lib/hook-utils.sh`), copied — not imported — into
each carrying plugin by
a dedicated `scripts/sync-*.sh`, tracked in
`scripts/cross-plugin-source-registry.txt`, and
  drift-checked by `scripts/check-cross-plugin-source-drift.sh --check`.
- That mechanism is scoped to clusters meant to stay **byte-identical**.
Running
`check-cross-plugin-source-drift.sh discover` confirms it never even
flags the five
assert-helper files as a cluster candidate — they live at different
paths per plugin and
are not byte-identical, so they fall outside that mechanism's scope
entirely.
- Reading all five files: they are already three genuinely different
shapes, not one library
that drifted — a hook-contract shape (`guardrails`/`claude-ops`:
`ok`/`bad`, `PASS`/`FAIL`,
`make_sink`/`wait_for_sink`), a skill-script shape
(`source-control`/`repo-hygiene`: `pass`/`fail`,
`FAILED`/`CASE_NUM`, file-existence assertions), and a vendored-seam
shape (`work-items`: same
primitives, but owned by the seam itself so it stays correct wherever
the seam is resolved
  from, independent of this repo's tooling).
- Consolidating would mean designing a fourth, unified assertion API and
rewriting every
existing `*.test.sh` onto it — a bigger, riskier change than the
coupling it would remove,
and it would cross the plugin-independence boundary
`docs/PLUGIN-PHILOSOPHY.md`'s design
boundary section already draws (no plugin imports files from a sibling
plugin).
- Exit-code taxonomies (`remove-path.sh` 0/1/2/3/4,
`git-tree-reset-batch.sh` 0/1/2 forwarding
a child's 5/7, `check-skill-portability.sh` 0/1/2) encode genuinely
different per-script
contracts, not arbitrary numbering — each script already documents its
own `Exit:` line, and
a shared usage/exit helper would either flatten those contracts or grow
per-caller branching.
- Deferred, not rejected: `guardrails-test-helpers.sh` and
`claude-ops-test-helpers.sh` are the
one pair that already share a shape closely. If they converge to
byte-identical, vendoring
just that pair through the existing `lib/` + `sync-*.sh` + registry
mechanism is the smaller,
precedented move — recorded as the trigger in the owner doc rather than
acted on now.

## Verification

- `shellcheck` clean on all 6 edited shell files.
- Full `check-skill-portability.test.sh` suite: 16/16 pass.
- `check-cross-plugin-source-drift.sh --check`: no unregistered or
drifted clusters.
- `check-changelog-parity.sh --check`: passes with every version bump.
- Ran every `*.test.sh` that sources an edited helper
(repo-hygiene/clean, guardrails hooks,
claude-ops hooks, work-items adapters/lib) — all green, confirming the
comment-only edits
  changed no behavior.
- `markdownlint-cli2` and `lychee` clean on the new and modified docs.

## Related

- Scope note: issue #820's title says "disk-hygiene/clean", but
`disk-hygiene` is Python-only
(`hygiene.py`) with no shell assert-helper — the actual duplication
lives in the 5 plugins
the issue body names (repo-hygiene, source-control, guardrails,
claude-ops, work-items) plus
root `scripts/`. Treating the title as a triage typo (disk-hygiene vs.
repo-hygiene, both
"-hygiene" plugins with a `clean` skill) rather than touching
disk-hygiene.
- **`do-not-merge` held.** This session has had exceptionally heavy
concurrent-lane traffic
against these same 5 plugins — this PR has been rebased/re-derived nine
times as siblings
merged (#839, #826, #857, #877, #870, #844) or rebased in place (#840,
#882, #861, each more
than once). Current picture, last verified fresh at commit `e75e45ed`
(`mergeable: MERGEABLE`;
all 5 plugins re-checked against current `main` AND every live open PR):
- `repo-hygiene` (claims 0.4.6): no open-PR collision. Main is at 0.4.5.
- `source-control` (claims 0.16.1): held behind **#882**
(`fix/511-babysit-self-identity-decouple`,
claims 0.16.0, open) and **#840** (claims 0.15.10, open). Main is at
0.15.9.
- `claude-ops` (claims 0.17.5): **no open-PR collision anymore** — #844
(the PR this leg was
previously held behind) has merged, landing at exactly 0.17.4; this
claim stays one past it.
    Main is at 0.17.4.
- `work-items` (claims 0.20.1): held behind **#861**
(`feat/613-mini-sdlc-pipeline-ssot`). #861
itself has re-derived its claim twice as `main` moved — from 0.19.0 up
to 0.20.0 (following
#857's Jira-adapter minor bump into main) — so this PR's claim moved
from 0.19.1 to 0.20.1 to
    stay ahead. Main is at 0.19.0.
  - `guardrails` (claims 0.9.6): no open-PR collision. Main is at 0.9.5.
- This plugin set has produced a new collision within minutes of nearly
every prior check —
including siblings re-deriving their own claims upward more than once,
an unrelated PR
landing at the exact same version by coincidence, and legs clearing and
new ones opening.
Re-run the full collision protocol (`gh pr list --repo
melodic-software/claude-code-plugins
--state open --json number,headRefName,files` filtered per plugin, AND a
fresh diff of each
plugin's version on `main` since this PR's last rebase) immediately
before removing
    `do-not-merge` — do not trust this snapshot.

Closes #820

Work-class: C2 (mechanical) — attended triage 2026-07-23,
operator-ratified. 🤖

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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.

mini-SDLC stage 1: durable pipeline-shape SSOT + work-skill wire-in (child of #513)

1 participant