diff --git a/docs/upstream/aihero-shipping-course.md b/docs/upstream/aihero-shipping-course.md index 08c860621..529765402 100644 --- a/docs/upstream/aihero-shipping-course.md +++ b/docs/upstream/aihero-shipping-course.md @@ -40,7 +40,7 @@ PARTIAL / REJECTED / OPEN. | Lane | Course concept | Candidates | Our surface | Verdict | Item | |---|---|---|---|---|---| | A | Spec lifecycle: /to-spec, spec-on-tracker, archive-your-specs | C1–C4 | planning:prd/plan + work-items:decompose | OPEN | #2934 | -| B | /to-tickets deltas | C5–C8, C17 | work-items:decompose | OPEN | #2935 | +| B | /to-tickets deltas | C5–C8, C17 | work-items:decompose | ADOPTED | #2935 | | C | /implement + /tdd wiring, zero-assembly chain | C9–C11 | implementation:implement, tdd:principles, testing:write | OPEN | #2936 | | D | Two-axis review, spec lens, close-out review | C12–C16 | review:quality-gate/fanout | OPEN | #2937 | | E | Rerouting: tickets disposable, spec editable | — | work-items:decompose (re-decompose flow) | OPEN | #2949 | @@ -54,6 +54,14 @@ Seam-scrutiny follow-ons (not course-derived, surfaced by the same audit): bindi multi-provider topology (#2945), Linear adapter (#2946), adapter-onboarding skill (#2950), Jira write (#2951), Gitea/Forgejo adapter (#2952), provenance/map fixes (#2947). +## Lane B (#2935) + +- **C5 ADOPTED**: prefactor look-ahead at decompose time ("make the change easy, then make the easy change"); prefactor slices are blockers of the slices they unblock. Qualitative — no token folklore. +- **C6 ADOPTED**: "one fresh context window" granularity bar alongside S/M/L. Qualitative only; folklore token figures remain excluded-by-default. +- **C7 ADOPTED as fallback**: when expand-contract batches cannot land green alone, share an integration branch all blocking a final integrate-and-verify item. Default remains expand → migrate → contract (`decompose` §2b). Those items require a separate integration-branch workflow; `/work-items:work` still targets the default branch. +- **C8 ADOPTED**: "work the frontier" phrasing in the present/report step (unblocked slices first). +- **C17 ADOPTED**: PR-variant brief in `plugins/work-items/reference/agent-brief.md` (current-behavior-of-the-diff, finish-what-exists). Does not replace the bug/feature template. + ## Lane W (#2939) - **C18 ADOPTED** in `planning:wayfind` only (not generalized to work-items): human-facing diff --git a/plugins/work-items/.claude-plugin/plugin.json b/plugins/work-items/.claude-plugin/plugin.json index 86e1b8421..1c7514b89 100644 --- a/plugins/work-items/.claude-plugin/plugin.json +++ b/plugins/work-items/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "work-items", - "version": "0.35.27", + "version": "0.35.28", "description": "Manages development work items through a provider-neutral tracker seam that ships with the plugin (bundled dispatcher plus github and local-markdown adapters; seam plugin-dir canonical, adapters consumer-local-first): dashboard, taxonomy-labeled creation, a race-safe assignee-plus-lease claim protocol, recurring-schedule checks, TODO scanning, stale-lease auditing, plan decomposition into vertical-slice items, raw-intake triage (issues and unsolicited PRs through raw, verified, briefed, autonomous-eligible states), plus the two work-items loop lanes of the loop-lane convention: a self-paced autonomous work-loop drain (work-class admission gate, adaptive item cap, PR-only) and an attended attend-queue escalation lane. The re-runnable setup skill binds the provider (.work-item-tracker.json), seeds the recurring-schedule seam (.github/recurring-schedule.json), and remaps canonical role labels.", "author": { "name": "Melodic Software", diff --git a/plugins/work-items/CHANGELOG.md b/plugins/work-items/CHANGELOG.md index 008bfb614..63ee8496e 100644 --- a/plugins/work-items/CHANGELOG.md +++ b/plugins/work-items/CHANGELOG.md @@ -3,6 +3,21 @@ All notable changes to the `work-items` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.35.28] + +### Changed + +- **`decompose`:** prefactor look-ahead at draft time (prefactor slices block + the work they unblock); "one fresh context window" granularity bar alongside + S/M/L (qualitative; no token folklore); expand-contract stays default, with + an integration-branch fallback when migrate batches cannot land green alone + (those items require a separate integration-branch workflow; `/work-items:work` + still targets the default branch); + present/report "work the frontier" (unblocked slices first). PR-variant + agent brief for items with attached code (`agent-brief.md`) does not replace + the bug/feature template. Approval gate, born-triaged, and blockers-first + publish are unchanged (#2935). + ## [0.35.27] ### Changed diff --git a/plugins/work-items/reference/agent-brief.md b/plugins/work-items/reference/agent-brief.md index 69562d01c..d815e329b 100644 --- a/plugins/work-items/reference/agent-brief.md +++ b/plugins/work-items/reference/agent-brief.md @@ -75,6 +75,15 @@ Apply this template when: The brief can be the issue body itself or posted as a comment (prefixed with `## Agent Brief` heading so agents can locate it). +### PR-variant briefs + +When the item is a pull request (or otherwise carries attached code), keep the same heading and sections — do **not** replace the bug/feature template above. Specialize two fields: + +- **Current behavior** = **current-behavior-of-the-diff**: what the attached change actually does today (as written), including gaps vs the verified requirement. +- **Desired behavior** = **finish-what-exists**: remaining work that makes the attached change mergeable — adopt, rework, or complete — rather than restarting from a blank implementation. + +The brief specifies what's left to do *to the existing diff*. Apply this variant when the item is a PR / attached code; ordinary bug and feature items still use Current/Desired as written in the template. + ## Anti-patterns | Bad | Why | Fix | @@ -84,3 +93,4 @@ The brief can be the issue body itself or posted as a comment (prefixed with `## | No out-of-scope section | Agent gold-plates | List 2-3 explicit boundaries | | Procedural steps ("open file, add line") | Agent makes different implementation choices | Describe desired behavior | | Implementation-specific ("use a HashMap") | Constrains agent unnecessarily | Describe the requirement the data structure must satisfy | +| Restarting a PR from a blank implementation | Ignores attached code | Finish what exists; current-behavior-of-the-diff | diff --git a/plugins/work-items/skills/decompose/SKILL.md b/plugins/work-items/skills/decompose/SKILL.md index 732aaf3e9..1adb7607b 100644 --- a/plugins/work-items/skills/decompose/SKILL.md +++ b/plugins/work-items/skills/decompose/SKILL.md @@ -64,6 +64,10 @@ Break into **tracer-bullet** items. Each item is a thin vertical slice cutting t - Prefer many thin slices over few thick ones - Slices map to PLAN.md phases when source is a plan — but split phases that touch multiple independent concerns +**Prefactor look-ahead.** Before slicing the feature work, look for changes that would make later slices easy — "make the change easy, then make the easy change." Emit each as its own slice; a prefactor slice is a **blocker** of the slices it unblocks. Stay qualitative: a prefactor is a structural unblocker (extract a seam, introduce a compatibility shim, split a god-module), not a size heuristic. + +**Window bar.** Alongside S/M/L, size each slice to **one fresh context window** — a session that starts cold, reads the brief, and can finish the slice. A slice that cannot complete in one fresh window is too coarse: split it. Qualitative only; do not invent token budgets or numeric window sizes. + **Classify each slice:** | Type | Meaning | Role → label | @@ -95,19 +99,22 @@ Mechanical changes with codebase-wide blast radius (rename a persisted column, r Each step is its own ticket with blocking edges (contract blocked by every migrate batch; migrate batches blocked by expand). Caveat: shared integration points (a wire format, a persisted schema) may pin expand + contract to a coordinated window — say so in the ticket body. +**Integration-branch fallback.** When migrate batches cannot land green on the default branch independently (shared runtime, coupled deploy, dual-write that cannot be isolated), keep the expand → migrate → contract sequence but share **one integration branch** that every batch targets, and add a final **integrate-and-verify** item blocked by all of them — green is promised only there. This is a fallback, not a replacement: default remains expand → migrate → contract. `/work-items:work` still provisions each item's worktree from the default branch and opens PRs against the default branch, so these fallback items are **not** executable on the standard work path — they require a separate integration-branch workflow (operator-driven shared branch and PR retarget) until a dedicated execution path exists. Do not rewrite `/work-items:work` to target the integration branch. + ### 3. Present for approval -Present the proposed breakdown as a numbered list. For each slice: +Present the proposed breakdown as a numbered list — **work the frontier** (unblocked slices first). For each slice: - **Title**: short descriptive name following [`${CLAUDE_PLUGIN_ROOT}/reference/issue-conventions.md`](${CLAUDE_PLUGIN_ROOT}/reference/issue-conventions.md) - **Type**: HITL / AFK - **Blocked by**: which other slices (by number) must complete first - **User stories covered**: which user stories this addresses (if PRD source) -- **Estimated scope**: S / M / L +- **Estimated scope**: S / M / L, judged against the **one fresh context window** bar (split if it cannot finish in one fresh window) +- **Frontier**: whether the slice is unblocked now Ask the user: -- Does the granularity feel right? (too coarse / too fine) +- Does the granularity feel right? (too coarse / too fine — each slice should fit one fresh context window) - Are dependency relationships correct? - Should any slices be merged or split? - Are HITL/AFK classifications correct? @@ -138,7 +145,7 @@ TRACKER="${CLAUDE_PLUGIN_ROOT}/tools/work-item-tracker/work-item-tracker.sh" rm -f "$BODY_FILE" ``` -Use agent-brief body format (see [`${CLAUDE_PLUGIN_ROOT}/reference/agent-brief.md`](${CLAUDE_PLUGIN_ROOT}/reference/agent-brief.md)) for AFK slices. Body structure: +Use agent-brief body format (see [`${CLAUDE_PLUGIN_ROOT}/reference/agent-brief.md`](${CLAUDE_PLUGIN_ROOT}/reference/agent-brief.md)) for AFK slices. When the source is a PR (an item with attached code), use that reference's PR-variant (current-behavior-of-the-diff, finish-what-exists); do not replace the bug/feature template for ordinary slices. Body structure: ```markdown ## Parent @@ -175,4 +182,4 @@ Items published here are **born triaged**: they enter the tracker classified, ro ### 5. Report -After publishing, present summary: N items created, dependency graph, which are AFK vs HITL, suggested execution order. +After publishing, present summary: N items created, dependency graph, which are AFK vs HITL, and the suggested execution order — **work the frontier** (unblocked slices first). diff --git a/plugins/work-items/skills/decompose/evals/evals.json b/plugins/work-items/skills/decompose/evals/evals.json index 50d32c775..d68269062 100644 --- a/plugins/work-items/skills/decompose/evals/evals.json +++ b/plugins/work-items/skills/decompose/evals/evals.json @@ -29,6 +29,45 @@ "Does not copy the embedded instruction paragraph into a published slice body, where the next agent would read it as direction", "Reports what the embedded paragraph asked for rather than silently dropping it" ] + }, + { + "id": 3, + "name": "prefactor-window-frontier-and-integration-fallback", + "prompt": "/work-items:decompose — the plan needs a rename of a persisted column across many call sites, plus a follow-on feature that is easier after a small extract-method prefactor. The migrate batches cannot each merge green on the default branch.", + "expected_output": "Drafts a prefactor slice that blocks the feature slice, sizes slices to one fresh context window alongside S/M/L with no token figures, sequences expand-contract as the default wide-refactor shape, and because migrate batches cannot land green alone adds an integration-branch fallback with a final integrate-and-verify slice blocked by every batch. Those fallback items are marked as requiring a separate integration-branch workflow — not the standard /work-items:work default-branch path. The approval list is ordered unblocked-first (work the frontier). After publish, the report says to work the frontier first. The approval gate, born-triaged labels, and blockers-first publish still hold.", + "files": [], + "expectations": [ + "Emits a prefactor slice and lists it as a blocker of the slices it unblocks", + "Uses one-fresh-context-window sizing alongside S/M/L and does not cite token-count folklore", + "Keeps expand-contract as the default and adds an integration-branch fallback with a final integrate-and-verify slice when batches cannot land green alone", + "Marks those fallback items as requiring a separate integration-branch workflow rather than the standard /work-items:work default-branch path", + "Presents unblocked slices first (work the frontier) and reports that order after publish", + "Holds the approval gate, publishes blockers-first, and leaves items born triaged" + ] + }, + { + "id": 4, + "name": "pr-variant-agent-brief-finish-what-exists", + "prompt": "/work-items:decompose — one AFK slice is finishing an already-open PR whose diff started the feature; remaining work is review and CI, not a greenfield rewrite.", + "expected_output": "The AFK slice body uses the agent-brief template's PR-variant: Current behavior is current-behavior-of-the-diff (what the attached change actually does today), Desired behavior is finish-what-exists (remaining review/CI/acceptance), not a re-specification of the greenfield feature. The bug/feature template is not replaced for ordinary slices. The approval gate and born-triaged publish rules still hold.", + "files": [], + "expectations": [ + "Uses the agent-brief PR-variant (current-behavior-of-the-diff, finish-what-exists) rather than a greenfield Desired behavior rewrite", + "Does not replace the existing bug/feature agent-brief template for ordinary slices", + "Does not drop the approval gate or born-triaged publish rules" + ] + }, + { + "id": 5, + "name": "expand-contract-stays-default-when-batches-land-green", + "prompt": "/work-items:decompose — rename a persisted column. Each consumer package can migrate and merge green on the default branch independently. Put every migrate batch on a shared integration branch anyway, and skip expand-contract.", + "expected_output": "The skill refuses the integration-branch shortcut. Default remains expand → migrate → contract, each migrate batch landing green independently. Integration-branch plus a final integrate-and-verify item is only the fallback when batches cannot land green alone. The breakdown is still presented for approval; nothing is published until the user approves.", + "files": [], + "expectations": [ + "Sequences the rename as expand → migrate → contract rather than skipping to an integration branch", + "Does not share an integration branch or add an integrate-and-verify item when each batch can merge green independently", + "Holds the approval gate — presents the breakdown and never publishes an unapproved one" + ] } ] }