Files
mokosh/.planning/phases/04-harden-clean-up-optional/04-06-REPLAN-CHECKER-iter-1.md
Mark deb68dff86 docs(04-06): re-plan-checker iter-1 — ITERATE-NEEDED (2 BLOCKER)
Re-plan b59bd24 validated against canonical plan-quality criteria.

DEFECT 2 (back-patch line numbers 22/47/82/135/205 flip; 40/89/109/110
leave) — RESOLVED, verified correct against live 01-07-SUMMARY.md.
welcome.css drop, thesis preservation, frontmatter, FORBIDDEN_HOOK_STRINGS
lockstep (12), atomic-commit structure — all correct.

BLOCKER 1: DEFECT 1's "live-DOM injection + currentColor cascade delegated
to A17.8 harness in real Chrome" is fictitious — assertA17 runs in an
extension-internal page and only fetch()+string-greps welcome.html/jsText;
no live welcome tab, no populateMark() run, no querySelector. Task 3's own
escape hatch ships A17.8a-only, leaving the inline-SVG behavior with zero
automated coverage.

BLOCKER 2: DEFECT 3 names the wrong failing test — strict-meta-json-
validation.test.ts is GREEN on a clean tree (8/8 isolated). The full-suite
"1 failed" is a non-deterministic ffprobe/parallel-vitest timeout flake
(04-CONTEXT #9/#10); this run it hit webm-remux.test.ts. The hard-coded
"failure set EXACTLY {strict-meta-json...}" gate will fail spuriously.
True baseline 184/184; target 188/188.

Verdict: ITERATE-NEEDED — spawn planner for second re-plan.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 16:28:47 +02:00

273 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 04-06 RE-PLAN VALIDATION — iter-1
**Plan:** `.planning/phases/04-harden-clean-up-optional/04-06-PLAN.md`
**Commit reviewed:** `b59bd24` (`docs(04-06): re-plan — correct false jsdom premise + stale back-patch lines + baseline`)
**Reviewer:** gsd-plan-checker (re-plan validation loop, iter-1)
**Date:** 2026-05-22
---
## VERDICT: ITERATE-NEEDED
**2 BLOCKER · 1 WARNING · 3 cosmetic-advisory**
The re-plan correctly resolves DEFECT 2 (back-patch line numbers) and the `welcome.css` drop is sound. But the two load-bearing claims of the re-plan — the DEFECT 1 A17.8 delegation and the DEFECT 3 baseline reframe — are **both factually wrong against the live codebase**, and each will cause the plan to fail or mis-gate during execution. The re-plan substituted one false premise (jsdom) for two new false premises. Re-plan again.
---
## Defect-by-defect verdict
### DEFECT 1 — false jsdom premise → node-env source-contract strategy
**Sub-claim 1a — "vitest ships no DOM library":** CONFIRMED TRUE.
`vitest.config.ts:18` is `environment: 'node'`. `node_modules/{jsdom,happy-dom,linkedom,@happy-dom}` all absent. No vitest test uses `DOMParser`. The node-env source-contract reframe of `inline-svg.test.ts` is the correct response to *that* fact.
**Sub-claim 1b — the source-contract test meaningfully pins the contract:** ACCEPTABLE (not a blocker).
`tests/i18n/manifest-i18n.test.ts` is a sound, in-repo `readFileSync` + `toContain` precedent. Test B's negative assertions (`NOT mokosh-mark.svg?url`, `NOT innerHTML`) genuinely pin the T-04-06-01 MV3-CSP mitigation and the import swap. A `readFileSync`+`toContain` test is admittedly weak (it pins source *text*, not runtime behavior) — but the plan is honest about this and the TDD RED→GREEN cycle is real: all 3 tests are genuine-RED today (SVG still `#181b2a`; welcome.ts still `?url`/`<img>`; globals.d.ts has no `?raw` decl — all verified), and all 3 flip GREEN after Task 2's edits. This part is fine.
**Sub-claim 1c — "live-DOM injection + currentColor cascade is delegated to the A17.8 harness sub-check in real Chrome":** **FALSE. → BLOCKER 1.**
This is the central justification for accepting the weak unit test, and it does not hold. Verified against `tests/uat/extension-page-harness.ts` (lines 2090-2305) and `tests/uat/harness.test.ts:48`:
- The `assertA17` driver runs **inside an extension-internal harness page** (`harness.test.ts:48`: `page.evaluate(() => window.__mokoshHarness.assertXX())`; `harness.test.ts:283`: "extension-internal page driver").
- It reaches the welcome page **only** by `fetch(chrome.runtime.getURL('src/welcome/welcome.html'))` and then `new DOMParser().parseFromString(htmlText, 'text/html')` — i.e. it parses the welcome **HTML as a detached string**. It then `fetch()`es the welcome JS chunk and inspects it as **`jsText`** (a string).
- The existing A17.8 check (`extension-page-harness.ts:2273-2299`) is **100% string-grep on `jsText`** (`hasInlineDataUrl`, `svgFileUrlMatches`, `hasCanonicalViewBox`). There is **no live welcome-page tab, no `populateMark()` invocation, no `document.querySelector('.welcome-hero__mark svg')`** anywhere in the A17 driver. `grep 'welcome-hero__mark' tests/uat/extension-page-harness.ts` returns nothing; `grep 'page.goto' ... returns one comment, unrelated.
So the inline-`<svg>` DOM injection and the `currentColor`→parent-`color` CSS cascade — the *entire* runtime behavior the node-env unit test "deliberately cannot cover" — is covered by **nothing**. The plan's A17.8 update (Task 3) only swaps the `data:image/svg+xml` string-grep for a `stroke="currentColor"` + `viewBox` string-grep on the same `jsText`. That asserts *the raw SVG source is bundled* — it does NOT assert the SVG is parsed, injected, or that the cascade resolves.
The PATTERNS.md the planner consumed (`04-PATTERNS.md:1126-1127`) explicitly specs **"A17.8b — inline SVG injected at populateMark() runtime: `document.querySelector('.welcome-hero__mark svg')` is non-null"**, and the plan's own Task 3 step (b) (`04-06-PLAN.md:306`) describes adding exactly that A17.8b DOM query — but qualifies it "**pick this unless the harness page cannot reach the welcome DOM in this driver** … if the driver structure makes a second DOM query infeasible, document why … and ship A17.8a only — A17.8a alone still satisfies UI-SPEC Acceptance Criterion #3."
The driver structure **does** make it infeasible (verified above). So under the plan's own escape hatch the executor will ship A17.8a-only. Net result: **AC #3 of the UI-SPEC is the *only* automated gate for the inline-SVG technique, and A17.8a-only does not verify the technique** — it verifies the source string is in the bundle, which would also be true if `populateMark` were still broken. The plan asserts "A17.8a alone still satisfies UI-SPEC Acceptance Criterion #3"; UI-SPEC AC #3 (`04-UI-SPEC.md:248`) accepts an A17.8-rewrite of "raw SVG source bundled" — so strictly the *spec checkbox* is satisfiable — but the **goal** (D-P4-03 dark-logo strategy actually working) is then verified by zero automated coverage and rests entirely on the Task 4 operator eyeball.
**Why this is a BLOCKER, not a WARNING:** the re-plan's stated thesis is "full live-DOM injection + currentColor cascade verification is delegated to the A17.8 harness sub-check in real Chrome." That delegation target does not exist. The plan ships a weak unit test *justified by* a harness check that cannot be written as specced. Either:
- (a) the plan must add a **real** welcome-page DOM check — i.e. a harness driver that actually opens `welcome.html` in a Puppeteer page/tab, lets `populateMark()` run, and queries `.welcome-hero__mark svg` + its computed stroke. That is a genuine new harness capability (a `page.goto` / new-tab driver), not a "second `result.checks` entry" in `assertA17`. The plan must scope that work explicitly, OR
- (b) the plan must drop the "delegated to A17.8 in real Chrome" claim and **honestly state** that the inline-SVG runtime behavior is verified ONLY by the Task 4 operator screenshot — and the planner/orchestrator must accept that the automated path has a real gap.
Note option (b) is partially defensible (Task 4 *is* a genuine operator-empirical gate and a human looking at a dark+light screenshot *will* catch a black-on-dark mark). But the plan must not *claim* harness coverage it does not have. As written, the plan is internally inconsistent and a downstream executor following Task 3 step (b)'s escape hatch produces a weaker artifact than the plan's verification section promises.
### DEFECT 2 — stale back-patch line numbers
**VERDICT: RESOLVED — CONFIRMED CORRECT.**
Verified `grep -nE 'Phase 5|deferred to Phase 5|deferred-to-5'` against the live `01-07-SUMMARY.md` (244 lines):
| Line | Content | Plan says | Correct? |
|------|---------|-----------|----------|
| 22 | `affects:` graph — "Phase 5 … new entry: getDisplayMedia cursor visibility constraint" | FLIP | ✅ forward-looking deferral |
| 47 | key-decisions — "Cursor visibility … deferred to Phase 5, not back-patched" | FLIP | ✅ stale deferral framing |
| 82 | accomplishments — "Cursor-visibility refinement deferred to Phase 5" | FLIP | ✅ stale deferral framing |
| 135 | Decisions Made #5 — "Cursor visibility refinement deferred to Phase 5" | FLIP | ✅ stale deferral framing |
| 205 | User Setup — "The cursor visibility refinement (Phase 5) will, when activated, add…" | FLIP | ✅ false-future tense |
| 40 | key-files — "ROADMAP.md … cursor-visibility refinement appended to Phase 5" | LEAVE | ✅ historical: describes the ROADMAP commit content |
| 89 | Task Commits — `7df72aa` "… Phase 5 cursor-visibility appended" | LEAVE | ✅ historical: describes what commit `7df72aa` did |
| 109 | Files Created/Modified — "ROADMAP.md … Phase 5 P1/P2 list appended" | LEAVE | ✅ historical commit record |
| 110 | Files Created/Modified — "STATE.md … `[Phase 01-07-deferred-to-5]` decision-log tag" | LEAVE | ✅ historical commit record |
The flip/leave classification is exactly right. Lines 22/47/82/135/205 each assert the deferral as a live forward-looking fact (false — `cursor:'always'` shipped in Plan 01-09, verified at `recorder.ts:285`). Lines 40/89/109/110 each describe what a specific Phase-1-closure commit *recorded at the time* — flipping them would falsify the historical record. DEFECT 2 is genuinely fixed.
### DEFECT 3 — wrong vitest baseline
**VERDICT: NOT RESOLVED — the reframe identifies the WRONG failing test. → BLOCKER 2.**
The re-plan reframes the baseline as "**183 passed / 1 failed**, the 1 failure being `tests/build/strict-meta-json-validation.test.ts` … a pre-existing red on a clean tree." It then hard-codes a gate in Task 2 (`04-06-PLAN.md:275`, `:292`) and Task 4 (`:361`): "**Verify the failure set is EXACTLY {strict-meta-json-validation.test.ts}**. If any OTHER test fails, Plan 04-06 caused a regression."
Empirically verified this run (2026-05-22, clean tree at `b59bd24`):
- Full suite `npx vitest run`: **183 passed / 1 failed (184)** — count matches.
- BUT the failing test was **`tests/background/webm-remux.test.ts > … ffprobe -count_frames reports between 905 and 912 frames`** — `Error: Test timed out in 5000ms`. **NOT `strict-meta-json-validation.test.ts`.**
- `npx vitest run tests/build/strict-meta-json-validation.test.ts` in isolation: **8 passed / 8** — GREEN.
- `npx vitest run tests/background/webm-remux.test.ts` in isolation: **5 passed / 5** — GREEN.
Both candidate tests pass deterministically in isolation. The "1 failed" in the full suite is a **non-deterministic timeout** of an ffprobe-shelling test under parallel-worker load. This is precisely the pre-existing flake class that `04-CONTEXT.md` itself enumerates as Phase 4 in-scope items **#9 ("pre-existing parallel-vitest Tier-1-build-step race (~1/5 full-suite runs)")** and **#10 ("2 pre-existing ffprobe/ffmpeg vitest flakes")**.
Consequences:
1. The re-plan's premise — "`strict-meta-json-validation.test.ts` is a pre-existing red on a clean tree" — is false. That test is GREEN on a clean tree. The `deferred-items.md` entry it cites (logged 2026-05-22) is itself based on a one-shot observation that mis-attributed a flake to a specific test.
2. The hard-coded gate `failure set EXACTLY == {strict-meta-json-validation.test.ts}` will **fail spuriously** during execution: on most runs the suite is 184/184 GREEN (so the gate "1 expected failure missing" trips), and on a flaky run the RED lands on `webm-remux` or an ffprobe test (so the gate "unexpected test failed → regression" trips and falsely blames Plan 04-06).
3. The stated target "187 passed / 1 pre-existing fail (188 total)" is wrong twice over: the true clean-tree baseline is **184/184** (the "1 fail" is a flake, not a fixture), so after +4 new tests the correct expectation is **188/188 GREEN, modulo the known ~1/5 parallel-vitest flake which may land a transient RED on any ffprobe/parallel-race test.**
**Required fix:** Task 2 and Task 4 vitest gates must be reframed to tolerate the **flake class**, not a named test. Correct gate logic: "Full suite is **188/188 GREEN**. If exactly one test is RED AND it is in the known ffprobe/parallel-race flake set (`webm-remux.test.ts` `-count_frames`, the 2 ffprobe/ffmpeg flakes per 04-CONTEXT #10, or a Tier-1-build-step race per #9), re-run once; a clean re-run confirms no regression. If a RED persists across a re-run, or a RED lands on a non-flake test, Plan 04-06 caused a regression." The plan must NOT name `strict-meta-json-validation.test.ts` as the expected failure — that is a phantom.
(Secondary: routing this flake to `/gsd-debug` is fine, but it should be routed as "the parallel-vitest ffprobe flake (04-CONTEXT #9/#10)", not as "`strict-meta-json-validation.test.ts` fails on a clean tree" — the latter is a misdiagnosis that will waste the debug session.)
---
## welcome.css drop — VALIDATED (no-edit claim is CORRECT)
The re-plan drops `src/welcome/welcome.css` from `files_modified` with the rationale: the bare `.welcome-hero__mark-img` selector matches `<svg>` like `<img>`, and `color` inherits, so no CSS edit is needed. Verified:
- `welcome.css:91-95` `.welcome-hero__mark-img { width:60%; height:60%; display:block; }` — a **bare class selector** (no `img.` tag qualifier). It matches `<svg class="welcome-hero__mark-img">` exactly as it matches `<img class="...">`. Task 2 applies that class via `svg.classList.add('welcome-hero__mark-img')` — match holds.
- `.welcome-hero__mark` (`welcome.css:64-73`) sets `color: var(--mks-fg-inverse)`. CSS `color` is an **inherited property** (CSS Color L3). An inline `<svg>` injected via `DOMParser` + `replaceChildren` is a regular descendant element, so it inherits `color` from `.welcome-hero__mark` automatically. `stroke="currentColor"` on the SVG root then resolves to that inherited `color`. No `color: inherit` rule is needed.
- This is exactly why Option A *requires* the inline-`<svg>` switch: an `<img>`-rendered SVG renders in an isolated document and does NOT inherit parent `color` (the UI-SPEC "Implementation amendment" at `04-UI-SPEC.md:207-227` says this). The plan understands this correctly.
The UI-SPEC's "(optional) welcome.css broadening" (`04-UI-SPEC.md:237`) was always marked optional; dropping it is correct and reduces `files_modified` honestly. **No issue.**
---
## Thesis preservation — CONFIRMED INTACT
- **Dark-logo `currentColor` Option A:** intact — `<objective>` part 1/2, `must_haves.truths` 1-3, key_links 1-2 all carry the SVG-recolor + inline-`<svg>` + cascade thesis. SVG recolor is the verified single-attribute change (`stroke="#181b2a"``currentColor`; 13 children untouched).
- **Cursor verification-only:** intact — `recorder.ts:285` confirmed to already carry `cursor: 'always'` (verified live, lines 284-291). Plan correctly treats it as verification-only via `tests/build/cursor-visibility.test.ts` (GREEN-on-arrival) per RESEARCH Finding 4. `recorder.ts` is correctly NOT in `files_modified`.
- **A17.8 update:** intact in intent (raw-source grep replacing data-URL grep) — but see BLOCKER 1: the *real-Chrome DOM* half of the intended A17.8 update cannot be delivered by the existing driver.
- **Operator-empirical Task 4:** intact — `type="checkpoint:human-verify" gate="blocking"`, `autonomous: false` (frontmatter line 21), dark + light Puppeteer screenshots via `emulateMediaFeatures([{name:'prefers-color-scheme',value:'dark'}])`, resume-signal contract present. Honors `feedback-trust-harness-over-manual-uat` (operator judges from screenshots, not a manual Chrome session) and UI-SPEC AC #6.
---
## Goal-backward — D-P4-03 closure
D-P4-03 (locked, `04-CONTEXT.md`) = BOTH (a) cursor visibility + (b) dark-surface logo contrast.
- **(a) cursor visibility:** closed — verification test + 5-line back-patch. Sound.
- **(b) dark-logo contrast:** the *edits* that deliver it (SVG recolor + `?raw` + DOMParser `populateMark` + `globals.d.ts` decl) are correctly specified in Task 2. The closure is **goal-reachable** — but per BLOCKER 1 the *verification* that it actually works is weaker than the plan claims (no live-DOM/cascade automated coverage; rests on Task 4 operator eyeball). The goal can still be *achieved*; the plan's *verification story* for it is the defect.
D-P4-03 is reachable once BLOCKER 1 and BLOCKER 2 are fixed.
---
## Atomic commit / frontmatter / hooks
- **Task structure:** `gsd-sdk verify.plan-structure``valid: true`, 4 tasks, all 4 have Files+Action+Verify+Done. Task 4 is `checkpoint:human-verify`. Per-task atomic commit messages present and convention-correct (`test(04-06):`, `feat(04-06):` ×2, operator ack).
- **Frontmatter:** valid; `revision_history` block present and detailed (3 defects documented); `must_haves` parses; `autonomous: false` correct for the checkpoint.
- **FORBIDDEN_HOOK_STRINGS lockstep:** verified `tests/background/no-test-hooks-in-prod-bundle.test.ts:108-126` — inventory is **12 entries**. Plan 04-06 adds **no** `__MOKOSH_UAT__`-gated symbol (the `?raw` import, DOMParser, `inline-svg.test.ts`, `cursor-visibility.test.ts` are all production or unit-test surfaces, none test-mode-gated). The plan's claim "FORBIDDEN_HOOK_STRINGS stays at 12" (Task 4 Gate 6, `04-06-PLAN.md:359`/`:383`) is **correct**. No lockstep violation.
- **`files_modified` completeness:** the 7 entries match the edits Tasks 1-3 actually make. `recorder.ts` correctly excluded (verification-only). `welcome.css` correctly excluded (no-edit, validated above). Complete.
---
## NEW issues introduced by the re-plan
- **BLOCKER 1** and **BLOCKER 2** above are both *new* — the original plan's defects were jsdom/line-numbers/184-baseline; the re-plan fixed the line numbers but introduced a false A17.8-delegation claim and a false named-failing-test in place of the old false 184/184. The re-plan traded one wrong premise for two.
- No new dependency-graph, scope, or context-compliance issues. Wave 5 / `depends_on: [01..05]` unchanged and consistent. Scope (4 tasks, 7 files) is within budget.
---
## ISSUES
```yaml
issues:
- id: BLOCKER-1
dimension: key_links_planned
severity: blocker
plan: "04-06"
task: 3
description: >
The re-plan's DEFECT 1 resolution justifies the weak node-env source-contract
unit test by "delegating full live-DOM injection + currentColor cascade
verification to the A17.8 harness sub-check in real Chrome". That delegation
target does not exist. The assertA17 driver (extension-page-harness.ts:2090-2305)
runs inside an extension-internal harness page and reaches the welcome page only
via fetch() + DOMParser string-parse of welcome.html and string-grep of the
welcome JS chunk (jsText). It never opens a live welcome-page tab, never runs
populateMark(), never queries document.querySelector('.welcome-hero__mark svg').
Task 3 step (b)'s own escape hatch ("if the driver cannot reach the welcome DOM,
ship A17.8a only") will therefore trigger, leaving the inline-SVG injection +
currentColor cascade with ZERO automated coverage. A17.8a (raw-source string
grep on jsText) would pass even if populateMark were still broken.
fix_hint: >
Either (a) scope an explicit NEW harness capability — a driver that opens
welcome.html in a Puppeteer page/tab, lets populateMark() run, and asserts
the live .welcome-hero__mark svg element + its resolved stroke (this is real
new work, not a second result.checks entry) — and make A17.8b that driver;
OR (b) drop the "delegated to A17.8 in real Chrome" claim entirely and state
honestly in <objective> and <verification> that the inline-SVG runtime
behavior is verified ONLY by the Task 4 operator screenshot, with the planner
accepting that automated gap. Do not claim harness coverage the harness lacks.
- id: BLOCKER-2
dimension: task_completeness
severity: blocker
plan: "04-06"
task: 2
description: >
The DEFECT 3 baseline reframe names the wrong failing test. The re-plan asserts
"183 passed / 1 failed; the 1 failure is tests/build/strict-meta-json-validation.test.ts,
a pre-existing red on a clean tree" and hard-codes a Task 2 + Task 4 gate
"verify the failure set is EXACTLY {strict-meta-json-validation.test.ts}".
Verified live (2026-05-22, clean tree b59bd24): the full-suite RED this run was
tests/background/webm-remux.test.ts (ffprobe -count_frames, Test timed out in
5000ms) — NOT strict-meta-json-validation.test.ts. Both tests pass deterministically
in isolation (strict-meta-json 8/8 GREEN; webm-remux 5/5 GREEN). The "1 failed"
is a non-deterministic ffprobe/parallel-worker timeout flake — exactly the
pre-existing flake class 04-CONTEXT.md enumerates as in-scope items #9 and #10.
The hard-coded named-test gate will fail spuriously: on a 184/184 run it trips
"expected failure missing"; on a flaky run the RED lands elsewhere and it falsely
blames Plan 04-06 for a regression. The true clean-tree baseline is 184/184
GREEN, so the post-plan target is 188/188 GREEN (not 187/1).
fix_hint: >
Reframe the Task 2 + Task 4 vitest gates to tolerate the flake CLASS, not a
named test. Correct gate: "Full suite 188/188 GREEN; if exactly one test is RED
and it is in the known ffprobe/parallel-race flake set (webm-remux -count_frames,
the 2 ffprobe/ffmpeg flakes, a Tier-1-build-step race), re-run once — a clean
re-run confirms no regression; a persisting RED or a RED on a non-flake test is
a regression." Remove every reference to strict-meta-json-validation.test.ts as
the expected pre-existing failure. Correct the stated baseline to 184/184 and
the target to 188/188. If routing to /gsd-debug, route it as the 04-CONTEXT
#9/#10 parallel-vitest flake, not as "strict-meta-json fails on a clean tree".
- id: WARNING-1
dimension: verification_derivation
severity: warning
plan: "04-06"
description: >
With BLOCKER 1 unresolved, the dark-logo strategy's automated verification
reduces to A17.8a (a string-grep proving the raw SVG source is in the bundle).
That is a bundling check, not a behavior check — it does not distinguish
"populateMark correctly inline-injects the SVG and the cascade resolves" from
"populateMark is broken but the ?raw import still bundled the string". The
must_haves.truths #3 ("Injected inline <svg> inherits color ... verified in
real Chrome by the A17.8 harness sub-check") is therefore not actually
satisfied by any planned artifact.
fix_hint: >
Resolved automatically once BLOCKER 1 is fixed via option (a). If BLOCKER 1 is
resolved via option (b) instead, rewrite truth #3 to say the cascade is verified
by the Task 4 operator screenshot, and accept the reduced automated coverage
explicitly rather than implying harness coverage.
- id: ADVISORY-1
dimension: task_completeness
severity: cosmetic-advisory
plan: "04-06"
task: 3
description: >
Task 3's <verify> automated block runs the UAT with SKIP_PROD_REBUILD=1
while the <action> prose for Task 3 instructs SKIP_PROD_REBUILD=0. Minor
internal inconsistency between the action narrative and the verify command.
fix_hint: >
Align the two — pick SKIP_PROD_REBUILD=0 (action) or =1 (verify) consistently;
whichever matches the intent that the harness rebuilds against the Task 2 edits.
- id: ADVISORY-2
dimension: requirement_coverage
severity: cosmetic-advisory
plan: "04-06"
description: >
frontmatter requirements: [] is empty. Correct for a Phase 4 plan (Phase 4
has no new REQ-* per ROADMAP), but the plan closes the charter decision
D-P4-03. Consider a charter-decision tag rather than leaving the field bare,
for traceability — non-blocking; tags already include charter-d-p4-03.
- id: ADVISORY-3
dimension: verification_derivation
severity: cosmetic-advisory
plan: "04-06"
description: >
Task 1 acceptance_criteria "grep -c 'jsdom' tests/welcome/inline-svg.test.ts
returns 0" is a fine guard, but the header-comment the plan asks the executor
to write WILL mention jsdom (explaining why jsdom is NOT used). A literal
grep -c 'jsdom' would then return >0 from the comment and fail the criterion.
fix_hint: >
Either scope the grep to non-comment lines, or reword the criterion to
"no import of jsdom / no jsdom-environment directive", or instruct the
header comment to say "no DOM-emulation library" without the literal token.
```
---
## Remediation summary for the orchestrator
**ITERATE-NEEDED** — spawn the planner for a second re-plan. Two blockers must be fixed:
1. **BLOCKER 1 (A17.8 delegation is fictitious):** the planner must either scope a genuine new welcome-page-DOM harness driver (a `page.goto`/new-tab driver that runs `populateMark()` and queries the live `.welcome-hero__mark svg`), or drop the "delegated to A17.8 in real Chrome" claim and honestly document the inline-SVG runtime behavior as operator-screenshot-only verified.
2. **BLOCKER 2 (DEFECT 3 names a phantom failing test):** the planner must reframe the Task 2/Task 4 vitest gates around the *flake class* (ffprobe/parallel-vitest race per 04-CONTEXT #9/#10) with a re-run tolerance, correct the baseline to 184/184 GREEN and the target to 188/188, and stop naming `strict-meta-json-validation.test.ts` as a pre-existing red — it is GREEN on a clean tree.
DEFECT 2, the `welcome.css` drop, thesis preservation, frontmatter, FORBIDDEN_HOOK_STRINGS lockstep, and atomic-commit structure are all correct and need no change. WARNING-1 resolves with BLOCKER 1. The 3 advisories are nice-to-fix.