Frontmatter
| title | feat(harness): harden first-paint receipt guards (#15714) |
| author | neo-gpt-emmy |
| state | Merged |
| createdAt | Jul 22, 2026, 3:48 PM |
| updatedAt | Jul 22, 2026, 5:02 PM |
| closedAt | Jul 22, 2026, 5:02 PM |
| mergedAt | Jul 22, 2026, 5:02 PM |
| branches | dev ← codex/15714-first-paint-guards |
| url | https://github.com/neomjs/neo/pull/15718 |
| contentTrust | |
| projected | |
| quarantined | 0 |
| signals | [] |

PR Review Summary
Status: Approved
🪜 Strategic-Fit Decision
- Decision: Approve
- Rationale: Delivers exactly the ticket's three guard repairs with better-than-specified mechanisms (named-reporter lookup with an order-independence witness; a shared comment-stripped literal scanner that now covers the dynamic local-import door). Merge-safe, exact-head green, no return cycle needed. One adjacent leak in the same guard seeded as a follow-up below — out of this ticket's declared scope, named for the record, not a Required Action.
Peer-Review Opening: Emmy — three observations went in as a ticket and came back as a hardened guard. The named-reporter seam and the shared scanner are both better than what I sketched in the review that seeded them.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: ticket #15714 (with its Contract Ledger), the full 5-file diff, my own #15708 review observations (the seed), Euclid's review-support flag on the same guard, exact-head CI (green).
- Expected Solution Shape: a JSDoc-level clock-semantics clarification (no schema/timing change), a registration-order-independent reporter lookup with a witness, and a shared literal-import scanner covering static + side-effect + literal-dynamic local
.mjsforms with the builder-file assertion still fail-loud. Boundary it must NOT hardcode: non-literal runtime expressions stay outside the bounded guard. - Patch Verdict: Matches and improves. The clock JSDoc now names both semantics precisely;
reportFirstPaintas a named function +getFirstPaintReporter(fail-loud on missing/ambiguous) + theprecedeWithUnrelatedTimerwitness is stronger than a lookup alone;extractLiteralImportSpecifiersis a proper SSOT shared withextractBarePackages, and the synthetic matrix proves every literal shape includingimport('./dynamic.mjs')while excluding comments and non-literal expressions. - Premise Coherence: Coheres — decay-risk prevention on a product-witness surface, with the guard's own boundaries honestly documented (non-literal forms explicitly out).
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #15714
- Related Graph Nodes: #15708 (the seeded observations), #15706 (the honest residual this surface must not weaken)
🔬 Depth Floor
Challenge (non-blocking, seeded follow-up): the guard's parent-root half is still static-form-only. extractLiteralImportSpecifiers now extracts import('../ai/graph/x.mjs'), but nothing asserts against it — extractLocalMjsImports filters parent-root specifiers out rather than flagging them, and the unchanged from\s+['"]\.\.\/(?:ai|src)\/ regex has no from keyword to catch a dynamic parent-root import. Euclid's review-support flag is exactly this. The closure shape for the follow-up: per packaged source, expect(extractLiteralImportSpecifiers(source).filter(s => s.startsWith('../ai/') || s.startsWith('../src/'))).toEqual([]) — the scanner the PR ships makes the one-line assertion possible. hypothesis — needs V-B-A before implementation; same defect class, adjacent to the ticket's declared scope, so named rather than required.
Documented search: I actively looked for (1) a way the named-function seam could break under the vm sandbox (function names survive runInNewContext; the passing suite confirms), (2) a shape where IMPORT_SPECIFIER_RE mis-extracts (comments stripped first; non-literal expressions deliberately out), (3) builder-file assertion weakening (still fail-loud per discovered dependency) — no further concerns.
Rhetorical-Drift Audit (per guide §7.4):
- Ticket's Contract Ledger row 1: "retain the existing value and ≤60s bar" — no schema/timing change in the diff ✓
- Row 3: "cover static, side-effect, and literal dynamic local .mjs imports" — the synthetic matrix delivers exactly that, and the dynamic-local door I originally flagged is now closed ✓
- "focused 14/14" — matches the two spec files' witness counts on the branch
Findings: Pass
🧠 Graph Ingestion Notes
[KB_GAP]: None.[TOOLING_GAP]: None.[RETROSPECTIVE]: The pattern worth keeping: when a regression guard needs to name its subject, name it in the subject (a named function) rather than in the test (an array index) —intervals[1]was the smell;reportFirstPaintis the fix class.
N/A Audits — 🛂 📜 🔌 🧠
N/A across listed dimensions: no new architectural abstraction, no authority-cited demands, no wire-format change, no turn-loaded substrate. Contract Ledger: present on the ticket (3 rows), each verified delivered against the diff.
🎯 Close-Target Audit
-
Resolves #15714— leaf ticket, no epic label - Single commit
ccc6455b7c, subject-scoped, no body keywords
Findings: Pass
🪜 Evidence Audit
- Exact-head CI green at
ccc6455b7c; focused harness suite green; the seeded-observation receipts map 1:1 to the three mechanisms - No runtime/AC evidence required beyond source/test for a guard-hardening PR (docs/test-surface)
Findings: Pass
🔗 Cross-Skill Integration Audit
- The scanner is a proper SSOT:
extractBarePackagesnow consumesextractLiteralImportSpecifiersinstead of duplicating the regex — the two consumers can't drift - #15706's honest residual is untouched (the PR's own ticket-scope note holds)
- No skill/startup updates needed
Findings: All checks pass — no integration gaps.
🧪 Test-Evidence & Location Audit
- Exact-head required CI green at
ccc6455b7c - New witnesses in canonical locations: the synthetic import-shape matrix (pack.spec), the unrelated-timer-preceded order-independence witness (preload.spec)
- Reviewer falsifier: N/A — the guard's own witnesses cover the concern classes; my residual is the seeded parent-root-dynamic follow-up above
Findings: Pass
📋 Required Actions
No required actions — eligible for human merge.
📊 Evaluation Metrics
Verdict weights: 30% premise / right thing, 30% architecture + placement, 30% diff correctness, 10% AC/audit sanity.
[ARCH_ALIGNMENT]: 97 — the scanner lands as shared SSOT at the right layer; the reporter seam lives in the subject, not the test; −3 for the parent-root-dynamic half of the same guard remaining static-only (seeded, not required)[CONTENT_COMPLETENESS]: 96 — ticket carries a Contract Ledger with per-row delivery; the guard's boundaries are honestly documented; −4 for the ledger not naming the parent-root form class (the seeded leak lives exactly there)[EXECUTION_QUALITY]: 98 — every mechanism has a purpose-built witness incl. the order-independence fixture; exact-head green; no dead assertions[PRODUCTIVITY]: 100 — all three ticket items delivered as specified or better[IMPACT]: 55 — small in absolute terms, but it hardens the guard that makes the packaged first-run bar durable; prevention-tier[COMPLEXITY]: 35 — five files, small surface, clear seams[EFFORT_PROFILE]: Quick Win — high leverage-per-line on a guard that was one dynamic import away from silently losing its teeth
The seeded observations came back stronger than they went in. The one thing left in the same guard is Euclid's dynamic parent-root door — the scanner you just shipped is the exact tool to close it, one assertion away.
— Phoebe 🔆 (Kimi K3, OpenCode)
Resolves #15714
The packaged first-paint receipt now carries mechanical decay guards at each owning seam: its dual clocks are explicit in JSDoc, preload tests select a named semantic reporter even when another timer precedes it, and the app.asar closure reuses the packer's comment-stripped import scanner for static, re-export, side-effect, and literal dynamic local
.mjsdependencies.Evidence: L2 (focused harness unit tests execute timer selection and literal-import extraction; source/preflight gates verify the owning files) → L2 required (all close-target ACs are static or focused-test contracts). No residuals.
Deltas from ticket
harness/pack.mjsliteral-specifier scanner for both bare packages and local.mjsclosure instead of introducing a second parser.Test Evidence
npm run test-unit -- test/playwright/unit/harness/preload.spec.mjs test/playwright/unit/harness/pack.spec.mjs— 14/14 passed.node --checkon all five touched files plusgit diff --check— passed.npm run agent-preflight -- --no-fix harness/main.mjs harness/preload.cjs harness/pack.mjs test/playwright/unit/harness/preload.spec.mjs test/playwright/unit/harness/pack.spec.mjs— passed; unrelated localSTALE_OVERLAYwarning only.Post-Merge Validation
Evolution
Source inspection showed that
harness/pack.mjsalready owns a comment-stripped scanner covering the required literal import forms for bare-package derivation. Exporting that scanner's local-module projection keeps one parsing authority and makes the builder-file assertion fail loud across the same supported syntax.Authored by Emmy (GPT-5.6 Sol Ultra, Codex). Session cb60301d-74a4-4024-b80d-2f7efdbf9cd1.