Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
22b5c2b
docs(469): initialize active bug folder from the existing open issue
drmoisan Aug 29, 2026
c0c8331
docs(469): record residual-scope verification research
drmoisan Aug 29, 2026
6b6e1ff
docs(469): rewrite the spec against verified residual scope
drmoisan Aug 29, 2026
513e5e4
docs(469): add the atomic plan for the comment-accuracy scope
drmoisan Aug 29, 2026
0073c5a
chore(memory): record 469 preparation learnings
drmoisan Aug 29, 2026
762b96b
docs(469): apply preflight round-one revisions to the plan
drmoisan Aug 29, 2026
19aeda5
chore(memory): record orchestrator learnings from the 469 preparation
drmoisan Aug 29, 2026
ca4df41
Merge remote-tracking branch 'origin/main' into bug/qfc-collection-mo…
drmoisan Aug 29, 2026
2698f58
chore(memory): extend the 469 planner seams with round-one findings
drmoisan Aug 29, 2026
2f1b302
docs(469): apply preflight round-two revisions to the plan
drmoisan Aug 29, 2026
6d2c067
docs(469): apply preflight round-three revisions to the plan
drmoisan Aug 29, 2026
31dcb06
chore(memory): record preflight learnings from the 469 preparation
drmoisan Aug 29, 2026
30d2aeb
Merge remote-tracking branch 'origin/main' into bug/qfc-collection-mo…
drmoisan Aug 30, 2026
be9bedb
Merge remote-tracking branch 'origin/main' into agent-aa906dbb07d3405…
drmoisan Aug 31, 2026
fafb881
docs(quickfiler): align diagnostics defect documentation
drmoisan Aug 31, 2026
c70927b
docs(quickfiler): record issue 469 validation evidence
drmoisan Aug 31, 2026
6fbdbc7
docs(review): add issue 469 audit artifacts
drmoisan Aug 31, 2026
87757e3
docs(qa): record issue 469 P6 gate evidence
drmoisan Aug 31, 2026
d69a572
docs(qa): reconcile issue 469 CSharpier baseline evidence
drmoisan Aug 31, 2026
b7cbd11
docs(qa): reconcile issue 469 command evidence
drmoisan Aug 31, 2026
e8e628f
ci(format): recover CI formatter configuration
drmoisan Aug 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude/agent-memory/atomic-executor/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
- ["Skip the pointless drain" note makes a negative test vacuous](project_preflight_drain_scope_optimization_note_makes_test_vacuous.md) — a cosmetic "path
- [Sanitisation task cannot sweep its own record](project_sanitisation_task_cannot_sweep_its_own_record.md) — exactly one resi
- [Conjunctive criteria break the one-artifact citation rule](project_preflight_conjunctive_criterion_citation_gap.md) — "cites exactly o
- [Pre-edit gate cites the post-edit replacement table](project_preedit_gate_cites_postedit_replacement_table.md) — baseline asserts s
- [Caller-stated preflight count drifts before execution](project_caller_stated_preflight_count_drifts_before_execution.md) — 42 quoted vs 48 measured; read the plan's own clause
- [Orchestrator override does not satisfy an AC](project_orchestrator_override_does_not_satisfy_an_ac.md) — proceed past the gate,
## Build / toolchain environment
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
name: preedit-gate-cites-postedit-replacement-table
description: A Phase-0 pre-edit citation gate that sources its literals from the plan's own "replacement text" table asserts post-edit strings before the edit, so it can only fail
metadata:
type: project
---

A baseline citation-re-verification task that says "the N pre-edit tokens named in the R<k> table
each have count 1" is unsatisfiable when the R<k> table is the plan's *replacement* text table,
whose value column holds post-edit text. Before any edit those literals have count 0, so the gate
fails and the executor halts in Phase 0. The pre-edit literals normally live in a separate
"Currently reads" / verified-facts table earlier in the plan.

The companion signal is that the task's command block contains no command producing those N counts,
while the acceptance bullet demands them — an acceptance condition naming an observation the task
never makes.

**Why:** Plans that renumber or restate literals in two tables (current text and replacement text)
invite a cross-reference to the wrong one. Observed on the issue #469 comment-accuracy plan at
`[P0-T15]`, round 3, after the same text had survived two earlier preflight rounds.

**How to apply:** For every pre-edit / baseline assertion, check which internal table the plan cites
and confirm that table's value column holds the *pre*-edit spelling. Then check the task's command
block actually emits each asserted count. Related: [[project_preflight_gate_literal_extract_from_plan_not_retype]],
[[project_exact_count_gate_vs_remediation_loop]].
2 changes: 2 additions & 0 deletions .claude/agent-memory/atomic-planner/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- [#677 R1–R8](project_677_keyboard_focus_leak_plan_seams.md) — ctor param REJECTED (5 reflection-arity tests); typed harness for compile-red; internal 9-arg ctor, never ambient SetSynchronizationContext; per-file non-vacuity floors
- [#635](project_635_reflective_caller_audit_plan_seams.md) — evidence-only audit: tracked plan inflates its own sweep; scan hits its own pattern list; spec said six sites, tree has eight; pathspec breadth inflates a count
- [#440 R1–R4](project_440_breadcrumb_left_arrow_plan_seams.md) — deletion-only change voids a diff-derived changed-line gate; `(Rebuild target(s))`, NOT `(Rebuild target)`; `.csharpierignore` matches the `.cobertura.xml` suffix; `.dotnet-sdk` IS gitignored (`.gitignore:350`); cite an AC by sentence only after counting its sentences; `Include` resolves against the declaring project's dir
- [#469 R1–R3](project_469_comment_accuracy_plan_seams.md) — defect-number SWAP voids whole-file token gates; `- [x] AC1` is a prefix of `AC10`; unconditional base-merge task; Phase 0 insert renumbers artifact FILENAMES; pre-edit vs post-edit table cited wrong; evidence dir rule ≠ recorded path form
- [#644](project_644_ac16_referral_revision_seams.md) — AC's named instrument prints no figure; substitute's noise (~0.028pp) exceeds the 0.01pp delta; check-off task → referral task pinning the UNCHECKED state
- [#644 cycle 2](project_644_cycle2_sweep_gate_evasion_seams.md) — rewording out of a detector's match set is gate evasion; SHA-256 pair for untracked prior artifacts; bound the porcelain `??` scope
- [#644 PA-7](project_644_pa7_redaction_plan_seams.md) — untracked audit artifact still enters main; name-status diff blind to it; mandated literal contradicted its own stated intent
Expand Down Expand Up @@ -66,6 +67,7 @@
- [CSharpier "Formatted N files" is processed count](csharpier-formatted-n-is-processed-count.md) — a restart-on-rewrite loop keyed on it never terminates; define rewritten-count via before/after SHA-256
- [Repo-wide csharpier format breaks zero-diff ACs](csharpier-repowide-format-breaks-zero-diff-acs.md) — scope the mutating pass to the plan's own path list
- [.csharpierignore scope](csharpierignore-scope-packages-config.md) — only `*.csproj`/`*.props`/`*.targets` are excluded; `packages.config` is NOT
- [.gitignore bracket classes defeat a literal grep](gitignore-bracket-classes-defeat-literal-grep.md) — `[Tt]est[Rr]esult*/` does ignore `TestResults/`; never claim a path is tracked from a literal search
- [`/Logger:trx` needs `/ResultsDirectory`](trx-needs-resultsdirectory.md) — TRX lands in `TestResults\` relative to cwd; give each run task its own `p#-t#` subdirectory
- [`[expect-fail]` needs a synchronous seam](expect-fail-needs-a-synchronous-seam.md) — async-void boundaries false-GREEN; re-run RED analysis after scoping `Times.Never()`
- [Invoke-MSTestWithCoverage.ps1](reference_invoke_mstest_with_coverage_script.md) — canonical full-suite Cobertura runner
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
name: gitignore-bracket-classes-defeat-literal-grep
description: Never conclude a path is untracked from a literal grep of .gitignore — this repo writes bracketed character classes ([Tt]est[Rr]esult*/, [Bb]in/, [Oo]bj/) that a literal search misses
metadata:
type: feedback
---

Before asserting in a plan that some path is or is not gitignored, search `.gitignore` with a
character-class-tolerant pattern (or read the file), never with the literal directory name.

**Why:** This repository's `.gitignore` uses the Visual Studio template's bracketed-case form. A grep
for the literal `TestResults` returns nothing even though `.gitignore:39` is `[Tt]est[Rr]esult*/`,
which does match `TestResults/`. On the #469 plan this produced a false factual claim in the plan
prose ("`TestResults` and `*.trx` are NOT ignored") that survived into a self-review enumeration and
was only caught by [[trx-needs-resultsdirectory]], which had recorded the real line. A plan that
states a wrong tree fact is a defect even when the command it justifies happens to be harmless.

Known bracketed entries at the time of writing: `:26` `[Bb]in/`, `:27` `[Oo]bj/`, `:39`
`[Tt]est[Rr]esult*/`, `:40` `[Bb]uild[Ll]og.*`. Plain entries include `:144` `coverage/*`.

**How to apply:** Any plan task whose acceptance depends on a clean tree, or whose prose explains
where a tool's output lands, must cite the `.gitignore` line number and quote the entry verbatim in
its bracketed form. Grep with a pattern like `[Tt]est|[Bb]in|[Oo]bj` or just read the first ~60 lines
of `.gitignore`. Relatedly, do not route tool output somewhere merely because a literal grep
suggested the default location was tracked. See [[agent-memory-is-tracked-scope-git-gates]] for the
converse trap, where a path that looks like tooling scratch actually IS tracked.
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
---
name: project-469-comment-accuracy-plan-seams
description: Issue #469 plan seams — defect-number SWAP voids whole-file token gates; digit-only edits make numstat exact; terminal clean-tree acceptance unreachable; scoped format vs repo-wide check contradiction; base-merge task + Phase 0 renumber; pre-edit vs post-edit table mix-up; evidence dir rule does not constrain recorded path form
metadata:
type: project
---

Issue #469 turned out to be documentation-accuracy only: three of four defects were already merged,
and the fourth's residual action is open issue #629. The plan is comment/XML-doc/`because:`-string
edits with zero executable-line change.

**A renumbering SWAP makes every whole-file token gate vacuous.** Both `Issue #469 defect 1` and
`Issue #469 defect 2` already existed in BOTH edited files at branch head, so "the file contains
`Issue #469 defect 2`" passes before any work. Every gate had to become a combined single-line token
pairing the defect number with its distinguishing text (`Issue #469 defect 2: exactly one diagnostics
line`), plus the complementary must-become-zero token. This generalises to any A-to-B relabelling
where both labels are already present.

**Why:** a swap conserves the multiset of tokens; only their pairing with surrounding text changes.
**How to apply:** for any swap/rename plan, gate on the PAIRING, and always author the zero-match
companion alongside the one-match assertion.

**A single-character substitution makes exact `--numstat` derivable.** All eight renumbering sites
were one-digit changes on one physical line each, so line length and line count are invariant and the
plan could assert exactly `2 2` and `6 6` per file. Verify the digit-only property by reading each
line before promising an exact numstat; a rewrap would void it.

**Spec line counts were off by one and research line counts were wrong.**
`QfcCollectionControllerDefects468MoveTests.cs` is 497, not the spec's 498;
`QfcHomeController.Metrics.cs` is 215, not the research doc's "232, approximate" and not the 216 the
plan's own first pass asserted in four places; and the research cited `:351` for a site that is
actually `:352`. Re-derive every count and citation even when two upstream documents agree, and count
with a whole-file line count rather than by reading a tail window — a `cat -n` tail read of a file
ending in a final newline is easy to misread as one line longer than it is. See
[[verify-test-provenance-before-planning-deletion]].

**Preflight round 1 (version 0.3) seams — the ones a first pass will miss:**

- **A terminal "clean tree" acceptance is unreachable when the task must tick its own checkbox.**
P7-T17 asserted empty `git status` over a pathspec containing the plan file it must mark `[x]` and
the artifact it must write. Committing either re-dirties the other. Author the acceptance as
"names no path other than the plan file and this task's own artifact" and state that committing
those two is the orchestrator's step after plan completion.
- **A scoped format pass and a repo-wide `check .` contradict each other.** If the format task
declines to sweep pre-existing drift (to protect a zero-executable-line-change AC), the check task
cannot demand repo-wide exit 0. Make the check baseline-relative: reported set must be a SUBSET of
the Phase 0 enumeration. Then re-check the clean-pass declaration task, which will still say "no
failure" and now needs "acceptance held, not exit code 0".
- **Branch on the exit code, never on an unobserved output literal.** The first pass keyed the format
branch on counting lines containing `Was not formatted` at CSharpier 1.2.6. No run was cited. If
the spelling differs the count is 0, the repo-wide mutating branch is taken silently, and the AC it
protected disappears.
- **Evidence captured before a mutating formatter is stale.** The changed-line-classification and
numstat evidence all ran in Phases 2-5; Phase 6's `format` then rewrites the same four files.
Re-assert the per-file numstat inside the format task itself.
- **`- [x] AC1` is a prefix of `- [x] AC10`..`AC13`.** Assert the spec's em-dash form
`- [x] AC1 —`. True-only-because-it-runs-first is not an assertion.
- **A `git diff origin/main` footprint enumeration must include what earlier branch commits added.**
This branch's own `issue.md` and `research/` document appear in every `origin/main`-anchored diff,
so an exact enumeration omitting them is unsatisfiable. Also scope the pathspec: tracked
`.claude/agent-memory/` modifications by other agents in the same worktree otherwise show up. See
[[agent-memory-is-tracked-scope-git-gates]].
- **AC10 named `vstest.console.exe /EnableCodeCoverage`, which no task runs.** The runsettings file
declares no coverage `DataCollector` and the pipeline is `dotnet-coverage`. Record the AC-to-task
realisation mapping and state the wording divergence explicitly rather than silently substituting.
- **Two contradictory totals in one sentence.** "must be 20" and "14 added and 14 deleted, 28 diff
lines" coexisted; a downstream task already depended on 28. Recompute every arithmetic figure from
its per-file components.

**Preflight round 2 (version 0.4) seams:**

- **A plan with `git diff origin/main` gates needs a Phase 0 task that MERGES `origin/main`.** Every
numstat/name-only/footprint gate is anchored to `origin/main`, so an upstream advance between
planning and execution silently re-scopes them. The task is unconditional — `git merge` exits 0 and
prints `Already up to date.` when there is nothing to do — and it must precede every baseline
capture, because a merge landing after a baseline invalidates that baseline (most directly the
`BASELINE_PASSED:` count). Use `merge`, never `rebase`: the force-push guard rejects the rewritten
history. Exit code alone is not evidence; re-assert rev-equality plus the gated line counts.
- **Inserting one Phase 0 task forces a whole-phase renumber, and the artifact FILENAMES carry the
task ID too.** The uppercase cross-references were 32 across 27 lines; the lowercase
`p0-t<N>-<slug>.<timestamp>.md` evidence names and a `/ResultsDirectory:TestResults\p0-t<N>` path
were a second, disjoint set the reference count did not cover. Remap both, DESCENDING (T14→T15
first), so a `replace_all` never collides with a number it has not yet processed.
- **A conditional branch stated only in prose is not executable.** P6-T1's prose described a scoped
`csharpier format` on the non-zero-baseline branch, but its command block held only the repo-wide
`format .`. An executor following the block verbatim takes the branch the prose exists to prevent.
Every branch a task's prose describes needs its own line in the task's command block.
- **`acceptance-criteria-tracking` forbids modifying criterion text, so "check it off, appending the
evidence path" is a policy conflict.** Reword to record the path in the task's progress output; the
criterion line changes only in its checkbox marker.
- **A base merge silently shifts line citations in files the plan does not edit.** The merge added one
`<Compile Include>` to `QuickFiler.Test.csproj`, moving two cited entries from `:135`/`:155` to
`:136`/`:156`. After ANY base reconciliation, re-derive every citation into a merged file, not only
into the files the plan edits.
- **A class-level summary that enumerates all four defect numbers is not a defect-N citation.**
`QfcCollectionControllerDefects468MoveTests.cs:17-18` reads "issue #469 defects 1," / "2, 3 and 4",
so it is invariant under a 1-for-2 swap. Grouping it with the defect-3 sites was a misclassification
even though the operative "needs no edit" conclusion was right.

**Preflight round 3 (version 0.5) seams:**

- **A plan that quotes both PRE-edit and POST-edit text in two tables will get the wrong one cited.**
P0-T15's baseline bullet said "the eight pre-edit tokens named in the R3 table". The R3 table's
third column is headed `Becomes` and holds POST-edit text, every token of which has count 0 at
branch head — so a Phase 0 acceptance demanding count 1 for them halts the executor before any
work. Name the SOURCE TABLE and its COLUMN HEADER in the bullet, and quote the eight literals
inline rather than referring to a table by name.
- **A re-verification task must produce every count its acceptance asserts.** P0-T15 listed eight
token counts in its acceptance but its PowerShell block held no command producing them. Walk each
acceptance clause of every command-bearing task back to a line in that task's own block.
- **Where-artifacts-are-written does not constrain what-paths-they-record.** The evidence-location
rule and the `enforce-evidence-locations.ps1` hook both check the DIRECTORY. Any acceptance
demanding verbatim tool output (MSBuild diagnostics, CSharpier unformatted-file enumerations)
publishes absolute paths carrying the account name, machine name and drive letter once a staging
task commits `evidence/`. Add an explicit "recorded paths are repository-relative" clause naming
the tasks, and carve out counts/exit codes/summary lines so the assertions keep their observables.
See [[../_shared_no_absolute_host_paths]].

**Local facts confirmed this pass:** the CSharpier manifest is `dotnet-tools.json` at the repository
ROOT (there is no `.config/` directory); `packages/` and `QuickFiler.Test/bin/Debug/` are absent from
a fresh agent worktree so restore-then-build must precede any test-count baseline;
`Invoke-MSTestWithCoverage.ps1` calls `Assert-CoberturaLineCoverageThreshold`, which throws below 80%
BEFORE the Koverage post-processing writes the XML, so a baseline task must record the thrown
percentage and continue rather than treating it as this change's failure. Related:
[[project_494_threshold_reconciliation_plan_seams]], [[reference_invoke_mstest_with_coverage_script]].
2 changes: 2 additions & 0 deletions .claude/agent-memory/orchestrator/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@
- [Epic-child nullable fan-in debt is deferred](project_epic_child_nullable_fanin_debt_deferred.md) — cross-child CS86xx fan-in is the
- [C# coverage has two denominators](csharp-coverage-denominator-two-figures.md) — filtered first-party ~85.9% clears the gate, unfiltered
- [lines-covered is nondeterministic; lines-valid is not](coverage-lines-covered-is-nondeterministic.md) — same-tree runs drift up to 4
- [Verify an issue is open in SUBSTANCE](verify-issue-still-open-in-substance.md) — grep the source for the issue number before preparing; the residual may already be its own issue
- [Reconcile plan numbers against your own measurements](reconcile-plan-numbers-against-your-own-measurements.md) — a stale line count passes a citation-only review and halts Phase 0
- [Preflight catches vacuous gates](preflight-catches-vacuous-gates.md) — MCP `ok:true` is not enough; executor preflight found 6 gates
- [Preflight: sweep task ordering + citation arity](preflight-sweep-task-ordering-and-citation-arity.md) — name both sweeps early; a
- [Revert plans must check test provenance](revert-plans-must-check-test-provenance.md) — verify each test against the pre-change sha; a
Expand Down
Loading
Loading