diff --git a/.claude/agent-memory/orchestrator/MEMORY.md b/.claude/agent-memory/orchestrator/MEMORY.md index 7286da5b2..7a7f2fc8b 100644 --- a/.claude/agent-memory/orchestrator/MEMORY.md +++ b/.claude/agent-memory/orchestrator/MEMORY.md @@ -1,76 +1,77 @@ -- [CLAUDE.md nullable command != the CI gate](project_claudemd_nullable_command_diverges_from_ci.md) — ci.yml omits `/p:Nullable=enable`; forced-flag CS86xx in a file with no `#nullable` pragma is a FALSE blocker (~414 errors red on main too). Repro ci.yml's command before accepting a subagent's nullable failure -- [Agent-worktree discovery + evidence hygiene](project_agent_worktree_discovery_and_evidence_hygiene.md) — the `\.claude\` test-glob exclusion discards ALL assemblies in an agent worktree (filter on the RELATIVE path; 0 discovered = filter bug); and never commit raw Cobertura dumps (81 MB on #507) -- [Completion-gate receipt shapes](completion-gate-receipt-shapes.md) — exact fields the MCP require_complete gate wants: delegation_receipts as a LIST, skill_receipts needs required:true, MCP receipts live under mcp_call_receipts with ok:true+evidence -- [JaCoCo not Cobertura for coverage evidence](jacoco-not-cobertura-for-evidence.md) — maintainer deleted ~20MB of committed Cobertura on 2026-08-08 (d0955dc4); convert to package-level JaCoCo BEFORE pushing, and generate artifacts/csharp/coverage.xml from it only when the figure clears 85% -- [Store-lockup watchdog null-model hazard](project_store_lockup_watchdog_null_model_hazard.md) — #260 watchdog is live; new startup COM attribution scopes need a responder phase-branch that returns before the disable-service write, or the watchdog thread crashes on the null store model -- [VS Code extension location](project_extension_location.md) — the extension lives at `extensions/drm-copilot/`, not at the repo root. -- [Verify package.json before vsce work](feedback_vsce_verify_package_location.md) — in multi-package repos, never assume the repo root is the publishable extension; locate it first. -- [Repo root is source of truth for codex bundle](feedback_repo_root_is_source_of_truth.md) — when repo `.codex/`, `.agents/`, `AGENTS.md` differ from bundled copies, update the bundle to match. -- [Evidence + lifecycle for every change](evidence-and-lifecycle-for-every-change.md) — evidence only under a feature folder; promote to issue + active folder before ANY implementation, even 1-file tooling fixes +- [CLAUDE.md nullable command != the CI gate](project_claudemd_nullable_command_diverges_from_ci.md) — ci.yml omits `/p:Nullable=enable`; CS86xx from the forced flag is a FALSE blocker +- [Agent-worktree discovery + evidence hygiene](project_agent_worktree_discovery_and_evidence_hygiene.md) — `\.claude\` test-glob filter must use the RELATIVE path; never commit raw Cobertura +- [Completion-gate receipt shapes](completion-gate-receipt-shapes.md) — exact fields require_complete wants: delegation_receipts as a LIST, skill_receipts required:true +- [JaCoCo not Cobertura for coverage evidence](jacoco-not-cobertura-for-evidence.md) — maintainer deletes committed Cobertura; convert to package-level JaCoCo before pushing +- [Store-lockup watchdog null-model hazard](project_store_lockup_watchdog_null_model_hazard.md) — new startup COM scopes need a phase-branch returning before the disable-service write +- [VS Code extension location](project_extension_location.md) — the extension lives at `extensions/drm-copilot/`, not the repo root +- [Verify package.json before vsce work](feedback_vsce_verify_package_location.md) — never assume the repo root is the publishable extension; locate it first +- [Repo root is source of truth for codex bundle](feedback_repo_root_is_source_of_truth.md) — when repo `.codex/`/`.agents/`/`AGENTS.md` differ from the bundle, update the bundle +- [Evidence + lifecycle for every change](evidence-and-lifecycle-for-every-change.md) — evidence only under a feature folder; promote to issue + active folder before ANY implementation - [Small-path = minor-audit selection](small-path-minor-audit-selection.md) — 1-3 production-file bug = small path + minor-audit, no spec.md, AC lives in issue.md -- [MCP tools available to orchestrator](mcp-tools-available-to-orchestrator.md) — if a worker reports MCP gate/lifecycle tools unavailable, run them from the orchestrator yourself, don't accept the block -- [potential_to_issue creates the GitHub issue](potential-to-issue-creates-github-issue.md) — the promotion tool opens the GitHub issue itself; do not also gh issue create -- [potential_to_issue needs an absolute path](potential-to-issue-needs-absolute-path.md) — in a worktree, workspace-relative potential_path fails "not found"; pass the absolute path from the new_potential_entry receipt -- [Promotion potential .md may not persist](promotion-potential-md-may-not-persist.md) — MCP promotion creates the issue + populates active issue.md, but the potential/promoted .md may be absent on disk; recreate for audit trail, don't treat as failure -- [Remediation loop strict handoff](remediation-loop-strict-handoff.md) — remediation cycles run atomic-planner -> atomic-executor -> feature-review only; no direct typed-engineer worker calls; five required artifacts per cycle -- [Remediation-plan em-dash required](remediation-plan-em-dash-required.md) — the plan validator rejects `### Phase N (continued) — `; only canonical `### Phase N — <Title>` passes -- [new_active_feature_folder date prefix](new-active-feature-folder-date-prefix.md) — standalone feature folders get the YYYY-MM-DD- prefix automatically; epic-child folders don't (git mv those) -- [orchestrator-state validator divergence](orchestrator-state-validator-divergence.md) — MCP orchestrator-state check is stricter than the real SubagentStop hook; conform to the canonical schema's remediation_loop shape -- [orchestrator-state flat keys + step-status enum](orchestrator-state-flat-keys-and-enum.md) — validator needs FLAT top-level variable keys (not nested under "variables") and enum step statuses (in_progress not in-progress); fable_policy "available" => C3->opus -- [C# analyzer packages.config quirks](csharp-analyzer-packages-config-quirks.md) — non-SDK analyzer wiring needs manual roslyn subfolder selection; SecurityCodeScan.VS2019 breaks Roslyn 5.6 via CS8032 (can't be silenced by editorconfig) -- [Whole-repo CI gate is not out-of-scope](whole-repo-ci-gate-not-out-of-scope.md) — a pre-existing repo-wide csharpier/lint failure blocks the PR's required check (AC6); fix it, don't defer it -- [Honor user's per-cycle folder layout](feedback_verify_flat_artifact_layout_after_executor.md) — #181 user committed a per-cycle folder layout (<ts>-remediation/, <ts>-audit/); follow it. Only revert UNDIRECTED agent relocations, not the user's own reorg -- [Repo-wide coverage authority exception](feedback_repowide_coverage_authority_exception.md) — sole blocking finding = pre-existing repo-wide coverage shortfall + change-scope gates pass → surface authority-scoped exception, don't auto-cycle -- [Repo-wide coverage: run the FULL suite](feedback_repowide_coverage_run_full_suite.md) — measure repo-wide C# coverage by running ALL *.Test.dll together (like ci.yml); a single-assembly run reports a false-low number (20.21% vs true 81.19%). Verify before treating as a blocker -- [No coverage exemption when purpose is testability](feedback_no_coverage_exemption_when_purpose_is_testability.md) — for testability-purpose work, maintainer denies [ExcludeFromCodeCoverage] ratification; plan real interface/adapter seams instead (contrast #223 which was ratified) -- [Verify reducibility before accepting exemption count](feedback_verify_reducibility_before_accepting_exemption_count.md) — don't trust a delivered residual count at face value; cross-check against proven in-repo techniques, and confirm de-exempted tests execute the delegate, not just verify it was called -- [Migration posture before PR gate](feedback_migration_not_just_patch.md) — before step 10, report integration/migration posture (reachable in prod? persisted? old path retired?), not just a clean audit -- [Verify repro before bugfix cycle](feedback_verify_repro_before_bugfix_cycle.md) — for a latent/worked-around defect, ground-truth its reachability on HEAD before a red-before-green cycle; a correct workaround can make it unreproducible -- [VSTO startup STA threading directive](feedback_vsto_startup_sta_threading_directive.md) — minimize STA reliance, always pump, gate COM hookups on Outlook readiness, offload only non-COM compute; residual in scope only if the add-in causes it -- [Banned API in touched file is in scope](feedback_banned_api_in_touched_file_in_scope.md) — when a fix modifies a production file, remediate any banned API (DateTime.Now/UtcNow, Random.Shared, Thread.Sleep, Task.Delay) found in it; don't defer -- [Re-verify ground truth after user mid-cycle commit](feedback_reverify_ground_truth_after_user_midcycle_commit.md) — if the user rebases/commits mid-cycle, re-probe line counts/merge-base/csproj and re-plan before executing a preflighted plan -- [pr_context.summary.txt unreliable for gh + file classification](pr-context-summary-unreliable-gh-and-classification.md) — verify gh with `which gh`/`gh auth status` and author the PR body from the real diff, not the summary's "gh unavailable"/"0 core-logic changes" lines -- [pr-author agent unavailable; run skill in-thread](pr-author-hook-blocks-gh-in-this-repo.md) — Agent(pr-author) type not registered here; author body+SHA256 receipt in-thread and the hook permits gh pr create; also carries the verified checkpoint schema + step-status enum -- [Tests must not trigger UX or a live worker](feedback_tests_must_not_trigger_ux_or_live_worker.md) — never start a real BackgroundWorker/form in unit tests (pops MessageBox, touches COM); seam the worker body and inject an inert delegate -- [Commit everything before the S9 CI gate](feedback_commit_before_ci_gate.md) — a post-gate commit (even docs/memory) moves the head SHA and forces an S9 re-run; finish all commits, then run S9 once -- [Git-blame regressions before novel hypotheses](feedback_gitblame_regressions_before_novel_hypothesis.md) — for a "was working, now wrong" symptom, git-blame the exact lines and diff the responsible refactor commit first; re-confirm the exact symptom; treat a failed fix's mechanism as refuted (#269 fore/back swap from #236 refactor) -- [Flaky CI: PhysicalFileInfoAdapter test](project_flaky_ci_physicalfileinfoadapter_test.md) — PhysicalFileInfoAdapter_..._MirrorFileInfo intermittently fails CI opening real TaskMaster.sln; re-run failed job first, fix only if deterministic -- [Commit review artifacts + step8 preflight nuances](feedback_commit_review_artifacts_and_step8_preflight.md) — commit feature-review's artifacts before rebase/PR; set step8_status non-pending for PR preflight; ff-only merge to update main in a linked worktree -- [Epic self-merge step9 gate sequencing](epic-mode-pr-merge-gate-sequencing.md) — merge gate needs top-level epic_mode:true + step9_status "passed"; completion gate rejects "passed" → flip to "verified" after merge, before Stop -- [feature-review 85% coverage floor trap](feature-review-coverage-85-floor-trap.md) — do NOT generate artifacts/csharp/coverage.xml at 80-85% repo-wide; hook hard-codes 85% and forces a false FAIL (supersedes the stale "generate coverage.xml" note) -- [MCP plan validator em-dash behavior is version-dependent](mcp-plan-validator-defective-em-dash.md) — PASSED em-dash+LF plans on 2026-07-10 (F1/F2/F5 preps; contradicts older "rejects em-dash" finding); run it and observe, keep em-dash, executor preflight is still the substantive gate -- [collect_pr_context lands in main checkout](collect-pr-context-lands-in-main-checkout.md) — in a worktree, copy pr_context.* into the worktree before gh pr create; checkpoint + pr_* artifacts are gitignored (local-only) -- [MCP plan validator Edit/Write pervasive-diff](mcp-plan-validator-editwrite-pervasive-diff.md) — validator rejects an LF/no-BOM plan after an Edit/Write with "no canonical phase headings"; restore via git-bash cp/sed/perl, fold oversized bullets, executor preflight is the real gate -- [MCP plan validator requires LF](mcp-plan-validator-requires-lf.md) — the MCP plan validator rejects CRLF-line-ending plans (all headings/tasks fail); normalize CRLF→LF (content-preserving, not re-planning). Executor textual preflight tolerates CRLF, so a plan can be preflight-cleared yet fail the MCP gate -- [Swordfish epic: clean collection premise is false](project_swordfish_removal_false_clean_collection.md) — manifest claims a clean ConcurrentObservableCollection "already in repo" but it doesn't exist; F4 used List<T>, F2 must actually create it -- [Epic child PRs get no CI](project_epic_child_prs_no_ci.md) — ci.yml triggers only on PRs to main/development; child→integration PRs run zero checks by design, so CI-green is vacuous and merge proceeds on blocking_count==0 -- [Child-orchestrator PR hook reads SESSION ROOT](child-orchestrator-pr-hook-reads-session-root.md) — when session cwd != feature worktree, pr-author hook + collect_pr_context resolve against session root; stage body/receipt/checkpoint there and backup-swap-restore the epic checkpoint around gh pr create -- [Agent-worktree hooks resolve to agent cwd](agent-worktree-hooks-resolve-to-agent-cwd.md) — in a .claude/worktrees/agent-<id> isolated worktree, PreToolUse+SubagentStop hooks read the agent worktree (proven by merge succeeding); do NOT copy checkpoint to session root (clobbers siblings). Contrast the named-worktree case -- [Epic #295 winforms testability](project_epic_295_winforms_testability.md) — design-phase-only mandate (research→spec→plan→preflight, then STOP); children 293/296/297/298; 298 depends on 297 -- [STA controls ratified as last resort](feedback_sta_controls_last_resort_ratified.md) — unshown WinForms controls on STA OK only after seams, in dedicated *.StaTests.cs files; Forms/popups/pumps still banned -- [Epic children need full lifecycle + PRs](feedback_epic_children_require_full_lifecycle_and_prs.md) — maintainer rejected executor-driver shortcut AND direct --no-ff child merges; child PRs mandatory even with vacuous CI -- [Verify subagent capability claims](feedback_verify_subagent_capability_claims.md) — never relay "agent type not registered" without checking .claude/agents frontmatter; demand verbatim error; blocked state, not silent fallback -- [Epic-child plan Phase 0 paths are stale](feedback_plan_phase0_paths_are_stale_in_epic_children.md) — epic-child plans cite the planning worktree's absolute paths for P0 policy reads; redirect the executor to the CURRENT worktree's files in the delegation prompt -- [Unplanned epic-child worktree mechanics](unplanned-epic-child-worktree-mechanics.md) — cross-worktree delegation works via absolute paths; atomic-executor runs C# tools via pwsh with explicit paths (vstest/csharpier not on PATH); collect_pr_context + PR/merge hooks resolve against session root -- [Epic generic-constraint cascades across children](epic-generic-constraint-cascades-multiple-children.md) — a ratified `where TKey : notnull` on a base type emits CS8714 in EVERY nullable-enabled unconstrained consumer; consumers span sibling children, so a one-file waiver estimate undercounts; enumerate ALL consumers first, child re-escalates rather than self-widening -- [Parallel epic children name collisions](parallel-epic-children-name-collisions.md) — siblings coin identical type names in shared namespaces; CS0101/CS0104 surface only at rebase; rename YOUR types, rerun toolchain, no re-review -- [Model-routing scripts absent on epic integration base](model-routing-scripts-absent-on-epic-integration-base.md) — on a PR-head-based epic integration branch the compute_complexity_floor/resolve_delegation_model/validate_orchestrator_state scripts may be missing; compute routing by hand, MCP validator still gates -- [Swordfish epic F5 ScoDictionary blocker (RESOLVED)](project_swordfish_epic_f5_blocked_on_old_scodictionary.md) — F5 (#308) once WI-0-halted on the OLD ScoDictionary Swordfish base (ScoDictionaryNew was a decoy); #315/PR #316 deleted it, F5 then completed. Lesson: grep the OLD class base + using, not just the *New replacement -- [Epic-child stale local integration ref](project_epic_child_stale_local_integration_ref.md) — local branch ref for the epic integration branch can be stale in an agent worktree; `git fetch` and branch from `origin/<branch>`, not the bare local name, before trusting a Phase-0 gate -- [Portable completion gate allows blocked child](portable-completion-gate-allows-blocked-child.md) — TaskMaster has no Python validator, so orchestrator SubagentStop uses the portable PS path (no require-complete); a blocked child can terminate + open PR by setting blocked_reason=none, steps 5-8 non-pending, halt in next_step/custom fields -- [Epic-child rebase shared-memory conflict](epic-child-rebase-shared-memory-conflict.md) — rebase child onto advanced integration tip; only conflict is shared agent-memory MEMORY.md index (union it); prove disjoint source + zero sibling-symbol refs => no rebuild; regenerate pr_context.summary.txt from real diff -- [Epic-child PR-gate gotchas](epic-child-pr-gate-gotchas.md) — isolated-worktree collect_pr_context writes to wrong checkout; hook reads nested epic_context.integration_branch; ci.yml only triggers on main/development so integration-base PRs merge on CLEAN -- [Parallel preparation children share one worktree](parallel-preparation-children-shared-worktree.md) — prep-mode epic children can run concurrently in ONE dir/index/checkpoint; use a child-scoped checkpoint path + pathspec-scoped commit; don't revert the sibling's canonical checkpoint write -- [Parallel epic children conflict on agent-memory index](parallel-epic-children-conflict-on-agent-memory-index.md) — late child PR conflicts ONLY on .claude/agent-memory/<agent>/MEMORY.md (each executor appends an index line); resolve by union, re-run build gate, PR flips to CLEAN -- [Epic-child self-merge: step9 passed vs verified](epic-child-self-merge-step9-passed-vs-verified.md) — enforce-epic-merge-gate.ps1 needs on-disk step9_status "passed"+epic_mode:true; MCP validator REJECTS the "passed" enum; keep "passed" for the merge, flip to "verified" after, revalidate -- [Epic-child agent-memory merge conflicts](epic-child-agent-memory-merge-conflicts.md) — parallel children's child->integration PR shows CONFLICTING solely on shared .claude/agent-memory/*/MEMORY.md index files; resolve by union, then re-verify post-merge before push -- [Epic-child nullable fan-in debt is deferred](project_epic_child_nullable_fanin_debt_deferred.md) — per-child #nullable gate is scoped to the child's own branch; cross-child CS86xx fan-in accumulates on integration (tip already carried 15 pre-merge) and is the Wave-2 capstone's job — merge on blocking_count==0+CLEAN, don't over-remediate sibling files -- [C# coverage has two denominators](csharp-coverage-denominator-two-figures.md) — filtered first-party ~85.9% clears the gate, unfiltered ~70.4% doesn't; measure before trusting the "85% floor trap" note, and project Cobertura to JaCoCo -- [Preflight catches vacuous gates](preflight-catches-vacuous-gates.md) — MCP plan validator ok:true is not enough; executor preflight found 6 gates that passed while verifying nothing (empty diffs, unsatisfiable acceptance, uncompilable assertions) -- [Bash tool mangles MSBuild switches](bash-tool-mangles-msbuild-switches.md) — /m becomes M:/ (MSB1008); run C# tools via pwsh -NoProfile with absolute paths, after nuget restore; carries verified VS18 tool locations -- [Analyzer gate is vacuous without /t:Rebuild](msbuild-analyzer-gate-vacuous-without-rebuild.md) — /t:Build after any earlier build skips CoreCompile on all 18 projects and returns EXIT 0 having compiled NOTHING; demand /t:Rebuild + an /fl log + a csc.exe-count > 0 acceptance -- [Aggregate vstest crash: isolate per assembly](vstest-aggregate-crash-isolate-per-assembly.md) — "Test host process crashed / Total tests: Unknown" is environmental (QuickFiler WinFormsPumpHost, #511); re-run the 9 assemblies with /InIsolation for the real verdict, and check the csproj graph before owning the blame -- [Direct-csproj build facts (AnyCPU vs "Any CPU"; CS2002)](csharp-direct-csproj-build-facts.md) — a single-project build needs `/p:Platform=AnyCPU` (no space) while the .sln needs `"Any CPU"`; and TreatWarningsAsErrors does NOT promote CS2002, so don't call the duplicate a latent build-breaker -- [Model-routing hook reads the canonical path only](model-routing-hook-reads-canonical-path-only.md) — enforce-model-routing-receipt.ps1 hardcodes artifacts/orchestration/orchestrator-state.json; a child-scoped checkpoint alone gets you MODEL_ROUTING_RECEIPT_BLOCKED. Mirror it (safe in an isolated agent worktree) -- [One executor per worktree](one-executor-per-worktree.md) — a stale checkpoint is NOT a dead delegation (executors don't own it); never launch a second executor into a live worktree; recover by re-verifying the committed tree, not by adjudicating artifact provenance -- [Removing a halt requires branch propagation](removing-a-halt-requires-branch-propagation.md) — converting a mid-plan HALT into a recorded-blocker continuation strands downstream tasks whose acceptance still demands the blocked artifact; relay it as "propagate to ALL consumers" and make branch-completeness the next preflight's explicit check +- [MCP tools available to orchestrator](mcp-tools-available-to-orchestrator.md) — if a worker reports MCP tools unavailable, run them yourself; don't accept the block +- [potential_to_issue creates the GitHub issue](potential-to-issue-creates-github-issue.md) — the promotion tool opens the issue itself; do not also `gh issue create` +- [potential_to_issue needs an absolute path](potential-to-issue-needs-absolute-path.md) — workspace-relative `potential_path` fails in a worktree; pass the absolute path +- [Promotion potential .md may not persist](promotion-potential-md-may-not-persist.md) — the potential/promoted .md may be absent on disk; recreate it, don't treat as failure +- [Remediation loop strict handoff](remediation-loop-strict-handoff.md) — cycles run atomic-planner -> atomic-executor -> feature-review only; five artifacts per cycle +- [Remediation-plan em-dash required](remediation-plan-em-dash-required.md) — the validator rejects `### Phase N (continued) — X`; only canonical `### Phase N — X` passes +- [new_active_feature_folder date prefix](new-active-feature-folder-date-prefix.md) — standalone folders get the YYYY-MM-DD- prefix automatically; epic-child folders don't +- [orchestrator-state validator divergence](orchestrator-state-validator-divergence.md) — the MCP check is stricter than the real SubagentStop hook; conform to the canonical schema +- [orchestrator-state flat keys + step-status enum](orchestrator-state-flat-keys-and-enum.md) — FLAT top-level variable keys and enum step statuses (in_progress, not in-progress) +- [C# analyzer packages.config quirks](csharp-analyzer-packages-config-quirks.md) — non-SDK analyzer wiring needs manual roslyn subfolder choice; SecurityCodeScan breaks Roslyn 5.6 +- [Whole-repo CI gate is not out-of-scope](whole-repo-ci-gate-not-out-of-scope.md) — a pre-existing repo-wide csharpier/lint failure blocks the PR's required check; fix it +- [Honor user's per-cycle folder layout](feedback_verify_flat_artifact_layout_after_executor.md) — follow the user's own reorg; only revert UNDIRECTED agent relocations +- [Repo-wide coverage authority exception](feedback_repowide_coverage_authority_exception.md) — pre-existing repo-wide shortfall + passing change-scope gates => surface an exception, don't cycle +- [Repo-wide coverage: run the FULL suite](feedback_repowide_coverage_run_full_suite.md) — run ALL *.Test.dll together; a single-assembly run reports a false-low number +- [No coverage exemption when purpose is testability](feedback_no_coverage_exemption_when_purpose_is_testability.md) — maintainer denies ExcludeFromCodeCoverage here; plan real seams +- [Verify reducibility before accepting exemption count](feedback_verify_reducibility_before_accepting_exemption_count.md) — cross-check a delivered residual count against proven in-repo techniques +- [Migration posture before PR gate](feedback_migration_not_just_patch.md) — before step 10, report integration/migration posture, not just a clean audit +- [Verify repro before bugfix cycle](feedback_verify_repro_before_bugfix_cycle.md) — ground-truth a latent defect's reachability on HEAD; a workaround can make it unreproducible +- [VSTO startup STA threading directive](feedback_vsto_startup_sta_threading_directive.md) — minimize STA reliance, always pump, gate COM hookups on Outlook readiness +- [Banned API in touched file is in scope](feedback_banned_api_in_touched_file_in_scope.md) — remediate DateTime.Now/Random.Shared/Thread.Sleep/Task.Delay in any file you modify +- [Re-verify ground truth after user mid-cycle commit](feedback_reverify_ground_truth_after_user_midcycle_commit.md) — re-probe and re-plan before executing an already-preflighted plan +- [pr_context.summary.txt is unreliable](pr-context-summary-unreliable-gh-and-classification.md) — verify gh yourself, author from the real diff, and re-check the summary's SHAs (it may be stale) +- [pr-author agent unavailable; run skill in-thread](pr-author-hook-blocks-gh-in-this-repo.md) — no Agent(pr-author) here; author body+SHA256 receipt in-thread and the hook permits gh +- [Tests must not trigger UX or a live worker](feedback_tests_must_not_trigger_ux_or_live_worker.md) — never start a real BackgroundWorker/form in unit tests; seam and inject an inert delegate +- [Commit everything before the S9 CI gate](feedback_commit_before_ci_gate.md) — a post-gate commit moves the head SHA and forces an S9 re-run; commit first, gate once +- [Git-blame regressions before novel hypotheses](feedback_gitblame_regressions_before_novel_hypothesis.md) — for "was working, now wrong", blame the exact lines and diff the responsible refactor +- [Flaky CI: PhysicalFileInfoAdapter test](project_flaky_ci_physicalfileinfoadapter_test.md) — intermittently fails opening the real .sln; re-run the job first, fix only if deterministic +- [Commit review artifacts + step8 preflight](feedback_commit_review_artifacts_and_step8_preflight.md) — commit feature-review's artifacts before rebase/PR; step8_status must be non-pending +- [Epic self-merge step9 gate sequencing](epic-mode-pr-merge-gate-sequencing.md) — merge gate needs epic_mode:true + step9 "passed"; completion gate rejects it, flip to "verified" +- [feature-review 85% coverage floor trap](feature-review-coverage-85-floor-trap.md) — do NOT emit artifacts/csharp/coverage.xml at 80-85%; the hook hard-codes 85% and forces a FAIL +- [MCP plan validator em-dash is version-dependent](mcp-plan-validator-defective-em-dash.md) — it has PASSED em-dash+LF plans; run it and observe rather than pre-editing +- [collect_pr_context lands in main checkout](collect-pr-context-lands-in-main-checkout.md) — copy pr_context.* into the worktree before gh pr create; pr_* artifacts are gitignored +- [MCP plan validator Edit/Write pervasive-diff](mcp-plan-validator-editwrite-pervasive-diff.md) — it can reject an LF plan after an Edit with "no canonical phase headings"; restore via shell tools +- [MCP plan validator requires LF](mcp-plan-validator-requires-lf.md) — it rejects CRLF plans; normalize CRLF->LF (a checkout artifact under core.autocrlf, not a plan defect) +- [Swordfish epic: clean collection premise is false](project_swordfish_removal_false_clean_collection.md) — the manifest's "already in repo" ConcurrentObservableCollection doesn't exist +- [Epic child PRs get no CI](project_epic_child_prs_no_ci.md) — ci.yml triggers only on main/development, so child->integration PRs run zero checks; merge on blocking_count==0 +- [Child-orchestrator PR hook reads SESSION ROOT](child-orchestrator-pr-hook-reads-session-root.md) — when session cwd != feature worktree, stage body/receipt/checkpoint at the session root +- [Agent-worktree hooks resolve to agent cwd](agent-worktree-hooks-resolve-to-agent-cwd.md) — in an isolated agent worktree, hooks read that worktree; do NOT copy the checkpoint to session root +- [Epic #295 winforms testability](project_epic_295_winforms_testability.md) — design-phase-only mandate; children 293/296/297/298, and 298 depends on 297 +- [STA controls ratified as last resort](feedback_sta_controls_last_resort_ratified.md) — unshown WinForms controls on STA are OK only after seams, in dedicated *.StaTests.cs +- [Epic children need full lifecycle + PRs](feedback_epic_children_require_full_lifecycle_and_prs.md) — maintainer rejected executor-driver shortcuts and direct child merges; PRs are mandatory +- [Verify subagent capability claims](feedback_verify_subagent_capability_claims.md) — never relay "agent type not registered" without checking .claude/agents yourself +- [Epic-child plan Phase 0 paths are stale](feedback_plan_phase0_paths_are_stale_in_epic_children.md) — plans cite the planning worktree's absolute paths; redirect the executor to the current one +- [Unplanned epic-child worktree mechanics](unplanned-epic-child-worktree-mechanics.md) — cross-worktree delegation works via absolute paths; C# tools need pwsh + explicit paths +- [Epic generic-constraint cascades across children](epic-generic-constraint-cascades-multiple-children.md) — a `where TKey : notnull` emits CS8714 in EVERY consumer; enumerate all of them first +- [Parallel epic children name collisions](parallel-epic-children-name-collisions.md) — siblings coin identical type names; CS0101/CS0104 surface only at rebase; rename YOUR types +- [Model-routing scripts absent on epic integration base](model-routing-scripts-absent-on-epic-integration-base.md) — compute the floor/model by hand; the MCP validator still gates +- [Swordfish epic F5 ScoDictionary blocker (RESOLVED)](project_swordfish_epic_f5_blocked_on_old_scodictionary.md) — grep the OLD class base and using, not just the *New replacement +- [Epic-child stale local integration ref](project_epic_child_stale_local_integration_ref.md) — `git fetch` and branch from `origin/<branch>`, never the bare local name +- [Portable completion gate allows blocked child](portable-completion-gate-allows-blocked-child.md) — no Python validator here, so a blocked child can still terminate and open a PR +- [Epic-child rebase shared-memory conflict](epic-child-rebase-shared-memory-conflict.md) — the only rebase conflict is the shared MEMORY.md index; union it, no rebuild needed +- [Epic-child PR-gate gotchas](epic-child-pr-gate-gotchas.md) — isolated-worktree collect_pr_context writes to the wrong checkout; the hook reads nested epic_context +- [Parallel preparation children share one worktree](parallel-preparation-children-shared-worktree.md) — prep-mode children run concurrently in ONE dir; use a child-scoped checkpoint path +- [Parallel children conflict on agent-memory index](parallel-epic-children-conflict-on-agent-memory-index.md) — late child PRs conflict ONLY on MEMORY.md index lines; resolve by union +- [Epic-child self-merge: step9 passed vs verified](epic-child-self-merge-step9-passed-vs-verified.md) — the merge hook needs "passed", the MCP validator rejects it; flip to "verified" after +- [Epic-child agent-memory merge conflicts](epic-child-agent-memory-merge-conflicts.md) — CONFLICTING solely on shared MEMORY.md index files; union, then re-verify post-merge +- [Epic-child nullable fan-in debt is deferred](project_epic_child_nullable_fanin_debt_deferred.md) — cross-child CS86xx fan-in is the capstone's job; don't over-remediate sibling files +- [C# coverage has two denominators](csharp-coverage-denominator-two-figures.md) — filtered first-party ~85.9% clears the gate, unfiltered ~70.4% doesn't; measure before trusting +- [Preflight catches vacuous gates](preflight-catches-vacuous-gates.md) — MCP `ok:true` is not enough; executor preflight found 6 gates that passed while verifying nothing +- [Bash tool mangles MSBuild switches](bash-tool-mangles-msbuild-switches.md) — `/m` becomes `M:/` (MSB1008); run C# tools via `pwsh -NoProfile` with absolute paths +- [Analyzer gate is vacuous without /t:Rebuild](msbuild-analyzer-gate-vacuous-without-rebuild.md) — `/t:Build` after any earlier build skips CoreCompile and compiles NOTHING at EXIT 0 +- [Aggregate vstest crash: isolate per assembly](vstest-aggregate-crash-isolate-per-assembly.md) — "Test host process crashed" is environmental; re-run per assembly with /InIsolation +- [Direct-csproj build facts (AnyCPU; CS2002)](csharp-direct-csproj-build-facts.md) — a single project needs `AnyCPU` (no space) while the .sln needs `"Any CPU"`; TWAE doesn't promote CS2002 +- [Model-routing hook reads the canonical path only](model-routing-hook-reads-canonical-path-only.md) — it hardcodes artifacts/orchestration/orchestrator-state.json; a child-scoped file alone is blocked +- [No helper scripts under evidence/](feedback_no_helper_scripts_under_evidence.md) — feature-review's language match is extension-only and path-blind; one retained `.ps1` forces a coverage FAIL +- [One executor per worktree](one-executor-per-worktree.md) — a stale checkpoint is NOT a dead delegation; never launch a second executor into a live worktree +- [Removing a halt requires branch propagation](removing-a-halt-requires-branch-propagation.md) — converting a HALT into a recorded blocker strands downstream tasks; propagate to ALL consumers diff --git a/.claude/agent-memory/orchestrator/feedback_no_helper_scripts_under_evidence.md b/.claude/agent-memory/orchestrator/feedback_no_helper_scripts_under_evidence.md new file mode 100644 index 000000000..a9f6be249 --- /dev/null +++ b/.claude/agent-memory/orchestrator/feedback_no_helper_scripts_under_evidence.md @@ -0,0 +1,12 @@ +--- +name: no-helper-scripts-under-evidence +description: Tell executors never to commit a helper .ps1/.py/.ts script under a feature's evidence/ tree; feature-review's language-set match is extension-only and path-blind, so it forces a mandatory-coverage FAIL +metadata: + type: feedback +--- + +Instruct every `atomic-executor` delegation to capture a helper script's OUTPUT into the evidence `.md` artifact and NOT to commit the script file itself anywhere under `<FEATURE>/evidence/`. + +**Why:** On #394 (utilitiescs-test-cs2002-duplicate-compile-entry) the executor retained a 27-line `duplicate-sweep.ps1` under `<FEATURE>/evidence/baseline/` "for reproducibility". `feature-review`'s `Get-ChangedLanguageSet` matches on file extension alone and is completely path-blind — it does not care that the file sits under a docs/evidence tree rather than production source. One retained `.ps1` therefore put PowerShell into the branch's changed-language set, which triggers the mandatory coverage-verification rule, which has no artifact and no Pester test behind it. Result: a FAIL and a full remediation cycle (planner + executor + reaudit) on a branch whose only real change was deleting one line from a `.csproj`. The plan had only ever required capturing the script's output. + +**How to apply:** Put the prohibition in the delegation prompt, not just in the plan. When a plan task needs a non-trivial shell/XML/parsing step, the task should say "run the command and record its command text and complete output in the evidence artifact" — never "write a script and commit it". If a helper script has already been committed, the proportionate remediation is `git rm` it (the sibling `.md` artifact already carries its logic and output verbatim), not building out Pester/PoshQC/coverage tooling for a one-off audit helper. Applies equally to `.py`, `.ts`, `.psm1`, `.psd1`. See [[feature-review-coverage-85-floor-trap]] for the adjacent coverage-gate trap. diff --git a/.claude/agent-memory/orchestrator/pr-context-summary-unreliable-gh-and-classification.md b/.claude/agent-memory/orchestrator/pr-context-summary-unreliable-gh-and-classification.md index 7825b4c9d..c9a65f73c 100644 --- a/.claude/agent-memory/orchestrator/pr-context-summary-unreliable-gh-and-classification.md +++ b/.claude/agent-memory/orchestrator/pr-context-summary-unreliable-gh-and-classification.md @@ -15,4 +15,6 @@ metadata: **How to apply:** Trust the bundle for base/head/merge-base, autoclose candidates, and the additional-context-file enumeration. For PR creation feasibility, run `which gh && gh auth status`. For the PR body's "What Changed", read the actual diff. Note the autoclose list may also contain non-issue tokens (e.g. `#COV-001`, an exception ID) — emit `Closes` only for the real canonical issue number. +**Stale-content variant (verified 2026-08-10, #394 in an agent worktree):** `collect_pr_context` returned `ok:true` and listed the worktree artifact paths, but did NOT overwrite an existing `artifacts/pr_context.summary.txt` that a `feature-review` subagent had hand-authored earlier in the same run. The stale file still described a file the remediation cycle had since deleted, so authoring the PR body from it would have described the wrong diff. Always read the summary after the collector call and check its head/merge-base SHAs against `git rev-parse HEAD` / `git merge-base`; if they do not match, regenerate the summary yourself before authoring. + **Worktree write quirk (verified 2026-07-08, #264 in an agent worktree):** when run with `workspace_root` set to an agent worktree, `collect_pr_context` returned `ok` and listed worktree artifact paths, but wrote NOTHING to the worktree `artifacts/` and did NOT refresh the main-checkout copy either (its `pr_context.summary.txt` kept a stale mtime from a prior feature's run). The `enforce-pr-author-skill.ps1` hook checks `artifacts/pr_context.summary.txt` relative to the gh-invocation cwd (the worktree) and requires `receipt.created_at` strictly newer than that file's mtime. Fix: generate `artifacts/pr_context.summary.txt` yourself in the worktree from the real `git log`/`git diff --stat base...HEAD`, then author `pr_body_<N>.md`, compute the SHA-256, and write the receipt with `created_at` newer than the summary you just wrote. The hook validates the receipt/body/SHA and the summary's existence+mtime — not the summary's content — so a self-authored summary satisfies it.