feat(lifecycle): sub-issue board hygiene — parent-aware gates + reconciler-owned de-boarding#283
Merged
Merged
Conversation
Extend the issue-state GraphQL read with the native parent link (IssueState.parent_number) and give every gate and --groom-entry a closed sub_issue verdict that reroutes an OPEN parented issue to its parent, instead of misrouting a task unit to grooming from its own (noise) board stage. Reproduced #263 misroute is a regression fixture. Refs #266 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…se/groom-verify best-effort de-board + docs The reconciler's closed repair set grows to six: an OPEN native sub-issue carrying its own board item is archived (reversible, hides from views) with an audit comment naming the parent — the Project tracks the parent. --decompose and --groom-verify best-effort de-board the subs they touch; --groom-verify surfaces still-boarded subs as warnings, never failures, because the auto-add CI races verification. lifecycle.md and the route-reference verdict tables document rule 6 and the sub_issue verdict. Refs #267 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rule 6 and treat archived board items as not-on-board Two review-confirmed defects in the sub-issue de-boarding change: - The global reconcile sweep only enumerated the four late-stage status columns, so a CI-auto-added sub-issue (which lands with no Status) never reached rule 6 — the convergence guarantee failed for exactly the async-add race it was built for. The sweep now also covers no:status, stub, brainstormed, and planned. - projectItems includes archived items by default, so a de-boarded sub still presented its item on re-read, re-firing rule 6 with a duplicate audit comment every run. ISSUE_QUERY now selects isArchived and parse_issue_state treats archived items as not-on-board, making de-boarding idempotent against real GraphQL. Also: verb_gate/verb_groom_entry threading pinned by verb-level tests, _deboard_subissue never-raises contract extended to malformed JSON, rule-ordering and provenance-ordering freezes added (164 tests, was 157). Refs #265 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collaborator
Author
Comprehensive review record (wf-review)Three lenses ran against the risk surface (acceptance-criteria conformance, Python correctness/failure handling, test sufficiency). Findings and dispositions:
Both P1 fixes were re-verified by the original finding reviewer: CONFIRMED-RESOLVED, no new defects; residual Acceptance-criteria lens: PASS on all 11 criteria across #265/#266/#267, including an empirical failing-then-passing check of the regression fixture against main (54 failures pre-change, 0 post-change). Final gates on HEAD c120a12: 164 unittest OK · bun test 426 pass · typecheck clean · skills:check 20 copies in sync · docs current. Review verdict: ready (no unresolved P1/P2). |
Merged
aagnone3
added a commit
that referenced
this pull request
Jul 22, 2026
…doff for sub-issues Complements the sub_issue gate verdict and reconciler rule 6 shipped in PR #283: --claim refuses an OPEN sub-issue with a structured sub_issue_claim error before any board write; --backfill reads candidate parentage in one batched GraphQL query and skips parented issues (reported as skipped_sub_issues) instead of add-then-archive churn; the planning ready boundary now requires handoffs to name the parent as the sole wf-development entry point.
aagnone3
added a commit
that referenced
this pull request
Jul 22, 2026
…doff for sub-issues (#280) * feat(lifecycle): claim guard, backfill exclusion, and parent-only handoff for sub-issues Complements the sub_issue gate verdict and reconciler rule 6 shipped in PR #283: --claim refuses an OPEN sub-issue with a structured sub_issue_claim error before any board write; --backfill reads candidate parentage in one batched GraphQL query and skips parented issues (reported as skipped_sub_issues) instead of add-then-archive churn; the planning ready boundary now requires handoffs to name the parent as the sole wf-development entry point. * docs(lifecycle): document the sub_issue_claim refusal in claim semantics
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #265
Summary
Makes the lifecycle engine sub-issue-aware so the board matches the committed design ("the Project tracks the parent"):
sub_issuegate verdict (feat(lifecycle): parent-aware issue state + sub_issue gate verdict #266). The issue-state GraphQL read now selects the nativeparent { number }link (IssueState.parent_number). Every gate (--gate <cmd>) and--groom-entryshort-circuits an OPEN parented issue to a new closedsub_issueverdict carryingparent: Nand anextinstruction — no gate ever routes a task unit to grooming from its own (noise) board stage. The reproduced docs(wf-skills): state owned lifecycle transitions as observable postconditions in the wf-* routers #263 misroute (route_to_planfor a sub-issue of a planned parent) is a regression fixture.gh project item-archive— reversible via--undo) with an audit comment naming the parent.--decomposeand--groom-verifybest-effort de-board the subs they touch;--groom-verifyreports still-boarded subs aswarnings(never failures — the auto-add CI fires asynchronously and can land after verification; the TTL-cached reconciler is the convergence guarantee).lifecycle.mddocuments rule 6, thesub_issueverdict row, and the auto-repaired board-membership invariant; verdict tables inworkflows-work.md,workflows-plan.md, andworkflows-brainstorm.mdgained thesub_issuerow. Vendored script copies synced.Key decisions: archive (not delete) as the removal primitive — reversible and non-destructive; rule 6 evaluated before the stage-regression rules (de-boarding supersedes Status repair on a noise stage); terminal (CLOSED) sub-issues untouched.
Testing
sub_issuererouting, the docs(wf-skills): state owned lifecycle transitions as observable postconditions in the wf-* routers #263 regression fixture, rule-6 pure-core + integration (archive + audit comment, idempotent second run, CLOSED/parentless untouched, rule-ordering preemption, CI-add-after-verify race, failed-archive reporting), decompose/groom-verify de-board seams and warnings.python3 -m unittest plugins/agentic-engineering/tests/lifecycle_board_test.py(157 OK),bun test(426 pass),bun run typecheck,bun run skills:check(20 copies in sync),bun run docs:build && bun run docs:check.--gate work --issue 266returnedverdict: sub_issue, parent: 265against the real board.Post-Deploy Monitoring & Validation
repairs_applied[].rule == "sub_issue_on_board"andrepairs_failed[].error_code == "deboard_failed".python3 plugins/agentic-engineering/scripts/lifecycle_board.py --gate work --issue <open-sub>→verdict: sub_issuewith the correctparent.python3 plugins/agentic-engineering/scripts/lifecycle_board.py --reconcile --force→ any leaked open sub-issue (e.g. docs(wf-skills): state owned lifecycle transitions as observable postconditions in the wf-* routers #263/test(plugin): guardrail — every owned lifecycle transition maps to an engine procedure and read-back #264 if still boarded) leaves the board with an audit comment; a second run is a no-op.stubtask units on the board; gates never tell an agent to groom a sub-issue.deboard_failederrors → revert the PR (the rule is additive; archived items are restorable viagh project item-archive --undoor--backfill).