Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
922f477
docs(issue-648): seed active minor-audit bug folder and acceptance cr…
drmoisan Sep 1, 2026
eaec155
docs(issue-648): record preparation research findings
drmoisan Sep 1, 2026
5f10cdb
docs(issue-648): record preflight-ready minimal-audit plan
drmoisan Sep 1, 2026
5000513
chore(agent-memory): record issue-648 planner and researcher findings
drmoisan Sep 1, 2026
47e4af8
chore(agent-memory): record planner validator tool-surface constraint
drmoisan Sep 1, 2026
f1f5830
docs(issue-648): apply preflight round 1 revisions to plan
drmoisan Sep 1, 2026
ee5d77b
docs(issue-648): apply preflight round 2 revisions to plan
drmoisan Sep 1, 2026
a167046
docs(issue-648): apply preflight round 3 revision to plan
drmoisan Sep 1, 2026
993ad48
chore(agent-memory): record clean-tree gate ordering remedy
drmoisan Sep 1, 2026
937052c
chore(agent-memory): record issue-648 orchestrator lessons
drmoisan Sep 1, 2026
c418f93
Merge branch 'main' into bug/wpfuidispatchertests-ungated-static-swap…
drmoisan Sep 1, 2026
84c9adc
Merge remote-tracking branch 'origin/main' into bug/wpfuidispatcherte…
drmoisan Sep 1, 2026
2ecc00c
docs(issue-648): reconcile plan citations against advanced origin/main
drmoisan Sep 1, 2026
8d93397
fix(quickfiler-test): route WpfUiDispatcherTests static swap through …
drmoisan Sep 1, 2026
c5346ff
chore(issue-648): record the P2-T18 commit artifact and close the pla…
drmoisan Sep 1, 2026
08868ba
docs(issue-648): replace raw cobertura evidence with jacoco projections
drmoisan Sep 1, 2026
6f45546
docs(issue-648): record feature-review audit artifacts
drmoisan Sep 1, 2026
d51617f
docs(agent-memory): record issue 648 execution and review lessons
drmoisan Sep 1, 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
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,35 @@ vacuous, the fix is either a single-line literal from the same construct (`.Subs
its own line, or the full assignment line) or, preferably, a named test whose node ID is
stable under reformatting.

## Execution-time remedy when it reaches the executor (2026-09-01, #648)

Preflight does not always catch it, because the literal does not exist in the tree yet: the plan
directs the executor to CREATE it. #648's `[P1-T2]` directed
`await UiThreadDispatcherFixture.BeginTransactionAsync().ConfigureAwait(false)` and `[P1-T6]` then
asserted the token `UiThreadDispatcherFixture.BeginTransactionAsync` matched a line. At the statement's
16-column indent the expression is 121 chars, so CSharpier emits the three-line chain break — the same
shape it had already produced at the sibling call site
`QuickFiler.Test/Controllers/QfcItemController.UiThreadDispatcherFixtureTests.cs:47-49`. The token then
matches nothing whatever the executor writes.

**Confirm it empirically, do not infer it.** Write the directed form, run
`dotnet tool run csharpier check <file>`, and read the complaint. If the only complaint is
`different line endings`, the content shape you wrote IS CSharpier's output, so the chain break is not
avoidable by hand-formatting and the gate is genuinely unsatisfiable in that shape.

**Remedy that preserves the directed semantics:** split the single expression into two statements so
the qualified call lands alone on one line under the width limit.

```csharp
Task<UiThreadDispatcherTransaction> gate =
UiThreadDispatcherFixture.BeginTransactionAsync();
UiThreadDispatcherTransaction transaction = await gate.ConfigureAwait(false);
```

A one-invocation chain is not broken by CSharpier; it breaks after `=` instead, which keeps
`Receiver.Method` contiguous. Same method, same awaited task, same `ConfigureAwait(false)`. Record the
deviation and its measurement in the verifying task's artifact — the deviating task's own acceptance
was "the four structural checks pass", so the shape that makes them pass is the shape it demanded.

Related: [[feedback-verify-line-citations-with-numbered-output]],
[[csharpier-formats-xml-print-width]].
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,16 @@ baseline check had exited 0 over 1554 files.
[[count-idiom-pitfalls-csharpier-and-measureobject]].
- Running `csharpier format` immediately after Writing each new file — before the final QA loop —
avoids the restart entirely, but only if the plan does not gate on a pristine first pass.

**It is not limited to NEW files (2026-09-01, #648).** Overwriting an EXISTING tracked CRLF `.cs` file
with the Write tool also lands LF, so a single-file plan that edits one long-standing file still burns
a mandatory loop iteration. #648's `[P2-T1]` executed twice for exactly this reason and recorded
`LoopIterations: 2`. Any plan with a Phase 2 loop ceiling must budget the restart even when it creates
no new file.

**A SHA-256 pair DOES discriminate where porcelain does not.** The bullet above is right that
`git status --porcelain` is byte-identical across a repairing format run. #648's `[P2-T1]` recorded
`SHA256Before`/`SHA256After` instead and the pair separated the two executions cleanly: unequal on the
repairing run (`3fa83d3e…` → `c7f4ae79…`), equal on the clean one (`c7f4ae79…` both sides). Prefer a
content hash over a porcelain pair whenever a plan needs a write-mode formatter observation and cannot
use a pre-format `check` exit code.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ reason: eleven earlier Phase 5 artifacts were also still uncommitted.
- Flag it in the completion report as a plan-text/mechanics tension so the planner can fix the
wording next time. Suggested planner fix: word the gate as "names at most one path, and if it names
one, that path is the plan file", or add an intermediate commit before the terminal capture.
- Second validated planner fix (issue #648 plan, cleared at preflight round 4): order the commit task
as commit -> **capture and retain** `git status --porcelain <pathspec>` -> write the artifact from
the retained output -> flip the checkbox -> a second `git add`/commit that the task text explicitly
declares housekeeping and outside its acceptance. The capture must precede the artifact write
because the artifact itself lives under the status pathspec; a capture taken afterwards always sees
it as untracked. This makes the residual genuinely empty at capture time and keeps the unverifiable
final step out of the acceptance clause. The remaining gap — nothing executes a check after the
second commit — is the irreducible fixpoint and is acceptable.
- Scope every terminal `git status` by pathspec. `.claude/agent-memory/**` is tracked and other agents
write to it, so an unscoped clean-tree gate is unsatisfiable for reasons unrelated to the feature.
See [[project_agent_memory_tracked_breaks_unscoped_git_gates]].
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ The TaskMaster worktree pins a repo-local .NET SDK and routes `dotnet` through a

**Meaningful nullable gate on a touched legacy project (the correct recipe):** the legacy first-party projects (e.g. QuickFiler) are NOT nullable-annotated and produce a large pre-existing error population when genuinely recompiled under the nullable gate (QuickFiler ~540 unique errors; `-m` parallel double-reports so `grep -c` shows ~1080). The baseline "0 errors" only means nothing recompiled. To validate a change without the vendored noise: (1) restore all outputs with a plain analyzer `-t:Build` (non-nullable, rebuilds cleaned vendored projects to 0 errors); (2) `touch` only the changed source files; (3) run the solution `-t:Build` nullable gate — MSBuild recompiles only the touched projects (their sources are newer) and leaves up-to-date vendored/other projects skipped, so their pre-existing nullable debt does not surface. To PROVE a change adds zero new nullable diagnostics, capture a controlled pre-change count: `git stash push -- <changed .cs files>`, restore outputs, touch+nullable-build, count errors; then `git stash pop`. Identical pre/post error counts with every touched-file diagnostic merely line-shifted by the inserted-line count = no-regression proof. After any Rebuild/stash dance, finish with a plain analyzer `-t:Build` to restore Debug outputs before vstest.

**Update (2026-09-01, issue #648): BOTH policy gates are fully green on a solution-wide `/t:Rebuild`, and the whole "genuine recompile surfaces a big pre-existing error population" workaround is currently unnecessary.** On `bug/wpfuidispatchertests-ungated-static-swap-648`, based on `origin/main` at `c7b4f08f`, a cold worktree ran the two CLAUDE.md-literal commands verbatim — `msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true` and the same with `/p:TreatWarningsAsErrors=true` — and each produced **`Build succeeded.` / 5 Warning(s) / 0 Error(s)`, exit 0**, with 63 and 67 `CoreCompile:` entries respectively, so these were genuine recompiles and not incrementality no-ops. All 5 warnings on both gates are the identical System.Reactive 7.0.0 `packages.config` notice, one per owning project (`UtilitiesCS`, `ToDoModel`, `QuickFiler`, `TaskMaster`, `UtilitiesCS.Test`); zero are compiler or analyzer diagnostics. The vendored `SVGControl` / `UtilitiesSwordfish.NET.General` error population recorded above is gone from this solution. Note the current policy commands do **not** pass `/p:Nullable=enable` and **do** use `/t:Rebuild` — the inverse of the older entries here; do not reintroduce the flag. The stash-dance and `CoreCompileInputs.cache`-delete recipes below remain recorded for the case where the population returns, but re-verify before reaching for either.

**Pre-existing CS0618 in first-party:** UtilitiesCS/TaskMaster use obsolete IAsyncEnumerable `SelectAwait`/`WhereAwait`/`ForEachAwaitAsync` overloads (warning-only; not promoted under the analyzer `-t:Build` step which omits TWAE). An incremental baseline build may not re-emit them while a later full build does — explains baseline-vs-final warning-count deltas without any new diagnostic.

**Coverage:** repo uses `dotnet-coverage collect ... -- <vstest> <asm> /Settings:scripts/vscode/TaskMaster.cli.runsettings /InIsolation` producing Cobertura. Raw repo-wide @line-rate (~71.6%) includes vendored Swordfish/SVGControl; first-party denominator (#197) excludes them. The helper `Invoke-MSTestWithCoverage.ps1` throws on a single-assembly SearchRoot (`$testAssemblies.Count` under StrictMode when the filter yields one string) — invoke dotnet-coverage directly instead. See [[project_coverage_firstparty_denominator_method]] and [[project_qfc227_coverage_tooling]] (plain `dotnet-coverage merge -f cobertura` on a `.coverage` file worked fine for `UtilitiesCS.Test`, contrary to an earlier QuickFiler-session note that it produced empty output).
Expand Down
Loading
Loading