From 40a3fd53ebbed4e26e7707274728c7a8ab3aab0e Mon Sep 17 00:00:00 2001 From: Dan Moisan Date: Tue, 11 Aug 2026 09:28:19 -0400 Subject: [PATCH 1/2] docs(research): promote parallel-surface blockers to issues #545/#546 Planning /parallel-plan for Lanes B-M halted before any delegation. Two report-only defects promoted through the MCP lifecycle so they survive outside a planner session: - #545: config/blast-radius.json was pushed down verbatim in #544 and describes the governance payload's layout, not TaskMaster's. Verified via Get-BlastRadius/Test-BlastRadiusConflict: the mandatory docs/features/active//** glob falls under module docs, making the conflict graph a clique (fully serial execution), while TaskMaster.sln, Directory.Build.targets, .editorconfig, coverage.config and .github/workflows/** are absent from shared_surfaces (real build-file collisions dropped silently under F1a). - #546: the 2026-08-10 research doc records the cohort library as absent from both repos. It exists at .claude/lib/bash/compute-cohorts.sh and upstream at scripts/dev_tools/parallel_cohort_computation.py; the false negative came from git grep alternation without -E. Also records the second, independent blocker in agent memory: depends_on is a prohibited key at every level of the parallel surface (parallel-orchestration.md invariant 10, M7), so "lanes parallel, issues within a lane sequential" is inexpressible there. Lane work should use /epic-plan per lane, where waves express intra-lane ordering natively. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01DQp1dund9kqDP8ye2wzCdk (cherry picked from commit 17d96c01a59fc23337fb9eb9d5354b9db3d83bd3) --- .../agent-memory/parallel-planner/MEMORY.md | 3 +- ...roject_parallel_cannot_express_ordering.md | 30 +++++ .../project_parallel_surface_partial_port.md | 71 ++++++----- ...-radius-config-not-ported-to-taskmaster.md | 111 ++++++++++++++++++ ...earch-doc-cohort-library-false-negative.md | 85 ++++++++++++++ 5 files changed, 270 insertions(+), 30 deletions(-) create mode 100644 .claude/agent-memory/parallel-planner/project_parallel_cannot_express_ordering.md create mode 100644 docs/features/potential/promoted/2026-08-11-blast-radius-config-not-ported-to-taskmaster.md create mode 100644 docs/features/potential/promoted/2026-08-11-research-doc-cohort-library-false-negative.md diff --git a/.claude/agent-memory/parallel-planner/MEMORY.md b/.claude/agent-memory/parallel-planner/MEMORY.md index 2299e3ed..749ab865 100644 --- a/.claude/agent-memory/parallel-planner/MEMORY.md +++ b/.claude/agent-memory/parallel-planner/MEMORY.md @@ -1,4 +1,5 @@ # Parallel Planner Memory Index -- [Parallel surface is a partial port](project_parallel_surface_partial_port.md) — cohort computation never landed in TaskMaster or drm-copilot; /parallel-plan cannot reach a ready checkpoint +- [Parallel surface port status + config blocker](project_parallel_surface_partial_port.md) — infra landed via PR #544, but config/blast-radius.json is unfit for C#/VSTO and yields zero parallelism +- [Parallel surface cannot express ordering](project_parallel_cannot_express_ordering.md) — depends_on/wave are prohibited; lane-sequential or flight-ordered work belongs to /epic-plan - [drm-copilot is the governance upstream](reference_drm_copilot_upstream.md) — check it when a rule/config/library a skill references is missing locally diff --git a/.claude/agent-memory/parallel-planner/project_parallel_cannot_express_ordering.md b/.claude/agent-memory/parallel-planner/project_parallel_cannot_express_ordering.md new file mode 100644 index 00000000..78168f48 --- /dev/null +++ b/.claude/agent-memory/parallel-planner/project_parallel_cannot_express_ordering.md @@ -0,0 +1,30 @@ +--- +name: parallel-surface-cannot-express-ordering +description: The parallel surface expresses ordering only as blast-radius contention; any "A must land before B" requirement needs the epic surface instead +metadata: + type: project +--- + +The `parallel` surface cannot express a required order between items. `depends_on` and `wave` are +prohibited keys in both the run manifest and the planner checkpoint, and cohorts are derived purely +from computed blast-radius contention. + +**Why:** the surface was designed for thematically unrelated items that share no dependency edge. +Contention only guarantees that two conflicting items do not run *concurrently* — it says nothing +about which runs *first*, because cohort indices come from Welsh-Powell degree ordering +(`(-degree, item_key)` ascending), not from intent. Requesting ordering from the operator is +explicitly out of scope for the planner. + +**How to apply:** when an operator frames work as lanes with sequential items, or as ordered flights +("fix the coverage gates before certifying anything against them"), that is a dependency graph. +Route it to `/epic-plan` + `/epic-orchestrate`, which model explicit `depends_on` edges and wave +layering. Do not attempt to encode the ordering as artificially widened blast radii — the skill +forbids manipulating a radius to steer the conflict graph, and widening to force serialization is the +same manipulation as narrowing to suppress it. + +A second, subtler gap: items outside the run's manifest are invisible to cohort scheduling. If +another surface (an epic, a manual branch) is concurrently editing shared build, coverage, or CI +surfaces, the parallel run cannot see the contention and will schedule against gates that are +actively changing. Check for in-flight work on shared surfaces before planning a run. + +See [[parallel-surface-partial-port]] for the current port status and the config blocker. diff --git a/.claude/agent-memory/parallel-planner/project_parallel_surface_partial_port.md b/.claude/agent-memory/parallel-planner/project_parallel_surface_partial_port.md index 207c6728..885937dc 100644 --- a/.claude/agent-memory/parallel-planner/project_parallel_surface_partial_port.md +++ b/.claude/agent-memory/parallel-planner/project_parallel_surface_partial_port.md @@ -1,40 +1,53 @@ --- name: parallel-surface-partial-port -description: The parallel orchestration surface is only partially ported into TaskMaster from drm-copilot; cohort computation never landed in either repo, so parallel-plan cannot reach a ready checkpoint +description: The parallel surface is now structurally present in TaskMaster (PR #544) but config/blast-radius.json was pushed down verbatim and is unfit for the C#/VSTO layout, so parallel-plan yields zero parallelism metadata: type: project --- -As of 2026-08-10 the `parallel` orchestration surface in TaskMaster is an **incomplete port** from -the upstream [[drm-copilot-is-claude-governance-upstream]] repo. Verify current state before -relying on this — the gaps are expected to close as the port continues. +Status as of 2026-08-11. Supersedes the 2026-08-10 assessment, which was wrong on one hard blocker. +Verify against the repo before relying on this. -**Present in TaskMaster:** `.claude/lib/blast-radius/*.psm1` (PowerShell port, includes -`Test-BlastRadiusConflict`), `.claude/hooks/enforce-parallel-*.ps1`, the six `.claude/skills/parallel-*` -skills, both `.claude/agents/parallel-*.md`, and settings.json hook wiring. The MCP validators -`parallel-planner-state` and `parallel-kickoff` dispatch correctly (verified by probe). +**Structurally present now.** PR #544 ("(chore): push down claude parallel orchestrator", merged to +`main` as `2073f717`) landed the governance payload from [[drm-copilot-is-claude-governance-upstream]]: +`.claude/rules/parallel-orchestration.md`, `config/blast-radius.json`, `route_id: parallel` in +`config/orchestration-routing.json`, and `.claude/lib/bash/compute-cohorts.sh` + +`parallel-cohorts.sh`. Already present before that: `.claude/lib/blast-radius/*.psm1`, +`.claude/hooks/enforce-parallel-*.ps1`, the six `parallel-*` skills, both `parallel-*` agents. MCP +`parallel-planner-state` and `parallel-kickoff` dispatch correctly. -**Missing in TaskMaster:** `config/blast-radius.json`, `.claude/rules/parallel-orchestration.md`, -and `route_id: parallel` in `config/orchestration-routing.json` (routes are only small, large, -remediation, preparation, epic). +**Cohort computation is NOT missing — the earlier verdict was a false negative.** `compute_cohorts` +exists upstream at `scripts/dev_tools/parallel_cohort_computation.py` (commit `663d71ee`, issue #445) +with `compute_concurrency_batches`, and TaskMaster now has the bash entry point +`.claude/lib/bash/compute-cohorts.sh` (no Python or Poetry required; emits compact JSON identical to +the Python authority). The 2026-08-10 "absent from both repos" finding came from +`git grep -in "compute_cohorts|welsh"` **without `-E`** — git grep defaults to basic regex, so the +`|` was matched literally and the search could never hit. Always pass `-E` when using alternation. -**Missing in BOTH repos:** the cohort-computation library (`compute_cohorts` / Welsh-Powell -coloring). `git grep -in "compute_cohorts|welsh"` returns nothing tracked in drm-copilot. The -`feature/parallel-cohort-scheduler-445` branch and its feature folder exist, but no code landed; -the parallel epic merged F7/F8 (hooks, drift, schemas, validators) without it. +**The real remaining blocker: `config/blast-radius.json` is unfit for this repo.** It was pushed +down verbatim and describes the governance payload's own layout, not TaskMaster's. It lists modules +`.claude/**`, `config/**`, `docs/**`, `tests/**` and shared surfaces `.claude/settings.json`, +`config/orchestration-routing.json`, `config/blast-radius.json`. Verified consequences (probed +directly through `Get-BlastRadius` / `Test-BlastRadiusConflict`): -**Why:** the parallel surface was built in drm-copilot and is being distributed into consumer repos -like TaskMaster; the port is mid-flight and F2 (cohort scheduler) was never implemented upstream. +1. **Zero parallelism.** `Get-BlastRadius` always appends the feature-folder glob + `docs/features/active//**`, and module `docs` maps to `docs/**`, so *every* item carries + module `docs` and every pair conflicts with reason `module_overlap`. The conflict graph is a + complete graph, Welsh-Powell yields one cohort per item, and an N-item run is fully serial. +2. **Fail-open on real collisions.** TaskMaster's actual root shared surfaces (`TaskMaster.sln`, + `Directory.Build.targets`, `.editorconfig`, `coverage.config`, `.github/workflows/**`) are not in + `shared_surfaces`. Per the F1a rule, a separator-free root token is admitted only as an exact + member of that list, so a plan editing `coverage.config` or `Directory.Build.targets` produces a + radius that does not mention them at all. Two items editing the same build config are reported + non-conflicting once the `docs` edge above is removed. +3. **C# projects attribute to no module.** None of the 9 production or 9 test project directories + (`QuickFiler/`, `UtilitiesCS/`, `ToDoModel/`, ...) appear in `modules`; `tests/` in TaskMaster + holds only `scripts/` (PowerShell), not the C# test projects. -**How to apply:** `/parallel-plan` cannot produce a valid ready checkpoint in TaskMaster. Cohort -seeding and the P5 recomputation-parity check both require the absent library, and self-implementing -the coloring would make the parity check compare an implementation against itself. Halt and report -rather than fanning out preparation delegations. Note also that the skill's -`poetry run python -c "from scripts.dev_tools..."` invocation form does not apply here: TaskMaster has -no `scripts/dev_tools/`, no `pyproject.toml`, and no `poetry.lock` — the port is PowerShell. - -Also note drm-copilot's `config/blast-radius.json` is **not** reusable in TaskMaster: its modules -(`scripts/dev_tools`, `packages/mcp-server`, `extensions/drm-copilot`) and shared surfaces -(`poetry.lock`, `package-lock.json`) describe drm-copilot's own layout, not a C#/VSTO repo. Copying -it would under-report contention, the opposite of the fail-closed direction the F1a corrections -(issue #452 / PR #453) established. +**How to apply:** treat `/parallel-plan` as unable to produce a *useful* run until +`config/blast-radius.json` is authored for TaskMaster (enumerate the real `.csproj` module set and +the real root shared surfaces, and keep the feature-folder glob from collapsing the graph). Fixing it +is a design decision about which surfaces are shared in a C#/VSTO repo, so promote it as an issue +rather than editing the just-merged config inside a planner run. Separately, the parallel schema +prohibits `depends_on` and `wave`, so any requirement of the form "these items must land in a given +order" belongs to `/epic-plan`, not to this surface — see [[parallel-surface-cannot-express-ordering]]. diff --git a/docs/features/potential/promoted/2026-08-11-blast-radius-config-not-ported-to-taskmaster.md b/docs/features/potential/promoted/2026-08-11-blast-radius-config-not-ported-to-taskmaster.md new file mode 100644 index 00000000..0fa01f9b --- /dev/null +++ b/docs/features/potential/promoted/2026-08-11-blast-radius-config-not-ported-to-taskmaster.md @@ -0,0 +1,111 @@ +# blast-radius-config-not-ported-to-taskmaster (Issue #545) + +- Date captured: 2026-08-11 +- Author: Dan Moisan +- Status: Promoted -> docs/features/active/blast-radius-config-not-ported-to-taskmaster/ (Issue #545) + +> Automation note: Keep the section headings below unchanged; the promotion tooling maps each of them into the GitHub bug issue template. + +- Issue: #545 +- Issue URL: https://github.com/drmoisan/TaskMaster/issues/545 +- Last Updated: 2026-08-11 +## Summary + +`config/blast-radius.json` was pushed down verbatim from the `.claude` governance payload (PR #544) and describes that payload's own directory layout rather than TaskMaster's. As a result the parallel orchestration surface produces a complete conflict graph (zero parallelism) while simultaneously failing to detect real collisions on TaskMaster's build-level shared surfaces. + +## Environment + +- OS/version: Windows 11 Pro 10.0.26200 +- Python version: n/a — the blast-radius port in TaskMaster is PowerShell (`.claude/lib/blast-radius/*.psm1`) +- Command/flags used: `Get-BlastRadius`, `Test-BlastRadiusConflict` from `.claude/lib/blast-radius/BlastRadius.psm1` +- Data source or fixture: `config/blast-radius.json` at commit `2073f717` + +## Steps to Reproduce + +1. Check out `main` at `2073f717` (or later). +2. Import `.claude/lib/blast-radius/BlastRadius.psm1`. +3. Call `Get-BlastRadius` for two items in unrelated lanes touching unrelated C# files (for example issue 480 touching a `QuickFiler` source file and issue 287 touching a `ToDoModel` source file). +4. Call `Test-BlastRadiusConflict` on the resulting pair. +5. Separately, call `Get-BlastRadius` for two items that both edit `coverage.config` and `Directory.Build.targets`. + +## Expected Behavior + +- Step 4: two items editing unrelated C# projects should report `conflict=False`, allowing them to be colored into the same cohort and executed concurrently. +- Step 5: two items editing the same root build files should report those files in their shared-surface sets and report `conflict=True` with a shared-surface reason. + +## Actual Behavior + +- Step 4 reports `conflict=True reasons=[module_overlap]`. `Get-BlastRadius` always appends the mandatory feature-folder glob `docs/features/active//**` (`BlastRadius.psm1:171`), and module `docs` maps to `docs/**`. Every item therefore carries module `docs`, every pair overlaps, the conflict graph is a clique, and Welsh-Powell yields one cohort per item. A 59-item run would execute fully serially. Observed pairs: + + ``` + A(480 QuickFiler.cs) vs B(287 ToDoModel.cs) truly independent conflict=True reasons=[module_overlap] + A(480) vs E(468) same QuickFiler .csproj conflict=True reasons=[module_overlap] + ``` + +- Step 5 reports empty shared-surface sets. TaskMaster's real root shared surfaces are absent from `shared_surfaces`, and under the F1a rule a separator-free root token is admitted only as an exact member of that list, so it is dropped silently: + + ``` + C(512) paths: [docs/features/active/2026-08-11-c-512/**] shared: [] + D(494) paths: [docs/features/active/2026-08-11-d-494/**] shared: [] + ``` + + The real collision is invisible, masked only incidentally by the degenerate `docs` edge. Correcting the module map alone would turn this into a reported false negative. + +- Additionally, none of the nine production or nine test C# project directories appear in `modules`, so C# work attributes to no module. `tests/` in TaskMaster contains only `scripts/` (PowerShell), not the C# test projects. + +## Logs / Screenshots + +- [x] Attached minimal logs or snippet +- Snippet — the committed config as of `2073f717`: + + ```json + { + "version": 1, + "shared_surfaces": [ + ".claude/settings.json", + "config/orchestration-routing.json", + "config/blast-radius.json" + ], + "shared_surface_globs": [], + "modules": { + "claude-runtime": [".claude/**"], + "config": ["config/**"], + "docs": ["docs/**"], + "tests": ["tests/**"] + }, + "over_breadth_fraction": 0.25 + } + ``` + +## Impact / Severity + +- [x] Blocker +- [ ] High +- [ ] Medium +- [ ] Low + +Blocker for the parallel orchestration surface specifically: the surface is unusable in TaskMaster until the truth table reflects this repository. The current state is fail-closed on parallelism (serial execution, which is safe but delivers nothing) and fail-open on build-surface collisions (which is not safe once the clique is fixed). + +## Suspected Cause / Notes + +The governance push-down (`c1c10c3b`, "(chore): push down claude parallel orchestrator") copied `config/blast-radius.json` verbatim from the source payload. The file is repository-shape-specific data, not portable governance, so verbatim push-down is the wrong transport for it. + +Files to inspect: + +- `config/blast-radius.json` +- `.claude/lib/blast-radius/BlastRadius.psm1` (line 171 appends the mandatory feature-folder glob) +- `.claude/rules/parallel-orchestration.md` (F1a shared-surface admission rule) + +## Proposed Fix / Validation Ideas + +- [ ] Enumerate the nine production/test `.csproj` directory pairs as `modules` entries so C# work attributes to a real module. +- [ ] Add TaskMaster's real root shared surfaces to `shared_surfaces`: `TaskMaster.sln`, `Directory.Build.targets`, `.editorconfig`, `coverage.config`, plus `.github/workflows/**` via `shared_surface_globs`. +- [ ] Resolve the `docs` module so the mandatory feature-folder glob stops collapsing the conflict graph into a clique. Options: narrow `docs` to the non-feature documentation subtrees, or exclude the per-item feature-folder glob from module attribution. +- [ ] Unit coverage areas: Pester tests over `Get-BlastRadius` module attribution and `Test-BlastRadiusConflict` for (a) two unrelated C# items → no conflict, (b) two items sharing a root build file → conflict with a shared-surface reason, (c) two items in the same `.csproj` → conflict. +- [ ] Integration scenario to retest: seed a two-item generation-0 cohort table and confirm both items color into the same cohort. +- [ ] Manual verification notes: re-run the two probes above and confirm the reported reasons invert. + +## Next Step + +- [x] Promote to GitHub issue (bug-report template) +- [ ] Move to active fix folder / branch diff --git a/docs/features/potential/promoted/2026-08-11-research-doc-cohort-library-false-negative.md b/docs/features/potential/promoted/2026-08-11-research-doc-cohort-library-false-negative.md new file mode 100644 index 00000000..f9de1942 --- /dev/null +++ b/docs/features/potential/promoted/2026-08-11-research-doc-cohort-library-false-negative.md @@ -0,0 +1,85 @@ +# research-doc-cohort-library-false-negative (Issue #546) + +- Date captured: 2026-08-11 +- Author: Dan Moisan +- Status: Promoted -> docs/features/active/research-doc-cohort-library-false-negative/ (Issue #546) + +> Automation note: Keep the section headings below unchanged; the promotion tooling maps each of them into the GitHub bug issue template. + +- Issue: #546 +- Issue URL: https://github.com/drmoisan/TaskMaster/issues/546 +- Last Updated: 2026-08-11 +## Summary + +`docs/research/2026-08-10-parallel-bug-flighting-and-surface-blockers.md` records the cohort-computation library as absent from both TaskMaster and drm-copilot and instructs the next reader to treat it as new work. The library exists in both repositories. The document's unblock checklist therefore sends a reader to reimplement code that is already present. + +## Environment + +- OS/version: Windows 11 Pro 10.0.26200 +- Python version: n/a for the TaskMaster entry point (bash); the upstream authority is Python +- Command/flags used: `git grep -in "compute_cohorts|welsh"` (the original, defective verification) +- Data source or fixture: `docs/research/2026-08-10-parallel-bug-flighting-and-surface-blockers.md` at commit `41213a1c` + +## Steps to Reproduce + +1. Read §2.1 and §7 item 1 of `docs/research/2026-08-10-parallel-bug-flighting-and-surface-blockers.md`. +2. Observe the claim that `compute_cohorts` (Welsh-Powell coloring) does not exist in TaskMaster or in drm-copilot, and that closing the blocker is "new work, not a port." +3. Check `.claude/lib/bash/compute-cohorts.sh` in TaskMaster. +4. Check `scripts/dev_tools/parallel_cohort_computation.py` in drm-copilot. + +## Expected Behavior + +The research document's blocker inventory should reflect the actual state of both repositories, so that a reader resuming the plan closes only the blockers that are genuinely open. + +## Actual Behavior + +Both files exist: + +- TaskMaster carries a bash entry point at `.claude/lib/bash/compute-cohorts.sh` (present at commit `2073f717`, executable, 4463 bytes). It requires neither Python nor Poetry, so the skill's `poetry run python -c "from scripts.dev_tools..."` invocation form is not the applicable one here. +- The upstream authority is `C:\Users\DanMoisan\repos\drm-copilot\scripts\dev_tools\parallel_cohort_computation.py` (commit `663d71ee`, issue #445). + +The P5 recomputation-parity concern recorded alongside the blocker is also resolved: the bash port documents itself as reproducing the Python authority's output byte-for-byte, so a parity check compares two independent implementations rather than a module against itself. + +## Logs / Screenshots + +- [x] Attached minimal logs or snippet +- Snippet: + + ``` + $ ls -la .claude/lib/bash/compute-cohorts.sh + -rwxr-xr-x 1 DanMoisan 197121 4463 Aug 11 09:19 .claude/lib/bash/compute-cohorts.sh + ``` + +## Impact / Severity + +- [ ] Blocker +- [x] High +- [ ] Medium +- [ ] Low + +High rather than Blocker: the document is a resumable plan of record explicitly intended to be read instead of re-deriving the analysis. A false "does not exist, build it" entry in its unblock checklist causes duplicated implementation work and misdirects attention away from the one blocker that is genuinely open (the blast-radius truth table). + +## Suspected Cause / Notes + +The verification used `git grep -in "compute_cohorts|welsh"` without `-E`. `git grep` defaults to basic regular expressions, so the `|` was matched as a literal pipe character and the search could not match either token. The negative result was recorded as a confirmed absence. + +Sections to correct: + +- §2.1 (surface-blocker analysis) +- §7 item 1 (unblock checklist) +- Any P5 recomputation-parity note that depends on the absence claim + +## Proposed Fix / Validation Ideas + +- [ ] Correct §2.1 and §7 item 1 to record both files as present, with their paths and commits. +- [ ] Note the `git grep` basic-regex pitfall inline so the correction is self-justifying to a later reader. +- [ ] Update the P5 parity note to reflect that two independent implementations exist. +- [ ] Restate the remaining open blocker (the TaskMaster-specific `config/blast-radius.json` truth table) as the single item gating the parallel surface. +- [ ] Unit coverage areas: n/a — documentation-only change. +- [ ] Integration scenario to retest: n/a. +- [ ] Manual verification notes: confirm both cited paths resolve at the recorded commits before publishing the correction. + +## Next Step + +- [x] Promote to GitHub issue (bug-report template) +- [ ] Move to active fix folder / branch From 5829033865b4d07228da34528e415e5dac40b720 Mon Sep 17 00:00:00 2001 From: Dan Moisan Date: Fri, 14 Aug 2026 22:01:00 -0400 Subject: [PATCH 2/2] docs(memory): rescue stranded epic-orchestrator and epic-planner memories These ten agent-memory files were left uncommitted in the worktree at TaskMaster-wt/2026-08-10T13-56, whose branch (TaskMaster-wt-2026-08-10T13-56) is already a strict ancestor of main. Removing that worktree during merged- worktree cleanup would have destroyed them, so they are consolidated here before deletion. Both MEMORY.md index edits are pure appends over main's current content (verified with a CR-normalized diff): 2 new epic-orchestrator entries and 6 new epic-planner entries, each pointing at one of the 8 new memory files. No existing entry is modified or removed. Co-Authored-By: Claude Opus 5 (1M context) --- .../agent-memory/epic-orchestrator/MEMORY.md | 2 + ...back_prepared_epic_stale_child_branches.md | 25 ++++++++++ ...roject_child_pr_ci_gap_integration_base.md | 28 +++++++++++ .claude/agent-memory/epic-planner/MEMORY.md | 6 +++ ..._doc_edits_need_execution_authorization.md | 35 +++++++++++++ ...existing_issues_skip_potential_to_issue.md | 36 ++++++++++++++ ...ep_child_by_committing_then_relaunching.md | 49 +++++++++++++++++++ .../project_lane_a_gate_fidelity_epic.md | 35 +++++++++++++ ...ence_epic_kickoff_validator_table_rules.md | 32 ++++++++++++ ..._prepared_plan_crlf_hazard_at_execution.md | 22 +++++++++ 10 files changed, 270 insertions(+) create mode 100644 .claude/agent-memory/epic-orchestrator/feedback_prepared_epic_stale_child_branches.md create mode 100644 .claude/agent-memory/epic-orchestrator/project_child_pr_ci_gap_integration_base.md create mode 100644 .claude/agent-memory/epic-planner/feedback_governance_doc_edits_need_execution_authorization.md create mode 100644 .claude/agent-memory/epic-planner/feedback_preexisting_issues_skip_potential_to_issue.md create mode 100644 .claude/agent-memory/epic-planner/feedback_recover_dead_prep_child_by_committing_then_relaunching.md create mode 100644 .claude/agent-memory/epic-planner/project_lane_a_gate_fidelity_epic.md create mode 100644 .claude/agent-memory/epic-planner/reference_epic_kickoff_validator_table_rules.md create mode 100644 .claude/agent-memory/epic-planner/reference_prepared_plan_crlf_hazard_at_execution.md diff --git a/.claude/agent-memory/epic-orchestrator/MEMORY.md b/.claude/agent-memory/epic-orchestrator/MEMORY.md index 3a228d2a..719e5043 100644 --- a/.claude/agent-memory/epic-orchestrator/MEMORY.md +++ b/.claude/agent-memory/epic-orchestrator/MEMORY.md @@ -8,4 +8,6 @@ - [Epic checkpoint schema gotchas](project_epic_checkpoint_schema_gotchas.md) — max_parallel_features (1-8) REQUIRED; waves[] uses feature_folders key; wave-barrier notices are unconditional on unmerged deps (expected mid-flight, MCP returns ok:false but merging a dep clears its specific line); additive extra keys tolerated; Python CLI validator absent in TaskMaster (use MCP) - [Merged child worktree defer removal — two causes](feedback_merged_child_worktree_still_locked_defer_removal.md) — non-force git worktree remove fails exit 128 for framework-lock (shared session pid) OR uncommitted files; never force mid-wave. Locks release PIECEMEAL — retry every deferral each resume (a merged child's lock can clear while siblings stay locked); a child may own a named-feature worktree + a secondary agent worktree - [Cross-child annotation fan-in debt](project_cross_child_annotation_fanin_debt.md) — parallel per-file opt-in annotation children fan in NEW diagnostics on the integrated tree that no scope-locked child can fix; a green per-child gate ≠ green integrated-tree gate; reserve a capstone full-tree gate + carry residuals as blocking capstone_inputs +- [Child PRs on an integration base get ZERO CI](project_child_pr_ci_gap_integration_base.md) — TaskMaster ci.yml triggers pull_request only on [main, development]; merge-on-green silently becomes merge-on-nothing. Verify the trigger list yourself; gate the integrated tree with `gh workflow run ci.yml --ref `; never edit the workflow mid-epic +- [Prepared-epic stale child branches collide](feedback_prepared_epic_stale_child_branches.md) — after /epic-plan the child bug/* branches survive as local refs (strict ancestors of the integration tip); delete them pre-wave-0 or execution children get suffixed branches; also tell each child to checkout -B from origin/integration - [Constraint-propagation waivers cascade serially](feedback_constraint_propagation_waiver_cascades_serially.md) — a ratified generic-base constraint implicates cross-child consumers ONE FILE AT A TIME (waiver grew 1→2→3→4, then CLOSED via assembly-wide enumeration: each generic base has a Wrapper+Converter consumer → symmetric closed set); re-escalate per new consumer never widen blind, but DO demand the enumeration to bound it; expect plan-literal targets ([P9 "four bases" wording; solution-wide-zero) to be DEVIATIONS to document not fail — solution-wide zero is the capstone's gate, the child's is its isolated cluster diff --git a/.claude/agent-memory/epic-orchestrator/feedback_prepared_epic_stale_child_branches.md b/.claude/agent-memory/epic-orchestrator/feedback_prepared_epic_stale_child_branches.md new file mode 100644 index 00000000..4d0b1fcb --- /dev/null +++ b/.claude/agent-memory/epic-orchestrator/feedback_prepared_epic_stale_child_branches.md @@ -0,0 +1,25 @@ +--- +name: prepared-epic-stale-child-branches +description: After /epic-plan, the prepared child branches survive as stale local refs that collide when execution children recreate them; delete them pre-wave-0 after proving ancestry into the integration branch +metadata: + type: feedback +--- + +Before launching wave 0 of an `epic-planner`-prepared epic, check for leftover local child +branches (`bug/*`, `feature/*`) from preparation and delete them once ancestry is proven. + +**Why:** `epic-planner` prepares each child on its own branch, then fans the preparation commits +into `epic/-integration`. The child branches are left behind as local refs. When an +execution child later runs `git checkout -b `, the name is taken, and the framework +falls back to a suffixed branch (the `-r2` pattern visible in older QuickFiler worktrees), which +desynchronizes the branch recorded in the epic checkpoint from the branch the child actually +pushes and PRs from. Related: [[feedback_hung_child_recovery_blocked_by_removal_gate]]. + +**How to apply:** Prove each stale branch is a strict ancestor of the integration branch first — +`git rev-list --left-right --count epic/-integration...` must show `0` on the right +side. Then `git branch -D` it; nothing is lost because the work is already reachable from a pushed +ref. Leave the *remote* copies alone: they are ancestors of the integration tip, so a child's first +push is a fast-forward. Also tell each child to `git checkout -B +origin/epic/-integration` explicitly — the framework creates the isolated worktree from the +session HEAD, not from the integration branch, so the prepared feature folder and its committed +`plan-path` are otherwise absent from the child's tree. diff --git a/.claude/agent-memory/epic-orchestrator/project_child_pr_ci_gap_integration_base.md b/.claude/agent-memory/epic-orchestrator/project_child_pr_ci_gap_integration_base.md new file mode 100644 index 00000000..600d943d --- /dev/null +++ b/.claude/agent-memory/epic-orchestrator/project_child_pr_ci_gap_integration_base.md @@ -0,0 +1,28 @@ +--- +name: child-pr-ci-gap-integration-base +description: TaskMaster's ci.yml triggers pull_request only on [main, development], so epic child PRs based on the integration branch get zero CI checks; use workflow_dispatch on the integration branch as the integrated-tree gate +metadata: + type: project +--- + +In TaskMaster, `.github/workflows/ci.yml` declares `pull_request: branches: [main, development]`. +An epic child PR whose base is `epic/-integration` matches no workflow trigger, so +`gh pr view --json statusCheckRollup` returns empty and `mergeStateStatus` is `CLEAN`. The child's +S9 merge-on-green step has nothing to parse. + +**Why:** This silently converts merge-on-green into merge-on-nothing for every child in an epic. +A child that reports "CI green" against an integration base has not been gated by CI at all — it +has at best run local CI-equivalent commands. The failure would otherwise surface only at the final +integration-to-`main` PR, after every child has already merged, which is the most expensive place +to discover it. Compare [[project_cross_child_annotation_fanin_debt]]: a green per-child gate is +not a green integrated-tree gate, and here the per-child gate does not even exist. + +**How to apply:** Verify the trigger list yourself early in any epic run rather than trusting a +child's CI claim — read `.github/workflows/ci.yml` from the integration ref. Then: (1) tell each +child in its kickoff prompt that no CI will run and that local CI-equivalent verification is +mandatory and must be recorded as feature evidence; (2) `ci.yml` also declares +`workflow_dispatch`, so run `gh workflow run ci.yml --ref epic/-integration` at each wave +boundary to gate the *integrated* tree; (3) rely on the final `main`-based integration PR for the +authoritative full-CI gate. Do not "fix" this by adding the integration branch to the workflow's +trigger list mid-epic — a `.github/workflows/**` diff is itself Blocking under the +`modified-workflow-needs-green-run` policy rule and is outside every child's scope. diff --git a/.claude/agent-memory/epic-planner/MEMORY.md b/.claude/agent-memory/epic-planner/MEMORY.md index 8db34744..dd00daac 100644 --- a/.claude/agent-memory/epic-planner/MEMORY.md +++ b/.claude/agent-memory/epic-planner/MEMORY.md @@ -6,3 +6,9 @@ - [Concurrent prep children need worktree isolation](feedback_concurrent_prep_children_worktree_isolation.md) — each concurrent prep child gets isolation:worktree + child-scoped orchestrator-state..json or siblings overwrite the canonical checkpoint - [Force-remove prep-child worktree](feedback_prep_child_worktree_force_remove.md) — worktree remove may block on uncommitted orchestrator-agent-memory scratch; force-remove is safe once HEAD == merged tip and only .claude/agent-memory/orchestrator/** is dirty - [epic-planner-state require_ready_for_execution mode](reference_epic_planner_state_ready_for_execution_mode.md) — hardened contract wants execution-time launch/topology/model-routing receipts epic-planner doesn't produce; validate with DEFAULT call, don't fabricate; run against integration worktree root +- [Pre-existing issues: skip potential_to_issue](feedback_preexisting_issues_skip_potential_to_issue.md) — epics scoped from an open backlog must tell each prep child to call only new_active_feature_folder, or every child files a duplicate issue +- [Governance-doc edits need execution authorization](feedback_governance_doc_edits_need_execution_authorization.md) — issues that are defects IN CLAUDE.md/.claude/rules collide with the policy-compliance hard constraint; plan it, scope the suspension per child, make /epic-run the authorization act +- [Recover a dead prep child: commit, then relaunch](feedback_recover_dead_prep_child_by_committing_then_relaunching.md) — infra-killed children leave the whole feature folder uncommitted and epic-planner has no SendMessage; commit to bug/, push, force-remove the worktree, relaunch as a resume +- [Prepared-plan CRLF hazard at execution](reference_prepared_plan_crlf_hazard_at_execution.md) — plans commit LF but core.autocrlf=true makes them CRLF in a fresh worktree; the MCP plan validator has rejected that — tell epic-orchestrator to re-normalize +- [epic-kickoff validator table rules](reference_epic_kickoff_validator_table_rules.md) — the table must immediately follow "## Feature Summary" (first line after it is parsed as the header), issue_num must be a bare integer, and trailing prose becomes a phantom row +- [Lane A gate-fidelity epic](project_lane_a_gate_fidelity_epic.md) — build-ci-coverage-gate-fidelity is Flight 0 of the blocked parallel run; #513 is un-fixable here (lives in drm-copilot); nullable debt is a follow-on epic diff --git a/.claude/agent-memory/epic-planner/feedback_governance_doc_edits_need_execution_authorization.md b/.claude/agent-memory/epic-planner/feedback_governance_doc_edits_need_execution_authorization.md new file mode 100644 index 00000000..7e5275ce --- /dev/null +++ b/.claude/agent-memory/epic-planner/feedback_governance_doc_edits_need_execution_authorization.md @@ -0,0 +1,35 @@ +--- +name: governance-doc-edits-need-execution-authorization +description: An epic whose issues require editing CLAUDE.md or .claude/rules/** collides with the policy-compliance-order hard constraint; plan it, scope it, and make the user's kickoff the authorization point +metadata: + type: feedback +--- + +Some bug issues are defects *in* the governance documents themselves (wrong toolchain commands, +contradictory coverage thresholds). Fixing them requires editing `CLAUDE.md` and +`.claude/rules/**`, which the `policy-compliance-order` skill hard constraint prohibits: "Do NOT +modify policy documents under `.claude/rules/` or `.github/instructions/`." + +Do not treat this as a planning blocker and do not silently ignore it. Resolve it structurally: + +1. **Planning is unaffected.** Preparation produces specs and atomic plans that *propose* the + edits; no governance file is modified. Say this explicitly in the checkpoint. +2. **Record a `governance_edit_authorization` block** in `epic-planner-state.json` naming the + exact files, the issues that require them, and `status: required_at_execution`. +3. **Put an "Execution Authorization Required" section in `epic.md`** and repeat it in the kickoff + artifact, so running `/epic-run ` is the visible authorization act. +4. **Scope the suspension per child, in the delegation prompt.** State that the constraint is + suspended for that feature only, only at the sites its issues enumerate, and add the hard + limit: no policy requirement may be relaxed, weakened, or deleted in order to make a gate pass. +5. **Partition the shared file between siblings.** Two children editing `CLAUDE.md` in different + sections merge cleanly only if each is told which region it owns and which regions belong to a + sibling. In the Lane A epic, feature 512 owned the C# toolchain command block and feature 494 + owned § UT2 coverage; each prompt named the other's region as off-limits. That let both stay + in different waves without a fake `depends_on` edge. + +**Why:** An agent cannot grant itself or a subagent permission to edit configuration or policy. +The user's own `/epic-run` command is the only thing that can, so the plan's job is to make that +authorization explicit, bounded, and reviewable rather than to smuggle it into a delegation prompt. + +Related: [[check-inflight-branches-before-decomposition]], +[[preexisting-issues-skip-potential-to-issue]]. diff --git a/.claude/agent-memory/epic-planner/feedback_preexisting_issues_skip_potential_to_issue.md b/.claude/agent-memory/epic-planner/feedback_preexisting_issues_skip_potential_to_issue.md new file mode 100644 index 00000000..6a65c470 --- /dev/null +++ b/.claude/agent-memory/epic-planner/feedback_preexisting_issues_skip_potential_to_issue.md @@ -0,0 +1,36 @@ +--- +name: preexisting-issues-skip-potential-to-issue +description: When an epic decomposes an existing bug backlog, prep children must skip potential_to_issue and call only new_active_feature_folder, or every child files a duplicate issue +metadata: + type: feedback +--- + +An epic scoped from an existing issue backlog (rather than from fresh potential entries) must tell +every preparation child, in the delegation prompt, NOT to run the first two promotion steps: + +> Issue #N is already open and its potential entry is already promoted at +> `docs/features/potential/promoted/`. Do NOT call `new_potential_bug_entry` or +> `potential_to_issue` — `potential_to_issue` always creates a NEW issue and would duplicate #N. +> Call only `new_active_feature_folder` with `issue_number = N`. Record the promotion receipts +> truthfully: note that the potential-entry and issue receipts refer to pre-existing artifacts +> rather than newly created ones. Do not fabricate receipts. + +**Why:** `mcp__drm-copilot__potential_to_issue` has no idempotent path; it always creates a new +issue. A default-behaviour child following `feature-promotion-lifecycle` literally would file a +duplicate of every backlog issue the epic is supposed to close. The `preparation` route still +wants promotion receipts, so the child must record the pre-existing artifacts truthfully instead +of inventing them. + +Two related traps seen in the Lane A run (2026-08-10): +- The promoted potential file under `docs/features/potential/promoted/` is often far richer than + the GitHub issue body, which frequently reads "(not provided in potential file)" in every + section. Point children at the promoted file, not just `gh issue view`. +- A backlog issue marked `- Work Mode: minor-audit` whose body has no populated + `## Acceptance Criteria` fails the minor-audit eligibility check. Per + `feature-promotion-lifecycle`, fail closed to the full path (`full-bug`) and say so in the + prompt, rather than letting the child discover the integrity failure mid-run. + +**How to apply:** Check `gh issue view --json state` for every candidate during the +epic-worthiness gate. Any already-open issue gets this paragraph in its delegation prompt. +Related: [[concurrent-prep-children-worktree-isolation]], +[[check-inflight-branches-before-decomposition]]. diff --git a/.claude/agent-memory/epic-planner/feedback_recover_dead_prep_child_by_committing_then_relaunching.md b/.claude/agent-memory/epic-planner/feedback_recover_dead_prep_child_by_committing_then_relaunching.md new file mode 100644 index 00000000..b07a8f7d --- /dev/null +++ b/.claude/agent-memory/epic-planner/feedback_recover_dead_prep_child_by_committing_then_relaunching.md @@ -0,0 +1,49 @@ +--- +name: recover-dead-prep-child-by-committing-then-relaunching +description: A preparation child killed by an API/spend-limit error leaves its whole feature folder uncommitted; commit it to the child branch yourself, then relaunch from that commit — SendMessage is not available to epic-planner +metadata: + type: feedback +--- + +When a preparation-mode child dies on an infrastructure error (API failure, org monthly spend +limit) rather than a task failure, its worktree survives but **its entire feature folder is +typically uncommitted** — the preparation-mode kickoff line only tells it to commit *after* +`PREFLIGHT: ALL CLEAR`, so a child killed before that point has committed nothing. + +`SendMessage` is **not** in the `epic-planner` tool set (only `Agent`, `Read`, `Grep`, `Glob`, +`Write`, `Edit`, `Bash`, and the MCP validator), so resuming a child in place is not possible even +when the caller asks for it. Relaunching naively is destructive, because a fresh `Agent` call gets +a **new** worktree and the old worktree's uncommitted work is never seen. + +Recovery procedure: + +1. `git -C status --porcelain` and `git -C log --oneline origin/..HEAD` for + every surviving worktree. Uncommitted feature folder plus zero commits is the common shape. +2. Commit each worktree's work onto its own `bug/` branch yourself, with explicit pathspecs + (`docs/features/active/` plus `.claude/agent-memory`), stating in the message that + epic-planner preserved it after an infrastructure termination and that preflight was not + reached. +3. `git push -u origin bug/` for each — durable backup, and it lets a fresh worktree check + the branch out. +4. Force-remove the now-clean worktrees. Required, not optional: git refuses to check a branch out + in two worktrees, so the old worktree must go before the relaunched child can use the branch. + Some agent worktrees are locked and need `git worktree remove -f -f`. +5. Relaunch with a prompt whose first section is "THIS IS A RESUME, NOT A FRESH RUN": check out the + preserved branch, merge the current integration tip, enumerate the artifacts that already exist, + and state the specific remaining step. + +Two things the relaunched child must be told explicitly: + +- **Rebuild the child-scoped checkpoint.** `artifacts/` is gitignored, so the checkpoint does not + travel with the branch and is absent in the new worktree. +- **Trust on-disk artifacts over the dead run's `next_step`.** Child checkpoints lag badly; one + child's checkpoint said `next_step: S2_research` while its folder already held research, three + feature documents, an atomic plan, and nine evidence artifacts. + +Also re-verify each child's real state rather than the last reported line: a caller's summary of +"where it left off" is a report from the dead agent's context, not ground truth, and findings held +only in that context (for example a preflight's specific blocking-defect list) are gone and must +be regenerated by re-running the gate. + +Related: [[concurrent-prep-children-worktree-isolation]], [[prep-child-worktree-force-remove]], +[[prepared-plan-crlf-hazard-at-execution]]. diff --git a/.claude/agent-memory/epic-planner/project_lane_a_gate_fidelity_epic.md b/.claude/agent-memory/epic-planner/project_lane_a_gate_fidelity_epic.md new file mode 100644 index 00000000..2a8ad222 --- /dev/null +++ b/.claude/agent-memory/epic-planner/project_lane_a_gate_fidelity_epic.md @@ -0,0 +1,35 @@ +--- +name: lane-a-gate-fidelity-epic +description: The build-ci-coverage-gate-fidelity epic is Lane A / Flight 0 of the blocked parallel-bug run; it must land before the other 59 open bugs can be certified +metadata: + type: project +--- + +Epic `build-ci-coverage-gate-fidelity` (planned 2026-08-10, integration branch +`epic/build-ci-coverage-gate-fidelity-integration`) delivers Lane A of +`docs/research/2026-08-10-parallel-bug-flighting-and-surface-blockers.md` as a conventional epic. + +**Why:** The `/parallel-plan` surface is hard-blocked (missing `compute_cohorts`, missing +`config/blast-radius.json` — see the user-level memory `parallel-surface-not-ported-taskmaster`). +§9 of that research document names `/epic-plan` on Lane A as the fallback available today. Lane A +is Flight 0: it must run first and alone, because the repository's coverage gates measure an +inflated denominator and the nullable gate cannot fail, so running any of the other 59 open bugs +first would certify them against gates that cannot fail. + +**How to apply:** +- Nine issues, five features, three waves. Wave 0: 441 (+478), 512 (+492, +509, +522), 394. + Wave 1: 457. Wave 2: 494. +- **Issue 513 is excluded and cannot be fixed in TaskMaster.** `collect_pr_context`'s + classification step lives at `extensions/drm-copilot/src/lib/pr-context/collector-output.ts` in + the `drm-copilot` repository. File it upstream; do not re-investigate whether TaskMaster can + close it. +- Nullable *debt* burn-down (~195-220 `CS86xx` in `UtilitiesCS.csproj`) is deliberately a + follow-on epic. Issue 492 separates "make the gate report truthfully" from "fix what it + reports"; only the first is in this epic. +- Non-DAG coordination risk: feature 441 changes every coverage figure in the repository, which + invalidates the committed baselines that the 21 unmerged branches of the QuickFiler per-file + coverage epic (#136) gate on. No file conflict, but decide merge order before landing either + epic on `main`. + +Related: [[governance-doc-edits-need-execution-authorization]], +[[preexisting-issues-skip-potential-to-issue]]. diff --git a/.claude/agent-memory/epic-planner/reference_epic_kickoff_validator_table_rules.md b/.claude/agent-memory/epic-planner/reference_epic_kickoff_validator_table_rules.md new file mode 100644 index 00000000..8720bce3 --- /dev/null +++ b/.claude/agent-memory/epic-planner/reference_epic_kickoff_validator_table_rules.md @@ -0,0 +1,32 @@ +--- +name: epic-kickoff-validator-table-rules +description: The epic-kickoff MCP validator parses the first line after "## Feature Summary" as the table header and requires integer-only issue_num, so the epic-plan skill's own template shape can fail validation +metadata: + type: reference +--- + +`mcp__drm-copilot__validate_orchestration_artifacts` with `artifact_type: "epic-kickoff"` enforces +structural rules the `epic-plan` skill template does not spell out. Three of them cost a +validate-fix-revalidate cycle each on the `build-ci-coverage-gate-fidelity` run (2026-08-11): + +1. **The feature table must immediately follow the `## Feature Summary` heading.** The validator + treats the first non-blank line after that heading as the header row. A sentence of prose there + (for example "Nine issues, five features, three waves") is parsed as the header and fails with + `feature table headers must be: issue_num | feature_folder | wave | complexity | plan-path`. + Put any narrative sentence *before* the heading, not between the heading and the table. +2. **`issue_num` cells must be bare integers.** A feature that closes several issues cannot write + `441 (+478)` or `512 (+492, +509, +522)`; those fail with + `feature row N issue_num must be an integer`. Record the primary `issue_num` in the table and + list the additional closed issues in a separate section. +3. **Trailing prose immediately after the table is parsed as another table row.** Leave a heading + between the table and whatever follows. + +Also keep the `## Invocation Prompt` paragraph on unwrapped lines. The template in the skill shows +it hard-wrapped; validation is easier to satisfy when the manifest path, the integration branch, +and the atomic-execution resume clause are each contiguous rather than split across a newline. + +**How to apply:** write the kickoff artifact, validate it with the `epic-kickoff` type BEFORE +committing, and fix these first. Validate the mirrored copy under +`artifacts/orchestration/epic-kickoff-.md`; the committed copy at +`docs/features/epics//epic-kickoff.md` must be byte-identical, so copy after validating. +Related: [[epic-planner-state-required-fields]], [[epic-plan-tooling-not-vendored]]. diff --git a/.claude/agent-memory/epic-planner/reference_prepared_plan_crlf_hazard_at_execution.md b/.claude/agent-memory/epic-planner/reference_prepared_plan_crlf_hazard_at_execution.md new file mode 100644 index 00000000..6b707640 --- /dev/null +++ b/.claude/agent-memory/epic-planner/reference_prepared_plan_crlf_hazard_at_execution.md @@ -0,0 +1,22 @@ +--- +name: prepared-plan-crlf-hazard-at-execution +description: Prepared atomic plans commit as LF but core.autocrlf=true materializes them CRLF in a fresh worktree, and the MCP plan validator has rejected CRLF plans +metadata: + type: reference +--- + +An epic-planner run commits each child's approved atomic plan to the integration branch as an LF +blob. This repository sets `core.autocrlf=true`, so when `epic-orchestrator` later checks the +integration branch out into a fresh child worktree, the plan file materializes as CRLF. The MCP +`validate_orchestration_artifacts` `plan` validator has previously rejected CRLF plans. + +The plan passes the validator during preparation (in the child's own worktree, where the file was +just written as LF) and can fail it at execution time in a new worktree, with no change to the +committed blob. + +**How to apply:** Carry this as an explicit note in the epic kickoff artifact and in the planning +checkpoint's `execution_notes`, addressed to `epic-orchestrator`: re-normalize each prepared plan +to LF before re-running the plan validator gate in a newly created worktree. Do not treat the +resulting validator failure as a defect in the prepared plan. + +Related: [[epic-plan-tooling-not-vendored]].