diff --git a/.github/workflows/README.md b/.github/workflows/README.md
index 8daec7969..0a4347b07 100644
--- a/.github/workflows/README.md
+++ b/.github/workflows/README.md
@@ -113,7 +113,7 @@ and GitHub restricts it by default from 2026-11-02.
| Secret | Holds |
| --- | --- |
-| `DEPENDABOT_REPAIR_APP_ID` | the numeric App identifier |
+| `DEPENDABOT_REPAIR_APP_ID` | the App's Client ID, passed to the token action's `client-id` input (the numeric App ID is not stored) |
| `DEPENDABOT_REPAIR_APP_PRIVATE_KEY` | the App's PEM private key |
A repository admin provisions both by hand. The procedure — creating the App, granting it contents
diff --git a/.github/workflows/dependabot-repair.yml b/.github/workflows/dependabot-repair.yml
index fa7eac91f..b9c2f4785 100644
--- a/.github/workflows/dependabot-repair.yml
+++ b/.github/workflows/dependabot-repair.yml
@@ -10,8 +10,8 @@ name: dependabot-repair
# name appears nowhere in this file: it is a security regression for a convenience gain, and GitHub
# restricts it by default from 2026-11-02.
#
-# Credential: a GitHub App installation token minted from DEPENDABOT_REPAIR_APP_ID and
-# DEPENDABOT_REPAIR_APP_PRIVATE_KEY. When those secrets are absent the token step fails, the job
+# Credential: a GitHub App installation token minted from the App's Client ID, stored in
+# DEPENDABOT_REPAIR_APP_ID, and the private key in DEPENDABOT_REPAIR_APP_PRIVATE_KEY. When those secrets are absent the token step fails, the job
# stops before it can push, and the pull request keeps the behaviour it has today. See
# .github/workflows/README.md for the degraded mode and the installation runbook.
@@ -48,7 +48,7 @@ jobs:
id: app-token
uses: actions/create-github-app-token@v3
with:
- app-id: ${{ secrets.DEPENDABOT_REPAIR_APP_ID }}
+ client-id: ${{ secrets.DEPENDABOT_REPAIR_APP_ID }}
private-key: ${{ secrets.DEPENDABOT_REPAIR_APP_PRIVATE_KEY }}
- name: Checkout the Dependabot branch
diff --git a/QuickFiler.Test/QuickFiler.Test.csproj b/QuickFiler.Test/QuickFiler.Test.csproj
index ad3ddafda..9fd57ab0b 100644
--- a/QuickFiler.Test/QuickFiler.Test.csproj
+++ b/QuickFiler.Test/QuickFiler.Test.csproj
@@ -5,7 +5,6 @@
-
Debug
@@ -534,7 +533,6 @@
-
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
diff --git a/SVGControl/app.config b/SVGControl/app.config
index 57e0ab003..05b1ceb18 100644
--- a/SVGControl/app.config
+++ b/SVGControl/app.config
@@ -12,11 +12,11 @@
-
+
-
+
diff --git a/docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md b/docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md
index f64e14259..b2d7b0e17 100644
--- a/docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md
+++ b/docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md
@@ -96,13 +96,13 @@ permissions listed in step 6 below and skip to step 10.
8. Under **Where can this GitHub App be installed?**, select **Only on this account**.
9. Click **Create GitHub App**.
-### Part B — Record the App ID and generate a private key
+### Part B — Record the Client ID and generate a private key
-10. On the App's settings page that appears after creation, locate the **App ID** in the "About"
- section near the top of the page and record it. The adjacent **Client ID** is also shown; record
- it as well, because the `actions/create-github-app-token` action now documents `client-id` as
- the recommended input and continues to accept the legacy `app-id` input. Neither value is a
- secret in the cryptographic sense, but this runbook stores the App ID as a repository secret to
+10. On the App's settings page that appears after creation, locate the **Client ID** in the "About"
+ section near the top of the page and record it. The numeric **App ID** shown beside it is not
+ needed: the repair workflow passes the Client ID to the `actions/create-github-app-token` action
+ as its `client-id` input, which the action documents as the recommended input. The Client ID is
+ not a secret in the cryptographic sense, but this runbook stores it as a repository secret to
keep the workflow configuration uniform.
11. On the same page, scroll to the **Private keys** section and click **Generate a private key**.
A `.pem` file downloads automatically. GitHub issues the key in PKCS#1 `RSAPrivateKey` PEM
@@ -126,9 +126,9 @@ permissions listed in step 6 below and skip to step 10.
19. Click **Settings** on the repository navigation bar.
20. In the sidebar's "Security" section, select **Secrets and variables**, then **Actions**.
21. Select the **Secrets** tab, then click **New repository secret**.
-22. Create the App ID secret:
+22. Create the Client ID secret:
- **Name** — `DEPENDABOT_REPAIR_APP_ID`
- - **Secret** — the App ID value recorded in step 10
+ - **Secret** — the Client ID value recorded in step 10
- Click **Add secret**.
23. Click **New repository secret** again and create the private key secret:
- **Name** — `DEPENDABOT_REPAIR_APP_PRIVATE_KEY`
@@ -151,7 +151,7 @@ permissions listed in step 6 below and skip to step 10.
id: app-token
uses: actions/create-github-app-token@v3
with:
- app-id: ${{ secrets.DEPENDABOT_REPAIR_APP_ID }}
+ client-id: ${{ secrets.DEPENDABOT_REPAIR_APP_ID }}
private-key: ${{ secrets.DEPENDABOT_REPAIR_APP_PRIVATE_KEY }}
- name: Check out the Dependabot branch
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/code-review.2026-09-30T10-30.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/code-review.2026-09-30T10-30.md
new file mode 100644
index 000000000..e06f8579a
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/code-review.2026-09-30T10-30.md
@@ -0,0 +1,91 @@
+# Code Review — package-manifest-consistency-residuals (Issue #929)
+
+- Artifact timestamp label: 2026-09-30T10-30 (caller-assigned)
+- Branch: `bug/package-manifest-consistency-residuals-929`; head `5ce3c8c3b`; source diff base `231e1c0b5`
+- Review method: Read, Grep and Glob over the item worktree (Bash forbidden by the caller); no command executed
+- Companion artifacts: `policy-audit.2026-09-30T10-30.md`, `feature-audit.2026-09-30T10-30.md`
+- Total blocking findings: **0**
+- Total non-blocking findings: **7** (code-level; the policy audit carries five further procedural or evidence-hygiene items)
+
+## Executive Summary
+
+The change is small, targeted and matches the bugfix workflow: a tree-reading regression test file was authored and observed red before the fixes and green after, the fixes are the minimal edits the issue names (two deleted `` lines, two corrected `bindingRedirect` lines, one workflow input rename with its documentation), and the only production PowerShell edit is a three-line comment refresh. The two added in-memory detector tests and the four tree tests follow the conventions of the sibling suites (`$PSScriptRoot`-resolved reads, Arrange/Act/Assert comments, `-Because` on every assertion, no mocks, no files written). All toolchain gates passed on the final iteration.
+
+No blocking defect was found. Seven non-blocking observations are recorded below; none changes behaviour and none is required before merge. Five are cosmetic or style; two are pre-existing conditions outside the diff that the review surfaces for follow-up (a wall-clock wait in a QuickFiler.Test timing test, and tracked `.csproj.bak` copies still carrying the removed token).
+
+## Findings Table
+
+| Severity | File | Location | Finding | Recommendation | Rationale | Evidence |
+|---|---|---|---|---|---|---|
+| Minor (non-blocking) | `QuickFiler.Test/Controllers/QfcDatamodelLivenessTests.cs` (outside the diff) | line 189 (`RemainingLoadActive_AcrossAsyncVoidFirstAwait_StaysTrueWhileLoaderProduces`), wait at line 172/192 | Test relies on a real five-second `Task.Wait(TimeSpan.FromSeconds(5))`; it failed once in local iteration 1 under the full parallel run and passed in the baseline and iteration 2 on the same tree. A second, different timing test (`QfcItemController.UiThreadDispatcherFixtureTests.cs` line 206) failed once on CI run 36722780748. | List for follow-up: replace the wall-clock wait with the deterministic completion signal the determinism rule requires, and examine the dispatcher-fixture test for the same class. Not a change for this branch. | `.claude/rules/general-unit-test.md` bans real wall-clock waits in test code; both tests are pre-existing and no `.cs` file changed here. | `evidence/qa-gates/p2-t7-mstest-coverage.iter1.2026-09-28T20-01.md`; `evidence/qa-gates/p2-t3-pester.iter2.2026-09-28T20-01.md` (run-level conclusion) |
+| Minor (non-blocking) | `QuickFiler.Test/QuickFiler.Test.csproj.bak`, `QuickFiler/QuickFiler.csproj.bak` (outside the diff) | whole files | Two of eight tracked `*.csproj.bak` copies still carry the `altcover` token after the live imports were removed. MSBuild does not read `.bak`, so AC1's project-file scope is satisfied. | List for follow-up: delete the eight tracked `.bak` copies (plan decision D12 deliberately left them). | Tracked backup copies of project files are stale duplicates that future censuses have to exclude by pathspec. | Grep `altcover` (case-insensitive) over the worktree excluding `docs/`; `evidence/baseline/p0-t1-worktree-anchor.2026-09-28T20-01.md` BAK-TRACKED list |
+| Minor (non-blocking) | `docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md` | line 301 | Sources entry still reads "Private key generation and App ID location (steps 10-12)" although step 10 now records the Client ID and states the App ID is not needed. | Reword to "Client ID location" when the runbook is next touched. | Comment/citation text drifted from the instruction it cites; the instruction itself (steps 10, 22, YAML sample) is correct. | Read of lines 99-106, 129-132, 154, 298-321 |
+| Minor (non-blocking) | `.github/workflows/dependabot-repair.yml` | line 14 | Header comment line is roughly 150 characters; the surrounding block wraps near 100. | Re-wrap the two-line credential sentence when the file is next edited. | Readability only; actionlint does not police comment width. | Read of lines 13-16 |
+| Minor (non-blocking) | `tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1` | lines 92-110 | Test 2 asserts two assemblies (`Fizzler`, `System.Runtime.CompilerServices.Unsafe`) inside one `It` via `foreach`; a Fizzler failure stops the block before the Unsafe assertions run. | Optional: split into two `It` blocks or use a `-ForEach` data-driven `It`, so each assembly reports independently. | `.claude/rules/powershell.md`: one behaviour per `It`. The census in test 1 is a deliberate single assertion over a set and is acceptable as written. | Read of the file |
+| Info (non-blocking) | `tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1` | lines 65-90 | Test 1 enumerates every top-level directory that holds a `packages.config` and exactly one `.csproj`; directories with zero or several project files are silently skipped. On this tree every manifest directory has exactly one project file, so nothing is skipped today. | Optional hardening: assert the skipped-directory count is zero, or assert the pair count equals the number of `packages.config` files found, so a future multi-project directory cannot drop out of the census unnoticed. | The `Should -BeGreaterThan 9` floor guards against an empty census but not against partial coverage of the tree. | Read of lines 67-74 |
+| Info (non-blocking) | feature folder evidence (`Timestamp:` fields) | all executor artifacts | Labels lead the embedded UTC clock readings by 38 to 72 minutes (for example P2-T3 iter2 labelled `10-58` with RUN-START `13:46:37Z`, i.e. 09:46 local), so they are sequence labels rather than clock readings. | None for this branch; future executors should stamp from the clock. | Evidence hygiene; the gates demonstrably ran (JUNIT-WRITTEN follows RUN-START in every artifact; CI run ids are third-party facts). | `evidence/regression-testing/p1-t2-tree-test-fail-before.2026-09-28T20-01.md`, `p1-t11-...`, `evidence/qa-gates/p2-t3-pester.iter2.2026-09-28T20-01.md`; worktree `artifacts/pester/powershell-coverage.xml` report name `Pester (09/30/2026 09:47:03)` |
+
+## Scope Reviewed
+
+| Path | Lines / shape | Reviewed how |
+|---|---|---|
+| `QuickFiler.Test/QuickFiler.Test.csproj` | 2 deletions (570 to 568) | Grep confirms no `altcover` token remains in any `*.csproj`, `*.config`, `*.props`, `*.targets`; P1-T4 quotes the two deleted lines |
+| `SVGControl/app.config` | 2 changed lines (15, 19) | Read in full; compared with `SVGControl.csproj` lines 58 and 82 and `packages.config` lines 4 and 10 |
+| `.github/workflows/dependabot-repair.yml` | lines 13-14, 51 | Read in full (173 lines) |
+| `.github/workflows/README.md` | line 116 | Grep |
+| 911 runbook | Part B heading, steps 10 and 22, YAML sample line 154 | Read lines 96-159 and 296-321 |
+| `scripts/dependencies/ConsistencyVerifier.psm1` | comment lines 221-223 | Read lines 180-320 and 424-480 |
+| `tests/scripts/dependencies/ConsistencyVerifier.Tests.ps1` | comments at 57-59 and 300; `It` blocks at 240-263; 337 lines | Read lines 1-30, 50-79, 210-329; Grep of every `Describe`/`Context`/`It` line |
+| `tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1` | new, 152 lines | Read in full |
+| `docs/features/potential/promoted/2026-09-28-package-manifest-consistency-residuals.md` | promoted record | present on disk; content is the issue body |
+| Feature folder | issue.md, plan (56 of 56), 61 evidence `.md`, 2 JaCoCo projections, 2 trx summaries | Glob (69 files); 30 artifacts read in full |
+
+## File-by-File Review
+
+### `QuickFiler.Test/QuickFiler.Test.csproj`
+
+The two removed elements were `Exists()`-guarded imports of `..\packages\altcover.8.6.45\build\netstandard2.0\AltCover.{props,targets}`. No manifest declares altcover, the restore never creates that folder (P0-T5 `ALTCOVER-RESTORED: False`), and CI has no cache fallback that could supply it, so the imports were inert and their removal cannot alter the build graph. The project has no `` guard to remove alongside (P0-T17 census; plan tree facts). Correct and minimal.
+
+### `SVGControl/app.config`
+
+Both `bindingRedirect` elements now name the assembly version the `` declares (`Fizzler, Version=1.3.1.0`; `System.Runtime.CompilerServices.Unsafe, Version=6.0.3.0`) and the `oldVersion` upper bound moves with it. The executor additionally verified the restored DLLs' `AssemblyName.Version` (P0-T18: `FIZZLER_ASM=1.3.1.0`, `UNSAFE_ASM=6.0.3.0`) and that `Invoke-BindingRedirectReconciliation` reports zero repairs after the edit (P1-T5). Hand-editing was the right call: the repair script only reconciles redirects for packages it upgraded (plan decision D2).
+
+### `.github/workflows/dependabot-repair.yml`
+
+`client-id` is the input `actions/create-github-app-token` documents as recommended; the runbook's Sources entry (line 318) records that `app-id` remains accepted as legacy, so the rename is behaviour-preserving for the action while removing the deprecation warning that the issue's linked run shows. The secret name is deliberately unchanged (decision D3), so no maintainer action is required for the merge and the workflow's degraded mode (token step fails, job stops before pushing) is unchanged. The header comment was updated to describe the Client ID semantics. Nothing in the `run:` blocks changed, so the `ci-workflows.md` exit-code rule is not engaged.
+
+### `.github/workflows/README.md` and the 911 runbook
+
+README line 116 and runbook steps 10 and 22 now say the secret holds the App's Client ID and that the numeric App ID is not stored. The runbook's YAML sample matches the workflow line for line. One stale citation phrase remains (Findings Table, row 3).
+
+### `scripts/dependencies/ConsistencyVerifier.psm1`
+
+Three comment lines inside the `.DESCRIPTION` of `Find-PackageAbsentFromManifest` now state that issue 929 removed the last live instance and that the shape survives as an in-memory fixture. Line count held at 499 (P2-T1 iter2). No executable line changed; the function body (lines 236-249) is byte-identical to the base per the caller's diff, and the CI JaCoCo documents show the same 158/160 covered lines before and after with the same two uncovered lines (430, 475), which is consistent with an unchanged body.
+
+### `tests/scripts/dependencies/ConsistencyVerifier.Tests.ps1`
+
+The two added `It` blocks sit in the existing `Context 'Package absent from the manifest'` and reuse the existing `$script:GuardedUnmanifestedProject` (two guarded altcover imports plus a declared `Contoso.Widgets` reference) and `$script:AgreeingProject` fixtures against `$script:Manifest`. The positive test pins three facts: FindingCount 2, every finding Kind `Import`, every PackageFolder `altcover.8.6.45`. The negative test filters to the Import kind and guards the empty subset with `ExaminedCount -gt 0`, the same guard pattern the sibling tests use. Comments at lines 57-59 and 300 no longer describe the fixture as live. Fixtures are here-strings; no file is written.
+
+### `tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1`
+
+- Header (lines 1-12): `Set-StrictMode -Version Latest`; module import by `$PSScriptRoot`; the two document paths and the `client-id` pattern are script-scoped constants; the header comment states the no-disk-write and no-`AC` rules.
+- `Get-TokenStepBlock` (14-43): re-implements the step-block slicing of `DependabotConfig.Tests.ps1` (a step runs from its `- name:` line to the next), returns the first step whose `uses:` line contains the token, and returns an empty `string[]` otherwise; the comma-return preserves array shape under StrictMode.
+- `Get-DependentAssemblyBlock` (45-60): single-line regex over the config text with `[regex]::Escape` on the assembly name; returns the first matching `` block.
+- Test 1 (65-90): census over top-level directories; `ExaminedCount` summed and asserted greater than zero before the zero-findings assertion, so a detector that never fired cannot pass vacuously; the failure message lists each offending Import as `: line ` (the P1-T2 message shows exactly that shape).
+- Test 2 (92-110): for each of the two assemblies, extracts the `Version=` from the `` and asserts `newVersion` equality and `oldVersion` suffix. See Findings Table row 5 for the granularity note.
+- Test 3 (112-125): exactly one `client-id:` line reading a secret and zero `app-id:` lines inside the token step.
+- Test 4 (127-151): extracts the secret name from the workflow, asserts the runbook's YAML sample passes `client-id` from that exact secret and no `app-id`, and asserts Part D (the secret-creation section) mentions `Client ID` and the secret name. The coupling to the workflow's own text is what makes AC6's "names that secret exactly as the workflow names it" a checked property rather than a duplicated literal.
+
+Residual risk recorded by the plan (A2): test 4 reads the runbook at its active-folder path; the eventual feature-promotion move of the 911 folder must update `$script:RunbookPath` in the same change.
+
+## Positive Observations
+
+- Fail-before / pass-after evidence is complete and specific: four red tests with messages quoting the exact defect values, then three green and one red at the intermediate step, then four green.
+- Decision D1 avoided adding a production rule the detector already had, keeping the production diff to comments.
+- Every gate substitution mandated by the coordinator's PowerShell ruling is recorded in the artifact it affects with a `GATE-SUBSTITUTION:` line.
+- Committed coverage evidence is in the permitted projection form; the raw documents were left gitignored under `coverage/` and `artifacts/`, which let this review read the per-line JaCoCo data directly.
+- The two P2 loop iterations are both recorded, including the failed one, with an attribution paragraph rather than a silent retry.
+
+## Blocking Count
+
+Blocking: 0. Non-blocking: 7 in this artifact. No remediation inputs are produced.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t1-worktree-anchor.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t1-worktree-anchor.2026-09-28T20-01.md
new file mode 100644
index 000000000..a367f6d37
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t1-worktree-anchor.2026-09-28T20-01.md
@@ -0,0 +1,40 @@
+# P0-T1 — Worktree anchor
+
+Timestamp: 2026-09-30T09-09
+Command: git rev-parse --show-toplevel; git rev-parse --abbrev-ref HEAD; git fetch origin main; git rev-parse origin/main; git merge-base origin/main HEAD; git rev-parse HEAD; git cat-file -t ; git cat-file -t ; git rev-list --count ..HEAD; git merge-base --is-ancestor 231e1c0b55105aeb626bf5a6e8d0266a567cacad HEAD; git status --porcelain --untracked-files=all; git ls-files -- "*.csproj.bak"; git diff --name-only HEAD -- (all run from )
+EXIT_CODE: 0
+Output Summary:
+- show-toplevel:
+- Branch: bug/package-manifest-consistency-residuals-929
+- origin/main (after fetch): b305903e275b8abf58e8e65831c189f517568fe4
+- BASE-SHA (merge-base origin/main HEAD): 231e1c0b55105aeb626bf5a6e8d0266a567cacad (git cat-file -t: commit)
+- P0-START (HEAD): 481b33c594d8412cb64e604ff53295db215ac2f1 (git cat-file -t: commit)
+- git rev-list --count ..HEAD: 8 (recorded as measured)
+- MERGED-MAIN-ANCESTOR: 0 (git merge-base --is-ancestor 231e1c0b55105aeb626bf5a6e8d0266a567cacad HEAD exited 0; the worktree carries the 2026-09-30 merge of origin/main)
+- Seven-path diff against HEAD: empty (no Write Set source file is already modified)
+- Note: origin/main has advanced to b305903e2 since the branch merged 231e1c0b5; the merge-base remains 231e1c0b5, so is the merged tip as the plan states.
+
+BASE-UNTRACKED:
+```
+ M .claude/agent-memory/atomic-executor/MEMORY.md
+ M .claude/agent-memory/atomic-planner/MEMORY.md
+?? .claude/agent-memory/atomic-executor/index_csharp_nullable_and_component_gotchas.md
+?? .claude/agent-memory/atomic-executor/index_pwsh_git_and_gate_mechanics_misc.md
+?? .claude/agent-memory/atomic-executor/index_test_isolation_and_coverage.md
+?? .claude/agent-memory/atomic-executor/project_hygiene_pattern_array_comma_precedence_and_regex_token_hits.md
+?? .claude/agent-memory/atomic-planner/project_929_manifest_residuals_plan_seams.md
+```
+No entry matches *.cs, *.csproj, packages.config or app.config.
+
+BAK-TRACKED:
+```
+QuickFiler.Test/QuickFiler.Test.csproj.bak
+QuickFiler/QuickFiler.csproj.bak
+Tags/Tags.csproj.bak
+TaskTree/TaskTree.csproj.bak
+TaskVisualization.Test/TaskVisualization.Test.csproj.bak
+TaskVisualization/TaskVisualization.csproj.bak
+ToDoModel.Test/ToDoModel.Test.csproj.bak
+ToDoModel/ToDoModel.csproj.bak
+```
+Eight tracked .csproj.bak copies (the plan names two carrying altcover tokens; all eight are recorded). They are not project files and are not edited (decision D12).
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t10-msbuild-analyzers.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t10-msbuild-analyzers.2026-09-28T20-01.md
new file mode 100644
index 000000000..827eb2a1b
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t10-msbuild-analyzers.2026-09-28T20-01.md
@@ -0,0 +1,13 @@
+# P0-T10 — Analyzer rebuild baseline (CMD-MSBUILD-ANALYZERS)
+
+Timestamp: 2026-09-30T09-21
+Command: pwsh -NoProfile -Command 'Set-Location ""; msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true "/flp:LogFile=coverage\analyzers.msbuild.log;Verbosity=normal"; "MSBUILD_EXIT=$LASTEXITCODE"; $l = "coverage\analyzers.msbuild.log"; "OUT_LINES=" + @(Select-String -LiteralPath $l -SimpleMatch -Pattern ("/out:obj" + [char]92 + "Debug" + [char]92)).Count; "CS0006_LINES=" + @(Select-String -LiteralPath $l -SimpleMatch -Pattern "CS0006").Count'
+EXIT_CODE: 0
+OUTLOOK-CLOSED: true
+Output Summary:
+- CMD-OUTLOOK: Get-Process outlook count printed 0 (Outlook not running; nothing terminated).
+- msbuild summary: "Build succeeded." / "0 Warning(s)" / "0 Error(s)" / "Time Elapsed 00:00:16.19"
+- MSBUILD_EXIT=0
+- OUT_LINES=36 (at least 18)
+- CS0006_LINES=0
+- The file log stays under the ignored coverage directory and is not committed.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t11-msbuild-nullable.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t11-msbuild-nullable.2026-09-28T20-01.md
new file mode 100644
index 000000000..d0c3489b1
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t11-msbuild-nullable.2026-09-28T20-01.md
@@ -0,0 +1,13 @@
+# P0-T11 — Nullable rebuild baseline (CMD-MSBUILD-NULLABLE)
+
+Timestamp: 2026-09-30T09-22
+Command: pwsh -NoProfile -Command 'Set-Location ""; msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:TreatWarningsAsErrors=true "/flp:LogFile=coverage\nullable.msbuild.log;Verbosity=normal" | Out-Null; "MSBUILD_EXIT=$LASTEXITCODE"; $l = "coverage\nullable.msbuild.log"; "OUT_LINES=" + @(Select-String -LiteralPath $l -SimpleMatch -Pattern ("/out:obj" + [char]92 + "Debug" + [char]92)).Count; Get-Content -LiteralPath $l -Tail 8'
+EXIT_CODE: 0
+OUTLOOK-CLOSED: true
+Output Summary:
+- CMD-OUTLOOK: @(Get-Process outlook -ErrorAction SilentlyContinue).Count printed 0 (nothing terminated).
+- Console output was discarded with Out-Null to keep the capture readable; the msbuild arguments are exactly CMD-MSBUILD-NULLABLE and the summary is read from the file log tail.
+- File log tail: "Build succeeded." / "0 Warning(s)" / "0 Error(s)" / "Time Elapsed 00:00:14.18"
+- MSBUILD_EXIT=0
+- OUT_LINES=36 (at least 18)
+- No Nullable property was added and the Rebuild target was used (CLAUDE.md C#1.3).
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t12-coverage-projection.2026-09-28T20-01.jacoco.xml b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t12-coverage-projection.2026-09-28T20-01.jacoco.xml
new file mode 100644
index 000000000..0c933d212
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t12-coverage-projection.2026-09-28T20-01.jacoco.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t12-mstest-coverage.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t12-mstest-coverage.2026-09-28T20-01.md
new file mode 100644
index 000000000..db3b33fa9
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t12-mstest-coverage.2026-09-28T20-01.md
@@ -0,0 +1,28 @@
+# P0-T12 — C# test and coverage baseline (CMD-MSTEST-COVERAGE)
+
+Timestamp: 2026-09-30T09-40
+Command: pwsh -NoProfile -Command 'Set-Location ""; & "\scripts\vscode\Invoke-MSTestWithCoverage.ps1" -SearchRoot .' (run detached with its combined output redirected to a session scratch log outside the repository, because the run exceeds a single tool-call window; the script and its arguments are unchanged)
+EXIT_CODE: 0
+Output Summary:
+- "Test Run Successful."
+- "Total tests: 7346" / "Passed: 7346"
+- First-party coverage: lines 56475/65736 (85.91%), branches 13656/17054 (80.08%)
+- Baseline line percentage L = 85.91; baseline branch percentage R = 80.08 (L at least 80 and R at least 75; the runner enforces both floors before printing the line)
+- MEETS-85: true (observation only, convention 10)
+- Test-result summary (copied): total 7346, executed 7346, passed 7346, failed 0; skipped 0 (derived); error 0, timeout 0, aborted 0, notExecuted 0, inconclusive 0; failed tests: none
+- Path-printing lines, with host prefixes replaced (convention 4):
+ - "Using vstest.console: \Microsoft Visual Studio\18\Community\Common7\IDE\Extensions\TestPlatform\vstest.console.exe"
+ - "Coverage output: \coverage\coverage.cobertura.xml"
+ - "Coverage projection: \coverage\coverage.cobertura.jacoco.xml"
+ - "Test-result summary: \coverage\test-results\mstest-coverage-run.summary.txt"
+ - "Done. Coverage artifact: \coverage\coverage.cobertura.xml"
+
+Copies:
+- docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t12-coverage-projection.2026-09-28T20-01.jacoco.xml — 1467 bytes; root element report; 9 package elements
+- docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t12-test-results.2026-09-28T20-01.summary.txt — 298 bytes
+
+Reconciliation: the sum of the projection's package LINE covered counters is 56475, equal to the line numerator A = 56475 on the printed line, so the copy describes this run.
+
+PROJECTION-RAW-ELEMENTS: 0 (Select-String over the copy for ", scan_folders ["scripts/dependencies","tests/scripts/dependencies"]); re-hash; git status --porcelain --untracked-files=all -- scripts/dependencies tests/scripts/dependencies; @(Get-Content -LiteralPath "scripts/dependencies/ConsistencyVerifier.psm1").Count
+EXIT_CODE: 0
+Output Summary:
+- MCP payload: {"ok":true,"tool":"run_poshqc_format","workspace_root":"","summary":"Ran bundled PoshQC format against '' with 2 selected scan folder(s)."} (ok recorded, not asserted)
+- scan_folders: ["scripts/dependencies","tests/scripts/dependencies"]
+- Hash sets: 13 entries before, 13 after (6 production, 7 test files); every hash identical
+- Rewrite count (hash difference): 0
+- REVERT-SET: empty
+- FORMAT-REWROTE-WRITE-SET: none
+- Post-run porcelain over the two folders: empty
+- VERIFIER-LINES: 499
+
+Hash set (identical before and after):
+```
+scripts\dependencies\AnalyzerItemRepair.psm1 102E3EBCF014F8365C3C65A834EDEC5FC9DAC9B1FFD6477E68D813335DB48F68
+scripts\dependencies\ConsistencyVerifier.psm1 2F37D7CBE2EC9739B4E7E1E08B76C653ACFA083F7AD73D008B616F9024E2EBFA
+scripts\dependencies\PackageCompatibility.psm1 89B31603872ED09C8E2DF2E94A597D42BF3A2019D4F49298D6859CEF7CBF41CD
+scripts\dependencies\PackageGraph.psm1 1CE9EABA3A43FF2446C3B63FFA53CE501537362C8E6EED6BB9DB4774F15C9BC6
+scripts\dependencies\ProjectConsistency.psm1 0E7B005A65B5614A0099F7A7286FE6692F87CC49FF09D749877F832C37D69EFE
+scripts\dependencies\Repair-PackageManifestConsistency.ps1 E69F61364EB1640C0FADFBBAE1F418250D2F508E8F26A048BE43F70DD659078A
+tests\scripts\dependencies\AnalyzerItemRepair.Tests.ps1 7C4CBC097681F98A629F94AD12D800A7E87652CA773825FA26F621969671D011
+tests\scripts\dependencies\ConsistencyVerifier.Tests.ps1 72928DAEE535364B263945689AE46BE024D8D08FF129381094A7D213B1D0E317
+tests\scripts\dependencies\DependabotConfig.Tests.ps1 3F738E78A77F028BBB97D86BD2B9A33DC8CB94F1ABB31F1DC306413CDE3B3C48
+tests\scripts\dependencies\PackageCompatibility.Tests.ps1 0EF34C85EBA0B70C24CC4EA662472FA97F33D20B527120278606B12F6D7010DC
+tests\scripts\dependencies\PackageGraph.Tests.ps1 910DD957F6377DD60A9F2EFC26E7597421E2C69505DE21E78E4B087729305EBE
+tests\scripts\dependencies\ProjectConsistency.Tests.ps1 BCB15A04404BD3792A1DCB65315DE2B4CD822087B9D3EB3006E8BE9EB81CA761
+tests\scripts\dependencies\Repair-PackageManifestConsistency.Tests.ps1 3348C5D17773A9DCC6EEFD3A85EF6874BB96CA9BE8B1F2A85C1EA9CB96756942
+```
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t14-poshqc-analyze.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t14-poshqc-analyze.2026-09-28T20-01.md
new file mode 100644
index 000000000..4629e5402
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t14-poshqc-analyze.2026-09-28T20-01.md
@@ -0,0 +1,13 @@
+# P0-T14 — PowerShell analyzer baseline (CMD-POSHQC-ANALYZE)
+
+Timestamp: 2026-09-30T09-43
+Command: MCP mcp__drm-copilot__run_poshqc_analyze (workspace_root , scan_folders ["scripts/dependencies","tests/scripts/dependencies"]); pwsh -NoProfile -Command 'Set-Location ""; "FILES=" + @(Get-ChildItem -Recurse -File -Path "scripts/dependencies","tests/scripts/dependencies" -Include *.ps1,*.psm1).Count'
+EXIT_CODE: 0
+Output Summary:
+- MCP payload (verbatim, host prefix replaced): {"ok":true,"tool":"run_poshqc_analyze","workspace_root":"","summary":"Ran bundled PoshQC analyze against '' with 2 selected scan folder(s)."}
+- No stderr excerpt was returned.
+- scan_folders: ["scripts/dependencies","tests/scripts/dependencies"]
+- PoshQC analyze: pass (0 findings); tool reports no count
+- FILES=13 (6 production, 7 test files)
+
+GATE-SUBSTITUTION: PoshQC analyze ok flag stands in for a diagnostic count
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t15-poshqc-test-mcp.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t15-poshqc-test-mcp.2026-09-28T20-01.md
new file mode 100644
index 000000000..88fb7651a
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t15-poshqc-test-mcp.2026-09-28T20-01.md
@@ -0,0 +1,23 @@
+# P0-T15 — PowerShell test baseline through the MCP route (CMD-POSHQC-TEST, CMD-JUNIT-READ)
+
+Timestamp: 2026-09-30T09-45
+Command: pwsh -NoProfile -Command '[DateTime]::UtcNow.ToString("o")' (RUN-START); MCP mcp__drm-copilot__run_poshqc_test (workspace_root , scan_folders ["tests/scripts/dependencies"]); CMD-JUNIT-READ; the PESTER-VERSION read command, appended to the same pwsh invocation as CMD-JUNIT-READ
+EXIT_CODE: 0
+Output Summary:
+- RUN-START: 2026-09-30T13:17:15.3091663Z
+- MCP payload (host prefix replaced): {"ok":true,"tool":"run_poshqc_test","workspace_root":"","summary":"Ran bundled PoshQC test against '' with 1 selected scan folder(s)."}
+- JUNIT-WRITTEN=2026-09-30T13:17:45.2888350Z (later than RUN-START; the document was written by this run)
+- JUNIT-ROOT tests=131 failures=0 errors=0 disabled=0
+- JUNIT-SUITE AnalyzerItemRepair.Tests.ps1 tests=13 failures=0 skipped=0
+- JUNIT-SUITE ConsistencyVerifier.Tests.ps1 tests=12 failures=0 skipped=0
+- JUNIT-SUITE DependabotConfig.Tests.ps1 tests=17 failures=0 skipped=0
+- JUNIT-SUITE PackageCompatibility.Tests.ps1 tests=8 failures=0 skipped=0
+- JUNIT-SUITE PackageGraph.Tests.ps1 tests=32 failures=0 skipped=0
+- JUNIT-SUITE ProjectConsistency.Tests.ps1 tests=18 failures=0 skipped=0
+- JUNIT-SUITE Repair-PackageManifestConsistency.Tests.ps1 tests=31 failures=0 skipped=0
+- Exactly 7 JUNIT-SUITE lines; no JUNIT-NOTPASSED line.
+- PESTER-VERSION: 5.6.1
+
+This route reports no coverage figure; P0-T16 reads the coverage baseline from CI.
+
+GATE-SUBSTITUTION: JUnit per-file counts stand in for a direct Pester run
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t16-pester.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t16-pester.2026-09-28T20-01.md
new file mode 100644
index 000000000..e73335543
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t16-pester.2026-09-28T20-01.md
@@ -0,0 +1,33 @@
+# P0-T16 — Pester coverage baseline from CI (CMD-CI-PESTER)
+
+Timestamp: 2026-09-30T09-47
+Command: CMD-CI-PESTER with RUN-ID 36666302259 and DIR coverage/ci-main-pester-36666302259-1 (pwsh -NoProfile -Command 'Set-Location ""; gh run view 36666302259 --repo drmoisan/TaskMaster --json databaseId,headSha,headBranch,event,status,conclusion,workflowName ...; gh run view --repo drmoisan/TaskMaster --job --log ...; gh run download 36666302259 --repo drmoisan/TaskMaster --name pester-coverage --dir "coverage/ci-main-pester-36666302259-1"; ...'), then git merge-base --is-ancestor 231e1c0b55105aeb626bf5a6e8d0266a567cacad HEAD
+EXIT_CODE: 0
+Output Summary:
+- RUN id=36666302259 head=231e1c0b55105aeb626bf5a6e8d0266a567cacad branch=main event=push status=completed conclusion=success workflow=CI
+- git merge-base --is-ancestor 231e1c0b55105aeb626bf5a6e8d0266a567cacad HEAD exited 0 (the run's head is an ancestor of the executor's HEAD)
+- PESTER-JOBS=1
+- JOB id=109731601928 name=pester / Run Pester suite with coverage status=completed conclusion=success
+- LOG-LINES=1085
+- Log lines (verbatim after SGR stripping; run 36666302259, head 231e1c0b5):
+ - "Tests Passed: 373, Failed: 0, Skipped: 0, Inconclusive: 0, NotRun: 0"
+ - "PESTER Passed=373 Failed=0 Skipped=0 Total=373"
+ - "COVERAGE LinePercent=94.51 Covered=1721 Total=1821"
+- BASELINE-TOTAL: 373 (Passed 373 + Failed 0 + Skipped 0, equal to the Total field 373)
+- DIR-PREEXISTS=False; DOWNLOAD-EXIT=0; ARTIFACT-FILES=1; DIR used: coverage/ci-main-pester-36666302259-1
+- REPORT-LINE covered=1721 missed=100; computed percent 1721 / 1821 * 100 = 94.51, equal to the log's LinePercent 94.51 and at least 80
+- MEETS-85: true (observation only, convention 10)
+- SOURCEFILE lines (run 36666302259, head 231e1c0b5):
+ - AnalyzerItemRepair.psm1 covered=106 missed=0
+ - ConsistencyVerifier.psm1 covered=158 missed=2
+ - PackageCompatibility.psm1 covered=33 missed=0
+ - PackageGraph.psm1 covered=164 missed=0
+ - ProjectConsistency.psm1 covered=103 missed=0
+ - Repair-PackageManifestConsistency.ps1 covered=213 missed=14
+- VERIFIER-COVERED: 158
+- VERIFIER-MISSED: 2
+- No TRANSCRIPTION-MISMATCH: the run's figures equal the coordinator's (Tests Passed 373, LinePercent 94.51, Covered 1721, Total 1821).
+
+Pester emits no branch counter, so no PowerShell branch figure is claimed. These figures stand in for a permitted evidence form that the committed-evidence section of CLAUDE.md does not define for the Pester route. The downloaded JaCoCo document stays under the ignored coverage directory and is not committed.
+
+GATE-SUBSTITUTION: CI Pester job 109731601928 stands in for a local coverage run
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t17-altcover-and-verifier-prefix.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t17-altcover-and-verifier-prefix.2026-09-28T20-01.md
new file mode 100644
index 000000000..ac65003ca
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t17-altcover-and-verifier-prefix.2026-09-28T20-01.md
@@ -0,0 +1,31 @@
+# P0-T17 — Pre-fix altcover state and read-only verifier baseline
+
+Timestamp: 2026-09-30T09-49
+Command: pwsh -NoProfile -Command 'Set-Location ""; $m = @(git grep -i -n altcover -- "*.csproj" "*/packages.config"); "ALTCOVER_LINES=$($m.Count)"; $m' then CMD-VERIFIER-WHATIF
+EXIT_CODE: 0
+Output Summary:
+- ALTCOVER_LINES=2
+ - QuickFiler.Test/QuickFiler.Test.csproj:8:
+ - QuickFiler.Test/QuickFiler.Test.csproj:537:
+- CMD-VERIFIER-WHATIF result line: ABSENT=2 DISAGREE=0 WRITTEN=0 SUCCESS=True PROJECTS=18 FILES=53 HASHES_EQUAL=True
+- DISAGREE (0) and SUCCESS (True) recorded as measured with no expectation: DISAGREE is computed over the in-memory repaired project text (Repair-PackageManifestConsistency.ps1 lines 411 to 422).
+- Information line (printed five times): "Manifest discovery: enumerated directories 35, returned files 53"
+- -WhatIf messages (operation "Rewrite in canonical inline form"), target paths with prefix replaced:
+ - \QuickFiler.Test\packages.config
+ - \QuickFiler\packages.config
+ - \SVGControl.Test\packages.config
+ - \Tags.Test\packages.config
+ - \Tags\packages.config
+ - \TaskMaster.Test\packages.config
+ - \TaskMaster\packages.config
+ - \TaskTree.Test\packages.config
+ - \TaskTree\packages.config
+ - \TaskVisualization.Test\packages.config
+ - \TaskVisualization\packages.config
+ - \ToDoModel.Test\packages.config
+ - \ToDoModel\packages.config
+ - \UtilitiesCS.Test\packages.config
+ - \UtilitiesCS\packages.config
+ - \VBFunctions.Test\packages.config
+ - \VBFunctions\packages.config
+- HASHES_EQUAL=True: the what-if run wrote nothing (FILES=53, at least 50).
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t18-redirect-prefix.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t18-redirect-prefix.2026-09-28T20-01.md
new file mode 100644
index 000000000..42826eb22
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t18-redirect-prefix.2026-09-28T20-01.md
@@ -0,0 +1,30 @@
+# P0-T18 — Pre-fix binding redirect state
+
+Timestamp: 2026-09-30T09-50
+Command: pwsh -NoProfile -Command 'Set-Location ""; (quote SVGControl/app.config lines 15 and 19 and SVGControl/SVGControl.csproj lines 58 and 82); "FIZZLER_ASM=" + [System.Reflection.AssemblyName]::GetAssemblyName((Resolve-Path "packages/Fizzler.1.3.1/lib/netstandard2.0/Fizzler.dll").Path).Version; "UNSAFE_ASM=" + [System.Reflection.AssemblyName]::GetAssemblyName((Resolve-Path "packages/System.Runtime.CompilerServices.Unsafe.6.1.2/lib/net462/System.Runtime.CompilerServices.Unsafe.dll").Path).Version; (CMD-REDIRECT-OBSERVE); (tree-wide Fizzler newVersion listing over */app.config)' — the plan's three commands run in one pwsh invocation
+EXIT_CODE: 0
+Output Summary:
+- SVGControl/app.config line 15: ` `
+- SVGControl/app.config line 19: ` `
+- SVGControl/SVGControl.csproj line 58: ` `
+- SVGControl/SVGControl.csproj line 82: ` `
+- FIZZLER_ASM=1.3.1.0
+- UNSAFE_ASM=6.0.3.0
+- FIZZLER_REPAIRS=1 UNSAFE_REPAIRS=1 EXAMINED=4 (the pre-fix drift as Invoke-BindingRedirectReconciliation sees it)
+
+Tree-wide Fizzler redirect listing (13 configs: 12 at 1.3.0.0, UtilitiesCS at 1.3.1.0):
+- SVGControl Fizzler 1.3.0.0 (in-scope AC2 target)
+- UtilitiesCS Fizzler 1.3.1.0 (already names 1.3.1.0)
+- OUT-OF-SCOPE-RESIDUAL: QuickFiler Fizzler 1.3.0.0
+- OUT-OF-SCOPE-RESIDUAL: QuickFiler.Test Fizzler 1.3.0.0
+- OUT-OF-SCOPE-RESIDUAL: SVGControl.Test Fizzler 1.3.0.0
+- OUT-OF-SCOPE-RESIDUAL: Tags Fizzler 1.3.0.0
+- OUT-OF-SCOPE-RESIDUAL: TaskMaster Fizzler 1.3.0.0
+- OUT-OF-SCOPE-RESIDUAL: TaskTree Fizzler 1.3.0.0
+- OUT-OF-SCOPE-RESIDUAL: TaskVisualization Fizzler 1.3.0.0
+- OUT-OF-SCOPE-RESIDUAL: TaskVisualization.Test Fizzler 1.3.0.0
+- OUT-OF-SCOPE-RESIDUAL: ToDoModel Fizzler 1.3.0.0
+- OUT-OF-SCOPE-RESIDUAL: ToDoModel.Test Fizzler 1.3.0.0
+- OUT-OF-SCOPE-RESIDUAL: UtilitiesCS.Test Fizzler 1.3.0.0
+
+The 11 out-of-scope residuals are already recorded in docs/features/potential/2026-08-04-stale-fizzler-and-unsafe-binding-redirects.md (decision D5). The tree-wide count matches the plan's expectation of 13.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t19-workflow-prefix-and-actionlint.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t19-workflow-prefix-and-actionlint.2026-09-28T20-01.md
new file mode 100644
index 000000000..d21b28396
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t19-workflow-prefix-and-actionlint.2026-09-28T20-01.md
@@ -0,0 +1,17 @@
+# P0-T19 — Pre-fix workflow, runbook and README state; actionlint baseline
+
+Timestamp: 2026-09-30T09-51
+Command: pwsh -NoProfile -Command 'Set-Location ""; $w = Get-Content ".github/workflows/dependabot-repair.yml"; "WF_APPID=" + ...; "WF_CLIENTID=" + ...; $rb = Get-Content "docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md"; "RB_APPID=" + ...; "RB_CLIENTID=" + ...; "RB_PARTB=" + ...; "README_NUMERIC=" + ...' (the plan's P0-T19 command verbatim) then CMD-ACTIONLINT
+EXIT_CODE: 0
+Output Summary:
+- WF_APPID=1
+- WF_CLIENTID=0
+- RB_APPID=1
+- RB_CLIENTID=0
+- RB_PARTB=1 (the Part B heading at line 99)
+- README_NUMERIC=1
+- actionlint version line: "1.7.7" (followed by "installed by downloading from release page" and "built with go1.23.4 compiler for windows/amd64")
+- Scoped lint of .github/workflows/dependabot-repair.yml: no output; SCOPED_EXIT=0
+- Repository-wide run-actionlint.ps1: no output; REPO_EXIT=0
+- Lint output recorded as empty: the baseline tree lints clean; the app-id deprecation is a runtime warning of the action, not a lint finding.
+- CI actionlint version: 1.7.7 (.github/workflows/_actionlint.yml line 26); local version 1.7.7.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t20-hygiene.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t20-hygiene.2026-09-28T20-01.md
new file mode 100644
index 000000000..c54250e3f
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t20-hygiene.2026-09-28T20-01.md
@@ -0,0 +1,12 @@
+# P0-T20 — Hygiene scan of the feature folder (CMD-HYGIENE)
+
+Timestamp: 2026-09-30T09-52
+Command: CMD-HYGIENE with FOLDER-LIST "docs/features/active/2026-09-28-package-manifest-consistency-residuals-929" (pwsh -NoProfile -Command 'Set-Location ""; $acct = Split-Path -Leaf $env:USERPROFILE; $machine = [System.Environment]::MachineName; ...; "PATTERNS=" ...; "SELFTEST=" ...; "SELFTEST_NEG=" ...; "SCANNED=... HITS=..."; ...'; the account and machine values are derived at run time and not recorded)
+EXIT_CODE: 0
+Output Summary:
+- PATTERNS=3
+- SELFTEST=1
+- SELFTEST_NEG=0
+- SCANNED=23 HITS=0 (at least 20: 19 Phase 0 .md artifacts, the projection and summary copies, issue.md and the plan)
+- Hit listing: empty
+- PRE-FIX-HITS: 0
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t21-commit.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t21-commit.2026-09-28T20-01.md
new file mode 100644
index 000000000..9cb9a4f71
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t21-commit.2026-09-28T20-01.md
@@ -0,0 +1,23 @@
+# P0-T21 — Phase 0 evidence commit
+
+Timestamp: 2026-09-30T09-54
+Command: git add -- docs/features/active/2026-09-28-package-manifest-consistency-residuals-929; git commit -m "docs(929): phase 0 baseline evidence" -m "Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com" -- docs/features/active/2026-09-28-package-manifest-consistency-residuals-929; git rev-parse HEAD; git show --name-only --format= HEAD; git status --porcelain --untracked-files=all; git push origin bug/package-manifest-consistency-residuals-929
+EXIT_CODE: 0
+Output Summary:
+- P0-HEAD: 488492f135c17c1ca4c8e6224bf7663a58c5e7b1 (differs from P0-START 481b33c594d8412cb64e604ff53295db215ac2f1)
+- Commit: "[bug/package-manifest-consistency-residuals-929 488492f13] docs(929): phase 0 baseline evidence" — 23 files changed
+- git show --name-only --format= HEAD: 23 paths, all under the feature folder (20 Phase 0 .md artifacts, the projection copy, the summary copy and the plan file with its check-offs); 0 paths outside it
+- FORMAT-REWROTE-WRITE-SET at P0-T13 was none, so no Write Set member was committed and the plain message applies.
+- Porcelain after the commit (only agent-memory entries, none of them staged or committed by this task):
+```
+ M .claude/agent-memory/atomic-executor/MEMORY.md
+ M .claude/agent-memory/atomic-planner/MEMORY.md
+?? .claude/agent-memory/atomic-executor/index_csharp_nullable_and_component_gotchas.md
+?? .claude/agent-memory/atomic-executor/index_pwsh_git_and_gate_mechanics_misc.md
+?? .claude/agent-memory/atomic-executor/index_test_isolation_and_coverage.md
+?? .claude/agent-memory/atomic-executor/project_hygiene_pattern_array_comma_precedence_and_regex_token_hits.md
+?? .claude/agent-memory/atomic-planner/project_929_manifest_residuals_plan_seams.md
+```
+- Push (per the caller's phase-boundary instruction): "481b33c59..488492f13 bug/package-manifest-consistency-residuals-929 -> bug/package-manifest-consistency-residuals-929"
+
+This artifact is written after the commit and is swept by the P1-T14 commit.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t3-sdk-bootstrap.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t3-sdk-bootstrap.2026-09-28T20-01.md
new file mode 100644
index 000000000..a21cd3bc2
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t3-sdk-bootstrap.2026-09-28T20-01.md
@@ -0,0 +1,12 @@
+# P0-T3 — Repository-pinned .NET SDK bootstrap
+
+Timestamp: 2026-09-30T09-14
+Command: pwsh -NoProfile -Command 'Set-Location ""; if (-not (Test-Path ".dotnet-sdk\sdk")) { & ".\scripts\vscode\Install-RepoDotNetSdk.ps1" }; dotnet --version; dotnet --list-sdks'
+EXIT_CODE: 0
+Output Summary:
+- .dotnet-sdk\sdk was absent before the run (fresh worktree), so Install-RepoDotNetSdk.ps1 ran and printed "Installed repo-local .NET SDK 8.0.205 to \.dotnet-sdk."
+- dotnet --version: 8.0.205
+- dotnet --list-sdks:
+ - 8.0.205 [\.dotnet-sdk\sdk]
+ - 10.0.401 [\dotnet\sdk] (machine-wide install)
+- The 8.0.205 line names the sdk folder under the repository-root .dotnet-sdk folder (Install-RepoDotNetSdk.ps1 line 36, global.json line 7).
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t4-tool-restore.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t4-tool-restore.2026-09-28T20-01.md
new file mode 100644
index 000000000..06104483e
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t4-tool-restore.2026-09-28T20-01.md
@@ -0,0 +1,10 @@
+# P0-T4 — dotnet tool restore
+
+Timestamp: 2026-09-30T09-15
+Command: pwsh -NoProfile -Command 'Set-Location ""; dotnet tool restore; "TOOL_RESTORE_EXIT=$LASTEXITCODE"'
+EXIT_CODE: 0
+Output Summary:
+- "Tool 'csharpier' (version '1.2.6') was restored. Available commands: csharpier"
+- "Restore was successful."
+- TOOL_RESTORE_EXIT=0
+- csharpier 1.2.6 is the version the repository-root dotnet-tools.json pins.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t5-package-restore.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t5-package-restore.2026-09-28T20-01.md
new file mode 100644
index 000000000..5865eec48
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t5-package-restore.2026-09-28T20-01.md
@@ -0,0 +1,12 @@
+# P0-T5 — Cold NuGet package restore
+
+Timestamp: 2026-09-30T09-16
+Command: pwsh -NoProfile -Command 'Set-Location ""; $before = @(Get-ChildItem -Path ".\packages" -Directory -ErrorAction SilentlyContinue).Count; "PACKAGE_DIRS_BEFORE=$before"; & ".\scripts\vscode\Invoke-Restore.ps1"; "RESTORE_EXIT=$LASTEXITCODE"; $after = @(Get-ChildItem -Path ".\packages" -Directory).Count; "PACKAGE_DIRS_AFTER=$after"; "ALTCOVER_RESTORED=" + (Test-Path "packages\altcover.8.6.45")'
+EXIT_CODE: 0
+Output Summary:
+- PACKAGE_DIRS_BEFORE=0 (fresh worktree; the cold state AC7 names)
+- "Using MSBuild: \Microsoft Visual Studio\18\Community\MSBuild\Current\Bin\MSBuild.exe"
+- Restore target over TaskMaster.sln; output ends "Build succeeded." / "0 Warning(s)" / "0 Error(s)" / "Time Elapsed 00:00:02.75"
+- RESTORE_EXIT=0
+- PACKAGE_DIRS_AFTER=172 (greater than 100 and not lower than PACKAGE_DIRS_BEFORE)
+- ALTCOVER-RESTORED: False (no manifest declares altcover, so the restore did not produce packages\altcover.8.6.45)
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t6-analyzer-item-census.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t6-analyzer-item-census.2026-09-28T20-01.md
new file mode 100644
index 000000000..1304e0025
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t6-analyzer-item-census.2026-09-28T20-01.md
@@ -0,0 +1,15 @@
+# P0-T6 — Analyzer Include item census
+
+Timestamp: 2026-09-30T09-17
+Command: pwsh -NoProfile -Command 'Set-Location ""; $items = @(); foreach ($p in @(git ls-files -- "*.csproj")) { $dir = Split-Path -Parent $p; foreach ($line in (Get-Content -LiteralPath $p)) { if ($line -match "Analyzer Include=""([^""]+)""") { $rel = $Matches[1]; $items += [pscustomobject]@{ Project = $p; Item = $rel; Resolves = (Test-Path -LiteralPath (Join-Path $dir $rel)) } } } }; "ANALYZER_ITEMS=$($items.Count) FILES=$(@($items | Select-Object -ExpandProperty Project -Unique).Count) UNRESOLVED=$(@($items | Where-Object { -not $_.Resolves }).Count)"; "SKEW_235=" + @(git grep -n "Meziantou.Analyzer.3.0.235" -- "*.csproj").Count; $items | Where-Object { -not $_.Resolves } | ForEach-Object { $_.Project + " " + $_.Item }'
+EXIT_CODE: 0
+Output Summary:
+- ANALYZER_ITEMS=162 FILES=17 UNRESOLVED=0
+- SKEW_235=0
+- Unresolved (project, item) listing: empty
+
+ANALYZER-ITEM-STATE: aligned
+
+No back-fill was performed and none is permitted by this plan; the AC7 back-fill clause is not exercised.
+
+The packages tree is ignored at .gitignore line 197 (`**/[Pp]ackages/*`), and the restore of P0-T5 is the only step that populated it (PACKAGE_DIRS_BEFORE=0, PACKAGE_DIRS_AFTER=172). Decision D8 governs.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t7-dotnet-coverage.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t7-dotnet-coverage.2026-09-28T20-01.md
new file mode 100644
index 000000000..96b1ae53c
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t7-dotnet-coverage.2026-09-28T20-01.md
@@ -0,0 +1,8 @@
+# P0-T7 — dotnet-coverage global tool
+
+Timestamp: 2026-09-30T09-18
+Command: pwsh -NoProfile -Command 'Set-Location ""; if (-not (Get-Command dotnet-coverage -ErrorAction SilentlyContinue)) { dotnet tool install --global dotnet-coverage }; (Get-Command dotnet-coverage).Source'
+EXIT_CODE: 0
+Output Summary:
+- Get-Command resolved dotnet-coverage to \.dotnet\tools\dotnet-coverage.exe (already installed; no install was run).
+- The coverage runner's absent-tool guard (Invoke-MSTestWithCoverage.ps1 lines 344 to 346) will not throw.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t8-pester-provision.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t8-pester-provision.2026-09-28T20-01.md
new file mode 100644
index 000000000..085289778
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t8-pester-provision.2026-09-28T20-01.md
@@ -0,0 +1,17 @@
+# P0-T8 — Pester provisioning (N/A, read-only listing)
+
+Timestamp: 2026-09-30T09-18
+Command: pwsh -NoProfile -Command 'Set-Location ""; Get-Module Pester -ListAvailable | Select-Object Name,Version | Format-Table -AutoSize | Out-String'
+EXIT_CODE: 0
+Output Summary:
+```
+Name Version
+---- -------
+Pester 5.6.1
+Pester 3.4.0
+```
+N/A: no raw Pester invocation in this plan; the MCP test route supplies its own Pester
+
+GATE-SUBSTITUTION: Pester provisioning replaced by the PoshQC MCP test route
+
+No Install-Module was run. The listing carries no expectation and is recorded as measured.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t9-csharpier-check.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t9-csharpier-check.2026-09-28T20-01.md
new file mode 100644
index 000000000..2b4d4a77d
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t9-csharpier-check.2026-09-28T20-01.md
@@ -0,0 +1,18 @@
+# P0-T9 — C# formatter baseline (CMD-CSHARPIER-CHECK)
+
+Timestamp: 2026-09-30T09-19
+Command: pwsh -NoProfile -Command 'Set-Location ""; dotnet tool run csharpier check .; "CSHARPIER_EXIT=$LASTEXITCODE"' followed by the CMD-CSHARPIER-CHECK XML-candidate companion command
+EXIT_CODE: 0
+Output Summary:
+- "Checked 1625 files in 7451ms."
+- CSHARPIER_EXIT=0
+- N = 1625 (greater than 900)
+
+CSHARPIER-FINDINGS: none
+
+XML-CANDIDATES: 3
+```
+artifacts\pester\pester-junit.xml
+artifacts\pester\powershell-coverage.koverage.xml
+artifacts\pester\powershell-coverage.xml
+```
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/phase0-instructions-read.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/phase0-instructions-read.2026-09-28T20-01.md
new file mode 100644
index 000000000..92d66cff6
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/phase0-instructions-read.2026-09-28T20-01.md
@@ -0,0 +1,28 @@
+# P0-T2 — Phase 0 instructions read
+
+Timestamp: 2026-09-30T09-12
+Command: Read each file below in order from ; line counts by pwsh -NoProfile -Command '@(Get-Content -LiteralPath ).Count'
+EXIT_CODE: 0
+Policy Order: CLAUDE.md, then .claude/rules/general-code-change.md, then .claude/rules/general-unit-test.md, then the language- and domain-specific rules (powershell, csharp, quality-tiers, tonality, ci-workflows, plan-acceptance-gates), then the three skills, as fixed by the policy-compliance-order skill.
+
+Files read (in order, with line counts):
+
+1. CLAUDE.md — 463 lines
+2. .claude/rules/general-code-change.md — 80 lines
+3. .claude/rules/general-unit-test.md — 105 lines
+4. .claude/rules/powershell.md — 97 lines
+5. .claude/rules/csharp.md — 96 lines
+6. .claude/rules/quality-tiers.md — 51 lines
+7. .claude/rules/tonality.md — 80 lines
+8. .claude/rules/ci-workflows.md — 42 lines
+9. .claude/rules/plan-acceptance-gates.md — 257 lines
+10. .claude/skills/atomic-plan-contract/SKILL.md — 245 lines
+11. .claude/skills/evidence-and-timestamp-conventions/SKILL.md — 176 lines
+12. .claude/skills/acceptance-criteria-tracking/SKILL.md — 104 lines
+
+Output Summary:
+- Twelve files read in the order above, each with a non-zero line count.
+- issue.md line 12 reads `- Work Mode: minor-audit`.
+- issue.md carries the heading `## Acceptance Criteria` (line 40) with exactly 7 lines matching `^- \[ \] AC\d+:` beneath it (AC1 to AC7, lines 44 to 50).
+- No spec.md, user-story.md or research.md exists in the feature folder (Test-Path False for each).
+- Coverage-floor conflict (convention 10): CLAUDE.md states an 80 percent PowerShell and C# line floor and a four-step toolchain loop; .claude/rules/general-unit-test.md, .claude/rules/quality-tiers.md and .claude/rules/powershell.md state 85 percent and a seven-stage loop. This plan gates on CLAUDE.md and records MEETS-85 as an observation only. The conflict is tracked as open GitHub issue 668.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/other/p2-t19-maintainer-followup.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/other/p2-t19-maintainer-followup.2026-09-28T20-01.md
new file mode 100644
index 000000000..9f107d665
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/other/p2-t19-maintainer-followup.2026-09-28T20-01.md
@@ -0,0 +1,15 @@
+# P2-T19 — Maintainer follow-up record (issue 929 Summary item 4)
+
+Timestamp: 2026-09-30T11-18
+Command: pwsh -NoProfile -Command 'Set-Location ""; "DEFERRED_UNCHECKED=" + @(Select-String -Path "docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/spec.md" -Pattern "^- \[ \] \*\*AC(18|19|20) ").Count'
+EXIT_CODE: 0
+Output Summary:
+- DEFERRED_UNCHECKED=3 (AC18, AC19 and AC20 remain unchecked in the 911 spec; this plan changed nothing there)
+
+This item is not an acceptance criterion and not a merge gate.
+
+- Acceptance criteria AC18, AC19 and AC20 of issue 911 remain deferred to the maintainer until a GitHub App credential is provisioned. Nothing in this change marks them passed.
+- The secret store remains unconfirmed: whether the Dependabot-triggered workflow_run that runs .github/workflows/dependabot-repair.yml reads repository Actions secrets or only Dependabot secrets is for the maintainer to confirm.
+- After this change merges, the secret named DEPENDABOT_REPAIR_APP_ID must hold the App's Client ID, not the numeric App ID: the workflow now passes that secret as the client-id input of actions/create-github-app-token. The private key stays in DEPENDABOT_REPAIR_APP_PRIVATE_KEY.
+- Runbook: docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md (Part B step 10 and Part D step 22 now instruct storing the Client ID).
+- Spec: docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/spec.md (AC18 to AC20).
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/other/p2-t21-reduced-audit-handoff.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/other/p2-t21-reduced-audit-handoff.2026-09-28T20-01.md
new file mode 100644
index 000000000..eac7c9e04
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/other/p2-t21-reduced-audit-handoff.2026-09-28T20-01.md
@@ -0,0 +1,153 @@
+# P2-T21 — Reduced-audit handoff index (issue 929)
+
+Timestamp: 2026-09-30T11-22
+Command: Enumerate the evidence tree with each artifact's first EXIT_CODE line; CMD-HYGIENE over the feature folder; pwsh -NoProfile -Command 'Set-Location ""; & ".\scripts\hygiene\Test-RepositoryHygiene.ps1"; "GUARD_EXIT=$LASTEXITCODE"'
+EXIT_CODE: 0
+Output Summary: index of the 61 evidence .md artifacts produced before this one, the committed coverage copies, the commits, the CI runs, the observations the plan requires to be carried forward, and the pre-commit hygiene and CI hygiene-guard results (appended below).
+
+## Anchors (P0-T1)
+
+- BASE-SHA: 231e1c0b55105aeb626bf5a6e8d0266a567cacad
+- P0-START: 481b33c594d8412cb64e604ff53295db215ac2f1
+- MERGED-MAIN-ANCESTOR: 0
+
+## Commits
+
+| Task | SHA | Message | Pushed |
+|---|---|---|---|
+| P0-T21 | 488492f135c17c1ca4c8e6224bf7663a58c5e7b1 | docs(929): phase 0 baseline evidence | yes |
+| P1-T14 | b96926588d562f994430e7ba7301de5de86f206c | fix(929): remove altcover imports, correct SVGControl redirects, pass client-id to the token action | yes |
+| P2-T20 | 9e41ffbcf069b1b4f0aa7fe8e5eab2483c561530 | docs(929): final QC evidence, coverage projection and acceptance check-off | yes |
+
+No P2-T1 formatter commit and no P2-T2 repair commit was made in either iteration (the formatter rewrote nothing and the analyzer reported ok true).
+
+P2-T20 commit transcription (the P2-T20 artifact is inside that commit):
+- Head: 9e41ffbcf069b1b4f0aa7fe8e5eab2483c561530
+- git show --name-only --format= HEAD: 32 paths, all under the feature folder, including evidence/qa-gates/p2-t20-ac-status-summary.2026-09-28T20-01.md, evidence/qa-gates/p2-t7-coverage-projection.2026-09-28T20-01.jacoco.xml, evidence/qa-gates/p2-t7-test-results.2026-09-28T20-01.summary.txt, issue.md and the plan
+- Porcelain after the commit: only agent-memory entries (the two modified MEMORY.md files and five untracked agent-memory notes)
+
+## Fail-before / pass-after pair
+
+- Fail-before: evidence/regression-testing/p1-t2-tree-test-fail-before.2026-09-28T20-01.md (RepositoryTreeConsistency.Tests.ps1 tests=4 failures=4; EXIT_CODE 1, ExpectedExitCode 1)
+- Pass-after: evidence/regression-testing/p1-t11-tree-test-pass-after.2026-09-28T20-01.md (tests=4 failures=0; root 137 failures 0)
+
+## Committed coverage evidence copies
+
+- Baseline: evidence/baseline/p0-t12-coverage-projection.2026-09-28T20-01.jacoco.xml and evidence/baseline/p0-t12-test-results.2026-09-28T20-01.summary.txt
+- Final: evidence/qa-gates/p2-t7-coverage-projection.2026-09-28T20-01.jacoco.xml and evidence/qa-gates/p2-t7-test-results.2026-09-28T20-01.summary.txt
+- All four are package-level projections or trx-derived summaries; no raw document is committed.
+
+## CI runs
+
+| Purpose | Run id | Head SHA | Pester job | Pester conclusion | Run conclusion |
+|---|---|---|---|---|---|
+| Baseline (P0-T16) | 36666302259 | 231e1c0b55105aeb626bf5a6e8d0266a567cacad (main) | 109731601928 | success | success |
+| Branch (P2-T3) | 36722780748 | b96926588d562f994430e7ba7301de5de86f206c | 109911885533 | success | failure (mstest-coverage job only: 1 of 7346 failed, Transaction_SecondCallerCannotInstallUntilTheFirstRestores) |
+
+## Carried-forward observations
+
+- ANALYZER-ITEM-STATE: aligned (P0-T6)
+- MEETS-85 observations: P0-T12 true (C# line 85.91); P0-T16 true (PowerShell 94.51); P2-T3 true (PowerShell 94.51, both iterations); P2-T7 true (C# line 85.92, iteration 2). Convention 10 conflict (CLAUDE.md 80 percent versus the rules' 85 percent) is tracked as open issue 668.
+- OUT-OF-SCOPE-RESIDUAL (P0-T18): eleven app.config files other than SVGControl and UtilitiesCS redirect Fizzler to 1.3.0.0 (QuickFiler, QuickFiler.Test, SVGControl.Test, Tags, TaskMaster, TaskTree, TaskVisualization, TaskVisualization.Test, ToDoModel, ToDoModel.Test, UtilitiesCS.Test); recorded in docs/features/potential/2026-08-04-stale-fizzler-and-unsafe-binding-redirects.md.
+- CSHARPIER-COUNTS-IGNORED-XML: false (P2-T4, both iterations)
+- P1-T13: no potential entry authored; coordinator ruling 2026-09-30
+- Maintainer follow-up (P2-T19): AC18 to AC20 of issue 911 remain deferred; the secret store is unconfirmed; DEPENDABOT_REPAIR_APP_ID must now hold the App's Client ID. Not an acceptance criterion and not a merge gate.
+
+## GATE-SUBSTITUTION lines carried by the artifacts
+
+- P0-T8: Pester provisioning replaced by the PoshQC MCP test route
+- P0-T14, P2-T2 (iter1, iter2): PoshQC analyze ok flag stands in for a diagnostic count
+- P0-T15, P1-T2, P1-T3, P1-T7, P1-T11: JUnit per-file counts stand in for a direct Pester run
+- P0-T16: CI Pester job 109731601928 stands in for a local coverage run
+- P2-T3 (iter1, iter2): CI Pester job on the pushed head stands in for a local coverage run
+
+## Final QC loop iterations
+
+- Iteration 1: P2-T1 to P2-T6 passed; P2-T7 failed (1 of 7346, RemainingLoadActive_AcrossAsyncVoidFirstAwait_StaysTrueWhileLoaderProduces in QuickFiler.Test/Controllers/QfcDatamodelLivenessTests.cs, a five-second wait that did not complete).
+- Iteration 2: P2-T1 to P2-T7 passed on the unchanged tree; P2-T8 attests iteration 2.
+
+## AC status summary
+
+- Source: issue.md `## Acceptance Criteria`; Total 7; Checked off 7; Remaining 0.
+
+## Evidence artifacts (path relative to the feature folder | task | EXIT_CODE)
+
+| Path | Task | EXIT_CODE |
+|---|---|---|
+| evidence/baseline/p0-t1-worktree-anchor.2026-09-28T20-01.md | P0-T1 | 0 |
+| evidence/baseline/phase0-instructions-read.2026-09-28T20-01.md | P0-T2 | 0 |
+| evidence/baseline/p0-t3-sdk-bootstrap.2026-09-28T20-01.md | P0-T3 | 0 |
+| evidence/baseline/p0-t4-tool-restore.2026-09-28T20-01.md | P0-T4 | 0 |
+| evidence/baseline/p0-t5-package-restore.2026-09-28T20-01.md | P0-T5 | 0 |
+| evidence/baseline/p0-t6-analyzer-item-census.2026-09-28T20-01.md | P0-T6 | 0 |
+| evidence/baseline/p0-t7-dotnet-coverage.2026-09-28T20-01.md | P0-T7 | 0 |
+| evidence/baseline/p0-t8-pester-provision.2026-09-28T20-01.md | P0-T8 | 0 |
+| evidence/baseline/p0-t9-csharpier-check.2026-09-28T20-01.md | P0-T9 | 0 |
+| evidence/baseline/p0-t10-msbuild-analyzers.2026-09-28T20-01.md | P0-T10 | 0 |
+| evidence/baseline/p0-t11-msbuild-nullable.2026-09-28T20-01.md | P0-T11 | 0 |
+| evidence/baseline/p0-t12-mstest-coverage.2026-09-28T20-01.md | P0-T12 | 0 |
+| evidence/baseline/p0-t13-poshqc-format.2026-09-28T20-01.md | P0-T13 | 0 |
+| evidence/baseline/p0-t14-poshqc-analyze.2026-09-28T20-01.md | P0-T14 | 0 |
+| evidence/baseline/p0-t15-poshqc-test-mcp.2026-09-28T20-01.md | P0-T15 | 0 |
+| evidence/baseline/p0-t16-pester.2026-09-28T20-01.md | P0-T16 | 0 |
+| evidence/baseline/p0-t17-altcover-and-verifier-prefix.2026-09-28T20-01.md | P0-T17 | 0 |
+| evidence/baseline/p0-t18-redirect-prefix.2026-09-28T20-01.md | P0-T18 | 0 |
+| evidence/baseline/p0-t19-workflow-prefix-and-actionlint.2026-09-28T20-01.md | P0-T19 | 0 |
+| evidence/baseline/p0-t20-hygiene.2026-09-28T20-01.md | P0-T20 | 0 |
+| evidence/baseline/p0-t21-commit.2026-09-28T20-01.md | P0-T21 | 0 |
+| evidence/regression-testing/p1-t1-tree-test-authored.2026-09-28T20-01.md | P1-T1 | 0 |
+| evidence/regression-testing/p1-t2-tree-test-fail-before.2026-09-28T20-01.md | P1-T2 | 1 (expected 1) |
+| evidence/regression-testing/p1-t3-verifier-import-tests.2026-09-28T20-01.md | P1-T3 | 1 (expected 1) |
+| evidence/qa-gates/p1-t4-altcover-imports-removed.2026-09-28T20-01.md | P1-T4 | 0 |
+| evidence/qa-gates/p1-t5-redirects-fixed.2026-09-28T20-01.md | P1-T5 | 0 |
+| evidence/qa-gates/p1-t6-workflow-client-id.2026-09-28T20-01.md | P1-T6 | 0 |
+| evidence/qa-gates/p1-t7-actionlint.2026-09-28T20-01.md | P1-T7 | 1 (expected 1) |
+| evidence/qa-gates/p1-t8-runbook-client-id.2026-09-28T20-01.md | P1-T8 | 0 |
+| evidence/qa-gates/p1-t9-readme-client-id.2026-09-28T20-01.md | P1-T9 | 0 |
+| evidence/qa-gates/p1-t10-verifier-comment.2026-09-28T20-01.md | P1-T10 | 0 |
+| evidence/regression-testing/p1-t11-tree-test-pass-after.2026-09-28T20-01.md | P1-T11 | 0 |
+| evidence/qa-gates/p1-t12-verifier-postfix.2026-09-28T20-01.md | P1-T12 | 0 |
+| evidence/qa-gates/p1-t14-commit.2026-09-28T20-01.md | P1-T14 | 0 |
+| evidence/qa-gates/p2-t1-poshqc-format.iter1.2026-09-28T20-01.md | P2-T1 iter1 | 0 |
+| evidence/qa-gates/p2-t2-poshqc-analyze.iter1.2026-09-28T20-01.md | P2-T2 iter1 | 0 |
+| evidence/qa-gates/p2-t3-pester.iter1.2026-09-28T20-01.md | P2-T3 iter1 | 0 |
+| evidence/qa-gates/p2-t4-csharpier-check.iter1.2026-09-28T20-01.md | P2-T4 iter1 | 0 |
+| evidence/qa-gates/p2-t5-msbuild-analyzers.iter1.2026-09-28T20-01.md | P2-T5 iter1 | 0 |
+| evidence/qa-gates/p2-t6-msbuild-nullable.iter1.2026-09-28T20-01.md | P2-T6 iter1 | 0 |
+| evidence/qa-gates/p2-t7-mstest-coverage.iter1.2026-09-28T20-01.md | P2-T7 iter1 | 1 (failed; loop restarted) |
+| evidence/qa-gates/p2-t1-poshqc-format.iter2.2026-09-28T20-01.md | P2-T1 iter2 | 0 |
+| evidence/qa-gates/p2-t2-poshqc-analyze.iter2.2026-09-28T20-01.md | P2-T2 iter2 | 0 |
+| evidence/qa-gates/p2-t3-pester.iter2.2026-09-28T20-01.md | P2-T3 iter2 | 0 |
+| evidence/qa-gates/p2-t4-csharpier-check.iter2.2026-09-28T20-01.md | P2-T4 iter2 | 0 |
+| evidence/qa-gates/p2-t5-msbuild-analyzers.iter2.2026-09-28T20-01.md | P2-T5 iter2 | 0 |
+| evidence/qa-gates/p2-t6-msbuild-nullable.iter2.2026-09-28T20-01.md | P2-T6 iter2 | 0 |
+| evidence/qa-gates/p2-t7-mstest-coverage.iter2.2026-09-28T20-01.md | P2-T7 iter2 | 0 |
+| evidence/qa-gates/p2-t8-attestation-and-coverage-delta.2026-09-28T20-01.md | P2-T8 | 0 |
+| evidence/qa-gates/p2-t9-file-size-audit.2026-09-28T20-01.md | P2-T9 | 0 |
+| evidence/qa-gates/p2-t10-change-footprint.2026-09-28T20-01.md | P2-T10 | 0 |
+| evidence/qa-gates/p2-t11-hygiene.2026-09-28T20-01.md | P2-T11 | 0 |
+| evidence/qa-gates/p2-t12-ac1-checkoff.2026-09-28T20-01.md | P2-T12 | 0 |
+| evidence/qa-gates/p2-t13-ac2-checkoff.2026-09-28T20-01.md | P2-T13 | 0 |
+| evidence/qa-gates/p2-t14-ac3-checkoff.2026-09-28T20-01.md | P2-T14 | 0 |
+| evidence/qa-gates/p2-t15-ac4-checkoff.2026-09-28T20-01.md | P2-T15 | 0 |
+| evidence/qa-gates/p2-t16-ac5-checkoff.2026-09-28T20-01.md | P2-T16 | 0 |
+| evidence/qa-gates/p2-t17-ac6-checkoff.2026-09-28T20-01.md | P2-T17 | 0 |
+| evidence/qa-gates/p2-t18-ac7-checkoff.2026-09-28T20-01.md | P2-T18 | 0 |
+| evidence/other/p2-t19-maintainer-followup.2026-09-28T20-01.md | P2-T19 | 0 |
+| evidence/qa-gates/p2-t20-ac-status-summary.2026-09-28T20-01.md | P2-T20 | 0 |
+
+Artifact count listed: 61 evidence .md files (at least 54), each present on disk at the time of this index.
+
+## Pre-commit checks
+
+CMD-HYGIENE over the feature folder:
+- PATTERNS=3
+- SELFTEST=1
+- SELFTEST_NEG=0
+- SCANNED=68
+- HITS=0
+- PRE-FIX-HITS: 0
+
+CI hygiene guard run locally (scripts/hygiene/Test-RepositoryHygiene.ps1 over every tracked file):
+- HYGIENE Findings=0
+- GUARD_EXIT=0
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t10-verifier-comment.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t10-verifier-comment.2026-09-28T20-01.md
new file mode 100644
index 000000000..8d4f15e73
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t10-verifier-comment.2026-09-28T20-01.md
@@ -0,0 +1,14 @@
+# P1-T10 — Verifier comment updated, line count held
+
+Timestamp: 2026-09-30T10-15
+Command: Edit scripts/dependencies/ConsistencyVerifier.psm1 lines 221 to 223; pwsh -NoProfile -Command 'Set-Location ""; "LINES=" + @(Get-Content -LiteralPath "scripts/dependencies/ConsistencyVerifier.psm1").Count; "LIVE=" + ...; "I929=" + ...; "NUMSTAT=" + (git diff --numstat 488492f135c17c1ca4c8e6224bf7663a58c5e7b1 -- scripts/dependencies/ConsistencyVerifier.psm1)'
+EXIT_CODE: 0
+Output Summary:
+- Replacement (three lines for three lines, same indentation):
+ - ` Issue 929 removed the last live instance, two Exists() guarded elements in`
+ - ` QuickFiler.Test naming an altcover package no manifest declared; the shape survives as`
+ - ` an in-memory test fixture. No exception is hard-coded for any package identifier.`
+- LINES=499 (equals VERIFIER-LINES 499 from P0-T13; at most 500)
+- LIVE=0
+- I929=1
+- NUMSTAT=3 3 scripts/dependencies/ConsistencyVerifier.psm1 (against P0-HEAD 488492f13)
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t12-verifier-postfix.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t12-verifier-postfix.2026-09-28T20-01.md
new file mode 100644
index 000000000..de034b384
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t12-verifier-postfix.2026-09-28T20-01.md
@@ -0,0 +1,13 @@
+# P1-T12 — Read-only verifier run on the fixed tree (CMD-VERIFIER-WHATIF)
+
+Timestamp: 2026-09-30T10-18
+Command: CMD-VERIFIER-WHATIF (pwsh -NoProfile -Command 'Set-Location ""; $files = @(Get-ChildItem -Path "*/packages.config","*/app.config","*/*.csproj" -File); ...; $r = & ".\scripts\dependencies\Repair-PackageManifestConsistency.ps1" -WhatIf; ...')
+EXIT_CODE: 0
+Output Summary:
+- Result line: ABSENT=0 DISAGREE=0 WRITTEN=0 SUCCESS=True PROJECTS=18 FILES=53 HASHES_EQUAL=True
+- ABSENT=0 (P0-T17 measured 2)
+- WRITTEN=0; HASHES_EQUAL=True (nothing written)
+- PROJECTS=18; FILES=53 (equal to the P0-T17 value)
+- DISAGREE=0 (equal to the P0-T17 value; this change moves no version); SUCCESS=True (recorded as measured)
+- Information line (printed five times): "Manifest discovery: enumerated directories 35, returned files 53"
+- -WhatIf messages: the same 17 "Rewrite in canonical inline form" targets P0-T17 recorded, each \\packages.config for QuickFiler.Test, QuickFiler, SVGControl.Test, Tags.Test, Tags, TaskMaster.Test, TaskMaster, TaskTree.Test, TaskTree, TaskVisualization.Test, TaskVisualization, ToDoModel.Test, ToDoModel, UtilitiesCS.Test, UtilitiesCS, VBFunctions.Test and VBFunctions.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t14-commit.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t14-commit.2026-09-28T20-01.md
new file mode 100644
index 000000000..36c7a2f36
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t14-commit.2026-09-28T20-01.md
@@ -0,0 +1,22 @@
+# P1-T14 — Hygiene scan, implementation commit and push
+
+Timestamp: 2026-09-30T10-21
+Command: CMD-HYGIENE with FOLDER-LIST "docs/features/active/2026-09-28-package-manifest-consistency-residuals-929","tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1",".github/workflows/dependabot-repair.yml",".github/workflows/README.md","docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md","scripts/dependencies/ConsistencyVerifier.psm1","tests/scripts/dependencies/ConsistencyVerifier.Tests.ps1"; @(Get-Content).Count per non-Markdown Write Set file; git add -- docs/features/active/2026-09-28-package-manifest-consistency-residuals-929; git commit -m "fix(929): remove altcover imports, correct SVGControl redirects, pass client-id to the token action" -m "Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com"; git push origin bug/package-manifest-consistency-residuals-929; git rev-parse HEAD; git show --name-only --format= HEAD; git status --porcelain --untracked-files=all; git ls-remote --heads origin bug/package-manifest-consistency-residuals-929
+EXIT_CODE: 0
+Output Summary:
+- Pre-commit hygiene: PATTERNS=3 SELFTEST=1 SELFTEST_NEG=0 SCANNED=43 HITS=0
+- PRE-FIX-HITS: 0
+- Line counts of the non-Markdown Write Set files (each at most 500):
+ - QuickFiler.Test/QuickFiler.Test.csproj 568
+ - SVGControl/app.config 23
+ - .github/workflows/dependabot-repair.yml 173
+ - scripts/dependencies/ConsistencyVerifier.psm1 499 (equals VERIFIER-LINES)
+ - tests/scripts/dependencies/ConsistencyVerifier.Tests.ps1 337
+ - tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1 152
+- Commit: "[bug/package-manifest-consistency-residuals-929 b96926588] fix(929): remove altcover imports, correct SVGControl redirects, pass client-id to the token action" — 22 files changed
+- Recorded head: b96926588d562f994430e7ba7301de5de86f206c (differs from P0-HEAD 488492f13)
+- git show --name-only --format= HEAD: 22 paths — the eight non-feature-folder Write Set paths (.github/workflows/README.md, .github/workflows/dependabot-repair.yml, QuickFiler.Test/QuickFiler.Test.csproj, SVGControl/app.config, the 911 runbook, scripts/dependencies/ConsistencyVerifier.psm1, tests/scripts/dependencies/ConsistencyVerifier.Tests.ps1, tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1) plus 14 paths under the feature folder (the P0-T21 artifact, twelve Phase 1 artifacts P1-T1 to P1-T12 and the plan)
+- Porcelain after the commit: only agent-memory entries (2 modified MEMORY.md files and 5 untracked agent-memory notes), none staged or committed
+- Push: "488492f13..b96926588 bug/package-manifest-consistency-residuals-929 -> bug/package-manifest-consistency-residuals-929" (exit 0)
+- PUSHED-HEAD: b96926588d562f994430e7ba7301de5de86f206c refs/heads/bug/package-manifest-consistency-residuals-929 (names the recorded head)
+- The push starts no CI run by itself (ci.yml lines 3 to 8); P2-T3 dispatches one. The pre-implementation hook accepted the commit of source paths; the executor did not create or edit the orchestrator checkpoint.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t4-altcover-imports-removed.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t4-altcover-imports-removed.2026-09-28T20-01.md
new file mode 100644
index 000000000..d9dc2cb7f
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t4-altcover-imports-removed.2026-09-28T20-01.md
@@ -0,0 +1,13 @@
+# P1-T4 — altcover Import elements removed
+
+Timestamp: 2026-09-30T10-06
+Command: Edit QuickFiler.Test/QuickFiler.Test.csproj (delete the two altcover Import lines); pwsh -NoProfile -Command 'Set-Location ""; "NUMSTAT=" + (git diff --numstat 231e1c0b55105aeb626bf5a6e8d0266a567cacad -- QuickFiler.Test/QuickFiler.Test.csproj); "LINES=" + @(Get-Content QuickFiler.Test/QuickFiler.Test.csproj).Count; "ALTCOVER_LINES=" + @(git grep -i -n altcover -- "*.csproj" "*/packages.config").Count'; git diff 231e1c0b55105aeb626bf5a6e8d0266a567cacad -- QuickFiler.Test/QuickFiler.Test.csproj
+EXIT_CODE: 0
+Output Summary:
+- NUMSTAT=0 2 QuickFiler.Test/QuickFiler.Test.csproj (0 added, 2 deleted)
+- LINES=568 (570 minus 2)
+- ALTCOVER_LINES=0 (P0-T17 measured 2 over the same pathspec)
+- Deleted lines, verbatim from git diff -- QuickFiler.Test/QuickFiler.Test.csproj:
+ - `- ` (hunk @@ -5,7 +5,6 @@)
+ - `- ` (hunk @@ -534,7 +533,6 @@)
+- No other change to the file.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t5-redirects-fixed.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t5-redirects-fixed.2026-09-28T20-01.md
new file mode 100644
index 000000000..3d7c74b08
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t5-redirects-fixed.2026-09-28T20-01.md
@@ -0,0 +1,13 @@
+# P1-T5 — SVGControl binding redirects corrected
+
+Timestamp: 2026-09-30T10-07
+Command: Edit SVGControl/app.config lines 15 and 19; git diff --numstat 231e1c0b55105aeb626bf5a6e8d0266a567cacad -- SVGControl/app.config; git diff 231e1c0b55105aeb626bf5a6e8d0266a567cacad -- SVGControl/app.config; CMD-REDIRECT-OBSERVE (all in one pwsh invocation beginning with Set-Location "")
+EXIT_CODE: 0
+Output Summary:
+- NUMSTAT=2 2 SVGControl/app.config (2 added, 2 deleted)
+- New lines, verbatim from git diff -- SVGControl/app.config (hunk @@ -12,11 +12,11 @@):
+ - line 15: `+ `
+ - line 19: `+ `
+- Indentation unchanged; the edit touched only the two bindingRedirect lines.
+- FIZZLER_REPAIRS=0 UNSAFE_REPAIRS=0 EXAMINED=4 (P0-T18 measured 1, 1 and 4 on the same command)
+- The Fizzler value 1.3.1.0 equals FIZZLER_ASM and the Unsafe value 6.0.3.0 equals UNSAFE_ASM from P0-T18.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t6-workflow-client-id.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t6-workflow-client-id.2026-09-28T20-01.md
new file mode 100644
index 000000000..8c9bcf08d
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t6-workflow-client-id.2026-09-28T20-01.md
@@ -0,0 +1,22 @@
+# P1-T6 — Repair workflow passes client-id
+
+Timestamp: 2026-09-30T10-09
+Command: Edit .github/workflows/dependabot-repair.yml lines 13, 14 and 51; pwsh -NoProfile -Command 'Set-Location ""; $w = Get-Content ".github/workflows/dependabot-repair.yml"; "WF_APPID=" + ...; "WF_CLIENTID=" + ...; "WF_SECRET=" + ...; "NUMSTAT=" + (git diff --numstat 231e1c0b55105aeb626bf5a6e8d0266a567cacad -- .github/workflows/dependabot-repair.yml)'; git diff 231e1c0b55105aeb626bf5a6e8d0266a567cacad -- .github/workflows/dependabot-repair.yml
+EXIT_CODE: 0
+Output Summary:
+- WF_APPID=0
+- WF_CLIENTID=1
+- WF_SECRET=1 (the secret name DEPENDABOT_REPAIR_APP_ID is unchanged, decision D3)
+- NUMSTAT=3 3 .github/workflows/dependabot-repair.yml (at most 3 added and 3 deleted)
+- Diff hunks, verbatim (lines 13, 14 and 51 only):
+
+```
+@@ -10,8 +10,8 @@ name: dependabot-repair
+-# Credential: a GitHub App installation token minted from DEPENDABOT_REPAIR_APP_ID and
+-# DEPENDABOT_REPAIR_APP_PRIVATE_KEY. When those secrets are absent the token step fails, the job
++# Credential: a GitHub App installation token minted from the App's Client ID, stored in
++# DEPENDABOT_REPAIR_APP_ID, and the private key in DEPENDABOT_REPAIR_APP_PRIVATE_KEY. When those secrets are absent the token step fails, the job
+@@ -48,7 +48,7 @@ jobs:
+- app-id: ${{ secrets.DEPENDABOT_REPAIR_APP_ID }}
++ client-id: ${{ secrets.DEPENDABOT_REPAIR_APP_ID }}
+```
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t7-actionlint.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t7-actionlint.2026-09-28T20-01.md
new file mode 100644
index 000000000..34aa2fbc7
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t7-actionlint.2026-09-28T20-01.md
@@ -0,0 +1,22 @@
+# P1-T7 — actionlint after the workflow edit, and the intermediate test state
+
+Timestamp: 2026-09-30T10-11
+Command: CMD-ACTIONLINT; RUN-START captured in the same pwsh invocation with [DateTime]::UtcNow.ToString("o"); MCP mcp__drm-copilot__run_poshqc_test (workspace_root , scan_folders ["tests/scripts/dependencies"]); CMD-JUNIT-READ
+EXIT_CODE: 1
+ExpectedExitCode: 1
+Output Summary:
+- actionlint version line: "1.7.7"
+- Scoped lint of .github/workflows/dependabot-repair.yml: no output; SCOPED_EXIT=0
+- Repository-wide run-actionlint.ps1: no output; REPO_EXIT=0
+- RUN-START: 2026-09-30T13:27:50.9467135Z
+- MCP payload (host prefix replaced): {"ok": false, "tool": "run_poshqc_test", "workspace_root": "", "summary": "Command exited with code 1."}
+- JUNIT-WRITTEN=2026-09-30T13:28:21.7740649Z (later than RUN-START)
+- JUNIT-ROOT tests=137 failures=1 errors=0 disabled=0
+- JUNIT-SUITE DependabotConfig.Tests.ps1 tests=17 failures=0 skipped=0 (the existing workflow static tests still hold after the edit)
+- JUNIT-SUITE RepositoryTreeConsistency.Tests.ps1 tests=4 failures=1 skipped=0
+- Other suites at failures=0: AnalyzerItemRepair 13, ConsistencyVerifier 14, PackageCompatibility 8, PackageGraph 32, ProjectConsistency 18, Repair-PackageManifestConsistency 31
+- JUNIT-NOTPASSED Repository tree consistency (issue 929).instructs the maintainer to store the Client ID in the secret the repair workflow reads by name
+- JUNIT-MESSAGE Expected 1, because the runbook sample must pass client-id from secrets.DEPENDABOT_REPAIR_APP_ID, but got 0.
+- Tests 1 to 3 now pass after P1-T4 to P1-T6; test 4 (the runbook secret-name test) still reproduces its defect until P1-T8 (decision D13).
+
+GATE-SUBSTITUTION: JUnit per-file counts stand in for a direct Pester run
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t8-runbook-client-id.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t8-runbook-client-id.2026-09-28T20-01.md
new file mode 100644
index 000000000..2241b69ee
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t8-runbook-client-id.2026-09-28T20-01.md
@@ -0,0 +1,37 @@
+# P1-T8 — Runbook instructs storing the Client ID
+
+Timestamp: 2026-09-30T10-13
+Command: Edit docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md (Part B heading, step 10, step 22, YAML sample line 154); the P1-T8 pwsh measurement command verbatim; git diff 231e1c0b55105aeb626bf5a6e8d0266a567cacad --
+EXIT_CODE: 0
+Output Summary:
+- RB_APPID=0
+- RB_CLIENTID=1
+- RB_SECRET=2 (step 22 and the YAML sample; at least 2)
+- RB_PARTB=0 (a search for "Record the App ID" returns 0 lines; P0-T19 measured 1)
+- PARTD_CLIENTID=2 (at least 1)
+- The citations at lines 301 and 318 were not edited.
+
+Diff hunks against , verbatim:
+```
+@@ -96,13 +96,13 @@ permissions listed in step 6 below and skip to step 10.
+-### Part B — Record the App ID and generate a private key
++### Part B — Record the Client ID and generate a private key
+-10. On the App's settings page that appears after creation, locate the **App ID** in the "About"
+- section near the top of the page and record it. The adjacent **Client ID** is also shown; record
+- it as well, because the `actions/create-github-app-token` action now documents `client-id` as
+- the recommended input and continues to accept the legacy `app-id` input. Neither value is a
+- secret in the cryptographic sense, but this runbook stores the App ID as a repository secret to
++10. On the App's settings page that appears after creation, locate the **Client ID** in the "About"
++ section near the top of the page and record it. The numeric **App ID** shown beside it is not
++ needed: the repair workflow passes the Client ID to the `actions/create-github-app-token` action
++ as its `client-id` input, which the action documents as the recommended input. The Client ID is
++ not a secret in the cryptographic sense, but this runbook stores it as a repository secret to
+@@ -126,9 +126,9 @@ permissions listed in step 6 below and skip to step 10.
+-22. Create the App ID secret:
++22. Create the Client ID secret:
+- - **Secret** — the App ID value recorded in step 10
++ - **Secret** — the Client ID value recorded in step 10
+@@ -151,7 +151,7 @@ permissions listed in step 6 below and skip to step 10.
+- app-id: ${{ secrets.DEPENDABOT_REPAIR_APP_ID }}
++ client-id: ${{ secrets.DEPENDABOT_REPAIR_APP_ID }}
+```
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t9-readme-client-id.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t9-readme-client-id.2026-09-28T20-01.md
new file mode 100644
index 000000000..3061b8f4b
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t9-readme-client-id.2026-09-28T20-01.md
@@ -0,0 +1,13 @@
+# P1-T9 — Workflows README secret row names the Client ID
+
+Timestamp: 2026-09-30T10-14
+Command: Edit .github/workflows/README.md line 116; pwsh -NoProfile -Command 'Set-Location ""; $r = Get-Content ".github/workflows/README.md"; "README_NUMERIC=" + ...; "README_CLIENTID=" + ...; "NUMSTAT=" + (git diff --numstat 231e1c0b55105aeb626bf5a6e8d0266a567cacad -- .github/workflows/README.md)'; git diff 231e1c0b55105aeb626bf5a6e8d0266a567cacad -- .github/workflows/README.md
+EXIT_CODE: 0
+Output Summary:
+- README_NUMERIC=0 (P0-T19 measured 1)
+- README_CLIENTID=1 (at least 1)
+- NUMSTAT=1 1 .github/workflows/README.md (1 added, 1 deleted)
+- Diff (hunk @@ -113,7 +113,7 @@):
+ - `-| `DEPENDABOT_REPAIR_APP_ID` | the numeric App identifier |`
+ - `+| `DEPENDABOT_REPAIR_APP_ID` | the App's Client ID, passed to the token action's `client-id` input (the numeric App ID is not stored) |`
+- The table shape is unchanged and the edit introduces no backticked three-part version literal (the AC26 test in DependabotConfig.Tests.ps1 reads every such literal in this file).
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t1-poshqc-format.iter1.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t1-poshqc-format.iter1.2026-09-28T20-01.md
new file mode 100644
index 000000000..d15f2c141
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t1-poshqc-format.iter1.2026-09-28T20-01.md
@@ -0,0 +1,32 @@
+# P2-T1 — PowerShell QC step 1, format (iteration 1)
+
+Timestamp: 2026-09-30T10-23
+Command: Get-FileHash -Algorithm SHA256 over every .ps1, .psm1 and .psd1 file under scripts/dependencies and tests/scripts/dependencies; MCP mcp__drm-copilot__run_poshqc_format (workspace_root , scan_folders ["scripts/dependencies","tests/scripts/dependencies"]); re-hash; git status --porcelain --untracked-files=all -- scripts/dependencies tests/scripts/dependencies; @(Get-Content -LiteralPath "scripts/dependencies/ConsistencyVerifier.psm1").Count
+EXIT_CODE: 0
+Output Summary:
+- MCP payload (host prefix replaced): {"ok":true,"tool":"run_poshqc_format","workspace_root":"","summary":"Ran bundled PoshQC format against '' with 2 selected scan folder(s)."}
+- scan_folders: ["scripts/dependencies","tests/scripts/dependencies"]
+- Hash sets: 14 entries before and 14 after (6 production, 8 test files); every hash identical
+- Write Set rewrite count: 0
+- REVERT-SET: empty
+- Post-revert porcelain over the two folders: empty
+- ConsistencyVerifier.psm1 line count: 499 (equals VERIFIER-LINES)
+- No REWRITE-NUMSTAT capture was needed (no rewrite); no commit made; the loop does not restart.
+
+Hash set (identical before and after):
+```
+scripts\dependencies\AnalyzerItemRepair.psm1 102E3EBCF014F8365C3C65A834EDEC5FC9DAC9B1FFD6477E68D813335DB48F68
+scripts\dependencies\ConsistencyVerifier.psm1 00604D4F0731A2B432797CBBF85AE5DABAE1D17190A07DCA2348D272D1FBA920
+scripts\dependencies\PackageCompatibility.psm1 89B31603872ED09C8E2DF2E94A597D42BF3A2019D4F49298D6859CEF7CBF41CD
+scripts\dependencies\PackageGraph.psm1 1CE9EABA3A43FF2446C3B63FFA53CE501537362C8E6EED6BB9DB4774F15C9BC6
+scripts\dependencies\ProjectConsistency.psm1 0E7B005A65B5614A0099F7A7286FE6692F87CC49FF09D749877F832C37D69EFE
+scripts\dependencies\Repair-PackageManifestConsistency.ps1 E69F61364EB1640C0FADFBBAE1F418250D2F508E8F26A048BE43F70DD659078A
+tests\scripts\dependencies\AnalyzerItemRepair.Tests.ps1 7C4CBC097681F98A629F94AD12D800A7E87652CA773825FA26F621969671D011
+tests\scripts\dependencies\ConsistencyVerifier.Tests.ps1 CC9AD3DFE9799F943AE464A04C4E8AA00A389283B510DB8759A1BA474231C719
+tests\scripts\dependencies\DependabotConfig.Tests.ps1 3F738E78A77F028BBB97D86BD2B9A33DC8CB94F1ABB31F1DC306413CDE3B3C48
+tests\scripts\dependencies\PackageCompatibility.Tests.ps1 0EF34C85EBA0B70C24CC4EA662472FA97F33D20B527120278606B12F6D7010DC
+tests\scripts\dependencies\PackageGraph.Tests.ps1 910DD957F6377DD60A9F2EFC26E7597421E2C69505DE21E78E4B087729305EBE
+tests\scripts\dependencies\ProjectConsistency.Tests.ps1 BCB15A04404BD3792A1DCB65315DE2B4CD822087B9D3EB3006E8BE9EB81CA761
+tests\scripts\dependencies\Repair-PackageManifestConsistency.Tests.ps1 3348C5D17773A9DCC6EEFD3A85EF6874BB96CA9BE8B1F2A85C1EA9CB96756942
+tests\scripts\dependencies\RepositoryTreeConsistency.Tests.ps1 B4312DE871FCA6A2E690D9F3B6B9269F7E4631735A87719FC4BFE85919CBBD9A
+```
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t1-poshqc-format.iter2.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t1-poshqc-format.iter2.2026-09-28T20-01.md
new file mode 100644
index 000000000..b8b1c9cf7
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t1-poshqc-format.iter2.2026-09-28T20-01.md
@@ -0,0 +1,14 @@
+# P2-T1 — PowerShell QC step 1, format (iteration 2)
+
+Timestamp: 2026-09-30T10-55
+Command: Get-FileHash -Algorithm SHA256 over every .ps1, .psm1 and .psd1 file under scripts/dependencies and tests/scripts/dependencies; MCP mcp__drm-copilot__run_poshqc_format (workspace_root , scan_folders ["scripts/dependencies","tests/scripts/dependencies"]); re-hash; git status --porcelain --untracked-files=all -- scripts/dependencies tests/scripts/dependencies; @(Get-Content -LiteralPath "scripts/dependencies/ConsistencyVerifier.psm1").Count
+EXIT_CODE: 0
+Output Summary:
+- Iteration 2 follows the iteration 1 P2-T7 failure (qa-gates/p2-t7-mstest-coverage.iter1.2026-09-28T20-01.md).
+- MCP payload (host prefix replaced): {"ok":true,"tool":"run_poshqc_format","workspace_root":"","summary":"Ran bundled PoshQC format against '' with 2 selected scan folder(s)."}
+- scan_folders: ["scripts/dependencies","tests/scripts/dependencies"]
+- Hash sets: 14 entries before and 14 after (6 production, 8 test files); every hash identical, and identical to the iteration 1 set
+- Write Set rewrite count: 0
+- REVERT-SET: empty
+- Post-revert porcelain over the two folders: empty
+- ConsistencyVerifier.psm1 line count: 499 (equals VERIFIER-LINES)
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t10-change-footprint.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t10-change-footprint.2026-09-28T20-01.md
new file mode 100644
index 000000000..5e515a837
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t10-change-footprint.2026-09-28T20-01.md
@@ -0,0 +1,101 @@
+# P2-T10 — Change footprint (CMD-FOOTPRINT)
+
+Timestamp: 2026-09-30T11-09
+Command: git diff --name-only 481b33c594d8412cb64e604ff53295db215ac2f1 -- . together with git status --porcelain --untracked-files=all (P0-START anchor; both run in one pwsh invocation beginning with Set-Location "")
+EXIT_CODE: 0
+Output Summary:
+- Every path in the union of the two captures is a Write Set member, lies under the feature folder, or lies under the agent-memory tree.
+- Paths outside the feature folder and the agent-memory tree: exactly the eight non-feature-folder Write Set paths named in P1-T14:
+ - .github/workflows/README.md
+ - .github/workflows/dependabot-repair.yml
+ - QuickFiler.Test/QuickFiler.Test.csproj
+ - SVGControl/app.config
+ - docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md
+ - scripts/dependencies/ConsistencyVerifier.psm1
+ - tests/scripts/dependencies/ConsistencyVerifier.Tests.ps1
+ - tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1
+- Paths matching *.cs: 0
+- Paths under .claude/rules, .github/instructions or the config directory: 0
+- Other *.csproj, packages.config or app.config paths: 0 (the count the AC7 check-off cites as proof that no analyzer item or manifest was changed on this branch)
+- Paths under docs/features/potential: 0
+- Agent-memory entries present (not this change's work, not staged): .claude/agent-memory/atomic-executor/MEMORY.md and .claude/agent-memory/atomic-planner/MEMORY.md (modified, tracked), plus five untracked agent-memory notes.
+
+Anchored name-only diff against P0-START, verbatim (git also printed two "LF will be replaced by CRLF" warnings, for the atomic-executor MEMORY.md and the plan file):
+```
+.claude/agent-memory/atomic-executor/MEMORY.md
+.claude/agent-memory/atomic-planner/MEMORY.md
+.github/workflows/README.md
+.github/workflows/dependabot-repair.yml
+QuickFiler.Test/QuickFiler.Test.csproj
+SVGControl/app.config
+docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t1-worktree-anchor.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t10-msbuild-analyzers.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t11-msbuild-nullable.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t12-coverage-projection.2026-09-28T20-01.jacoco.xml
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t12-mstest-coverage.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t12-test-results.2026-09-28T20-01.summary.txt
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t13-poshqc-format.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t14-poshqc-analyze.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t15-poshqc-test-mcp.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t16-pester.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t17-altcover-and-verifier-prefix.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t18-redirect-prefix.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t19-workflow-prefix-and-actionlint.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t20-hygiene.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t21-commit.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t3-sdk-bootstrap.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t4-tool-restore.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t5-package-restore.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t6-analyzer-item-census.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t7-dotnet-coverage.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t8-pester-provision.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t9-csharpier-check.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/phase0-instructions-read.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t10-verifier-comment.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t12-verifier-postfix.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t4-altcover-imports-removed.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t5-redirects-fixed.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t6-workflow-client-id.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t7-actionlint.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t8-runbook-client-id.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t9-readme-client-id.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t1-tree-test-authored.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t11-tree-test-pass-after.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t2-tree-test-fail-before.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t3-verifier-import-tests.2026-09-28T20-01.md
+docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/plan.2026-09-28T20-01.md
+scripts/dependencies/ConsistencyVerifier.psm1
+tests/scripts/dependencies/ConsistencyVerifier.Tests.ps1
+tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1
+```
+
+Porcelain capture, verbatim:
+```
+ M .claude/agent-memory/atomic-executor/MEMORY.md
+ M .claude/agent-memory/atomic-planner/MEMORY.md
+ M docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/plan.2026-09-28T20-01.md
+?? .claude/agent-memory/atomic-executor/index_csharp_nullable_and_component_gotchas.md
+?? .claude/agent-memory/atomic-executor/index_pwsh_git_and_gate_mechanics_misc.md
+?? .claude/agent-memory/atomic-executor/index_test_isolation_and_coverage.md
+?? .claude/agent-memory/atomic-executor/project_hygiene_pattern_array_comma_precedence_and_regex_token_hits.md
+?? .claude/agent-memory/atomic-planner/project_929_manifest_residuals_plan_seams.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t14-commit.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t1-poshqc-format.iter1.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t1-poshqc-format.iter2.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t2-poshqc-analyze.iter1.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t2-poshqc-analyze.iter2.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t3-pester.iter1.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t3-pester.iter2.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t4-csharpier-check.iter1.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t4-csharpier-check.iter2.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t5-msbuild-analyzers.iter1.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t5-msbuild-analyzers.iter2.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t6-msbuild-nullable.iter1.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t6-msbuild-nullable.iter2.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-coverage-projection.2026-09-28T20-01.jacoco.xml
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-mstest-coverage.iter1.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-mstest-coverage.iter2.2026-09-28T20-01.md
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-test-results.2026-09-28T20-01.summary.txt
+?? docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t8-attestation-and-coverage-delta.2026-09-28T20-01.md
+```
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t11-hygiene.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t11-hygiene.2026-09-28T20-01.md
new file mode 100644
index 000000000..66bf5748c
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t11-hygiene.2026-09-28T20-01.md
@@ -0,0 +1,14 @@
+# P2-T11 — Hygiene scan of the final footprint (CMD-HYGIENE)
+
+Timestamp: 2026-09-30T11-10
+Command: CMD-HYGIENE with FOLDER-LIST "docs/features/active/2026-09-28-package-manifest-consistency-residuals-929",".github/workflows/dependabot-repair.yml",".github/workflows/README.md","docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks","tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1" (account and machine values derived at run time and not recorded); plus a count of evidence .md files under the feature folder
+EXIT_CODE: 0
+Output Summary:
+- PATTERNS=3
+- SELFTEST=1
+- SELFTEST_NEG=0
+- SCANNED=61 HITS=0 (at least 45)
+- Hit listing: empty
+- PRE-FIX-HITS: 0
+- Evidence .md artifacts under the feature folder before this artifact: 51 — the 44 the plan counts for a single-iteration run plus the seven iteration 2 artifacts of P2-T1 to P2-T7 (the plan states that a further iteration only raises the count)
+- The two P2-T7 copies (projection and summary) and the two P0-T12 copies are included in the scan because their extensions are in the filter list.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t12-ac1-checkoff.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t12-ac1-checkoff.2026-09-28T20-01.md
new file mode 100644
index 000000000..df2214efa
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t12-ac1-checkoff.2026-09-28T20-01.md
@@ -0,0 +1,12 @@
+# P2-T12 — AC1 check-off
+
+Timestamp: 2026-09-30T11-11
+Command: Read the cited artifacts; Edit issue.md changing `- [ ] AC1:` to `- [x] AC1:`
+EXIT_CODE: 0
+Output Summary:
+- Evidence read:
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t4-altcover-imports-removed.2026-09-28T20-01.md — ALTCOVER_LINES=0 over every tracked project file and packages manifest; LINES=568; NUMSTAT 0 added / 2 deleted
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t5-msbuild-analyzers.iter2.2026-09-28T20-01.md — post-change analyzer rebuild MSBUILD_EXIT=0, CS0006_LINES=0, "0 Error(s)"
+- Quoted: ALTCOVER_LINES=0
+- Change to issue.md: only the AC1 line, `- [ ] AC1:` to `- [x] AC1:`; no other character changed.
+- Checked off AC: "AC1: `QuickFiler.Test/QuickFiler.Test.csproj` contains no `Import` element that references an `altcover` package path; ..."
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t13-ac2-checkoff.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t13-ac2-checkoff.2026-09-28T20-01.md
new file mode 100644
index 000000000..6ff412ae3
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t13-ac2-checkoff.2026-09-28T20-01.md
@@ -0,0 +1,12 @@
+# P2-T13 — AC2 check-off
+
+Timestamp: 2026-09-30T11-12
+Command: Read the cited artifacts; Edit issue.md changing `- [ ] AC2:` to `- [x] AC2:`
+EXIT_CODE: 0
+Output Summary:
+- Evidence read:
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t18-redirect-prefix.2026-09-28T20-01.md — FIZZLER_ASM=1.3.1.0; SVGControl.csproj line 58 declares Fizzler, Version=1.3.1.0; pre-fix FIZZLER_REPAIRS=1
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t5-redirects-fixed.2026-09-28T20-01.md — post-fix FIZZLER_REPAIRS=0; new line 15 ``
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t11-tree-test-pass-after.2026-09-28T20-01.md — the SVGControl redirect test passing (RepositoryTreeConsistency.Tests.ps1 tests=4 failures=0)
+- Change to issue.md: only the AC2 checkbox.
+- Checked off AC: "AC2: In `SVGControl/app.config`, the `Fizzler` binding redirect names newVersion 1.3.1.0 and an oldVersion range ending at 1.3.1.0, ..."
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t14-ac3-checkoff.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t14-ac3-checkoff.2026-09-28T20-01.md
new file mode 100644
index 000000000..988340bda
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t14-ac3-checkoff.2026-09-28T20-01.md
@@ -0,0 +1,12 @@
+# P2-T14 — AC3 check-off
+
+Timestamp: 2026-09-30T11-13
+Command: Read the cited artifacts; Edit issue.md changing `- [ ] AC3:` to `- [x] AC3:`
+EXIT_CODE: 0
+Output Summary:
+- Evidence read:
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t18-redirect-prefix.2026-09-28T20-01.md — UNSAFE_ASM=6.0.3.0; SVGControl.csproj line 82 declares System.Runtime.CompilerServices.Unsafe, Version=6.0.3.0; pre-fix UNSAFE_REPAIRS=1
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t5-redirects-fixed.2026-09-28T20-01.md — post-fix UNSAFE_REPAIRS=0; new line 19 ``
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t11-tree-test-pass-after.2026-09-28T20-01.md — the SVGControl redirect test (which checks both Fizzler and System.Runtime.CompilerServices.Unsafe) passing
+- Change to issue.md: only the AC3 checkbox.
+- Checked off AC: "AC3: In `SVGControl/app.config`, the `System.Runtime.CompilerServices.Unsafe` binding redirect names newVersion 6.0.3.0 and an oldVersion range ending at 6.0.3.0, ..."
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t15-ac4-checkoff.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t15-ac4-checkoff.2026-09-28T20-01.md
new file mode 100644
index 000000000..0bffe93cf
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t15-ac4-checkoff.2026-09-28T20-01.md
@@ -0,0 +1,14 @@
+# P2-T15 — AC4 check-off
+
+Timestamp: 2026-09-30T11-14
+Command: Read the cited artifacts; Edit issue.md changing `- [ ] AC4:` to `- [x] AC4:`
+EXIT_CODE: 0
+Output Summary:
+- Evidence read:
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t3-verifier-import-tests.2026-09-28T20-01.md — the two in-memory Import-kind tests ('reports an Import whose package the manifest does not declare, with Kind Import' and 'reports no Import finding when the manifest declares the imported package'); ConsistencyVerifier.Tests.ps1 suite tests=14 failures=0
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t2-tree-test-fail-before.2026-09-28T20-01.md — the tree Import test failing with 2 findings before the fix (QuickFiler.Test.csproj: line 8 and line 537 altcover.8.6.45)
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t11-tree-test-pass-after.2026-09-28T20-01.md — the tree Import test passing with 0 findings after AC1
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t12-verifier-postfix.2026-09-28T20-01.md — ABSENT=0 on the tree (P0-T17 measured 2)
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t3-pester.iter2.2026-09-28T20-01.md — the full local suite green (137 tests, 0 failures) and the CI Pester job green (379 passed, 0 failed)
+- Decision D1: the detection rule pre-existed (Find-PackageAbsentFromManifest reports an Import whose package id the sibling manifest omits); AC4 is discharged by explicit in-memory tests and the tree observation, not by a new production rule. The fixtures are in-memory strings; the tree test reads tracked files only and creates no temporary file.
+- Change to issue.md: only the AC4 checkbox.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t16-ac5-checkoff.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t16-ac5-checkoff.2026-09-28T20-01.md
new file mode 100644
index 000000000..2ef27189c
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t16-ac5-checkoff.2026-09-28T20-01.md
@@ -0,0 +1,12 @@
+# P2-T16 — AC5 check-off
+
+Timestamp: 2026-09-30T11-15
+Command: Read the cited artifacts; Edit issue.md changing `- [ ] AC5:` to `- [x] AC5:`
+EXIT_CODE: 0
+Output Summary:
+- Evidence read:
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t6-workflow-client-id.2026-09-28T20-01.md — WF_APPID=0, WF_CLIENTID=1, WF_SECRET=1
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t7-actionlint.2026-09-28T20-01.md — actionlint 1.7.7: SCOPED_EXIT=0 and REPO_EXIT=0 with empty output; DependabotConfig.Tests.ps1 tests=17 failures=0
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t11-tree-test-pass-after.2026-09-28T20-01.md — the workflow input test ('passes client-id and not app-id to the create-github-app-token step of the repair workflow') passing
+- The CI run 36722780748 on the pushed head also reports the actionlint job as success (P2-T3).
+- Change to issue.md: only the AC5 checkbox.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t17-ac6-checkoff.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t17-ac6-checkoff.2026-09-28T20-01.md
new file mode 100644
index 000000000..48957cfb9
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t17-ac6-checkoff.2026-09-28T20-01.md
@@ -0,0 +1,12 @@
+# P2-T17 — AC6 check-off
+
+Timestamp: 2026-09-30T11-16
+Command: Read the cited artifacts; Edit issue.md changing `- [ ] AC6:` to `- [x] AC6:`
+EXIT_CODE: 0
+Output Summary:
+- Evidence read:
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t8-runbook-client-id.2026-09-28T20-01.md — RB_APPID=0, RB_CLIENTID=1, RB_SECRET=2, RB_PARTB=0, PARTD_CLIENTID=2
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p1-t9-readme-client-id.2026-09-28T20-01.md — README row updated (README_NUMERIC=0, README_CLIENTID=1)
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t11-tree-test-pass-after.2026-09-28T20-01.md — the runbook secret-name test passing; it extracts the secret name from the workflow's client-id line and asserts it in the runbook sample and in Part D
+- Decision D3: the secret name DEPENDABOT_REPAIR_APP_ID is kept and now holds the App's Client ID; the workflow passes it as client-id. Renaming would require maintainer credential action; the secret is not yet provisioned, so the change is merge-safe without maintainer action.
+- Change to issue.md: only the AC6 checkbox.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t18-ac7-checkoff.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t18-ac7-checkoff.2026-09-28T20-01.md
new file mode 100644
index 000000000..8fdf9deea
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t18-ac7-checkoff.2026-09-28T20-01.md
@@ -0,0 +1,21 @@
+# P2-T18 — AC7 check-off
+
+Timestamp: 2026-09-30T11-17
+Command: Read the cited artifacts; Edit issue.md changing `- [ ] AC7:` to `- [x] AC7:`
+EXIT_CODE: 0
+Output Summary:
+- Evidence read:
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t5-package-restore.2026-09-28T20-01.md — cold restore: PACKAGE_DIRS_BEFORE=0, PACKAGE_DIRS_AFTER=172, "Build succeeded." and "0 Error(s)"
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t6-analyzer-item-census.2026-09-28T20-01.md
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t8-attestation-and-coverage-delta.2026-09-28T20-01.md and the seven iter2 artifacts it cites (P2-T1 to P2-T7, all EXIT_CODE 0)
+ - docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t10-change-footprint.2026-09-28T20-01.md
+- Quoted verbatim from the P0-T6 artifact:
+ - `ANALYZER-ITEM-STATE: aligned`
+ - `ANALYZER_ITEMS=162 FILES=17 UNRESOLVED=0`
+- The cold restore of P0-T5 (PACKAGE_DIRS_BEFORE=0) was followed by the P0-T10, P0-T11, P2-T5 and P2-T6 rebuilds exiting 0 with no back-fill performed (decision D8; the amended AC7's back-fill clause is permissive and was not exercised, so AC7 is satisfied with its text unchanged).
+- The P2-T10 footprint records 0 other *.csproj, packages.config or app.config paths, which shows that no analyzer item or manifest was changed on this branch.
+- No-new-failure comparison (P2-T8):
+ - C#: CSharpier check exit 0 with no findings (baseline exit 0, no findings); analyzer and nullable rebuilds exit 0 with 0 errors and OUT_LINES 36 (baseline identical); MSTest 7346 of 7346 passed with line 85.92 percent and branch 80.08 percent (baseline 7346 of 7346, 85.91 and 80.08; deltas +0.01 and 0.00).
+ - PowerShell: PoshQC format rewrote nothing, PoshQC analyze ok true, local PoshQC test 137 of 137 passed (baseline 131 of 131); CI Pester job 379 passed, 0 failed, LinePercent 94.51 on run 36722780748 (head b96926588) against 373 passed, 0 failed, LinePercent 94.51 on run 36666302259 (main, head 231e1c0b5).
+- Disclosure: the final QC loop needed two iterations. Iteration 1 failed at P2-T7 on one timing-dependent QuickFiler.Test test (RemainingLoadActive_AcrossAsyncVoidFirstAwait_StaysTrueWhileLoaderProduces, a five-second wait that did not complete); iteration 2 passed on the unchanged tree. Separately, the CI mstest-coverage job on run 36722780748 failed one different QuickFiler.Test test (Transaction_SecondCallerCannotInstallUntilTheFirstRestores). This change edits no C# source, both tests passed in the local baseline and in the final local iteration, and both are reported to the caller as pre-existing timing-dependent tests outside this issue's scope.
+- Change to issue.md: only the AC7 checkbox.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t2-poshqc-analyze.iter1.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t2-poshqc-analyze.iter1.2026-09-28T20-01.md
new file mode 100644
index 000000000..cfc9e44cb
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t2-poshqc-analyze.iter1.2026-09-28T20-01.md
@@ -0,0 +1,12 @@
+# P2-T2 — PowerShell QC step 2, analyze (iteration 1)
+
+Timestamp: 2026-09-30T10-24
+Command: MCP mcp__drm-copilot__run_poshqc_analyze (workspace_root , scan_folders ["scripts/dependencies","tests/scripts/dependencies"]); pwsh -NoProfile -Command 'Set-Location ""; "FILES=" + @(Get-ChildItem -Recurse -File -Path "scripts/dependencies","tests/scripts/dependencies" -Include *.ps1,*.psm1).Count'
+EXIT_CODE: 0
+Output Summary:
+- MCP payload (verbatim, host prefix replaced): {"ok":true,"tool":"run_poshqc_analyze","workspace_root":"","summary":"Ran bundled PoshQC analyze against '' with 2 selected scan folder(s)."}
+- scan_folders: ["scripts/dependencies","tests/scripts/dependencies"]
+- PoshQC analyze: pass (0 findings); tool reports no count
+- FILES=14 (P0-T14 measured 13, plus the created test file)
+
+GATE-SUBSTITUTION: PoshQC analyze ok flag stands in for a diagnostic count
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t2-poshqc-analyze.iter2.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t2-poshqc-analyze.iter2.2026-09-28T20-01.md
new file mode 100644
index 000000000..6f6f337fa
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t2-poshqc-analyze.iter2.2026-09-28T20-01.md
@@ -0,0 +1,12 @@
+# P2-T2 — PowerShell QC step 2, analyze (iteration 2)
+
+Timestamp: 2026-09-30T10-56
+Command: MCP mcp__drm-copilot__run_poshqc_analyze (workspace_root , scan_folders ["scripts/dependencies","tests/scripts/dependencies"]); pwsh -NoProfile -Command 'Set-Location ""; "FILES=" + @(Get-ChildItem -Recurse -File -Path "scripts/dependencies","tests/scripts/dependencies" -Include *.ps1,*.psm1).Count'
+EXIT_CODE: 0
+Output Summary:
+- MCP payload (verbatim, host prefix replaced): {"ok":true,"tool":"run_poshqc_analyze","workspace_root":"","summary":"Ran bundled PoshQC analyze against '' with 2 selected scan folder(s)."}
+- scan_folders: ["scripts/dependencies","tests/scripts/dependencies"]
+- PoshQC analyze: pass (0 findings); tool reports no count
+- FILES=14 (P0-T14 measured 13, plus the created test file)
+
+GATE-SUBSTITUTION: PoshQC analyze ok flag stands in for a diagnostic count
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t20-ac-status-summary.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t20-ac-status-summary.2026-09-28T20-01.md
new file mode 100644
index 000000000..5a96f5e74
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t20-ac-status-summary.2026-09-28T20-01.md
@@ -0,0 +1,25 @@
+# P2-T20 — Acceptance-criteria status summary
+
+Timestamp: 2026-09-30T11-19
+Command: Read the `## Acceptance Criteria` section of issue.md; CMD-HYGIENE with FOLDER-LIST "docs/features/active/2026-09-28-package-manifest-consistency-residuals-929"
+EXIT_CODE: 0
+Output Summary:
+
+### Acceptance Criteria Status
+- Source: docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/issue.md (`## Acceptance Criteria`, work mode minor-audit)
+- Total AC items: 7
+- Checked off (delivered): 7
+- Remaining (unchecked): 0
+- Items remaining: none
+
+Check-off tasks: AC1 P2-T12, AC2 P2-T13, AC3 P2-T14, AC4 P2-T15, AC5 P2-T16, AC6 P2-T17, AC7 P2-T18. AC18 to AC20 of issue 911 remain a maintainer follow-up record only (P2-T19) and are not marked passed.
+
+Pre-commit hygiene (CMD-HYGIENE over the feature folder):
+- PATTERNS=3
+- SELFTEST=1
+- SELFTEST_NEG=0
+- SCANNED=67
+- HITS=0
+- PRE-FIX-HITS: 0
+
+The head SHA, the git show listing and the porcelain capture of the commit that carries this artifact are transcribed into the P2-T21 index, because this artifact is inside the commit it describes.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t3-pester.iter1.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t3-pester.iter1.2026-09-28T20-01.md
new file mode 100644
index 000000000..db82b236b
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t3-pester.iter1.2026-09-28T20-01.md
@@ -0,0 +1,60 @@
+# P2-T3 — PowerShell QC step 3, test, with coverage read from CI (iteration 1)
+
+Timestamp: 2026-09-30T10-45
+Command: pwsh -NoProfile -Command '[DateTime]::UtcNow.ToString("o")' (RUN-START); MCP mcp__drm-copilot__run_poshqc_test (workspace_root , scan_folders ["tests/scripts/dependencies"]); CMD-JUNIT-READ; CMD-CI-LIST; CMD-CI-DISPATCH; CMD-CI-LIST (re-run); CMD-CI-WATCH with RUN-ID 36722780748; CMD-CI-PESTER with RUN-ID 36722780748 and DIR coverage/ci-branch-pester-36722780748-1
+EXIT_CODE: 0
+Output Summary:
+
+Local MCP test run:
+- RUN-START: 2026-09-30T13:34:53.3059426Z
+- MCP payload (host prefix replaced): {"ok":true,"tool":"run_poshqc_test","workspace_root":"","summary":"Ran bundled PoshQC test against '' with 1 selected scan folder(s)."}
+- JUNIT-WRITTEN=2026-09-30T13:35:27.6912381Z (later than RUN-START)
+- JUNIT-ROOT tests=137 failures=0 errors=0 disabled=0; no JUNIT-NOTPASSED line
+- JUNIT-SUITE RepositoryTreeConsistency.Tests.ps1 tests=4 failures=0 skipped=0
+- JUNIT-SUITE ConsistencyVerifier.Tests.ps1 tests=14 failures=0 skipped=0
+- JUNIT-SUITE DependabotConfig.Tests.ps1 tests=17 failures=0 skipped=0
+- Other suites: AnalyzerItemRepair 13, PackageCompatibility 8, PackageGraph 32, ProjectConsistency 18, Repair-PackageManifestConsistency 31, all failures=0
+
+Push check: git rev-parse HEAD = b96926588d562f994430e7ba7301de5de86f206c equals PUSHED-HEAD from P1-T14, so no push was made in this task.
+
+CI locate, dispatch and watch:
+- CMD-CI-LIST (first): HEAD=b96926588d562f994430e7ba7301de5de86f206c; REMOTE=b96926588d562f994430e7ba7301de5de86f206c refs/heads/bug/package-manifest-consistency-residuals-929; RUNS-FOR-HEAD=0 (no pull request run exists for this head)
+- CMD-CI-DISPATCH (once): printed the run URL for run 36722780748; DISPATCH-EXIT=0
+- CMD-CI-LIST (re-run 1): HEAD and REMOTE as above; RUNS-FOR-HEAD=1; RUN id=36722780748 head=b96926588d562f994430e7ba7301de5de86f206c event=workflow_dispatch status=queued conclusion=
+- Selected run: 36722780748 (greatest databaseId)
+- CMD-CI-WATCH invocation 1: returned on its own after the run completed; WATCH-EXIT=0
+
+CMD-CI-PESTER (run 36722780748, head b96926588d562f994430e7ba7301de5de86f206c):
+- RUN id=36722780748 head=b96926588d562f994430e7ba7301de5de86f206c branch=bug/package-manifest-consistency-residuals-929 event=workflow_dispatch status=completed conclusion=failure workflow=CI
+- PESTER-JOBS=1
+- JOB id=109911885533 name=pester / Run Pester suite with coverage status=completed conclusion=success
+- LOG-LINES=1097
+- Log lines (verbatim after SGR stripping):
+ - "Tests Passed: 379, Failed: 0, Skipped: 0, Inconclusive: 0, NotRun: 0"
+ - "PESTER Passed=379 Failed=0 Skipped=0 Total=379"
+ - "COVERAGE LinePercent=94.51 Covered=1721 Total=1821"
+- Total 379 equals BASELINE-TOTAL 373 plus 6 (four tree tests and two Import-kind tests); Failed 0; Skipped 0
+- DIR-PREEXISTS=False; DOWNLOAD-EXIT=0; ARTIFACT-FILES=1; DIR used: coverage/ci-branch-pester-36722780748-1
+- REPORT-LINE covered=1721 missed=100; computed percent 1721 / 1821 * 100 = 94.51, equal to the log's LinePercent 94.51 and at least 80
+- MEETS-85: true (observation only, convention 10)
+- SOURCEFILE lines (run 36722780748, head b96926588):
+ - AnalyzerItemRepair.psm1 covered=106 missed=0
+ - ConsistencyVerifier.psm1 covered=158 missed=2
+ - PackageCompatibility.psm1 covered=33 missed=0
+ - PackageGraph.psm1 covered=164 missed=0
+ - ProjectConsistency.psm1 covered=103 missed=0
+ - Repair-PackageManifestConsistency.ps1 covered=213 missed=14
+- ConsistencyVerifier.psm1 covered 158 is at least VERIFIER-COVERED 158 and missed 2 is at most VERIFIER-MISSED 2 (P0-T16, run 36666302259).
+
+Run-level conclusion (recorded as measured, reported to the caller, not a failure of this task): failure. Every job:
+- build-analyzers / Build with analyzers and code style enforcement: success
+- mstest-coverage / Run MSTest suite with coverage: failure — "Total tests: 7346 / Passed: 7345 / Failed: 1"; the failed test is Transaction_SecondCallerCannotInstallUntilTheFirstRestores (QuickFiler.Test/Controllers/QfcItemController.UiThreadDispatcherFixtureTests.cs), message "Expected observedByB to refer to because the first transaction restores before it releases the gate, so the waiter cannot observe the pre-restore value, but found System.Windows.Threading.Dispatcher ...". This change edits no C# source (the only QuickFiler.Test change removes two Exists()-guarded Import elements whose package was never restored), and the same test passed in the local P0-T12 run (7346 of 7346).
+- hygiene / Repository hygiene guard: success
+- pester / Run Pester suite with coverage: success
+- actionlint / actionlint: success
+- format-check / Verify formatting: success
+- build-nullable / Build with nullable warnings treated as errors: success
+
+Pester emits no branch counter, so no PowerShell branch figure is claimed. These figures stand in for a permitted evidence form that the committed-evidence section does not define for the Pester route. The downloaded JaCoCo document is left under the ignored coverage directory.
+
+GATE-SUBSTITUTION: CI Pester job on the pushed head stands in for a local coverage run
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t3-pester.iter2.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t3-pester.iter2.2026-09-28T20-01.md
new file mode 100644
index 000000000..7e61e59c2
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t3-pester.iter2.2026-09-28T20-01.md
@@ -0,0 +1,48 @@
+# P2-T3 — PowerShell QC step 3, test, with coverage read from CI (iteration 2)
+
+Timestamp: 2026-09-30T10-58
+Command: pwsh -NoProfile -Command '[DateTime]::UtcNow.ToString("o")' (RUN-START); MCP mcp__drm-copilot__run_poshqc_test (workspace_root , scan_folders ["tests/scripts/dependencies"]); CMD-JUNIT-READ; CMD-CI-LIST (twice); CMD-CI-WATCH with RUN-ID 36722780748; CMD-CI-PESTER with RUN-ID 36722780748 and DIR coverage/ci-branch-pester-36722780748-2
+EXIT_CODE: 0
+Output Summary:
+
+Local MCP test run:
+- RUN-START: 2026-09-30T13:46:37.9133883Z
+- MCP payload (host prefix replaced): {"ok":true,"tool":"run_poshqc_test","workspace_root":"","summary":"Ran bundled PoshQC test against '' with 1 selected scan folder(s)."}
+- JUNIT-WRITTEN=2026-09-30T13:47:26.1351476Z (later than RUN-START)
+- JUNIT-ROOT tests=137 failures=0 errors=0 disabled=0; no JUNIT-NOTPASSED line
+- JUNIT-SUITE RepositoryTreeConsistency.Tests.ps1 tests=4 failures=0 skipped=0
+- JUNIT-SUITE ConsistencyVerifier.Tests.ps1 tests=14 failures=0 skipped=0
+- JUNIT-SUITE DependabotConfig.Tests.ps1 tests=17 failures=0 skipped=0
+- Other suites: AnalyzerItemRepair 13, PackageCompatibility 8, PackageGraph 32, ProjectConsistency 18, Repair-PackageManifestConsistency 31, all failures=0
+
+Push check: HEAD b96926588d562f994430e7ba7301de5de86f206c equals PUSHED-HEAD (no P2-T1 or P2-T2 commit in either iteration), so no push was made.
+
+CI locate and watch (no dispatch: CMD-CI-DISPATCH was already made once for this pushed head in iteration 1, and the rule permits at most one dispatch per pushed head):
+- CMD-CI-LIST (first): HEAD=b96926588d562f994430e7ba7301de5de86f206c; REMOTE names HEAD; RUNS-FOR-HEAD=0 (a transient empty list from gh; the run was listed in iteration 1)
+- CMD-CI-LIST (re-run 1): HEAD and REMOTE as above; RUNS-FOR-HEAD=1; RUN id=36722780748 head=b96926588d562f994430e7ba7301de5de86f206c event=workflow_dispatch status=completed conclusion=failure; an unfiltered listing of the branch's ci.yml runs shows the same single run
+- Selected run: 36722780748
+- CMD-CI-WATCH invocation 1: "Run CI (36722780748) has already completed with 'failure'"; WATCH-EXIT=0
+
+CMD-CI-PESTER (second invocation against run 36722780748, head b96926588):
+- RUN id=36722780748 head=b96926588d562f994430e7ba7301de5de86f206c branch=bug/package-manifest-consistency-residuals-929 event=workflow_dispatch status=completed conclusion=failure workflow=CI
+- PESTER-JOBS=1; JOB id=109911885533 name=pester / Run Pester suite with coverage status=completed conclusion=success
+- LOG-LINES=1097
+- "Tests Passed: 379, Failed: 0, Skipped: 0, Inconclusive: 0, NotRun: 0"
+- "PESTER Passed=379 Failed=0 Skipped=0 Total=379"
+- "COVERAGE LinePercent=94.51 Covered=1721 Total=1821"
+- Total 379 equals BASELINE-TOTAL 373 plus 6; Failed 0; Skipped 0
+- DIR-PREEXISTS=False; DOWNLOAD-EXIT=0; ARTIFACT-FILES=1; DIR used: coverage/ci-branch-pester-36722780748-2
+- REPORT-LINE covered=1721 missed=100; computed percent 94.51, equal to the log's LinePercent and at least 80
+- MEETS-85: true (observation only, convention 10)
+- SOURCEFILE AnalyzerItemRepair.psm1 covered=106 missed=0
+- SOURCEFILE ConsistencyVerifier.psm1 covered=158 missed=2 (covered at least VERIFIER-COVERED 158; missed at most VERIFIER-MISSED 2)
+- SOURCEFILE PackageCompatibility.psm1 covered=33 missed=0
+- SOURCEFILE PackageGraph.psm1 covered=164 missed=0
+- SOURCEFILE ProjectConsistency.psm1 covered=103 missed=0
+- SOURCEFILE Repair-PackageManifestConsistency.ps1 covered=213 missed=14
+
+Run-level conclusion failure, recorded and reported as in iteration 1: every job succeeded except mstest-coverage / Run MSTest suite with coverage (1 of 7346 failed: Transaction_SecondCallerCannotInstallUntilTheFirstRestores, QuickFiler.Test/Controllers/QfcItemController.UiThreadDispatcherFixtureTests.cs). build-analyzers, hygiene, pester, actionlint, format-check and build-nullable: success.
+
+Pester emits no branch counter, so no PowerShell branch figure is claimed. These figures stand in for a permitted evidence form that the committed-evidence section does not define for the Pester route. The downloaded JaCoCo document is left under the ignored coverage directory.
+
+GATE-SUBSTITUTION: CI Pester job on the pushed head stands in for a local coverage run
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t4-csharpier-check.iter1.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t4-csharpier-check.iter1.2026-09-28T20-01.md
new file mode 100644
index 000000000..cdf2a53b5
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t4-csharpier-check.iter1.2026-09-28T20-01.md
@@ -0,0 +1,23 @@
+# P2-T4 — C# QC step 1, CSharpier check (iteration 1)
+
+Timestamp: 2026-09-30T10-47
+Command: pwsh -NoProfile -Command 'Set-Location ""; dotnet tool run csharpier check .; "CSHARPIER_EXIT=$LASTEXITCODE"' followed by the CMD-CSHARPIER-CHECK XML-candidate companion command
+EXIT_CODE: 0
+Output Summary:
+- "Checked 1625 files in 8208ms."
+- CSHARPIER_EXIT=0 (equal to the P0-T9 exit code 0)
+- CSHARPIER-FINDINGS: none (equal to the P0-T9 list)
+- XML-CANDIDATES: 6
+```
+artifacts\pester\pester-junit.xml
+artifacts\pester\powershell-coverage.koverage.xml
+artifacts\pester\powershell-coverage.xml
+coverage\ci-branch-pester-36722780748-1\pester-coverage.xml
+coverage\ci-main-pester-36666302259-1\pester-coverage.xml
+coverage\coverage.cobertura.jacoco.xml
+```
+- CHECKED-DELTA: 0 (1625 minus the P0-T9 value 1625)
+- XML-DELTA: 3 (6 minus the P0-T9 value 3)
+- CHECKED-DELTA equals 0, one of the two admissible values.
+- CSHARPIER-COUNTS-IGNORED-XML: false (three additional *.xml files under the ignored trees did not change "Checked N", so CSharpier 1.2.6 did not count them)
+- The check subcommand is read-only; no file was rewritten.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t4-csharpier-check.iter2.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t4-csharpier-check.iter2.2026-09-28T20-01.md
new file mode 100644
index 000000000..3f36d99ca
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t4-csharpier-check.iter2.2026-09-28T20-01.md
@@ -0,0 +1,24 @@
+# P2-T4 — C# QC step 1, CSharpier check (iteration 2)
+
+Timestamp: 2026-09-30T11-00
+Command: pwsh -NoProfile -Command 'Set-Location ""; dotnet tool run csharpier check .; "CSHARPIER_EXIT=$LASTEXITCODE"; ' (the check and its companion run in one pwsh invocation)
+EXIT_CODE: 0
+Output Summary:
+- "Checked 1625 files in 10893ms."
+- CSHARPIER_EXIT=0 (equal to the P0-T9 exit code 0)
+- CSHARPIER-FINDINGS: none (equal to the P0-T9 list)
+- XML-CANDIDATES: 7
+```
+artifacts\pester\pester-junit.xml
+artifacts\pester\powershell-coverage.koverage.xml
+artifacts\pester\powershell-coverage.xml
+coverage\ci-branch-pester-36722780748-1\pester-coverage.xml
+coverage\ci-branch-pester-36722780748-2\pester-coverage.xml
+coverage\ci-main-pester-36666302259-1\pester-coverage.xml
+coverage\coverage.cobertura.jacoco.xml
+```
+- CHECKED-DELTA: 0 (1625 minus the P0-T9 value 1625)
+- XML-DELTA: 4 (7 minus the P0-T9 value 3)
+- CHECKED-DELTA equals 0, one of the two admissible values.
+- CSHARPIER-COUNTS-IGNORED-XML: false (four additional *.xml files under the ignored trees did not change "Checked N")
+- The check subcommand is read-only; no file was rewritten.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t5-msbuild-analyzers.iter1.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t5-msbuild-analyzers.iter1.2026-09-28T20-01.md
new file mode 100644
index 000000000..8a8f74756
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t5-msbuild-analyzers.iter1.2026-09-28T20-01.md
@@ -0,0 +1,14 @@
+# P2-T5 — C# QC step 2, analyzer rebuild (iteration 1)
+
+Timestamp: 2026-09-30T10-49
+Command: CMD-OUTLOOK (pwsh -NoProfile -Command '"OUTLOOK_COUNT=" + @(Get-Process outlook -ErrorAction SilentlyContinue).Count'); pwsh -NoProfile -Command 'Set-Location ""; msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true "/flp:LogFile=coverage\analyzers.msbuild.log;Verbosity=normal" | Out-Null; "MSBUILD_EXIT=$LASTEXITCODE"; ...OUT_LINES...; ...CS0006_LINES...; Get-Content -LiteralPath $l -Tail 6'
+EXIT_CODE: 0
+OUTLOOK-CLOSED: true
+Output Summary:
+- CMD-OUTLOOK printed OUTLOOK_COUNT=0 (nothing terminated).
+- Console output was discarded with Out-Null to keep the capture readable; the msbuild arguments are exactly CMD-MSBUILD-ANALYZERS and the summary is read from the file log tail.
+- File log tail: "Build succeeded." / "0 Warning(s)" / "0 Error(s)" / "Time Elapsed 00:00:31.37"
+- MSBUILD_EXIT=0
+- OUT_LINES=36 (at least 18; equal to the P0-T10 value 36)
+- CS0006_LINES=0
+- This is the post-change solution rebuild AC7 names.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t5-msbuild-analyzers.iter2.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t5-msbuild-analyzers.iter2.2026-09-28T20-01.md
new file mode 100644
index 000000000..e1e41ea44
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t5-msbuild-analyzers.iter2.2026-09-28T20-01.md
@@ -0,0 +1,14 @@
+# P2-T5 — C# QC step 2, analyzer rebuild (iteration 2)
+
+Timestamp: 2026-09-30T11-01
+Command: CMD-OUTLOOK (pwsh -NoProfile -Command '"OUTLOOK_COUNT=" + @(Get-Process outlook -ErrorAction SilentlyContinue).Count'); pwsh -NoProfile -Command 'Set-Location ""; msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true "/flp:LogFile=coverage\analyzers.msbuild.log;Verbosity=normal" | Out-Null; "MSBUILD_EXIT=$LASTEXITCODE"; ...OUT_LINES...; ...CS0006_LINES...; Get-Content -LiteralPath $l -Tail 6'
+EXIT_CODE: 0
+OUTLOOK-CLOSED: true
+Output Summary:
+- CMD-OUTLOOK printed OUTLOOK_COUNT=0 (nothing terminated).
+- Console output was discarded with Out-Null; the msbuild arguments are exactly CMD-MSBUILD-ANALYZERS and the summary is read from the file log tail.
+- File log tail: "Build succeeded." / "0 Warning(s)" / "0 Error(s)" / "Time Elapsed 00:00:25.28"
+- MSBUILD_EXIT=0
+- OUT_LINES=36 (at least 18; equal to the P0-T10 value 36)
+- CS0006_LINES=0
+- This is the post-change solution rebuild AC7 names.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t6-msbuild-nullable.iter1.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t6-msbuild-nullable.iter1.2026-09-28T20-01.md
new file mode 100644
index 000000000..ef06afd28
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t6-msbuild-nullable.iter1.2026-09-28T20-01.md
@@ -0,0 +1,12 @@
+# P2-T6 — C# QC step 3, nullable rebuild (iteration 1)
+
+Timestamp: 2026-09-30T10-50
+Command: CMD-OUTLOOK (pwsh -NoProfile -Command '"OUTLOOK_COUNT=" + @(Get-Process outlook -ErrorAction SilentlyContinue).Count'); pwsh -NoProfile -Command 'Set-Location ""; msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:TreatWarningsAsErrors=true "/flp:LogFile=coverage\nullable.msbuild.log;Verbosity=normal" | Out-Null; "MSBUILD_EXIT=$LASTEXITCODE"; ...OUT_LINES...; Get-Content -LiteralPath $l -Tail 6'
+EXIT_CODE: 0
+OUTLOOK-CLOSED: true
+Output Summary:
+- CMD-OUTLOOK printed OUTLOOK_COUNT=0 (nothing terminated).
+- Console output was discarded with Out-Null; the msbuild arguments are exactly CMD-MSBUILD-NULLABLE and the summary is read from the file log tail.
+- File log tail: "Build succeeded." / "0 Warning(s)" / "0 Error(s)" / "Time Elapsed 00:00:21.14"
+- MSBUILD_EXIT=0
+- OUT_LINES=36 (at least 18; equal to the P0-T11 value 36)
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t6-msbuild-nullable.iter2.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t6-msbuild-nullable.iter2.2026-09-28T20-01.md
new file mode 100644
index 000000000..5508b8a64
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t6-msbuild-nullable.iter2.2026-09-28T20-01.md
@@ -0,0 +1,12 @@
+# P2-T6 — C# QC step 3, nullable rebuild (iteration 2)
+
+Timestamp: 2026-09-30T11-02
+Command: CMD-OUTLOOK (pwsh -NoProfile -Command '"OUTLOOK_COUNT=" + @(Get-Process outlook -ErrorAction SilentlyContinue).Count'); pwsh -NoProfile -Command 'Set-Location ""; msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:TreatWarningsAsErrors=true "/flp:LogFile=coverage\nullable.msbuild.log;Verbosity=normal" | Out-Null; "MSBUILD_EXIT=$LASTEXITCODE"; ...OUT_LINES...; Get-Content -LiteralPath $l -Tail 6'
+EXIT_CODE: 0
+OUTLOOK-CLOSED: true
+Output Summary:
+- CMD-OUTLOOK printed OUTLOOK_COUNT=0 (nothing terminated).
+- Console output was discarded with Out-Null; the msbuild arguments are exactly CMD-MSBUILD-NULLABLE and the summary is read from the file log tail.
+- File log tail: "Build succeeded." / "0 Warning(s)" / "0 Error(s)" / "Time Elapsed 00:00:31.26"
+- MSBUILD_EXIT=0
+- OUT_LINES=36 (at least 18; equal to the P0-T11 value 36)
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-coverage-projection.2026-09-28T20-01.jacoco.xml b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-coverage-projection.2026-09-28T20-01.jacoco.xml
new file mode 100644
index 000000000..417873222
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-coverage-projection.2026-09-28T20-01.jacoco.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-mstest-coverage.iter1.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-mstest-coverage.iter1.2026-09-28T20-01.md
new file mode 100644
index 000000000..851c571d7
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-mstest-coverage.iter1.2026-09-28T20-01.md
@@ -0,0 +1,15 @@
+# P2-T7 — C# QC step 4, MSTest with coverage (iteration 1) — FAILED, loop restarts as iter2
+
+Timestamp: 2026-09-30T10-53
+Command: pwsh -NoProfile -Command 'Set-Location ""; & "\scripts\vscode\Invoke-MSTestWithCoverage.ps1" -SearchRoot .' (run detached with its combined output redirected to a session scratch log outside the repository; the script and its arguments are unchanged)
+EXIT_CODE: 1
+Output Summary:
+- "Total tests: 7346" / "Passed: 7345" / "Failed: 1" / "Test Run Failed."
+- The runner then threw at Invoke-MSTestWithCoverage.ps1 line 262: "MSTest with coverage failed with exit code 1"; no "First-party coverage:" line, no "Coverage projection: " line and no "Test-result summary: " line were printed, so no projection or summary was copied for this iteration.
+- Failed test: RemainingLoadActive_AcrossAsyncVoidFirstAwait_StaysTrueWhileLoaderProduces (QuickFiler.Test/Controllers/QfcDatamodelLivenessTests.cs, line 192 via StartHeldOpenLoader line 172)
+- Error message: "Expected entered.Task.Wait(TimeSpan.FromSeconds(5)) to be True because the started worker must reach the injected loader, but found False."
+- "Coverage output" and "Results File" lines printed absolute paths under \coverage\ (placeholders applied, convention 4).
+
+Attribution: this change edits no C# source file. The only QuickFiler.Test change removes two Exists()-guarded Import elements whose package folder was never restored (P0-T5 ALTCOVER-RESTORED False), so the compiled test assembly is unaffected. The same test passed in the P0-T12 baseline (7346 of 7346). The failure is a five-second wall-clock wait inside the test that did not complete under a full parallel run, which is a pre-existing timing dependence outside the Write Set; it is reported to the caller and is not repaired on this branch.
+
+Loop action (convention 8): P2-T7 failed, so the loop restarts at P2-T1 with the artifact suffix iter2. No Write Set file is changed by the restart.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-mstest-coverage.iter2.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-mstest-coverage.iter2.2026-09-28T20-01.md
new file mode 100644
index 000000000..9229e5247
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-mstest-coverage.iter2.2026-09-28T20-01.md
@@ -0,0 +1,28 @@
+# P2-T7 — C# QC step 4, MSTest with coverage (iteration 2)
+
+Timestamp: 2026-09-30T11-06
+Command: pwsh -NoProfile -Command 'Set-Location ""; & "\scripts\vscode\Invoke-MSTestWithCoverage.ps1" -SearchRoot .' (run detached with its combined output redirected to a session scratch log outside the repository; the script and its arguments are unchanged)
+EXIT_CODE: 0
+Output Summary:
+- "Test Run Successful."
+- "Total tests: 7346" / "Passed: 7346"
+- First-party coverage: lines 56479/65736 (85.92%), branches 13657/17054 (80.08%)
+- Line percentage 85.92; branch percentage 80.08
+- MEETS-85: true (observation only, convention 10)
+- Test-result summary (copied): total 7346, executed 7346, passed 7346, failed 0; skipped 0 (derived); error 0, timeout 0, aborted 0, notExecuted 0, inconclusive 0; failed tests: none
+- Path-printing lines, with host prefixes replaced (convention 4):
+ - "Using vstest.console: \Microsoft Visual Studio\18\Community\Common7\IDE\Extensions\TestPlatform\vstest.console.exe"
+ - "Coverage output: \coverage\coverage.cobertura.xml"
+ - "Coverage projection: \coverage\coverage.cobertura.jacoco.xml"
+ - "Test-result summary: \coverage\test-results\mstest-coverage-run.summary.txt"
+ - "Done. Coverage artifact: \coverage\coverage.cobertura.xml"
+
+Copies:
+- docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-coverage-projection.2026-09-28T20-01.jacoco.xml — 1467 bytes; root element report; 9 package elements; PROJECTION-RAW-ELEMENTS: 0
+- docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-test-results.2026-09-28T20-01.summary.txt — 298 bytes
+
+Reconciliation: the projection's package LINE covered sum is 56479, equal to the line numerator on the printed line.
+
+The raw Cobertura and trx documents stay under the ignored coverage directory and are not copied.
+
+Iteration note: iteration 1 of this step failed on one timing-dependent test (qa-gates/p2-t7-mstest-coverage.iter1.2026-09-28T20-01.md); this iteration ran the same command on the same tree with no file changed between the two runs.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-test-results.2026-09-28T20-01.summary.txt b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-test-results.2026-09-28T20-01.summary.txt
new file mode 100644
index 000000000..81b9a776b
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-test-results.2026-09-28T20-01.summary.txt
@@ -0,0 +1,5 @@
+Test run outcome: Completed
+Total 7346, executed 7346, passed 7346, failed 0.
+Skipped 0, derived as total minus executed rather than reported by the test platform.
+Figures reported verbatim by the test platform: error 0, timeout 0, aborted 0, notExecuted 0, inconclusive 0.
+Failed tests: none
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t8-attestation-and-coverage-delta.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t8-attestation-and-coverage-delta.2026-09-28T20-01.md
new file mode 100644
index 000000000..1d8b44a9a
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t8-attestation-and-coverage-delta.2026-09-28T20-01.md
@@ -0,0 +1,34 @@
+# P2-T8 — Single-pass attestation and coverage reconciliation
+
+Timestamp: 2026-09-30T11-07
+Command: Read the seven final-iteration (iter2) artifacts P2-T1 to P2-T7 and the P0-T12 and P0-T16 baselines; compute the deltas below.
+EXIT_CODE: 0
+Output Summary:
+
+Final iteration: iter2 (iteration 1 failed at P2-T7 on one timing-dependent MSTest test; see qa-gates/p2-t7-mstest-coverage.iter1.2026-09-28T20-01.md).
+
+| Task | Artifact | EXIT_CODE | Expected | Timestamp |
+|---|---|---|---|---|
+| P2-T1 | docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t1-poshqc-format.iter2.2026-09-28T20-01.md | 0 | 0 | 2026-09-30T10-55 |
+| P2-T2 | docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t2-poshqc-analyze.iter2.2026-09-28T20-01.md | 0 | 0 | 2026-09-30T10-56 |
+| P2-T3 | docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t3-pester.iter2.2026-09-28T20-01.md | 0 | 0 | 2026-09-30T10-58 |
+| P2-T4 | docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t4-csharpier-check.iter2.2026-09-28T20-01.md | 0 | 0 (the P0-T9 exit code) | 2026-09-30T11-00 |
+| P2-T5 | docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t5-msbuild-analyzers.iter2.2026-09-28T20-01.md | 0 | 0 | 2026-09-30T11-01 |
+| P2-T6 | docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t6-msbuild-nullable.iter2.2026-09-28T20-01.md | 0 | 0 | 2026-09-30T11-02 |
+| P2-T7 | docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t7-mstest-coverage.iter2.2026-09-28T20-01.md | 0 | 0 | 2026-09-30T11-06 |
+
+- All seven exit codes equal their expected values.
+- The seven timestamps are non-decreasing in task order and all seven artifacts carry the iter2 suffix.
+
+C# coverage (P2-T7 iter2 minus P0-T12):
+- Line: 85.92 minus 85.91 = +0.01 percentage points (at least -0.5)
+- Branch: 80.08 minus 80.08 = 0.00 percentage points (at least -0.5)
+
+PowerShell coverage (CI Pester job):
+- Aggregate on the pushed head: 94.51 percent (run 36722780748, head b96926588d562f994430e7ba7301de5de86f206c, Pester job 109911885533 conclusion success); at least 80
+- Baseline: 94.51 percent (run 36666302259 on main, head 231e1c0b55105aeb626bf5a6e8d0266a567cacad, Pester job 109731601928 conclusion success)
+- ConsistencyVerifier.psm1 covered: 158 on the pushed head versus 158 at baseline (at least the P0-T16 value); missed 2 versus 2
+- No PowerShell branch figure exists: Pester emits no branch counter.
+- This change adds no new module, so no 90 percent new-module gate applies.
+
+Result: no blocking regression; no delta below -0.5.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t9-file-size-audit.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t9-file-size-audit.2026-09-28T20-01.md
new file mode 100644
index 000000000..fbfdc506a
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/qa-gates/p2-t9-file-size-audit.2026-09-28T20-01.md
@@ -0,0 +1,13 @@
+# P2-T9 — File size audit of the change footprint
+
+Timestamp: 2026-09-30T11-08
+Command: pwsh -NoProfile -Command 'Set-Location ""; foreach ($p in ) { "LINECOUNT " + $p + " " + @(Get-Content -LiteralPath $p).Count }'
+EXIT_CODE: 0
+Output Summary:
+- QuickFiler.Test/QuickFiler.Test.csproj: 568 (the post-merge 570 minus the two deleted imports)
+- SVGControl/app.config: 23
+- .github/workflows/dependabot-repair.yml: 173
+- scripts/dependencies/ConsistencyVerifier.psm1: 499 (equals VERIFIER-LINES 499; at most 500)
+- tests/scripts/dependencies/ConsistencyVerifier.Tests.ps1: 337 (at most 500)
+- tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1: 152 (at most 500)
+- Exactly 6 files listed. Markdown files (the workflows README, the 911 runbook, issue.md and the plan) are exempt from the 500-line cap and are deliberately not listed.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t1-tree-test-authored.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t1-tree-test-authored.2026-09-28T20-01.md
new file mode 100644
index 000000000..0a56ad91e
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t1-tree-test-authored.2026-09-28T20-01.md
@@ -0,0 +1,21 @@
+# P1-T1 — Repository tree consistency test authored
+
+Timestamp: 2026-09-30T10-00
+Command: Write tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1; then pwsh -NoProfile -Command 'Set-Location ""; (BOM, CR byte, non-ASCII byte and line counts); Select-String -Pattern "^\s*It '"'"'" ...; Select-String -Pattern "Start-Sleep","GetTempFileName","New-TemporaryFile","Mock" ...; Select-String for It, Describe or Context names matching AC followed by a digit' (the quote character built from [char]39 for the name checks)
+EXIT_CODE: 0
+WORKER: atomic-executor authored the file inline; no sub-agent dispatch tool is available to this executor, so the powershell-typed-engineer hand-off was performed within exactly the P1-T1 bounds.
+Output Summary:
+- File created: tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1
+- Encoding: UTF-8 with BOM (BOM=True); line endings LF (0 CR bytes); ASCII content (0 bytes above 127 after the BOM)
+- Line count: 152 (at most 200)
+- Set-StrictMode -Version Latest; BeforeAll resolves $script:RepoRoot from $PSScriptRoot as ConsistencyVerifier.Tests.ps1 line 4 does and imports scripts/dependencies/ConsistencyVerifier.psm1 with -Force
+- One Describe: 'Repository tree consistency (issue 929)'
+- It lines matching ^\s*It ': 4, named verbatim:
+ 1. 'reports no Import element whose package the sibling manifest omits, for every project directory that carries a manifest'
+ 2. 'names in the SVGControl binding redirects the assembly version the SVGControl project reference declares'
+ 3. 'passes client-id and not app-id to the create-github-app-token step of the repair workflow'
+ 4. 'instructs the maintainer to store the Client ID in the secret the repair workflow reads by name'
+- Select-String for Start-Sleep, GetTempFileName, New-TemporaryFile and Mock: 0 lines
+- It, Describe or Context names matching AC followed by a digit: 0
+- Test 1 formats each finding as ": line "; test 3 carries -Because text containing client-id and app-id; test 4 carries -Because text containing secret name and client-id.
+- The step-block helper re-implements the Get-WorkflowStepBlock approach locally (it is not dot-sourced); both helpers are defined inside BeforeAll.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t11-tree-test-pass-after.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t11-tree-test-pass-after.2026-09-28T20-01.md
new file mode 100644
index 000000000..eb479a1ec
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t11-tree-test-pass-after.2026-09-28T20-01.md
@@ -0,0 +1,24 @@
+# P1-T11 — Tree consistency tests pass after the fix
+
+Timestamp: 2026-09-30T10-17
+Command: pwsh -NoProfile -Command '[DateTime]::UtcNow.ToString("o")' (RUN-START); MCP mcp__drm-copilot__run_poshqc_test (workspace_root , scan_folders ["tests/scripts/dependencies"]); CMD-JUNIT-READ
+EXIT_CODE: 0
+Output Summary:
+- RUN-START: 2026-09-30T13:29:57.2124290Z
+- MCP payload (host prefix replaced): {"ok":true,"tool":"run_poshqc_test","workspace_root":"","summary":"Ran bundled PoshQC test against '' with 1 selected scan folder(s)."}
+- JUNIT-WRITTEN=2026-09-30T13:30:27.3304471Z (later than RUN-START)
+- JUNIT-ROOT tests=137 failures=0 errors=0 disabled=0 (131 plus 6)
+- Exactly 8 JUNIT-SUITE lines:
+ - AnalyzerItemRepair.Tests.ps1 tests=13 failures=0 skipped=0
+ - ConsistencyVerifier.Tests.ps1 tests=14 failures=0 skipped=0
+ - DependabotConfig.Tests.ps1 tests=17 failures=0 skipped=0
+ - PackageCompatibility.Tests.ps1 tests=8 failures=0 skipped=0
+ - PackageGraph.Tests.ps1 tests=32 failures=0 skipped=0
+ - ProjectConsistency.Tests.ps1 tests=18 failures=0 skipped=0
+ - Repair-PackageManifestConsistency.Tests.ps1 tests=31 failures=0 skipped=0
+ - RepositoryTreeConsistency.Tests.ps1 tests=4 failures=0 skipped=0
+- No JUNIT-NOTPASSED line.
+
+Fail-before / pass-after pair: the fail-before run is recorded at docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t2-tree-test-fail-before.2026-09-28T20-01.md (RepositoryTreeConsistency.Tests.ps1 tests=4 failures=4); this run records the same four tests passing.
+
+GATE-SUBSTITUTION: JUnit per-file counts stand in for a direct Pester run
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t2-tree-test-fail-before.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t2-tree-test-fail-before.2026-09-28T20-01.md
new file mode 100644
index 000000000..36dd73f9b
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t2-tree-test-fail-before.2026-09-28T20-01.md
@@ -0,0 +1,34 @@
+# P1-T2 — Tree consistency tests fail before the fix [expect-fail]
+
+Timestamp: 2026-09-30T10-02
+Command: pwsh -NoProfile -Command '[DateTime]::UtcNow.ToString("o")' (RUN-START); MCP mcp__drm-copilot__run_poshqc_test (workspace_root , scan_folders ["tests/scripts/dependencies"]); CMD-JUNIT-READ
+EXIT_CODE: 1
+ExpectedExitCode: 1
+Output Summary:
+- RUN-START: 2026-09-30T13:24:02.1235733Z
+- MCP payload (host prefix replaced): {"ok": false, "tool": "run_poshqc_test", "workspace_root": "", "summary": "Command exited with code 4."} (ok false, as expected)
+- JUNIT-WRITTEN=2026-09-30T13:24:39.4564261Z (later than RUN-START)
+- JUNIT-ROOT tests=135 failures=4 errors=0 disabled=0 (131 + 4)
+- JUNIT-SUITE AnalyzerItemRepair.Tests.ps1 tests=13 failures=0 skipped=0
+- JUNIT-SUITE ConsistencyVerifier.Tests.ps1 tests=12 failures=0 skipped=0
+- JUNIT-SUITE DependabotConfig.Tests.ps1 tests=17 failures=0 skipped=0
+- JUNIT-SUITE PackageCompatibility.Tests.ps1 tests=8 failures=0 skipped=0
+- JUNIT-SUITE PackageGraph.Tests.ps1 tests=32 failures=0 skipped=0
+- JUNIT-SUITE ProjectConsistency.Tests.ps1 tests=18 failures=0 skipped=0
+- JUNIT-SUITE Repair-PackageManifestConsistency.Tests.ps1 tests=31 failures=0 skipped=0
+- JUNIT-SUITE RepositoryTreeConsistency.Tests.ps1 tests=4 failures=4 skipped=0
+
+Not-passed test cases (exactly four, all under the Describe 'Repository tree consistency (issue 929)'):
+
+1. JUNIT-NOTPASSED Repository tree consistency (issue 929).reports no Import element whose package the sibling manifest omits, for every project directory that carries a manifest
+ JUNIT-MESSAGE Expected 0, because these Import elements name a package the sibling manifest omits: QuickFiler.Test.csproj: line 8 altcover.8.6.45; QuickFiler.Test.csproj: line 537 altcover.8.6.45, but got 2.
+2. JUNIT-NOTPASSED Repository tree consistency (issue 929).names in the SVGControl binding redirects the assembly version the SVGControl project reference declares
+ JUNIT-MESSAGE Expected strings to be the same, because the Fizzler redirect must name the referenced assembly version, but they were different. String lengths are both 7. Strings differ at index 4. Expected: '1.3.1.0' But was: '1.3.0.0'
+3. JUNIT-NOTPASSED Repository tree consistency (issue 929).passes client-id and not app-id to the create-github-app-token step of the repair workflow
+ JUNIT-MESSAGE Expected 1, because the token step must pass exactly one client-id input read from a secret, but got 0.
+4. JUNIT-NOTPASSED Repository tree consistency (issue 929).instructs the maintainer to store the Client ID in the secret the repair workflow reads by name
+ JUNIT-MESSAGE Expected a value, because the workflow client-id line must name the secret name the runbook has to match, but got $null or empty.
+
+Message literal checks: message 1 contains QuickFiler.Test.csproj and altcover.8.6.45; message 2 contains 1.3.0.0 and 1.3.1.0; message 3 contains client-id; message 4 contains secret name. No failure occurred in any other suite.
+
+GATE-SUBSTITUTION: JUnit per-file counts stand in for a direct Pester run
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t3-verifier-import-tests.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t3-verifier-import-tests.2026-09-28T20-01.md
new file mode 100644
index 000000000..db367ed0d
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/regression-testing/p1-t3-verifier-import-tests.2026-09-28T20-01.md
@@ -0,0 +1,24 @@
+# P1-T3 — Two Import-kind verifier tests and sibling comment updates
+
+Timestamp: 2026-09-30T10-04
+Command: Edit tests/scripts/dependencies/ConsistencyVerifier.Tests.ps1; pwsh -NoProfile -Command '[DateTime]::UtcNow.ToString("o")' (RUN-START); MCP mcp__drm-copilot__run_poshqc_test (workspace_root , scan_folders ["tests/scripts/dependencies"]); CMD-JUNIT-READ; Select-String -SimpleMatch for the four stale phrases; Select-String for test names matching AC followed by a digit; @(Get-Content).Count
+EXIT_CODE: 1
+ExpectedExitCode: 1
+WORKER: atomic-executor edited the file inline; no sub-agent dispatch tool is available to this executor, so the powershell-typed-engineer hand-off was performed within exactly the P1-T3 bounds.
+Output Summary:
+- Edits: the comment at lines 57 to 59 now states that the fixture reproduces the shape QuickFiler.Test/QuickFiler.Test.csproj carried at lines 8 and 537 until issue 929 removed both imports, keeps the no-hard-coded-exception sentence, and drops the "Tracked separately" sentence; the comment formerly at line 275 now reads "the shape QuickFiler.Test carried before issue 929"; two It blocks were added in the Context 'Package absent from the manifest' after the It block that began at line 228:
+ - 'reports an Import whose package the manifest does not declare, with Kind Import'
+ - 'reports no Import finding when the manifest declares the imported package'
+- RUN-START: 2026-09-30T13:25:29.0090061Z
+- MCP payload (host prefix replaced): {"ok": false, "tool": "run_poshqc_test", "workspace_root": "", "summary": "Command exited with code 4."}
+- JUNIT-WRITTEN=2026-09-30T13:26:06.8242883Z (later than RUN-START)
+- JUNIT-ROOT tests=137 failures=4 errors=0 disabled=0
+- JUNIT-SUITE ConsistencyVerifier.Tests.ps1 tests=14 failures=0 skipped=0 (12 existing plus 2)
+- JUNIT-SUITE RepositoryTreeConsistency.Tests.ps1 tests=4 failures=4 skipped=0 (red by design until P1-T4 to P1-T9; decision D13)
+- Every other suite at failures=0: AnalyzerItemRepair 13, DependabotConfig 17, PackageCompatibility 8, PackageGraph 32, ProjectConsistency 18, Repair-PackageManifestConsistency 31
+- The four JUNIT-NOTPASSED lines all name the RepositoryTreeConsistency tests
+- Stale phrases ("carries a live instance", "live shape", "lines 8 and 514", "Tracked separately") over the file: 0 lines
+- Test names matching AC followed by a digit: 0
+- File line count: 337 (at most 500)
+
+GATE-SUBSTITUTION: JUnit per-file counts stand in for a direct Pester run
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/feature-audit.2026-09-30T10-30.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/feature-audit.2026-09-30T10-30.md
new file mode 100644
index 000000000..72365fea5
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/feature-audit.2026-09-30T10-30.md
@@ -0,0 +1,80 @@
+# Feature Audit — package-manifest-consistency-residuals (Issue #929)
+
+- Artifact timestamp label: 2026-09-30T10-30 (caller-assigned)
+- Work mode: `minor-audit` (issue.md line 12); AC source: the `## Acceptance Criteria` section of issue.md only (AC1 to AC7)
+- Branch: `bug/package-manifest-consistency-residuals-929`; head `5ce3c8c3b`; source diff base `231e1c0b5`
+- Companion artifacts: `policy-audit.2026-09-30T10-30.md`, `code-review.2026-09-30T10-30.md`
+- Total blocking findings: **0**
+- Verdict: **PASS** — 7 of 7 acceptance criteria evaluated PASS; every executor check-off stands; no criterion is to be unchecked
+
+## Executive Summary
+
+Each of the seven acceptance criteria was evaluated against the files on disk in the item worktree and against the executor's committed evidence, not against the executor's check-off notes alone. AC1 to AC3 and AC5 to AC6 are verifiable by direct reading and all hold. AC4 holds on the two added in-memory detector tests plus the tree census test's red-then-green pair and the read-only verifier run whose absent-from-manifest count moved from 2 to 0. AC7 holds on the cold restore, the aligned analyzer census (no back-fill was needed, so the permissive back-fill clause was not exercised), and the two toolchains passing on the final iteration with no regression against the Phase 0 baseline. The one CI test failure and the one local iteration-1 test failure are on pre-existing timing-dependent C# tests and are not attributable to a change that edits no C# source. No blocking finding exists; follow-ups are listed for the orchestrator and not filed from this branch.
+
+## Scope and Baseline
+
+- Baseline: `231e1c0b55105aeb626bf5a6e8d0266a567cacad` (origin/main at merge 3091b8af9; P0-T1 BASE-SHA). Baseline measurements: MSTest 7346 of 7346, C# 85.91% lines / 80.08% branches (P0-T12); CI Pester on main run 36666302259: 373 passed, 94.51% lines (P0-T16); analyzer census `ANALYZER-ITEM-STATE: aligned`, `ANALYZER_ITEMS=162 FILES=17 UNRESOLVED=0` (P0-T6); pre-fix altcover lines 2 and verifier `ABSENT=2` (P0-T17); pre-fix redirect repairs 1 and 1 (P0-T18).
+- Post-change: MSTest 7346 of 7346, C# 85.92% / 80.08% (P2-T7 iter2); CI Pester on branch run 36722780748 head `b96926588`: 379 passed, 94.51% (P2-T3 iter2); verifier `ABSENT=0` (P1-T12); redirect repairs 0 and 0 (P1-T5).
+- Diff scope (P2-T10, verified on disk): `.github/workflows/README.md`, `.github/workflows/dependabot-repair.yml`, `QuickFiler.Test/QuickFiler.Test.csproj`, `SVGControl/app.config`, the 911 runbook, `scripts/dependencies/ConsistencyVerifier.psm1`, `tests/scripts/dependencies/ConsistencyVerifier.Tests.ps1`, `tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1`, the promoted record, and the feature folder. Zero `.cs` files; zero other `.csproj`, `packages.config` or `app.config` files.
+- Method: Read, Grep and Glob only (caller constraint). Branch head read from the worktree's git ref file. PR context artifacts are absent in the worktree and were not regenerable; scope was triangulated from the caller's diff, P2-T10 and disk.
+
+## Acceptance Criteria Inventory
+
+Source: `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/issue.md`, section `## Acceptance Criteria`, lines 44-50. Seven checkbox items, all `[x]` at review start. The maintainer follow-up paragraph (line 52) and Summary item 4 are not acceptance criteria and are not evaluated as such.
+
+| ID | Criterion (abridged) | State at review start |
+|---|---|---|
+| AC1 | No `altcover` `Import` in `QuickFiler.Test.csproj`; case-insensitive search across tracked project files and manifests returns zero | `[x]` |
+| AC2 | `SVGControl/app.config` Fizzler redirect newVersion 1.3.1.0 and oldVersion range ending at 1.3.1.0, matching the project reference | `[x]` |
+| AC3 | `SVGControl/app.config` System.Runtime.CompilerServices.Unsafe redirect newVersion 6.0.3.0 and range ending at 6.0.3.0, matching the project reference | `[x]` |
+| AC4 | Verifier reports an Import whose package is absent from the manifest and no finding when declared; both covered by in-memory Pester tests, no temporary files; zero findings against the tree after AC1 | `[x]` |
+| AC5 | Workflow passes `client-id`, no `app-id`; actionlint clean | `[x]` |
+| AC6 | Runbook instructs storing the Client ID (not the numeric App ID) in the secret the workflow reads, naming it exactly | `[x]` |
+| AC7 | Cold restore, solution rebuild succeeds (permissive back-fill clause), C# and PowerShell toolchains pass with no new failures relative to the Phase 0 baseline | `[x]` |
+
+## Acceptance Criteria Evaluation
+
+| ID | Verdict | Blocking | Evidence (reviewer-verified) |
+|---|---|---|---|
+| AC1 | PASS | No | Grep `altcover` (case-insensitive) over `*.csproj`, `*.config`, `*.props`, `*.targets` in the worktree: 0 matches. P1-T4: `ALTCOVER_LINES=0` over `*.csproj` and `*/packages.config` (P0-T17 measured 2), file 570 to 568 lines, the two deleted lines quoted verbatim. Residue: two tracked `.csproj.bak` copies still carry the token; they are not project files (MSBuild never reads `.bak`) and are outside the criterion's stated pathspec — recorded as a follow-up, not a gap. |
+| AC2 | PASS | No | `SVGControl/app.config` line 15: `oldVersion="0.0.0.0-1.3.1.0" newVersion="1.3.1.0"`; `SVGControl/SVGControl.csproj` line 58: `Fizzler, Version=1.3.1.0`; `packages.config` line 4 pins Fizzler 1.3.1. P0-T18 `FIZZLER_ASM=1.3.1.0`; P1-T5 `FIZZLER_REPAIRS=0`. Tree test 2 green (P1-T11). |
+| AC3 | PASS | No | `SVGControl/app.config` line 19: `oldVersion="0.0.0.0-6.0.3.0" newVersion="6.0.3.0"`; `SVGControl.csproj` line 82: `System.Runtime.CompilerServices.Unsafe, Version=6.0.3.0` (package 6.1.2 ships assembly version 6.0.3.0; P0-T18 `UNSAFE_ASM=6.0.3.0`); P1-T5 `UNSAFE_REPAIRS=0`. Tree test 2 green. |
+| AC4 | PASS | No | Positive case: `ConsistencyVerifier.Tests.ps1` lines 240-251 (`GuardedUnmanifestedProject` fixture at 60-71, two guarded altcover Imports; FindingCount 2, every Kind `Import`, every PackageFolder `altcover.8.6.45`). Negative case: lines 253-263 (`AgreeingProject` declares its imported package; Import-kind subset empty; ExaminedCount greater than 0). Fixtures are here-strings; Grep over both test files for `Out-File`, `Set-Content`, `Add-Content`, `New-Item`, `New-TemporaryFile`, `[System.IO.File]::Write*`, `Remove-Item`: none. Suite: 14 of 14 (P1-T3 onward). Tree: `RepositoryTreeConsistency.Tests.ps1` test 1 red with 2 findings on the base tree (P1-T2 message names lines 8 and 537 of `QuickFiler.Test.csproj`) and green after AC1 (P1-T11); read-only verifier `ABSENT=0` (P1-T12) versus 2 (P0-T17). The detection rule pre-existed (plan decision D1); the criterion asks for the behaviour and its tests, both of which are present. |
+| AC5 | PASS | No | `dependabot-repair.yml` line 51: `client-id: ${{ secrets.DEPENDABOT_REPAIR_APP_ID }}`; Grep `app-id` under `.github/workflows`: no match. actionlint 1.7.7 scoped and repository-wide exit 0 with no output (P1-T7); CI actionlint job on run 36722780748 succeeded. Tree test 3 green. |
+| AC6 | PASS | No | Runbook line 99 heading "Record the Client ID and generate a private key"; lines 101-106 instruct recording the Client ID and state the numeric App ID is not needed; lines 129-131 create the secret named `DEPENDABOT_REPAIR_APP_ID` with "the Client ID value recorded in step 10"; line 154 YAML sample `client-id: ${{ secrets.DEPENDABOT_REPAIR_APP_ID }}`, identical to workflow line 51. Tree test 4 extracts the secret name from the workflow and asserts it in the runbook (green). README line 116 aligned. Cosmetic residue at line 301 ("App ID location") noted in the code review. |
+| AC7 | PASS | No | Cold restore: P0-T5 `PACKAGE_DIRS_BEFORE=0`, `PACKAGE_DIRS_AFTER=172`, `Build succeeded.`, 0 errors. Analyzer census aligned, `UNRESOLVED=0` (P0-T6), so no back-fill occurred and the permissive clause was not exercised; P2-T10 records 0 other `.csproj`, `packages.config` or `app.config` paths changed. Rebuilds: P0-T10, P0-T11, P2-T5 iter2, P2-T6 iter2 each `Build succeeded.` 0 warnings 0 errors. C# toolchain final iteration: CSharpier check exit 0 (P2-T4), analyzer and nullable rebuilds exit 0, MSTest 7346 of 7346 with 85.92% / 80.08% (P2-T7 iter2) against baseline 7346 of 7346 with 85.91% / 80.08%. PowerShell toolchain: PoshQC format rewrote nothing (P2-T1), analyze pass (P2-T2), test 137 of 137 (P2-T3) against 131 of 131 baseline; CI Pester 379 of 379 at 94.51% against 373 of 373 at 94.51%. No new failure relative to the Phase 0 baseline. Iteration 1's single MSTest failure and CI run 36722780748's single `mstest-coverage` failure are assessed below as not attributable. |
+
+## Acceptance Criteria Check-off
+
+- Newly checked off by the reviewer: none (all seven were already `[x]`).
+- Left unchecked or recommended to uncheck: none. Each criterion evaluated PASS, so every existing `[x]` stands.
+- `issue.md` was not modified by this review.
+
+### Acceptance Criteria Status
+- Source: `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/issue.md` (`## Acceptance Criteria`)
+- Total AC items: 7
+- Checked off (delivered): 7
+- Remaining (unchecked): 0
+- Items remaining: none
+
+## CI Failure Attribution
+
+- CI run 36722780748 (workflow_dispatch, head `b96926588`): `pester`, `build-analyzers`, `build-nullable`, `format-check`, `actionlint`, `hygiene` succeeded; `mstest-coverage` failed 1 of 7346 (`Transaction_SecondCallerCannotInstallUntilTheFirstRestores`, `QuickFiler.Test/Controllers/QfcItemController.UiThreadDispatcherFixtureTests.cs` line 206, a dispatcher-fixture concurrency test).
+- Local final QC iteration 1 failed a different test (`RemainingLoadActive_AcrossAsyncVoidFirstAwait_StaysTrueWhileLoaderProduces`, `QfcDatamodelLivenessTests.cs` line 189, a five-second wall-clock wait); iteration 2 on the unchanged tree passed 7346 of 7346, as did the Phase 0 baseline.
+- Attribution: this change edits no `.cs` file. The only QuickFiler.Test edit removes two `Exists()`-guarded imports whose target folder is never restored (no manifest declares altcover; P0-T5 `ALTCOVER-RESTORED: False`; CI has no cache fallback since issue 936), so the compiled test assembly is unchanged. Both tests exist on the base tree (they arrived via the origin/main merge) and both passed twice locally on this tree. Two different tests failing once each on two different hosts is the signature of pre-existing timing dependence, not of this diff. Verdict: not attributable; AC7's "no new failures relative to the Phase 0 baseline" holds on the local baseline-versus-final comparison it names.
+- Residual gate owned by the orchestrator: the PR-time CI run on the branch head `5ce3c8c3b` (CI has so far built only `b96926588`; the later commits are feature-folder evidence and the second origin/main merge).
+
+## Recommended Follow-ups (list only; not filed from this branch)
+
+1. Promote the two timing-dependent QuickFiler.Test tests (`QfcDatamodelLivenessTests.cs` line 189 wall-clock `Task.Wait`; `QfcItemController.UiThreadDispatcherFixtureTests.cs` line 206) to an issue under the determinism rule (no real wall-clock waits in test code).
+2. Delete the eight tracked `*.csproj.bak` copies listed in P0-T1 BAK-TRACKED; two still carry the `altcover` token.
+3. Runbook line 301: reword "App ID location" to "Client ID location".
+4. `dependabot-repair.yml` line 14: re-wrap the header comment.
+5. Optional test hardening in `RepositoryTreeConsistency.Tests.ps1`: split test 2 per assembly; assert test 1 skips no manifest directory.
+6. Maintainer follow-up already recorded at P2-T19 (not a merge gate): provision the GitHub App credential with `DEPENDABOT_REPAIR_APP_ID` holding the Client ID, confirm the secret store for a Dependabot-triggered `workflow_run`, then exercise AC18 to AC20 of issue 911 and obtain the first green run of the modified workflow.
+7. Pre-existing: eleven other `app.config` files redirect Fizzler to 1.3.0.0 (tracked in `docs/features/potential/2026-08-04-stale-fizzler-and-unsafe-binding-redirects.md`).
+8. Executor evidence hygiene: `Timestamp:` labels should be clock readings; on this run they lead the embedded UTC stamps by 38 to 72 minutes.
+
+## Summary
+
+Verdict PASS. 7 of 7 acceptance criteria PASS; 0 blocking findings; no remediation inputs. The delivered change satisfies the issue's invariant (a project's files and its own `packages.config` agree, and the repair workflow is runnable once its credential exists) with a minimal diff, a red-then-green regression suite, and toolchain evidence that reconciles to the committed projections and the CI logs. The orchestrator's remaining gate is the PR-time CI run on the branch head.
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/issue.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/issue.md
new file mode 100644
index 000000000..ca8e11c35
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/issue.md
@@ -0,0 +1,83 @@
+# package-manifest-consistency-residuals (Issue #929)
+
+- Date captured: 2026-09-28
+- Author: Dan Moisan
+- Status: Promoted -> docs/features/active/package-manifest-consistency-residuals/ (Issue #929)
+
+> Automation note: Keep the section headings below unchanged; the promotion tooling maps each of them into the GitHub bug issue template.
+
+- Issue: #929
+- Issue URL: https://github.com/drmoisan/TaskMaster/issues/929
+- Last Updated: 2026-09-28
+- Work Mode: minor-audit
+
+## Summary
+Consolidates #912 with the remaining parts of #914. PRs #920 and #921 fixed 8 of the 10 stale binding redirects and the `Invoke-ProjectConsistencyRepair` fallback defect. All remaining items break one invariant: a project's files and its own `packages.config` must agree, and the repair workflow that maintains them must be runnable.
+
+1. **#912:** `QuickFiler.Test/QuickFiler.Test.csproj` lines 8 and 535 import `altcover.8.6.45` build assets. No `packages.config` declares `altcover`, so the imports are silently skipped by their `Exists()` guard.
+2. **#914 sub-item 3 residual:** two binding redirects in `SVGControl/app.config` are still stale:
+ - `Fizzler` redirects to 1.3.0.0, but the reference and the restored package are 1.3.1.0.
+ - `System.Runtime.CompilerServices.Unsafe` redirects to 6.0.2.0, but the reference and the restored package are 6.0.3.0.
+3. **#914 comment item 1:** `.github/workflows/dependabot-repair.yml:51` passes the deprecated `app-id` input to `actions/create-github-app-token@v3`. It should pass `client-id`, and the runbook should say to store the App's Client ID.
+4. **#914 sub-item 1 (verification only, requires the maintainer):** AC18, AC19 and AC20 of #911 can only be exercised after a GitHub App credential is provisioned. The runbook is at `docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md`. The secret store is also unconfirmed: a Dependabot-triggered `workflow_run` may read only Dependabot secrets. None of this is a merge gate for items 1 to 3.
+
+## Environment
+- OS/version: Windows 11 Pro 10.0.26200
+- Python version: not applicable (.NET Framework 4.8.1 packages.config projects, GitHub Actions)
+- Command/flags used: `nuget restore TaskMaster.sln` from cold; static inspection on `main` at `177b6d78e`
+- Data source or fixture: `QuickFiler.Test/QuickFiler.Test.csproj`, `QuickFiler.Test/packages.config`, `SVGControl/app.config`, `SVGControl/packages.config`, `.github/workflows/dependabot-repair.yml`
+
+## Steps to Reproduce
+1. `git grep -n altcover -- "*.csproj" "*packages.config"` finds two imports and no manifest entry.
+2. Compare the `SVGControl/app.config` `bindingRedirect newVersion` values for `Fizzler` and `System.Runtime.CompilerServices.Unsafe` with the referenced assembly versions.
+3. Read `dependabot-repair.yml:51`.
+
+## Expected Behavior
+- Every `..\packages\` import corresponds to a manifest entry.
+- Every binding redirect names the assembly version that actually ships.
+- The repair workflow uses the non-deprecated input.
+
+## Acceptance Criteria
+
+Derived on 2026-09-28 from the Expected Behavior section and Summary items 1 to 3 (the orchestrator added this section because the promoted record carried none). Summary item 4 is maintainer-credential-gated and is deliberately not an acceptance criterion; see the maintainer follow-up note below the list.
+
+- [x] AC1: `QuickFiler.Test/QuickFiler.Test.csproj` contains no `Import` element that references an `altcover` package path; a case-insensitive search for the token altcover across every tracked project file and packages manifest in the repository returns zero matches.
+- [x] AC2: In `SVGControl/app.config`, the `Fizzler` binding redirect names newVersion 1.3.1.0 and an oldVersion range ending at 1.3.1.0, matching the assembly version of the `Fizzler` reference in the SVGControl project file.
+- [x] AC3: In `SVGControl/app.config`, the `System.Runtime.CompilerServices.Unsafe` binding redirect names newVersion 6.0.3.0 and an oldVersion range ending at 6.0.3.0, matching the assembly version of the corresponding reference in the SVGControl project file.
+- [x] AC4: The package-manifest consistency verifier from issue 911 (the ConsistencyVerifier module under the scripts dependencies folder) reports a finding for a project whose file imports a build asset from a package directory whose package id is absent from that project's own packages manifest, and reports no such finding when the manifest declares the package. Both cases are covered by Pester tests whose fixtures are held in memory, with no temporary files, and the new detection reports zero findings against the repository tree after AC1 is applied.
+- [x] AC5: `.github/workflows/dependabot-repair.yml` passes `client-id` and no longer passes `app-id` to the `actions/create-github-app-token` step, and actionlint reports no error for that workflow.
+- [x] AC6: `docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md` instructs the maintainer to store the GitHub App's Client ID (not the numeric App ID) in the secret the workflow reads, and names that secret exactly as the workflow names it.
+- [x] AC7: After a cold package restore, the solution rebuild succeeds (a pre-existing analyzer package that the project files reference at a version no packages manifest declares may be back-filled into the ignored packages folder, provided the back-fill is recorded in evidence as a pre-existing out-of-scope defect and not repaired on this branch) and the repository C# toolchain (format check, analyzer rebuild, nullable rebuild, MSTest with coverage) and the PowerShell toolchain (PoshQC format, analyze, test) pass with no new failures relative to the Phase 0 baseline.
+
+Maintainer follow-up (not an acceptance criterion and not a merge gate): acceptance criteria AC18, AC19 and AC20 of issue 911 remain deferred to the maintainer until a GitHub App credential is provisioned, and the secret store (repository Actions secrets versus Dependabot secrets for a Dependabot-triggered workflow_run) remains to be confirmed by the maintainer. This item records that deferral and does not mark those criteria passed.
+
+## Actual Behavior
+As listed in the Summary.
+
+## Logs / Screenshots
+- [x] Attached minimal logs or snippet
+- Snippet: run https://github.com/drmoisan/TaskMaster/actions/runs/36281113978 fails at `Mint an installation token` with the deprecation warning for `app-id` (see the #914 comment of 2026-09-26).
+
+## Impact / Severity
+- [ ] Blocker
+- [ ] High
+- [x] Medium
+- [ ] Low
+
+## Suspected Cause / Notes
+- The altcover imports are left over from an evaluation whose manifest entry was removed.
+- The #911 repair pass reconciles redirects only for packages it upgraded, so the pre-existing drift in `SVGControl` was left in place.
+
+## Proposed Fix / Validation Ideas
+- [ ] Delete both altcover `` elements. AltCover is not used by the coverage route, which is `dotnet-coverage`.
+- [ ] Correct the two `SVGControl/app.config` redirects, preferably by running `scripts/dependencies/Repair-PackageManifestConsistency.ps1` rather than editing by hand.
+- [ ] Switch `app-id` to `client-id` in the workflow, update the runbook, and confirm with actionlint.
+- [ ] Add a verifier test case to the #911 consistency verifier that detects "an import whose package is absent from the manifest". Use the altcover case as the fixture shape, held in memory without temporary files.
+- [ ] Rebuild the solution after a cold restore to confirm it still succeeds.
+- [ ] Record AC18 to AC20 as deferred to the maintainer and cite the runbook. Do not mark them passed.
+
+## Next Step
+- [x] Promote to GitHub issue (bug-report template)
+- [ ] Move to active fix folder / branch
+
+Consolidates: #912, #914 (sub-items 1, 3 residual, and the `client-id` comment). #914 sub-item 2 moved to the coverage-runner item. #914 sub-item 4 is fixed by PR #920.
\ No newline at end of file
diff --git a/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/plan.2026-09-28T20-01.md b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/plan.2026-09-28T20-01.md
new file mode 100644
index 000000000..b25bb88bf
--- /dev/null
+++ b/docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/plan.2026-09-28T20-01.md
@@ -0,0 +1,383 @@
+# package-manifest-consistency-residuals (Issue #929) — Atomic Plan
+
+- **Issue:** #929 (bug, minor-audit)
+- **Branch:** bug/package-manifest-consistency-residuals-929
+- **Feature folder:** docs/features/active/2026-09-28-package-manifest-consistency-residuals-929
+- **Owner:** drmoisan
+- **Last Updated:** 2026-09-30T08-32
+- **Status:** Draft (revision 3.2, 2026-09-30: the preflight round 5 delta D-1 applied in place; the P2-T1 formatter-rewrite branch keys its commit on git diff --numstat HEAD and records a terminator-only rewrite without a commit, because .gitattributes line 4 sets `* text=auto`; awaiting preflight round 6)
+- **Version:** 1.3.2
+- **Task Count:** 56 (Phase 0: 21, Phase 1: 14, Phase 2: 21)
+- **Work Mode:** minor-audit (persisted marker in issue.md line 12)
+- **AC source:** the `## Acceptance Criteria` section of the feature folder's issue.md, AC1 to AC7, and nothing else. No spec.md, user-story.md or research.md exists in the feature folder and none may be created; their presence fails the run closed. AC7 carries the orchestrator's amendment permitting an evidence-recorded back-fill of a pre-existing analyzer package version into the ignored packages folder; the clause is permissive, and on the post-merge tree no back-fill is needed (P0-T6 expects UNRESOLVED=0), so a run that performs none satisfies AC7 with its text unchanged.
+
+## Conventions binding every task
+
+1. **Execution worktree.** Every command runs with the current directory at ``, the root of the non-isolated worktree the executor is given. Every pwsh invocation is written in the outer-single-quote, inner-double-quote form and begins with Set-Location to that root, because pwsh -File resolves a relative script path against the caller's directory and would run a sibling checkout's copy. A literal double quote inside such an inner string is written doubled, never backslash-escaped. A git command stated outside a pwsh invocation is issued as git -C followed by the stated arguments, with pathspecs kept repository-relative. No dotnet or msbuild command is issued outside a pwsh invocation that begins with Set-Location, because the Bash tool starts in the session checkout, which carries its own TaskMaster.sln and global.json. No gh-bearing command in this plan may contain the character sequence create: the pr-author PreToolUse hook (.claude/hooks/enforce-pr-author-skill-helpers.ps1 line 279) scans the whole command string, and for a wrapper-led segment such as pwsh -Command it applies ordinal case-insensitive containment of gh, pr and create in any arrangement (.claude/hooks/hook-command-invocation.ps1 lines 92 to 116 and 202 to 203), so a payload carrying -Property and createdAt is read as gh pr create and refused as PR_AUTHOR_SKILL_BLOCKED.
+2. **Evidence location.** Every artifact lands under docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/ in one of the kinds baseline, regression-testing, qa-gates, other. Every artifact carries `Timestamp:` (yyyy-MM-ddTHH-mm), `Command:`, `EXIT_CODE:` (one row per artifact; further exit codes are named `Output Summary:` lines) and `Output Summary:`. An artifact that records a deliberately non-zero run carries `ExpectedExitCode:` with the observed value.
+3. **Committed test evidence.** A coverage run is committed as the package-level JaCoCo projection plus the one-line first-party summary; a test run as the trx-derived summary. No raw .trx, raw .coverage, raw Cobertura document, raw Pester JaCoCo document or PoshQC JUnit document is copied under the evidence tree or named in any commit pathspec. The PoshQC test tool writes artifacts/pester/pester-junit.xml, artifacts/pester/powershell-coverage.xml and artifacts/pester/powershell-coverage.koverage.xml (all ignored at .gitignore line 57); the CI Pester job writes its JaCoCo document as the pester-coverage artifact, which the plan downloads under the coverage directory at the repository root (ignored at .gitignore line 150); in every case the figures are transcribed into the .md artifact, which stands in for a permitted form the section does not define for the Pester route. The CI hygiene guard (.github/workflows/_hygiene.yml, wired at ci.yml lines 36 to 38) fails the branch when a tracked .xml file's root element is report and it carries a class, sourcefile, method or line element (scripts/hygiene/Test-RepositoryHygiene.Rules.ps1 lines 114 to 119), so only the package-level projection may ever be committed.
+4. **Hygiene.** No committed text (evidence, plan, issue, potential entry, runbook, README, workflow) may contain an absolute host path, a developer account name or a host name. Use the placeholders ``, ``, ``, ``, ``, ``. Record expressions such as Join-Path $env:TEMP, never their values. Tool output that prints an absolute path (for example the coverage runner's "Using vstest.console: ", "Coverage output: ", "Coverage projection: ", "Test-result summary: " and "Done. Coverage artifact: " lines at Invoke-MSTestWithCoverage.ps1 lines 373, 375, 423, 447 and 456, the restore script's "Using MSBuild: " line, gh's "The file exists." download error line and -WhatIf target names) is recorded with the prefix replaced by its placeholder. The PoshQC JUnit document names every testsuite and testcase classname by absolute path and carries machine-name and user properties: only the leaf file name (Split-Path -Leaf) and the testcase name are ever transcribed, and a failure message carrying a path is transcribed with the prefix replaced by ``. The CI hygiene guard's rule B (Test-RepositoryHygiene.Rules.ps1 line 21) additionally fails the branch on any tracked line carrying a drive letter, a colon and a users segment, which the placeholders above never produce. A CMD-HYGIENE hit at any task that runs it (P0-T20, P1-T14, P2-T11, P2-T20, P2-T21) is remedied as P0-T20 states: the leaked value is replaced with its placeholder in the offending file this plan authored and CMD-HYGIENE is re-run until HITS=0, with the pre-fix hit count recorded; a hit in a scanned file this plan did not author stops the task with a report.
+5. **Git mechanics.** Never run a whole-tree add. Stage with explicit pathspecs. Commit messages contain none of the characters dollar, backtick, less-than, greater-than, so any attribution trailer is written without angle brackets, matching the form of commit f0e9b4c53. Anchored diffs use ``, the merge-base of origin/main and HEAD recorded at P0-T1, ``, the head recorded at P0-T21, or ``, the head recorded at P0-T1, where a task says so. The branch merged origin/main at commit 3091b8af9 on 2026-09-30 (second parent 231e1c0b55105aeb626bf5a6e8d0266a567cacad, the origin/main tip at that time), so `` is that merged tip unless main has since merged this branch, and a two-point diff against it lists only this branch's own changes: none of main's 105 merged commits lies between `` and HEAD. The value is recorded, never asserted. Porcelain gates assert scope, never membership or count: the agent-memory tree under the .claude directory may carry entries at any time and is excluded from every scope clause; the presence of the plan file in porcelain is never asserted either way.
+6. **No temporary files in tests, no sleeps.** The new Pester tests read tracked repository files resolved from $PSScriptRoot and hold every other fixture in memory. Start-Sleep, retries and timing hacks are prohibited in every test and in every command payload this plan states. Waiting for the CI run at P2-T3 is done by gh run watch, the GitHub CLI's own blocking poll, re-invoked unchanged when the executor's tool call times out before the run completes; each invocation is recorded.
+7. **Out-of-bounds trees.** No task writes under the .claude directory tree, under .github/instructions, under the config directory, or to any C# source file. A solution-wide Rebuild is issued through the literal msbuild commands below and never through the Invoke-VSBuild.ps1 wrapper, because that wrapper invokes Sync-PackageReferences.ps1 first (scripts/vscode/Invoke-VSBuild.ps1 lines 250 to 253), which rewrites project files outside the Write Set.
+8. **Loop rule for Phase 2.** The seven command tasks P2-T1 to P2-T7 run in order. If any of them fails, or rewrites a Write Set member, the loop restarts at P2-T1 and the next iteration's artifacts carry the suffix iter2, iter3 and so on. A PoshQC formatter rewrite of a tracked file outside the Write Set is pre-existing drift: P2-T1 reverts and lists it under D9, and it does not restart the loop. The C# formatter step P2-T4 runs the read-only check subcommand, which rewrites nothing, so no C# rewrite branch exists; P2-T4 states what a check failure does. `EXIT_CODE: SKIPPED` is not a passing outcome for any task in this plan.
+9. **Check-off protocol.** One acceptance criterion per check-off task (P2-T12 to P2-T18). A check-off changes only `- [ ]` to `- [x]` on the criterion's line in issue.md and cites the artifacts it read. A criterion whose evidence is incomplete stays unchecked and the gap is recorded.
+10. **Policy conflict, reported not resolved.** CLAUDE.md (highest precedence) states an 80 percent line floor and a four-step loop; .claude/rules/general-unit-test.md, .claude/rules/quality-tiers.md and .claude/rules/powershell.md state 85 percent and a seven-stage loop with no architecture, contract or integration stage configured for these files. This plan gates on CLAUDE.md; P0-T12, P0-T16, P2-T3 and P2-T7 each additionally record `MEETS-85:` true or false as an observation only, and the conflict is reported to the caller. The conflict is already tracked as open GitHub issue 668 (coverage threshold discrepancy between CLAUDE.md and the rules), so it is recorded here and not re-reported as a halt.
+11. **PowerShell gates are MCP-and-CI sourced (coordinator ruling 2026-09-30).** Every local PowerShell format, analyze and test gate runs through the PoshQC MCP tools with the worktree path passed explicitly. The analyze tool's ok flag is the lint result and is recorded as "PoshQC analyze: pass (0 findings); tool reports no count". Test counts and failure messages come from the JUnit document the test tool writes; coverage figures come only from the CI Pester job (P0-T16 for the baseline run on main, P2-T3 for the run on this branch's pushed head). No raw Invoke-Pester or Invoke-ScriptAnalyzer invocation exists in this plan; a gate criterion that neither PoshQC nor CI can produce stops the task with a report.
+
+## Re-derived tree facts (planner, 2026-09-28, worktree agent-a74dcedbc13b789fd; round 1 revision at HEAD c417c249a, round 2 revision at HEAD 62448256a, round 3 revision on 2026-09-30 at HEAD 3091b8af9, the merge of origin/main 231e1c0b5)
+
+| Fact | Location | Consequence |
+|---|---|---|
+| Two Exists()-guarded altcover imports | QuickFiler.Test/QuickFiler.Test.csproj lines 8 (AltCover.props) and 537 (AltCover.targets); the file is 570 lines (re-derived 2026-09-30 after the merge, which added two lines above the second import; before the merge they were 8 and 535 in a 568-line file) | AC1 edit removes exactly these two lines; no Error guard names altcover |
+| No manifest declares altcover | git grep over all packages.config returns nothing for altcover; two .csproj.bak copies also carry the token but are not project files | AC1 search pathspec is project files and manifests only; the .bak copies are recorded, not edited |
+| Stale redirects | SVGControl/app.config line 15 (Fizzler 0.0.0.0-1.3.0.0 / 1.3.0.0) and line 19 (Unsafe 0.0.0.0-6.0.2.0 / 6.0.2.0); the file has four dependentAssembly blocks | AC2, AC3 |
+| Reference versions | SVGControl/SVGControl.csproj line 58 (Fizzler, Version=1.3.1.0; HintPath line 59 under Fizzler.1.3.1) and line 82 (Unsafe, Version=6.0.3.0; HintPath line 83 under System.Runtime.CompilerServices.Unsafe.6.1.2); SVGControl/packages.config lines 4 and 10 pin 1.3.1 and 6.1.2 | Target values 1.3.1.0 and 6.0.3.0 |
+| Repair script cannot reconcile these redirects | scripts/dependencies/Repair-PackageManifestConsistency.ps1 line 425 skips the redirect pass unless the run applied an upgrade, and line 177 skips a candidate equal to the current version | Decision D2: hand-edit, observe with the pure module function |
+| Repair script verifies the repaired text, not the tree | scripts/dependencies/Repair-PackageManifestConsistency.ps1 lines 411 to 422 build the repaired project text in memory and pass it to Get-ProjectVerification, so a what-if run's VersionDisagreementCount describes the text after repair and may be 0 while the tree still disagrees | P0-T17 and P1-T12 record DISAGREE with no expectation |
+| Redirect reconciliation function | scripts/dependencies/ProjectConsistency.psm1 lines 271 to 375 (parameters AppConfigText, AssemblyName, AssemblyVersion; result carries Text, Repair, ExaminedCount), exported at 377 to 381; returns Repair records only when the text changes | Pre-fix count 1 per assembly, post-fix count 0 |
+| Absent-from-manifest detector already covers Import | scripts/dependencies/ConsistencyVerifier.psm1 lines 215 to 250; Import is a folder-bearing kind at scripts/dependencies/AnalyzerItemRepair.psm1 line 70; identity split at lines 95 to 126 keys on the manifest id, so a version-skewed known id is not "absent" | Decision D1: no new production rule |
+| Stale comment in the detector | ConsistencyVerifier.psm1 lines 221 to 223 state QuickFiler.Test "carries a live instance"; the module is 499 lines (git grep -c and Get-Content agree; a viewer that renders the position after the final newline shows a 500th empty line) | Line-count-neutral comment replacement (P1-T10) |
+| Existing in-memory altcover fixture | tests/scripts/dependencies/ConsistencyVerifier.Tests.ps1 lines 57 to 71 (comment at 57 to 59 cites lines 8 and 514, already stale, and carries a "Tracked separately" sentence), test at 272 to 290 (comment at 275 says "the live shape"); the file has 12 It blocks and 312 lines; header lines 7 to 10 forbid test names matching AC followed by a digit | Sibling comments updated; two explicit Import-kind tests added (P1-T3) |
+| Tree-wide Import census | Every package id named by a packages-directory Import in all 18 project files is declared by that project's manifest, except altcover in QuickFiler.Test | The tree-level Import test can be tree-wide and reports zero after AC1 |
+| Analyzer Include census | 162 Analyzer Include lines across 17 project files (re-derived 2026-09-30 on the post-merge tree; equals the 911 census); every item names a package folder its own directory's packages.config declares, and a search for Meziantou.Analyzer.3.0.235 over every project file returns 0 lines | P0-T6 pins 162 and 17 and expects UNRESOLVED=0 |
+| Deprecated input | .github/workflows/dependabot-repair.yml line 49 uses actions/create-github-app-token@v3, line 51 passes app-id from secrets.DEPENDABOT_REPAIR_APP_ID, lines 13 to 14 describe the secret | AC5 |
+| Runbook | docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md: Part B heading at line 99 reads "Record the App ID and generate a private key", step 10 at lines 101 to 106, step 22 at 129 to 132, YAML sample at 149 to 156 with app-id at 154, citations at 301 and 318 | AC6 |
+| Workflows README | .github/workflows/README.md line 116 says the secret holds "the numeric App identifier" (line 115 before the merge; the table is at lines 114 to 117) | Sibling doc edit (P1-T9) |
+| Existing workflow tests | tests/scripts/dependencies/DependabotConfig.Tests.ps1 has 17 It blocks, none asserting app-id; Get-WorkflowStepBlock at 156 to 178 is the step-parsing pattern; its AC26 test reads every backticked three-part version literal in the workflows README | Regression tests for AC5/AC6 use the same text-based style; the README edit adds no such literal |
+| actionlint | scripts/dev-tools/run-actionlint.ps1 runs actionlint-bin/actionlint.exe over the repository; CI runs version 1.7.7 (.github/workflows/_actionlint.yml line 26); success prints nothing and exits 0 | Decision D4 |
+| CI Pester scope | .github/workflows/_pester.yml line 41 runs tests/scripts/dependencies, tests/scripts/hygiene and tests/scripts/vscode; line 45 measures scripts/dependencies, scripts/hygiene and scripts/vscode; line 47 writes coverage/pester-coverage.xml; line 51 prints "PESTER Passed=... Failed=... Skipped=... Total=..."; line 64 prints "COVERAGE LinePercent=... Covered=... Total=..."; line 71 exits 1 below 80 percent; lines 74 to 80 upload that document as the artifact pester-coverage (one file). The tree holds 131 It blocks under tests/scripts/dependencies (7 files: AnalyzerItemRepair 13, DependabotConfig 17, PackageGraph 32, PackageCompatibility 8, ConsistencyVerifier 12, Repair-PackageManifestConsistency 31, ProjectConsistency 18), 31 under tests/scripts/hygiene (3 files) and 211 under tests/scripts/vscode (20 files), 373 in all | The new test file is collected by CI; CI is the coverage source (P0-T16, P2-T3); the local PoshQC test run over tests/scripts/dependencies reports 131 tests before this change and 137 after |
+| CI trigger | .github/workflows/ci.yml (name: CI, line 1) triggers on push to main and development, on pull_request to those branches, and on workflow_dispatch (lines 3 to 8); jobs pester (lines 33 to 35) and hygiene (lines 36 to 38) | A push to this branch alone starts no CI run: P2-T3 dispatches ci.yml on the branch ref unless a run for the pushed head already exists |
+| CI baseline run | ci.yml run 36666302259 on main at head 231e1c0b55105aeb626bf5a6e8d0266a567cacad, conclusion success; Pester job 109731601928 "pester / Run Pester suite with coverage" (coordinator-measured 2026-09-30: Tests Passed 373, Failed 0, Skipped 0; COVERAGE LinePercent=94.51 Covered=1721 Total=1821) | P0-T16 reads the run itself and records the figures it prints; the coordinator's figures are expectations, not acceptance values |
+| CI hygiene guard | .github/workflows/_hygiene.yml runs scripts/hygiene/Test-RepositoryHygiene.ps1 (line 24), which enumerates tracked files (Test-RepositoryHygiene.Git.ps1 line 70), skips the .claude prefix (line 35 of the entry script), reports a raw test-platform or coverage-collector document by content (rule A, Rules.ps1 lines 88 to 122) and any line carrying a user-profile path (rule B, Rules.ps1 line 21), printing "HYGIENE Findings=N" and exiting 1 on any finding | The committed projection copies are package-level and classify as jacoco-projection; P2-T21 runs the guard locally before its commit |
+| No CI package-cache fallback | .github/workflows/_build-analyzers.yml line 41 and _build-nullable.yml line 41 state "No restore-keys fallback (issue #936)" (the restore-keys lines the earlier revisions cited at 57 to 58 no longer exist) | The cache inference the removed P1-T13 entry would have stated is void; nothing in this plan depends on it |
+| PoshQC test output | mcp__drm-copilot__run_poshqc_test writes artifacts/pester/pester-junit.xml (root testsuites with tests, errors, failures and disabled attributes; one testsuite per test file whose name attribute is the file's absolute path, with tests, failures and skipped attributes; one testcase per It with name equal to Describe dot Context dot It, a status attribute and an absolute-path classname; hostname, machine-name and user properties) and artifacts/pester/powershell-coverage.xml, whose counters read 0 covered, plus artifacts/pester/powershell-coverage.koverage.xml (a JaCoCo-shaped document with a report root; present in the worktree on 2026-09-30); all three are ignored at .gitignore line 57. The document present in the worktree on 2026-09-30 reads tests=131 failures=0 with ConsistencyVerifier.Tests.ps1 tests=12 and DependabotConfig.Tests.ps1 tests=17 | CMD-JUNIT-READ derives every local test count from it; the coverage document is never a coverage source |
+| CSharpier and ignored XML | .csharpierignore (lines 4 to 8, 12 to 14, 16, 18) excludes the evidence tree, *.cobertura.xml, *.coverage, *.coveragexml, *.trx, project files, packages.config and app.config, and names neither artifacts/ nor coverage/; CSharpier 1.2.6 processes *.xml; whether it also honours .gitignore was not observed by the planner | P0-T9 and P2-T4 record the XML candidate list under artifacts/ and coverage/ beside "Checked N", and the P2-T4 gate admits a delta equal to the candidate-count delta or to zero, so those ignored files alone cannot break it |
+| Formatter scope | .csharpierignore lines 12, 16, 18 exclude project files, packages.config and app.config; line 4 excludes the evidence tree | CSharpier never touches the edited files |
+| Coverage runner | scripts/vscode/Invoke-MSTestWithCoverage.ps1 (461 lines after the merge; 26 lines changed by issue 928) lines 297 to 298 fix the results directory and trx name; line 313 dot-sources the new Invoke-MSTestWithCoverage.Scope.ps1 (scoped-run gate, issue 928); lines 344 to 346 throw when dotnet-coverage is absent; line 373 prints "Using vstest.console: " and line 375 "Coverage output: ", each with an absolute path; line 410 prints the one-line first-party report (format at Invoke-MSTestWithCoverage.FirstParty.ps1 line 120); lines 415 to 423 write and print the projection (line 423 prints "Coverage projection: " with an absolute path); lines 430 to 447 write and print the summary (warning at 436, "Test-result summary: " at 447); line 456 prints "Done. Coverage artifact: " with an absolute path; lines 459 to 461 guard the entry point; floors thrown at Invoke-MSTestWithCoverage.Threshold.ps1 lines 54 and 124 | CMD-MSTEST-COVERAGE; convention 4 names the path-printing lines |
+| Bootstrap | global.json pins SDK 8.0.205 under .dotnet-sdk (lines 3 and 7); scripts/vscode/Install-RepoDotNetSdk.ps1 default version at line 3 and install directory .dotnet-sdk under the repository root at line 36; scripts/vscode/Invoke-Restore.ps1 parameters at lines 1 to 10 and its "Using MSBuild: " line at 101 prints an absolute path; .gitignore ignores artifacts (57), coverage (150, `coverage/*`), packages (197, `**/[Pp]ackages/*`) and .dotnet-sdk (356, `.dotnet*/`) | P0-T3 to P0-T7 |
+| Analyzer items aligned | The merge of origin/main (analyzer-path hotfix 89e202ed6 among its 105 commits) removed the Meziantou.Analyzer.3.0.235 skew the earlier revisions described: the analyzer folders in use are AsyncFixer.2.1.0, Roslynator.Analyzers.5.0.0, Microsoft.CodeAnalysis.BannedApiAnalyzers.5.6.0, SonarAnalyzer.CSharp.10.34.0.3385, Meziantou.Analyzer.3.0.290 and MSTest.Analyzers.4.4.1, each declared by the sibling manifest | Decision D8 revised; a cold restore alone suffices; no back-fill, no nuget CLI, no potential entry |
+| Pre-existing transitive Fizzler redirects | 13 app.config files redirect Fizzler: 12 to 1.3.0.0 (SVGControl plus 11 others), UtilitiesCS to 1.3.1.0; only SVGControl and UtilitiesCS carry a Fizzler Reference; already recorded in docs/features/potential/2026-08-04-stale-fizzler-and-unsafe-binding-redirects.md (Draft) | Decision D5: redirect test scoped to SVGControl |
+| Promotion commit on the branch | The branch carries the promotion commit whose promoted record lies under docs/features/potential/promoted, outside the Write Set and the feature folder | CMD-FOOTPRINT is anchored at ``, not `` |
+
+## Decisions
+
+- **D1 — No new production detection rule.** The rule AC4 describes exists and is tested: Find-PackageAbsentFromManifest reports an Import whose package id the sibling manifest omits. AC4 is discharged by (a) two explicit in-memory Import-kind tests added beside the existing ones, (b) a new tree-reading regression test that fails on the current tree and passes after AC1, and (c) a read-only what-if run of the composition root whose AbsentFromManifestCount moves from 2 to 0. Editing the module for a rule it already has would be an opportunistic refactor.
+- **D2 — Redirects are hand-edited.** The repair script reconciles binding redirects only for packages the run upgraded (line 425) and skips a candidate equal to the current version (line 177), so no invocation can rewrite the two SVGControl lines; running it with any candidate would also rewrite other manifests through normalisation. The read-only observation that no redirect drift remains is Invoke-BindingRedirectReconciliation over the file text for each assembly returning zero Repair records, paired with the pre-fix count of one each at P0-T18.
+- **D3 — Secret name kept, value semantics changed.** The workflow keeps reading secrets.DEPENDABOT_REPAIR_APP_ID and passes it as `client-id`; the runbook and the workflows README instruct the maintainer to store the App's Client ID under that exact name. Reason: renaming would require maintainer credential action; the secret is not yet provisioned (issue item 4, 911 evidence p8-t1-credential-availability), so the token step already fails and the change is merge-safe without any maintainer action. AC6's "names that secret exactly as the workflow names it" is carried by a test that extracts the name from the workflow and asserts it in the runbook.
+- **D4 — actionlint gate.** The local runner scripts/dev-tools/run-actionlint.ps1 (repository-wide) plus a workflow-scoped invocation of actionlint-bin/actionlint.exe are the AC5 gate. actionlint prints nothing on success and exits 0; the recorded -version line is the proof the binary ran. CI's 1.7.7 is recorded beside the local version.
+- **D5 — Regression test file.** A new file tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1 holds four tests (Import census, SVGControl redirects, workflow input, runbook secret). It reads tracked files resolved from $PSScriptRoot, the pattern DependabotConfig.Tests.ps1 already uses in this folder, and creates nothing on disk. The Import test is tree-wide because the census found no other violation. The redirect test is scoped to SVGControl because eleven other configs redirect Fizzler to 1.3.0.0 without a Reference to compare against; that residual is tracked by the 2026-08-04 potential entry and is not widened into this fix.
+- **D6 — Line-count invariant.** ConsistencyVerifier.psm1 is 499 lines at the planning snapshot; the comment replacement at lines 221 to 223 is three lines for three lines. The gate is stated against `VERIFIER-LINES:`, the count P0-T13 records after the baseline format run as @(Get-Content -LiteralPath scripts/dependencies/ConsistencyVerifier.psm1).Count (expected 499), so a formatter rewrite in Phase 0 cannot make the gate unsatisfiable; the count must also be at most 500. Every later line count of that module uses the same Get-Content expression so the figures are comparable.
+- **D7 — msbuild literal commands.** The analyzer and nullable gates use the exact CLAUDE.md commands with a file logger under the coverage directory, never the Invoke-VSBuild.ps1 wrapper (convention 7). Outlook must be closed by the user and is never terminated.
+- **D8 — Analyzer items are aligned on the post-merge tree; the census is the evidence.** Revisions 1 and 2 described a skew (16 Analyzer Include items naming Meziantou.Analyzer.3.0.235 against manifests pinning 3.0.290) that made a cold rebuild fail CS0006 and required an environment back-fill. The origin/main merge at 3091b8af9 (hotfix 89e202ed6) removed it: on 2026-09-30 every one of the 162 Analyzer Include items names a folder its manifest declares and no project file names 3.0.235. AC7's "after a cold package restore, the solution rebuild succeeds" is therefore executed as: restore the solution (P0-T5), census every Analyzer Include for resolvability (P0-T6, expected UNRESOLVED=0 and `ANALYZER-ITEM-STATE: aligned`), then rebuild (P0-T10, P0-T11, P2-T5, P2-T6). No back-fill, no nuget CLI and no potential entry remain in the plan; an UNRESOLVED count above 0 at P0-T6 stops the run with a report, because it would describe a tree the coordinator has not measured. AC7's back-fill clause is permissive and stays unexercised; the P2-T18 check-off cites the aligned census and the P2-T10 zero count of other project files and manifests.
+- **D9 — PowerShell scope.** PoshQC format, analyze and test run with scan_folders equal to scripts/dependencies and tests/scripts/dependencies, the blast radius of this change; the test tool's scan_folders is tests/scripts/dependencies alone, so its JUnit root counts that folder only (131 before this change, 137 after). Coverage figures are read from the CI Pester job, whose population is the three test folders and three script folders _pester.yml names, so the aggregate figures are comparable between P0-T16 (main) and P2-T3 (this branch). A formatter rewrite of a file outside the Write Set is pre-existing drift: it is reverted and listed, never committed by this change, and it does not restart the Phase 2 loop (convention 8).
+- **D10 — Issue item 4 is a maintainer follow-up only.** AC18, AC19 and AC20 of issue 911 and the secret-store question are recorded at P2-T19 and never marked passed.
+- **D11 — Tree-reading tests and coverage.** The four tests exercise production lines in ConsistencyVerifier.psm1 already covered; the change adds no executable production line, so the per-file no-regression gate is the covered-line count of that module.
+- **D12 — The .csproj.bak copies.** QuickFiler.Test/QuickFiler.Test.csproj.bak and QuickFiler/QuickFiler.csproj.bak carry altcover tokens. They are not project files (MSBuild never reads a .bak), so AC1's search is scoped by pathspec to project files and manifests; their tracked status is recorded at P0-T1 and their removal is reported to the caller, not performed here.
+- **D13 — Test evidence shape under the MCP-and-CI ruling.** A local test task records the MCP payload's ok value, `EXIT_CODE:` 0 when ok is true and the JUnit root failures attribute is 0 and 1 otherwise, and the CMD-JUNIT-READ lines (root counts, one line per testsuite with its leaf name, and every non-passed testcase with its failure message). A task that runs while the four tree tests are red by design (P1-T3 and P1-T7) carries `ExpectedExitCode: 1` and states the exact root failure count it expects, so a fix leaking early or a test failing to reproduce its defect both fail the task. The four tests are red at P1-T2 and P1-T3 (P1-T4 to P1-T9 not yet applied), tests 1 to 3 are green and test 4 red at P1-T7 (P1-T8 not yet applied), and all are green from P1-T11 on. Coverage figures are never read locally: P0-T16 and P2-T3 read them from the CI Pester job's log and pester-coverage artifact.
+
+## Revision Log
+
+- **Revision 3.2 (2026-09-30, planner, worktree agent-a74dcedbc13b789fd; preflight round 5 delta D-1 applied in place; task IDs and the count of 56 unchanged; issue.md and every acceptance criterion untouched).**
+ - **D-1 (major) — the P2-T1 formatter commit can be refused.** .gitattributes line 4 sets `* text=auto`, so a PoshQC rewrite that changes line terminators only is normalised out of the content git commits, and the P2-T1 branch's git commit exits 1 with "nothing to commit" while the task demanded a commit SHA. P2-T1 now runs git diff --numstat HEAD -- after a non-zero Write Set rewrite count and records it as `REWRITE-NUMSTAT:`; a non-empty output takes the existing commit branch (re-run P1-T11, commit, record the SHA, restart as iter2) and an empty output records `FORMAT-REWRITE-TERMINATOR-ONLY:` with the member list and restarts as iter2 with no commit; the post-revert porcelain clause is evaluated after the commit, or after the numstat capture when no commit is made. Sibling adjustment: Residual Risk 6 no longer states unconditionally that a P0-T13 rewrite is committed at P0-T21, because the same rule reaches that step; P0-T21's own clauses hold in the terminator-only case without edit (the member stages nothing, the evidence commit succeeds, git show lists no path outside the feature folder, and the plain message applies because no rewrite is committed). Convention 8 (restart on any Write Set rewrite, no commit named), P2-T3 (push only when HEAD differs from `PUSHED-HEAD:`) and P2-T21 ("any P2-T1 formatter commit") were checked and hold for both branches unchanged.
+- **Revision 3.1 (2026-09-30, planner, worktree agent-a74dcedbc13b789fd at HEAD 3091b8af985df2410aaf83954825b3ef8a743452; preflight round 4 deltas applied in place, one entry per delta; task IDs and the count of 56 unchanged; issue.md and every acceptance criterion untouched).**
+ - **R1 (blocking) — Actions log colour escapes.** CMD-CI-PESTER now strips every SGR escape sequence from each captured log line before the three Select-String patterns run, because Pester colours each segment of its summary line in the Actions log (observed on job 109731601928 at preflight 2026-09-30) and the "Tests Passed: [0-9]+, Failed: [0-9]+" pattern matched nothing. Affects P0-T16 and P2-T3 through the shared block.
+ - **R2 (blocking) — the pr-author hook.** createdAt was removed from the run-list --json field list and created= from its RUN line; convention 1 now states that no gh-bearing command may contain the character sequence create and names the containment rule the hook applies to a pwsh-wrapped payload. Every other gh-bearing command (CMD-CI-PESTER, CMD-CI-LIST, CMD-CI-DISPATCH, CMD-CI-WATCH) was scanned for the sequence and carries none; the remaining occurrences of the word in this file are prose, an It name inside the test file P1-T1 authors and the tree-facts row quoting dependabot-repair.yml, none of them a command the executor issues.
+ - **R3 (major) — cancelled runs.** The single locate-and-dispatch block was replaced by CMD-CI-LIST, CMD-CI-DISPATCH and CMD-CI-WATCH with the rule stated under CMD-CI-DISPATCH: one dispatch per pushed head, re-list until a run for HEAD exists, watch the greatest databaseId, and re-list and re-select when the selected run reads conclusion=cancelled, because ci.yml lines 13 to 15 cancel an in-progress run on the same ref. A pull_request-event run for the same head satisfies RUNS-FOR-HEAD and suppresses the dispatch. P2-T3 was reworded to cite the three commands; no other reference to the removed block remains (the revision 3 entry below was reworded to describe it without naming it).
+ - **R4 (major) — download folder collision.** CMD-CI-PESTER prints DIR-PREEXISTS immediately before gh run download and requires False; `` is coverage/ci-main-pester-36666302259- at P0-T16 and coverage/ci-branch-pester-- at P2-T3, increasing by 1 on each further invocation against the same run; gh's "The file exists." error line is recorded under convention 4.
+ - **R5 (major) — pwsh-with-Set-Location form.** CMD-CSHARPIER-CHECK, CMD-MSBUILD-ANALYZERS, CMD-MSBUILD-NULLABLE and P0-T4 are now pwsh invocations beginning with Set-Location that print CSHARPIER_EXIT, MSBUILD_EXIT plus OUT_LINES (and CS0006_LINES for the analyzer build) and TOOL_RESTORE_EXIT; P0-T7 and P0-T8 payloads gained the Set-Location prefix; convention 1 gained the git -C and no-bare-dotnet-or-msbuild sentences; P0-T10, P0-T11, P2-T5 and P2-T6 state their acceptance in terms of OUT_LINES, CS0006_LINES and MSBUILD_EXIT.
+ - **R6 (minor) — failure-message text.** P1-T1 test (1) now formats a finding as ": line ", tests (3) and (4) carry -Because text with the literals client-id, app-id and secret name, and P1-T2 expects the four JUNIT-MESSAGE lines to contain QuickFiler.Test.csproj and altcover.8.6.45, 1.3.0.0 and 1.3.1.0, client-id, and secret name respectively.
+ - **R7 (minor) — path-printing lines.** CMD-MSTEST-COVERAGE, P0-T12 and convention 4 name the five lines "Using vstest.console: ", "Coverage output: ", "Coverage projection: ", "Test-result summary: " and "Done. Coverage artifact: " at Invoke-MSTestWithCoverage.ps1 lines 373, 375, 423, 447 and 456 (re-derived by the planner on 2026-09-30); P2-T7 inherits through its reference to P0-T12.
+ - **R8 (minor) — artifact totals.** P2-T11 states 44 evidence .md artifacts by that task (21 from Phase 0, 13 from Phase 1 with P1-T13 producing none, 10 from P2-T1 to P2-T10 in a single-iteration run); P2-T21's index floor was re-derived to 54 (the 44 plus P2-T11 to P2-T20); the P0-T20, P0-T21 and P1-T14 floors (20, 20, 12) were re-checked and hold.
+ - **R9 (minor) — P2-T21 commit list.** The index names the P2-T2 repair commit beside the P2-T1 formatter commit.
+ - **A1 (text correction).** The PoshQC test route also writes artifacts/pester/powershell-coverage.koverage.xml; convention 3, the tree-facts row and CMD-POSHQC-TEST name it.
+ - **A2 (residual risk, accepted).** Residual Risk 12 records that tree test 4 reads the 911 runbook at its active-folder path, which AC6 names, so the feature-promotion move of that folder must update the test path in the same change.
+- **Revision 3 (2026-09-30, planner, worktree agent-a74dcedbc13b789fd at HEAD 3091b8af985df2410aaf83954825b3ef8a743452).** The branch merged origin/main at merge commit 3091b8af9 (second parent 231e1c0b55105aeb626bf5a6e8d0266a567cacad; 105 commits from main including the analyzer-path hotfix 89e202ed6; clean automatic merge). The plan was authored against HEAD 14177b8cf. Every citation was re-derived against the post-merge tree by reading the files; no task ID changed and the task count stays 56.
+ - **Re-anchored figures (old to new):** QuickFiler.Test/QuickFiler.Test.csproj second altcover import line 535 to 537, line count 568 to 570, post-edit expectation 566 to 568 (P1-T4, P2-T9, P2-T12, D-table, tree facts, CITATION); .github/workflows/README.md row line 115 to 116 (P1-T9, Write Set, tree facts, CITATION); .github/workflows/_pester.yml lines 41 and 45 unchanged in number but now naming three folders each (tests/scripts/hygiene and scripts/hygiene added), lines 47, 51, 64, 71 and 74 to 80 newly cited; .gitignore coverage rule 144 to 150, packages rule 191 to 197, .dotnet-sdk rule 350 to 356, artifacts rule 57 newly cited (conventions 3, P0-T6, tree facts, CITATION); scripts/vscode/Invoke-MSTestWithCoverage.ps1 results-directory lines 283 to 284 became 297 to 298, dotnet-coverage guard 326 to 328 became 344 to 346, "Using vstest.console: " 355 became 373, first-party report 388 became 410, projection 393 to 401 became 415 to 423, summary 417 to 425 became 430 to 447, entry guard 437 became 459 to 461, and line 313 (dot-source of the new Invoke-MSTestWithCoverage.Scope.ps1) is newly cited (P0-T7, tree facts, CITATION); .github/workflows/_build-analyzers.yml and _build-nullable.yml restore-keys lines 57 to 58 no longer exist (line 41 now states "No restore-keys fallback (issue #936)"), so the CI package cache row and both CITATION lines were replaced; the Pester baseline population became 373 tests (131 dependencies, 31 hygiene, 211 vscode) and the local PoshQC population 131 (P0-T15, P0-T16, P1-T2, P1-T3, P1-T7, P1-T11, P2-T3).
+ - **Hotfix-obsoleted work:** the P0-T6 back-fill branch (NUGET-PATH, nuget install, `ANALYZER-ITEM-STATE: skewed-backfilled`, `PRE-EXISTING-OUT-OF-SCOPE-DEFECT:`) is N/A: the census stays, expects UNRESOLVED=0 and `ANALYZER-ITEM-STATE: aligned`, and any UNRESOLVED above 0 stops the run. Evidence: 0 lines match Meziantou.Analyzer.3.0.235 across every *.csproj; 162 Analyzer Include items across 17 files each name a folder the sibling packages.config declares. D8, Residual Risks 1 and 8, the P2-T18 check-off, the P2-T21 index and the AC7 sentence in the header were revised accordingly; AC7's text in issue.md is unchanged.
+ - **P0-T8 marked N/A:** no raw Pester invocation remains, so no Pester module provisioning is needed; the task records a read-only Get-Module listing and the JUnit framework-version property P0-T15 reads.
+ - **P1-T13 removed (coordinator ruling 2026-09-30):** the Meziantou potential entry is not authored; the coordinator checks the skew and files it through the promotion path if it survives. The ID stays as a stub with no action and no artifact. The entry's path was removed from the Write Set, from the P0-T20 remedy sentence, from the P1-T14 and P2-T11 folder lists and the P1-T14 git add pathspec, the P2-T10 and P1-T14 count "nine" became "eight", and the `PROMOTION-HANDOFF:` item was removed from P2-T21.
+ - **PowerShell-gate rewrites (coordinator ruling, LOCAL POWERSHELL GATES block):** CMD-PESTER-ALL and CMD-PESTER-FILE were replaced by CMD-JUNIT-READ (per-file counts from artifacts/pester/pester-junit.xml), CMD-CI-PESTER (figures from a CI Pester job) and a single branch-run locate block (superseded in revision 3.1 by CMD-CI-LIST, CMD-CI-DISPATCH and CMD-CI-WATCH); CMD-POSHQC-ANALYZE lost its paired Invoke-ScriptAnalyzer run, tuple list and multiset comparison (P0-T14, P2-T2); P0-T16 reads the baseline from CI run 36666302259 (head 231e1c0b5, Pester job 109731601928); P2-T3 runs the MCP test locally and reads coverage from the CI run on the pushed head, completing only after CI reports; P1-T14 gained the push; P1-T2, P1-T3, P1-T7, P1-T11 and P2-T8 were re-sourced; every substitution is recorded in the gate artifact by the executor as `GATE-SUBSTITUTION:`.
+ - **CSharpier count handling:** P0-T9 and P2-T4 record the list of *.xml files under artifacts/ and coverage/ (excluding *.cobertura.xml, which .csharpierignore excludes) beside "Checked N", and the P2-T4 gate admits a "Checked N" delta equal to the candidate-count delta or to zero (Residual Risk 10).
+ - **New CI facts folded in:** the hygiene guard (_hygiene.yml) is run locally at P2-T21 before its commit; ci.yml's trigger set means P2-T3 dispatches the workflow on the branch ref when no run exists for the pushed head.
+ - **Unchanged (verified 2026-09-30):** SVGControl files, scripts/dependencies (ConsistencyVerifier.psm1 499 lines, comment at 221 to 223), tests/scripts/dependencies (ConsistencyVerifier.Tests.ps1 312 lines, 12 It blocks, comments at 57 to 59 and 275, It at 228; DependabotConfig.Tests.ps1 17 It blocks, Get-WorkflowStepBlock at 156, AC26 test at 323), dependabot-repair.yml lines 13 to 14, 49 and 51, the 911 runbook (Part B at 99, step 22 at 129 to 132, YAML sample at 152 to 154, citations at 301 and 318), the 911 spec AC18 to AC20 at 506, 512 and 520, .csharpierignore, global.json, Install-RepoDotNetSdk.ps1, Invoke-Restore.ps1, Invoke-VSBuild.ps1 lines 245 and 250 to 253, run-actionlint.ps1, _actionlint.yml line 26, issue.md (work mode at line 12, AC1 to AC7 at 44 to 50).
+
+## Write Set
+
+Every repository file the execution diff creates, modifies or deletes:
+
+- `QuickFiler.Test/QuickFiler.Test.csproj` (modify: delete lines 8 and 537)
+- `SVGControl/app.config` (modify: lines 15 and 19)
+- `.github/workflows/dependabot-repair.yml` (modify: lines 13 to 14 and 51)
+- `.github/workflows/README.md` (modify: line 116)
+- `docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md` (modify: the Part B heading at line 99, steps 10 and 22, the sentence at lines 103 to 106, the YAML sample line 154)
+- `scripts/dependencies/ConsistencyVerifier.psm1` (modify: comment lines 221 to 223, line count held)
+- `tests/scripts/dependencies/ConsistencyVerifier.Tests.ps1` (modify: comments at 57 to 59 and 275, two It blocks added)
+- `tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1` (create)
+- `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/issue.md` (modify: check-offs only)
+- `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/plan.2026-09-28T20-01.md` (modify: check-offs only)
+- `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/` (create; every artifact named in a task line lies under this directory)
+
+Exclusions, by category: no C# source file, no other project file or manifest, no other app.config, no file under the .claude tree, no file under .github/instructions, no file under the config directory, no policy document, no file under docs/features/potential (the Meziantou potential entry of revisions 1 and 2 is not authored; the coordinator files it through the promotion path if the skew survives) and none under docs/features/potential/promoted. The two .csproj.bak copies are not edited. The eight non-feature-folder Write Set paths are the first eight entries above.
+
+## Command Reference
+
+Each block is stated once and cited by name. `` is the executor's worktree root; `` is the merge-base P0-T1 records; `` is the head P0-T1 records before any execution commit; `` is the head P0-T21 records; `` is a ci.yml run id and `` a download folder under the ignored coverage directory, both supplied by the calling task.
+
+**CMD-OUTLOOK** — precondition for the two solution-wide Rebuild commands only. Run Get-Process outlook -ErrorAction SilentlyContinue | Measure-Object | Select-Object -ExpandProperty Count; it must print 0 and the task's artifact records `OUTLOOK-CLOSED: true`. When it is non-zero the task stops and reports; the process is never terminated.
+
+**CMD-CSHARPIER-CHECK** — pwsh -NoProfile -Command 'Set-Location ""; dotnet tool run csharpier check .; "CSHARPIER_EXIT=$LASTEXITCODE"' The artifact's `EXIT_CODE:` is the CSHARPIER_EXIT value. Success prints one line beginning "Checked " and ending "ms." and CSHARPIER_EXIT=0. The check subcommand is read-only: it rewrites no file, so it has no formatter-rewrite branch anywhere in this plan. Every task that runs it also runs, immediately afterwards, pwsh -NoProfile -Command 'Set-Location ""; $root = (Get-Location).Path; $x = @(Get-ChildItem -Path "artifacts","coverage" -Recurse -File -Filter *.xml -ErrorAction SilentlyContinue | Where-Object { $_.Name -notlike "*.cobertura.xml" } | ForEach-Object { [System.IO.Path]::GetRelativePath($root, $_.FullName) } | Sort-Object); "XML-CANDIDATES=$($x.Count)"; $x' and records the count as `XML-CANDIDATES:` with the list. These are the *.xml files under the two ignored trees that .csharpierignore does not exclude (it excludes *.cobertura.xml but names neither artifacts/ nor coverage/); the PoshQC test tool, the coverage runner and the CI artifact downloads create such files between P0-T9 and P2-T4, and whether CSharpier counts gitignored files was not observed, so P2-T4 compares its "Checked N" against P0-T9's through this list rather than assuming either behaviour.
+
+**CMD-MSBUILD-ANALYZERS** — pwsh -NoProfile -Command 'Set-Location ""; msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true "/flp:LogFile=coverage\analyzers.msbuild.log;Verbosity=normal"; "MSBUILD_EXIT=$LASTEXITCODE"; $l = "coverage\analyzers.msbuild.log"; "OUT_LINES=" + @(Select-String -LiteralPath $l -SimpleMatch -Pattern ("/out:obj" + [char]92 + "Debug" + [char]92)).Count; "CS0006_LINES=" + @(Select-String -LiteralPath $l -SimpleMatch -Pattern "CS0006").Count' The artifact's `EXIT_CODE:` is the MSBUILD_EXIT value. The log lands under the coverage directory, which exists on every checkout (coverage/.gitkeep is tracked) and is ignored at .gitignore line 150.
+
+**CMD-MSBUILD-NULLABLE** — pwsh -NoProfile -Command 'Set-Location ""; msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:TreatWarningsAsErrors=true "/flp:LogFile=coverage\nullable.msbuild.log;Verbosity=normal"; "MSBUILD_EXIT=$LASTEXITCODE"; $l = "coverage\nullable.msbuild.log"; "OUT_LINES=" + @(Select-String -LiteralPath $l -SimpleMatch -Pattern ("/out:obj" + [char]92 + "Debug" + [char]92)).Count' The artifact's `EXIT_CODE:` is the MSBUILD_EXIT value; no CS0006 count is required for this build. Do not add a Nullable property and do not substitute the Build target (CLAUDE.md C#1.3). Non-vacuity for both msbuild commands is OUT_LINES, the count of log lines containing the substring /out:obj\Debug\ (built from [char]92 so no backslash crosses the Bash boundary), which must be at least 18 (one per compiled project).
+
+**CMD-MSTEST-COVERAGE** — pwsh -NoProfile -Command 'Set-Location ""; & "\scripts\vscode\Invoke-MSTestWithCoverage.ps1" -SearchRoot .' Success prints "Test Run Successful.", one line beginning "First-party coverage: lines " with both percentages, a line beginning "Coverage projection: " and a line beginning "Test-result summary: ". The projection is written beside the Cobertura output as coverage.cobertura.jacoco.xml and the summary as mstest-coverage-run.summary.txt under the test-results directory; both are copied into the evidence tree by the calling task, the raw documents never. The "Using vstest.console: ", "Coverage output: ", "Coverage projection: ", "Test-result summary: " and "Done. Coverage artifact: " lines (Invoke-MSTestWithCoverage.ps1 lines 373, 375, 423, 447 and 456) each print an absolute path and are recorded with the prefix replaced by its placeholder (convention 4).
+
+**CMD-JUNIT-READ** — pwsh -NoProfile -Command 'Set-Location ""; $p = "artifacts/pester/pester-junit.xml"; $f = Get-Item -LiteralPath $p; "JUNIT-WRITTEN=" + $f.LastWriteTimeUtc.ToString("o"); [xml]$j = Get-Content -LiteralPath $p -Raw; $r = $j.testsuites; "JUNIT-ROOT tests=$($r.tests) failures=$($r.failures) errors=$($r.errors) disabled=$($r.disabled)"; foreach ($s in @($r.testsuite)) { "JUNIT-SUITE " + (Split-Path -Leaf $s.name) + " tests=$($s.tests) failures=$($s.failures) skipped=$($s.skipped)" }; foreach ($c in @(@($r.testsuite) | ForEach-Object { $_.testcase } | Where-Object { $_.status -ne "Passed" })) { "JUNIT-NOTPASSED " + $c.name; if ($c.failure) { "JUNIT-MESSAGE " + [string]$c.failure.message } }' Run immediately after every CMD-POSHQC-TEST call. It reads the JUnit document the test tool wrote (ignored at .gitignore line 57) and prints the root counts, one JUNIT-SUITE line per test file with the leaf name only, and one JUNIT-NOTPASSED line per testcase whose status is not Passed with its failure message. The calling task records `RUN-START:` as the output of pwsh -NoProfile -Command '[DateTime]::UtcNow.ToString("o")' taken before the MCP call and requires JUNIT-WRITTEN to be later than it, so a stale document from an earlier run can never be read. Machine-name, user, cwd and classname values are never transcribed; a JUNIT-MESSAGE line carrying a path is transcribed with the worktree prefix replaced by `` (convention 4). The suite line whose leaf name is the file under test supplies that file's counts; the expected leaf names are AnalyzerItemRepair.Tests.ps1 (13), ConsistencyVerifier.Tests.ps1 (12, then 14 from P1-T3), DependabotConfig.Tests.ps1 (17), PackageCompatibility.Tests.ps1 (8), PackageGraph.Tests.ps1 (32), ProjectConsistency.Tests.ps1 (18), Repair-PackageManifestConsistency.Tests.ps1 (31) and, from P1-T1, RepositoryTreeConsistency.Tests.ps1 (4).
+
+**CMD-CI-PESTER `` ``** — pwsh -NoProfile -Command 'Set-Location ""; $run = gh run view --repo drmoisan/TaskMaster --json databaseId,headSha,headBranch,event,status,conclusion,workflowName | ConvertFrom-Json; "RUN id=$($run.databaseId) head=$($run.headSha) branch=$($run.headBranch) event=$($run.event) status=$($run.status) conclusion=$($run.conclusion) workflow=$($run.workflowName)"; $jobs = @((gh run view --repo drmoisan/TaskMaster --json jobs | ConvertFrom-Json).jobs); $pester = @($jobs | Where-Object { $_.name -like "pester*" }); "PESTER-JOBS=$($pester.Count)"; foreach ($job in $pester) { "JOB id=$($job.databaseId) name=$($job.name) status=$($job.status) conclusion=$($job.conclusion)" }; $esc = [string][char]27; $log = @(gh run view --repo drmoisan/TaskMaster --job $pester[0].databaseId --log) | ForEach-Object { $_ -replace ($esc + "[[][0-9;]*m"), "" }; "LOG-LINES=$($log.Count)"; $log | Select-String -Pattern "Tests Passed: [0-9]+, Failed: [0-9]+", "PESTER Passed=[0-9]+", "COVERAGE LinePercent=[0-9]+" | ForEach-Object { $_.Line }; "DIR-PREEXISTS=" + (Test-Path -LiteralPath ""); gh run download --repo drmoisan/TaskMaster --name pester-coverage --dir ""; "DOWNLOAD-EXIT=$LASTEXITCODE"; $files = @(Get-ChildItem -LiteralPath "" -File -Recurse); "ARTIFACT-FILES=$($files.Count)"; [xml]$d = Get-Content -LiteralPath $files[0].FullName -Raw; $line = @($d.SelectNodes("/report/counter")) | Where-Object { $_.type -eq "LINE" }; "REPORT-LINE covered=$($line.covered) missed=$($line.missed)"; $want = @("AnalyzerItemRepair.psm1","ConsistencyVerifier.psm1","PackageCompatibility.psm1","PackageGraph.psm1","ProjectConsistency.psm1","Repair-PackageManifestConsistency.ps1"); foreach ($sf in @($d.SelectNodes("//sourcefile") | Where-Object { $want -contains (Split-Path -Leaf $_.name) })) { $c = @($sf.SelectNodes("counter")) | Where-Object { $_.type -eq "LINE" }; "SOURCEFILE " + (Split-Path -Leaf $sf.name) + " covered=$($c.covered) missed=$($c.missed)" }' The gh CLI is reached only inside this pwsh invocation (the executor has Bash(pwsh *) and Bash(git *) only). Pester colours each segment of its summary line in the Actions log (observed on job 109731601928 at preflight 2026-09-30), so every captured line has its SGR escape sequences removed before matching; the class [[] matches a literal opening square bracket, so the expression carries no backslash. The three Select-String patterns carry a digit class so the workflow script's own echo in the log (the same literal followed by a dollar sign) does not match; "Tests Passed:" is Pester's summary line, "PESTER Passed=" is _pester.yml line 51 and "COVERAGE LinePercent=" is line 64. The run id is omitted from the --log call because gh ignores it when --job is given. `` is coverage/ci-main-pester-36666302259- at P0-T16 and coverage/ci-branch-pester-- at P2-T3, where is 1 for the first CMD-CI-PESTER invocation against that run and increases by 1 on each further invocation; DIR-PREEXISTS must print False, because a second gh run download into an existing --dir exits 1 with "The file exists.", and gh's error line carries an absolute path and is recorded under convention 4. The artifact holds one file, so ARTIFACT-FILES must be 1. The report LINE counter is read by XPath, as _pester.yml lines 53 to 61 do, because the document's DOCTYPE makes dotted access ambiguous; the percent is covered / (covered + missed) * 100 to two decimals and must equal the log's COVERAGE LinePercent figure, which proves the document is the log's source. Per-file LINE figures come from the sourcefile elements whose leaf name is one of the six scripts/dependencies file names, matched on the leaf so either package shape Pester may write is read; six SOURCEFILE lines are expected (AnalyzerItemRepair.psm1, ConsistencyVerifier.psm1, PackageCompatibility.psm1, PackageGraph.psm1, ProjectConsistency.psm1, Repair-PackageManifestConsistency.ps1). Pester emits no branch counter, so no PowerShell branch figure is claimed anywhere in this plan. The downloaded document is a raw JaCoCo document and stays under the coverage directory; only its figures are transcribed.
+
+**CMD-CI-LIST** — pwsh -NoProfile -Command 'Set-Location ""; $head = (git rev-parse HEAD).Trim(); "HEAD=$head"; $remote = (git ls-remote --heads origin bug/package-manifest-consistency-residuals-929).Trim(); "REMOTE=$remote"; $runs = @(gh run list --repo drmoisan/TaskMaster --workflow ci.yml --branch bug/package-manifest-consistency-residuals-929 --limit 50 --json databaseId,headSha,status,conclusion,event | ConvertFrom-Json | Where-Object { $_.headSha -eq $head } | Sort-Object -Property databaseId -Descending); "RUNS-FOR-HEAD=$($runs.Count)"; foreach ($r in $runs) { "RUN id=$($r.databaseId) head=$($r.headSha) event=$($r.event) status=$($r.status) conclusion=$($r.conclusion)" }' Lists the ci.yml runs for the current HEAD on this branch, greatest databaseId first. REMOTE must name HEAD, which proves the head was pushed before any dispatch. The --json list carries no timestamp field and the RUN line no timestamp value, under the convention 1 rule on the character sequence the pr-author hook refuses; ordering by databaseId supplies the recency the timestamp would have.
+
+**CMD-CI-DISPATCH** — pwsh -NoProfile -Command 'Set-Location ""; gh workflow run ci.yml --repo drmoisan/TaskMaster --ref bug/package-manifest-consistency-residuals-929; "DISPATCH-EXIT=$LASTEXITCODE"' ci.yml triggers on push only for main and development and otherwise on pull_request and workflow_dispatch (lines 3 to 8), so a push of this branch starts no run by itself. Rule: P2-T3 runs CMD-CI-LIST once. When RUNS-FOR-HEAD is 0 it runs CMD-CI-DISPATCH exactly once per pushed head; DISPATCH-EXIT must be 0, and a non-zero value stops the task with a report (Residual Risk 11). It then re-runs CMD-CI-LIST, never CMD-CI-DISPATCH, until RUNS-FOR-HEAD is at least 1, recording each re-run. The selected run is the first listed (greatest databaseId). CMD-CI-WATCH is re-invoked unchanged when the tool call times out, until it returns on its own; CMD-CI-PESTER then runs once. When CMD-CI-PESTER's RUN line reads conclusion=cancelled, the task re-runs CMD-CI-LIST, selects the greatest databaseId and watches that run, because a cancelled selection is a run superseded under ci.yml lines 13 to 15 (concurrency group keyed on the ref with cancel-in-progress true), not a test outcome. When a pull request for this branch already exists, its pull_request-event run for the same head SHA satisfies RUNS-FOR-HEAD and no dispatch is made.
+
+**CMD-CI-WATCH** — pwsh -NoProfile -Command 'Set-Location ""; gh run watch --repo drmoisan/TaskMaster --interval 60; "WATCH-EXIT=$LASTEXITCODE"' gh's own blocking poll (convention 6); each invocation is recorded.
+
+**CMD-POSHQC-FORMAT** — MCP tool mcp__drm-copilot__run_poshqc_format with workspace_root set to `` and scan_folders supplied explicitly as ["scripts/dependencies","tests/scripts/dependencies"]. The scan set must be explicit because no config/poshqc-scan.json exists. The tool exits 0 whether or not it rewrote anything, so its observation is a SHA-256 hash set taken before and after over every .ps1, .psm1 and .psd1 file under the two folders, plus git status --porcelain --untracked-files=all over the two folders.
+
+**CMD-POSHQC-ANALYZE** — MCP tool mcp__drm-copilot__run_poshqc_analyze with the same workspace_root and scan_folders. Its payload carries ok, tool, workspace_root and summary and no count, file list or diagnostic. Under convention 11 an ok value of true is the lint result and is recorded verbatim together with the exact line "PoshQC analyze: pass (0 findings); tool reports no count"; an ok value of false (or a payload without ok) is recorded verbatim and the task stops with a report (Phase 0) or fails the loop step (Phase 2). No Invoke-ScriptAnalyzer run, tuple list or count comparison exists anywhere in this plan; the executor records `GATE-SUBSTITUTION: PoshQC analyze ok flag stands in for a diagnostic count` in each analyze artifact.
+
+**CMD-POSHQC-TEST** — MCP tool mcp__drm-copilot__run_poshqc_test with workspace_root set to `` and scan_folders ["tests/scripts/dependencies"]. Its payload carries ok, tool, workspace_root and summary only; it also writes artifacts/pester/pester-junit.xml, artifacts/pester/powershell-coverage.xml and artifacts/pester/powershell-coverage.koverage.xml under the worktree (all three ignored at .gitignore line 57; the coverage document's counters read 0 covered and neither coverage document is ever a coverage source). Every test task records `RUN-START:` before the call, the payload verbatim after it, then runs CMD-JUNIT-READ and derives every count from its lines; `EXIT_CODE:` is 0 when ok is true and JUNIT-ROOT failures is 0, and 1 otherwise, with the ok value recorded beside it, so a task that expects red tests carries `ExpectedExitCode: 1`. Coverage is never read from this route: P0-T16 and P2-T3 read it from CI through CMD-CI-PESTER. The three XML files it writes are counted by CMD-CSHARPIER-CHECK's XML-CANDIDATES list.
+
+**CMD-ACTIONLINT** — pwsh -NoProfile -Command 'Set-Location ""; & ".\actionlint-bin\actionlint.exe" -version; & ".\actionlint-bin\actionlint.exe" ".github/workflows/dependabot-repair.yml"; "SCOPED_EXIT=$LASTEXITCODE"; & ".\scripts\dev-tools\run-actionlint.ps1"; "REPO_EXIT=$LASTEXITCODE"' Success prints the version line, then nothing from either lint invocation, then SCOPED_EXIT=0 and REPO_EXIT=0. The run-actionlint.ps1 script throws when the binary is absent, so an empty capture with both exits 0 and a version line present is the success-case observation.
+
+**CMD-VERIFIER-WHATIF** — pwsh -NoProfile -Command 'Set-Location ""; $files = @(Get-ChildItem -Path "*/packages.config","*/app.config","*/*.csproj" -File); $before = @($files | Get-FileHash -Algorithm SHA256 | ForEach-Object { $_.Hash }) -join ","; $r = & ".\scripts\dependencies\Repair-PackageManifestConsistency.ps1" -WhatIf; $after = @($files | Get-FileHash -Algorithm SHA256 | ForEach-Object { $_.Hash }) -join ","; "ABSENT=$($r.AbsentFromManifestCount) DISAGREE=$($r.VersionDisagreementCount) WRITTEN=$(@($r.WrittenPath).Count) SUCCESS=$($r.IsSuccess) PROJECTS=$($r.ExaminedProjectCount) FILES=$($files.Count) HASHES_EQUAL=$($before -eq $after)"' A read-only run: every write is behind ShouldProcess and the normalisation receives -WhatIf explicitly (script lines 443 to 446). HASHES_EQUAL=True is the non-write assertion and FILES must be at least 50 (18 project files, 18 manifests, 17 app.config files). The -WhatIf messages name absolute target paths and are recorded with the prefix replaced by its placeholder (convention 4). DISAGREE is computed over the in-memory repaired project text (script lines 411 to 422), so it carries no expectation anywhere in this plan.
+
+**CMD-REDIRECT-OBSERVE** — pwsh -NoProfile -Command 'Set-Location ""; Import-Module ".\scripts\dependencies\ProjectConsistency.psm1"; $t = [System.IO.File]::ReadAllText((Join-Path (Get-Location).Path "SVGControl/app.config")); $f = Invoke-BindingRedirectReconciliation -AppConfigText $t -AssemblyName "Fizzler" -AssemblyVersion "1.3.1.0"; $u = Invoke-BindingRedirectReconciliation -AppConfigText $t -AssemblyName "System.Runtime.CompilerServices.Unsafe" -AssemblyVersion "6.0.3.0"; "FIZZLER_REPAIRS=$(@($f.Repair).Count) UNSAFE_REPAIRS=$(@($u.Repair).Count) EXAMINED=$($f.ExaminedCount)"' The function is pure over text and writes nothing; the path is made absolute because a .NET file API resolves a relative path against the process directory, which Set-Location does not change; EXAMINED must be 4 (the file's four dependentAssembly blocks).
+
+**CMD-HYGIENE ``** — pwsh -NoProfile -Command 'Set-Location ""; $acct = Split-Path -Leaf $env:USERPROFILE; $machine = [System.Environment]::MachineName; $root = (Get-Location).Path; $bs = [regex]::Escape([string][char]92); $pattern = @(("(^|[^A-Za-z0-9_-])[A-Za-z]:" + $bs), ("(^|[^A-Za-z0-9])" + [regex]::Escape($acct) + "([^A-Za-z0-9]|$)"), ("(^|[^A-Za-z0-9])" + [regex]::Escape($machine) + "([^A-Za-z0-9]|$)")); $ext = @(".md",".txt",".xml",".yml",".ps1",".psm1"); $files = @(Get-ChildItem -Recurse -File -Path | Where-Object { $ext -contains $_.Extension }); $hits = @($files | Select-String -Pattern $pattern | Where-Object { $_.Line -notmatch "https?://" }); "PATTERNS=" + $pattern.Count; "SELFTEST=" + @(("Q:" + [string][char]92 + "x") | Select-String -Pattern $pattern).Count; "SELFTEST_NEG=" + @(("client-id:" + [string][char]92 + "s") | Select-String -Pattern $pattern).Count; "SCANNED=$($files.Count) HITS=$($hits.Count)"; $hits | ForEach-Object { [System.IO.Path]::GetRelativePath($root, $_.Path) + ":" + $_.LineNumber }' The drive-letter pattern requires a backslash after the colon so URLs do not match it, and a hit on a line carrying an https URL is excluded because the account-name pattern would otherwise flag a repository owner segment. PATTERNS must be 3, SELFTEST must be 1, SELFTEST_NEG must be 0, HITS must be 0 and SCANNED at least 1; every task that cites CMD-HYGIENE inherits all five conditions. Each concatenated element of the pattern array is parenthesised because the PowerShell comma operator binds more tightly than +, so an unparenthesised element splits into its fragments and the boundary fragments match every line; PATTERNS=3 and SELFTEST_NEG=0 fail when that happens. The drive-letter element also requires the letter to follow the start of the line or a character other than a letter, digit, underscore or hyphen, so a YAML-key regex such as the client-id pattern in P1-T1 (a key, a colon, then a backslash escape) does not match it; SELFTEST_NEG exercises that case. Hit locations are printed relative to the worktree root so the listing itself carries no host path. The drive-letter pattern is built from [char]92 because a doubled backslash is de-doubled between Bash and pwsh, which leaves a pattern that cannot match a backslash path. The account and machine values are derived at run time and are never written into any artifact.
+
+**CMD-FOOTPRINT** — git diff --name-only -- . together with git status --porcelain --untracked-files=all, both captured verbatim. It is anchored at because the branch already carries the promotion commit, whose promoted record under docs/features/potential/promoted lies outside the Write Set and the feature folder.
+
+### Phase 0 — Baseline Capture
+
+- [x] [P0-T1] Anchor the run: from `` run git rev-parse --show-toplevel, git rev-parse --abbrev-ref HEAD, git fetch origin main, git rev-parse origin/main, git merge-base origin/main HEAD (recorded as ``), git rev-parse HEAD (recorded as ``), git rev-list --count ..HEAD (recorded as measured, no literal asserted), git merge-base --is-ancestor 231e1c0b55105aeb626bf5a6e8d0266a567cacad HEAD followed by its exit code (recorded as `MERGED-MAIN-ANCESTOR:`; 0 proves the worktree carries the 2026-09-30 merge of origin/main, and 1 or 128 stops the task with a report because every re-anchored figure in this plan describes the post-merge tree), git status --porcelain --untracked-files=all (recorded verbatim as `BASE-UNTRACKED:`), git ls-files -- "*.csproj.bak" (recorded verbatim as `BAK-TRACKED:`), and git diff --name-only HEAD -- QuickFiler.Test/QuickFiler.Test.csproj SVGControl/app.config .github/workflows/dependabot-repair.yml .github/workflows/README.md docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md scripts/dependencies/ConsistencyVerifier.psm1 tests/scripts/dependencies/ConsistencyVerifier.Tests.ps1; write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t1-worktree-anchor.2026-09-28T20-01.md`. Acceptance: the recorded branch is exactly bug/package-manifest-consistency-residuals-929; `` and `` are each 40 hexadecimal characters and git cat-file -t on each prints commit; the seven-path diff against HEAD is empty (none of the files this plan edits is already modified); `BASE-UNTRACKED:` contains no entry matching *.cs, *.csproj, packages.config or app.config; `BAK-TRACKED:` is recorded whether empty or not; the show-toplevel output is recorded as ``, never as its value. Fails when the branch name differs or any Write Set source file is already dirty.
+
+- [x] [P0-T2] Read the policy documents in the order fixed by the policy-compliance-order skill — CLAUDE.md, .claude/rules/general-code-change.md, .claude/rules/general-unit-test.md, .claude/rules/powershell.md, .claude/rules/csharp.md, .claude/rules/quality-tiers.md, .claude/rules/tonality.md, .claude/rules/ci-workflows.md, .claude/rules/plan-acceptance-gates.md, then the skills .claude/skills/atomic-plan-contract/SKILL.md, .claude/skills/evidence-and-timestamp-conventions/SKILL.md and .claude/skills/acceptance-criteria-tracking/SKILL.md — and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/phase0-instructions-read.2026-09-28T20-01.md` carrying `Timestamp:`, `Policy Order:` and the explicit list of the twelve files read, each with its line count. Acceptance: twelve files are listed in that order, each with a non-zero integer line count, and the artifact records that issue.md carries `- Work Mode: minor-audit` at line 12 and a `## Acceptance Criteria` heading with exactly 7 checkbox lines matching `^- \[ \] AC\d+:` beneath it, that no spec.md, user-story.md or research.md exists in the feature folder, and the coverage-floor conflict of convention 10 with its issue number 668.
+
+- [x] [P0-T3] Provision the repository-pinned .NET SDK with the guarded form pwsh -NoProfile -Command 'Set-Location ""; if (-not (Test-Path ".dotnet-sdk\sdk")) { & ".\scripts\vscode\Install-RepoDotNetSdk.ps1" }; dotnet --version; dotnet --list-sdks' and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t3-sdk-bootstrap.2026-09-28T20-01.md`. Acceptance: dotnet --version prints 8.0.205, and dotnet --list-sdks prints a line of the form 8.0.205 [] in which the bracketed path names the sdk folder under the repository-root .dotnet-sdk folder (the path segments .dotnet-sdk\sdk are the last two before the closing square bracket; the install location is Install-RepoDotNetSdk.ps1 line 36 and global.json line 7); that line is recorded with the worktree prefix inside the brackets replaced by ``, so the recorded form reads 8.0.205 [\.dotnet-sdk\sdk]; every other SDK line the command prints (a machine-wide install) is recorded with its bracketed prefix replaced by `` or `` under convention 4, so the artifact carries no host path. Fails when dotnet prints the global.json errorMessage instead of a version, the state of a fresh worktree.
+
+- [x] [P0-T4] Run pwsh -NoProfile -Command 'Set-Location ""; dotnet tool restore; "TOOL_RESTORE_EXIT=$LASTEXITCODE"' and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t4-tool-restore.2026-09-28T20-01.md`. Acceptance: `EXIT_CODE: 0`, the TOOL_RESTORE_EXIT value, and the `Output Summary:` names csharpier at version 1.2.6, the version the repository-root dotnet-tools.json pins.
+
+- [x] [P0-T5] Restore NuGet packages with pwsh -NoProfile -Command 'Set-Location ""; $before = @(Get-ChildItem -Path ".\packages" -Directory -ErrorAction SilentlyContinue).Count; "PACKAGE_DIRS_BEFORE=$before"; & ".\scripts\vscode\Invoke-Restore.ps1"; "RESTORE_EXIT=$LASTEXITCODE"; $after = @(Get-ChildItem -Path ".\packages" -Directory).Count; "PACKAGE_DIRS_AFTER=$after"' and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t5-package-restore.2026-09-28T20-01.md`. Acceptance: the restore output contains "Build succeeded." and "0 Error(s)"; PACKAGE_DIRS_AFTER is an integer greater than 100 and not lower than PACKAGE_DIRS_BEFORE; PACKAGE_DIRS_BEFORE is recorded as measured (0 in a fresh worktree, which is the cold state AC7 names); the script's "Using MSBuild: " line is recorded with its absolute path replaced by `` (convention 4). The artifact also records `ALTCOVER-RESTORED:` as the boolean Test-Path of packages\altcover.8.6.45 after the restore; a restore cannot produce that folder because no manifest declares the package, so True means a lingering folder and is recorded, not asserted.
+
+- [x] [P0-T6] Census every Analyzer Include item for resolvability (the back-fill branch of revisions 1 and 2 is N/A after the origin/main merge; the census stays because it is the evidence): run pwsh -NoProfile -Command 'Set-Location ""; $items = @(); foreach ($p in @(git ls-files -- "*.csproj")) { $dir = Split-Path -Parent $p; foreach ($line in (Get-Content -LiteralPath $p)) { if ($line -match "Analyzer Include=""([^""]+)""") { $rel = $Matches[1]; $items += [pscustomobject]@{ Project = $p; Item = $rel; Resolves = (Test-Path -LiteralPath (Join-Path $dir $rel)) } } } }; "ANALYZER_ITEMS=$($items.Count) FILES=$(@($items | Select-Object -ExpandProperty Project -Unique).Count) UNRESOLVED=$(@($items | Where-Object { -not $_.Resolves }).Count)"; "SKEW_235=" + @(git grep -n "Meziantou.Analyzer.3.0.235" -- "*.csproj").Count; $items | Where-Object { -not $_.Resolves } | ForEach-Object { $_.Project + " " + $_.Item }' and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t6-analyzer-item-census.2026-09-28T20-01.md`. Acceptance: ANALYZER_ITEMS is exactly 162 and FILES exactly 17 (re-derived by the planner on 2026-09-30 on the post-merge tree); UNRESOLVED is exactly 0 and SKEW_235 is exactly 0; the artifact carries exactly one line `ANALYZER-ITEM-STATE: aligned` and the sentence "No back-fill was performed and none is permitted by this plan; the AC7 back-fill clause is not exercised."; it states that the packages tree is ignored at .gitignore line 197 and that the restore of P0-T5 is the only step that populated it. An UNRESOLVED or SKEW_235 value above 0 stops the run with a report listing every unresolved (project, item) pair: it would describe a tree the coordinator did not measure on 2026-09-30, no nuget back-fill exists in this plan, and every Rebuild below would fail CS0006 for a cause outside this issue. Decision D8 governs.
+
+- [x] [P0-T7] Provision the dotnet-coverage global tool with pwsh -NoProfile -Command 'Set-Location ""; if (-not (Get-Command dotnet-coverage -ErrorAction SilentlyContinue)) { dotnet tool install --global dotnet-coverage }; (Get-Command dotnet-coverage).Source' and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t7-dotnet-coverage.2026-09-28T20-01.md`. Acceptance: Get-Command resolves to a path (recorded with the user-profile prefix replaced by the placeholder); fails when it does not, because the coverage runner throws before running anything when the tool is absent (Invoke-MSTestWithCoverage.ps1 lines 344 to 346).
+
+- [x] [P0-T8] N/A (revision 3, 2026-09-30): Pester module provisioning is not needed because no raw Pester invocation remains in this plan; every test run goes through mcp__drm-copilot__run_poshqc_test, which loads its own Pester (the JUnit document's framework-version property, read at P0-T15, records the version it used). The executor records the read-only observation pwsh -NoProfile -Command 'Set-Location ""; Get-Module Pester -ListAvailable | Select-Object Name,Version | Format-Table -AutoSize | Out-String' (no Install-Module is run) and writes `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t8-pester-provision.2026-09-28T20-01.md` carrying `Timestamp:`, `Command:`, `EXIT_CODE:` (the listing command's exit code, expected 0), `Output Summary:` (the listing as printed, plus the line `N/A: no raw Pester invocation in this plan; the MCP test route supplies its own Pester`) and `GATE-SUBSTITUTION: Pester provisioning replaced by the PoshQC MCP test route`. Acceptance: the artifact exists with those fields; the listing content carries no expectation and is recorded as measured. The checkbox is ticked only once the artifact exists.
+
+- [x] [P0-T9] Capture the C# formatter baseline by running CMD-CSHARPIER-CHECK and writing `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t9-csharpier-check.2026-09-28T20-01.md`. Acceptance: `EXIT_CODE:` recorded as the CSHARPIER_EXIT value the command prints; the verbatim "Checked N files in Xms." line recorded with N as an integer greater than 900; `XML-CANDIDATES:` recorded as the count and the sorted list the CMD-CSHARPIER-CHECK companion command prints (the empty case as `XML-CANDIDATES: 0`); the full list of any files reported with findings recorded as `CSHARPIER-FINDINGS:` (expected empty, recorded as `CSHARPIER-FINDINGS: none`; a non-empty list is recorded with each path repository-relative and reported, not fixed, because no C# file is in the Write Set, and P2-T4 compares against it). Fails when no "Checked " line is present.
+
+- [x] [P0-T10] Capture the analyzer-build baseline: satisfy CMD-OUTLOOK, run CMD-MSBUILD-ANALYZERS, and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t10-msbuild-analyzers.2026-09-28T20-01.md` carrying `OUTLOOK-CLOSED: true` and the MSBUILD_EXIT, OUT_LINES and CS0006_LINES lines the command prints. Acceptance: `EXIT_CODE: 0` (the recorded MSBUILD_EXIT value), CS0006_LINES exactly 0, OUT_LINES at least 18 with the exact integer recorded, and the msbuild summary line "0 Error(s)" quoted. A non-zero exit stops the run with the first error line quoted verbatim: with P0-T6 green the only remaining causes are outside this issue and no later task can pass.
+
+- [x] [P0-T11] Capture the nullable-build baseline: satisfy CMD-OUTLOOK, run CMD-MSBUILD-NULLABLE, and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t11-msbuild-nullable.2026-09-28T20-01.md` carrying `OUTLOOK-CLOSED: true` and the MSBUILD_EXIT and OUT_LINES lines the command prints. Acceptance: `EXIT_CODE: 0` (the recorded MSBUILD_EXIT value), OUT_LINES at least 18 with the exact integer recorded, and "0 Error(s)" quoted. A non-zero exit stops the run with the first error line quoted verbatim.
+
+- [x] [P0-T12] Capture the C# test and coverage baseline by running CMD-MSTEST-COVERAGE and writing `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t12-mstest-coverage.2026-09-28T20-01.md`; copy the file the run printed after "Coverage projection: " to `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t12-coverage-projection.2026-09-28T20-01.jacoco.xml` and the file printed after "Test-result summary: " to `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t12-test-results.2026-09-28T20-01.summary.txt`. Acceptance: `EXIT_CODE: 0`; the "First-party coverage: lines A/B (L%), branches C/D (R%)" line quoted verbatim with L and R recorded as the numeric baseline percentages; the summary's total, passed and failed counts recorded with failed 0 and passed greater than 0; both copies made and their byte sizes recorded; the sum of the projection's package LINE covered counters equals A (the reconciliation that proves the copy describes this run); `MEETS-85:` recorded as true when L is at least 85 and false otherwise, an observation only under convention 10; the "Using vstest.console: ", "Coverage output: ", "Coverage projection: ", "Test-result summary: " and "Done. Coverage artifact: " lines (Invoke-MSTestWithCoverage.ps1 lines 373, 375, 423, 447 and 456) recorded with their absolute paths replaced by placeholders (convention 4); and the artifact states that the raw Cobertura and trx documents stay under the ignored coverage directory and are not copied; the projection copy's root element is report and it carries no class, sourcefile, method or line element (Select-String over the copy for the patterns " every path whose hash changed and that is not a Write Set member, record `VERIFIER-LINES:` as @(Get-Content -LiteralPath "scripts/dependencies/ConsistencyVerifier.psm1").Count after the run, and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t13-poshqc-format.2026-09-28T20-01.md`. Acceptance: both hash sets recorded with exactly 13 entries each (6 production files, 7 test files); the rewrite count derived from the hash difference recorded as an integer; the exact scan_folders value recorded; `REVERT-SET:` recorded explicitly, including the empty case as `REVERT-SET: empty`; `FORMAT-REWROTE-WRITE-SET:` recorded as the list of Write Set members the run rewrote, or as none; the post-revert porcelain over the two folders lists nothing but Write Set members; `VERIFIER-LINES:` recorded as an integer at most 500 (expected 499); and the MCP payload's ok value recorded but not asserted. The empty pre-revert case is the expected truthful result and is not a failure; a post-revert porcelain that still lists a reverted path is.
+
+- [x] [P0-T14] Capture the PowerShell analyzer baseline: run CMD-POSHQC-ANALYZE, then pwsh -NoProfile -Command 'Set-Location ""; "FILES=" + @(Get-ChildItem -Recurse -File -Path "scripts/dependencies","tests/scripts/dependencies" -Include *.ps1,*.psm1).Count' and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t14-poshqc-analyze.2026-09-28T20-01.md`. Acceptance: the MCP payload (ok, tool, workspace_root, summary, any stderr excerpt) recorded verbatim with the exact scan_folders value; ok is true and the artifact carries the exact line "PoshQC analyze: pass (0 findings); tool reports no count" and `EXIT_CODE: 0`; FILES recorded as exactly 13 (6 production, 7 test files); `GATE-SUBSTITUTION: PoshQC analyze ok flag stands in for a diagnostic count` recorded. An ok value of false is recorded verbatim with the summary and stderr excerpt and stops the run with a report: the pre-change folders are expected clean (the 911 close-out measured every finding in scripts/vscode, outside this scan set) and a red baseline here is a cause outside this issue. No Invoke-ScriptAnalyzer run, tuple list or route comparison is made.
+
+- [x] [P0-T15] Record the MCP test-route baseline and the local per-file test counts: record `RUN-START:`, run CMD-POSHQC-TEST, run CMD-JUNIT-READ, and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t15-poshqc-test-mcp.2026-09-28T20-01.md`. Acceptance: the payload's ok value and summary recorded verbatim; JUNIT-WRITTEN later than RUN-START (the document was written by this run); JUNIT-ROOT reads tests=131 failures=0 errors=0 (the 131 It blocks under tests/scripts/dependencies re-derived by the planner on 2026-09-30) and `EXIT_CODE: 0` under the CMD-POSHQC-TEST rule; exactly 7 JUNIT-SUITE lines, among them ConsistencyVerifier.Tests.ps1 tests=12 failures=0 and DependabotConfig.Tests.ps1 tests=17 failures=0, and no JUNIT-NOTPASSED line; the JUnit document's framework-version property value recorded as `PESTER-VERSION:` (read with pwsh -NoProfile -Command 'Set-Location ""; [xml]$j = Get-Content -LiteralPath "artifacts/pester/pester-junit.xml" -Raw; @($j.testsuites.testsuite)[0].properties.property | Where-Object { $_.name -eq "framework-version" } | ForEach-Object { $_.value }'; expected 5.6.1, recorded as measured); the artifact states that this route reports no coverage figure and that P0-T16 reads coverage from CI, and carries `GATE-SUBSTITUTION: JUnit per-file counts stand in for a direct Pester run`. A different tests total or a non-zero failures value is recorded and stops the run with a report.
+
+- [x] [P0-T16] Capture the Pester coverage baseline from the CI run on main that the branch merged: run CMD-CI-PESTER with `` 36666302259 and `` coverage/ci-main-pester-36666302259- ( is 1 for the first invocation and increases by 1 on each further invocation), and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t16-pester.2026-09-28T20-01.md` carrying `Timestamp:`, `Command:`, `EXIT_CODE:` (the pwsh invocation's exit code, expected 0) and `Output Summary:`. Acceptance: the RUN line records head=231e1c0b55105aeb626bf5a6e8d0266a567cacad, branch=main, status=completed, conclusion=success and workflow=CI, and the artifact records `git merge-base --is-ancestor 231e1c0b55105aeb626bf5a6e8d0266a567cacad HEAD` exiting 0 (the run's head is an ancestor of the executor's HEAD, so the baseline describes code this branch carries); PESTER-JOBS=1 with JOB id=109731601928 and conclusion=success; the "Tests Passed: N, Failed: N, Skipped: N, ..." line, the "PESTER Passed=... Failed=... Skipped=... Total=..." line and the "COVERAGE LinePercent=... Covered=... Total=..." line each quoted verbatim from the log, with Failed 0, Skipped 0 and Total greater than 300; `BASELINE-TOTAL:` recorded as Passed plus Failed plus Skipped from the PESTER line and equal to its Total field; the report LINE percent computed to two decimals from REPORT-LINE, equal to the log's LinePercent figure and at least 80; DIR-PREEXISTS=False, DOWNLOAD-EXIT=0 and ARTIFACT-FILES=1, with the `` value used recorded; `MEETS-85:` recorded as true when the percent is at least 85 and false otherwise, an observation only under convention 10; the six SOURCEFILE lines recorded as covered and missed integers, the ConsistencyVerifier.psm1 pair recorded as `VERIFIER-COVERED:` and `VERIFIER-MISSED:`; the run id and head SHA recorded beside every figure; the artifact states that Pester emits no branch counter, that the figures stand in for a permitted evidence form the committed-evidence section does not define for the Pester route, that the downloaded JaCoCo document stays under the ignored coverage directory, and `GATE-SUBSTITUTION: CI Pester job 109731601928 stands in for a local coverage run`. The coordinator measured Tests Passed 373, LinePercent 94.51, Covered 1721 and Total 1821 on 2026-09-30; a differing figure printed by the run is recorded as `TRANSCRIPTION-MISMATCH:` with both values and the run's own figure governs every later comparison. A run whose head, status or conclusion differs from the values above stops the task with a report.
+
+- [x] [P0-T17] Record the pre-fix altcover state and the read-only verifier baseline: run pwsh -NoProfile -Command 'Set-Location ""; $m = @(git grep -i -n altcover -- "*.csproj" "*/packages.config"); "ALTCOVER_LINES=$($m.Count)"; $m' then CMD-VERIFIER-WHATIF, and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t17-altcover-and-verifier-prefix.2026-09-28T20-01.md`. Acceptance: ALTCOVER_LINES is exactly 2 and both lines name QuickFiler.Test/QuickFiler.Test.csproj at lines 8 and 537; the what-if run prints ABSENT=2, WRITTEN=0, HASHES_EQUAL=True, PROJECTS=18 and FILES at least 50; DISAGREE and SUCCESS are recorded as measured, with no expectation stated for either: DISAGREE may be 0, because Get-ProjectVerification runs over the in-memory repaired project text (Repair-PackageManifestConsistency.ps1 lines 411 to 422) rather than over the tree; the "Manifest discovery" information line is quoted; every -WhatIf target path is recorded with its prefix replaced by ``.
+
+- [x] [P0-T18] Record the pre-fix redirect state: quote SVGControl/app.config lines 15 and 19 and SVGControl/SVGControl.csproj lines 58 and 82 verbatim; run pwsh -NoProfile -Command 'Set-Location ""; "FIZZLER_ASM=" + [System.Reflection.AssemblyName]::GetAssemblyName((Resolve-Path "packages/Fizzler.1.3.1/lib/netstandard2.0/Fizzler.dll").Path).Version; "UNSAFE_ASM=" + [System.Reflection.AssemblyName]::GetAssemblyName((Resolve-Path "packages/System.Runtime.CompilerServices.Unsafe.6.1.2/lib/net462/System.Runtime.CompilerServices.Unsafe.dll").Path).Version'; run CMD-REDIRECT-OBSERVE; run pwsh -NoProfile -Command 'Set-Location ""; foreach ($f in @(Get-ChildItem -Path "*/app.config" -File)) { $t = [System.IO.File]::ReadAllText($f.FullName); $m = [regex]::Match($t, "(?s)name=""Fizzler"".*?newVersion=""([^""]+)"""); if ($m.Success) { $f.Directory.Name + " Fizzler " + $m.Groups[1].Value } }'; write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t18-redirect-prefix.2026-09-28T20-01.md`. Acceptance: FIZZLER_ASM is 1.3.1.0 and UNSAFE_ASM is 6.0.3.0 (these confirm the issue's version claims against the restored assemblies and are what AC2 and AC3 name); FIZZLER_REPAIRS=1, UNSAFE_REPAIRS=1, EXAMINED=4 (the pre-fix drift as the reconciliation function sees it); the tree-wide Fizzler list records exactly 13 configs, 12 at 1.3.0.0 and UtilitiesCS at 1.3.1.0, with the 11 configs other than SVGControl and UtilitiesCS labelled `OUT-OF-SCOPE-RESIDUAL:` (SVGControl is the in-scope AC2 target; UtilitiesCS already names 1.3.1.0) with a citation of docs/features/potential/2026-08-04-stale-fizzler-and-unsafe-binding-redirects.md; a different tree-wide count is recorded and reported, not absorbed.
+
+- [x] [P0-T19] Record the pre-fix workflow, runbook and README state and the actionlint baseline: run pwsh -NoProfile -Command 'Set-Location ""; $w = Get-Content ".github/workflows/dependabot-repair.yml"; "WF_APPID=" + @($w | Select-String -Pattern "^\s+app-id:").Count; "WF_CLIENTID=" + @($w | Select-String -Pattern "^\s+client-id:").Count; $rb = Get-Content "docs/features/active/2026-09-19-dependabot-fanout-and-ci-failing-nuget-upgrades-911/runbooks/github-app-installation-token.runbook.md"; "RB_APPID=" + @($rb | Select-String -Pattern "^\s+app-id:").Count; "RB_CLIENTID=" + @($rb | Select-String -Pattern "^\s+client-id:").Count; "RB_PARTB=" + @($rb | Select-String -SimpleMatch -Pattern "Record the App ID").Count; "README_NUMERIC=" + @(Get-Content ".github/workflows/README.md" | Select-String -Pattern "numeric App identifier").Count' then CMD-ACTIONLINT, and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t19-workflow-prefix-and-actionlint.2026-09-28T20-01.md`. Acceptance: WF_APPID=1, WF_CLIENTID=0, RB_APPID=1, RB_CLIENTID=0, RB_PARTB=1 (the Part B heading at line 99), README_NUMERIC=1; the actionlint version line quoted verbatim; SCOPED_EXIT=0 and REPO_EXIT=0 with the lint output recorded as empty (the baseline tree lints clean; the deprecation is a runtime warning of the action, not a lint finding); the CI version 1.7.7 from .github/workflows/_actionlint.yml line 26 recorded beside the local version.
+
+- [x] [P0-T20] Run CMD-HYGIENE with `` set to "docs/features/active/2026-09-28-package-manifest-consistency-residuals-929" and write `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t20-hygiene.2026-09-28T20-01.md`. Acceptance: PATTERNS=3, SELFTEST=1, SELFTEST_NEG=0, HITS=0 and SCANNED at least 20 (the Phase 0 artifacts plus issue.md and the plan); the hit listing, when non-empty before a fix, is recorded as printed (repository-relative). Remedy: a hit in a file this plan's execution authored (every artifact under the evidence tree, and from Phase 1 on the Write Set text files) is fixed by replacing the leaked value with its placeholder in the offending file and re-running CMD-HYGIENE until HITS=0, with the pre-fix hit count recorded in the artifact as `PRE-FIX-HITS:` (0 when no fix was needed); a hit in a scanned file the execution did not author (issue.md and this plan file, whose only permitted edits are check-offs) stops the task with a report naming the file and line. Every later task that cites CMD-HYGIENE applies this same remedy.
+
+- [x] [P0-T21] Commit the Phase 0 evidence, plus any Write Set member P0-T13 listed under `FORMAT-REWROTE-WRITE-SET:`, with git add -- docs/features/active/2026-09-28-package-manifest-consistency-residuals-929 and git commit -m "docs(929): phase 0 baseline evidence" -- docs/features/active/2026-09-28-package-manifest-consistency-residuals-929 , then record git rev-parse HEAD (recorded as ``) and git status --porcelain --untracked-files=all in `docs/features/active/2026-09-28-package-manifest-consistency-residuals-929/evidence/baseline/p0-t21-commit.2026-09-28T20-01.md`. Acceptance: the recorded head differs from ``; the porcelain capture contains no entry outside the feature folder and the agent-memory tree; git show --name-only --format= HEAD lists at least 20 paths under the feature folder and, outside it, only the members P0-T13 listed. When a formatter rewrite is committed here the commit message reads "style(929): apply the PoshQC formatter to pre-existing drift, plus phase 0 baseline evidence" instead. The artifact is written after the commit and is swept by P1-T14.
+
+### Phase 1 — Constrained Implementation
+
+- [x] [P1-T1] Hand off to powershell-typed-engineer (when the executor has no sub-agent dispatch tool it authors the file inline within exactly these bounds and records the substitution as a `WORKER:` line in this task's artifact): create `tests/scripts/dependencies/RepositoryTreeConsistency.Tests.ps1` (UTF-8 with BOM, LF line endings, ASCII content only, Set-StrictMode -Version Latest, at most 200 lines, no Start-Sleep, no temporary file, no Mock) with a BeforeAll that resolves $script:RepoRoot from $PSScriptRoot as ConsistencyVerifier.Tests.ps1 line 4 does and imports scripts/dependencies/ConsistencyVerifier.psm1 with -Force, one Describe named 'Repository tree consistency (issue 929)', and exactly these four It blocks, named verbatim: (1) 'reports no Import element whose package the sibling manifest omits, for every project directory that carries a manifest' — enumerate the directories directly under $script:RepoRoot that contain packages.config and exactly one .csproj, assert the pair count is greater than 9, call Find-PackageAbsentFromManifest per pair with both texts read via [System.IO.File]::ReadAllText, keep findings whose Kind is Import as strings of the form ": line