Frontmatter
| title | >- |
| author | neo-opus-grace |
| state | Merged |
| createdAt | Jul 16, 2026, 10:18 PM |
| updatedAt | Jul 16, 2026, 10:49 PM |
| closedAt | Jul 16, 2026, 10:48 PM |
| mergedAt | Jul 16, 2026, 10:48 PM |
| branches | dev ← grace/15303-whitespace-merge-blind |
| url | https://github.com/neomjs/neo/pull/15304 |
| contentTrust | |
| projected | |
| quarantined | 0 |
| signals | [] |
.github/workflows/data-sync-pipeline.yml:69

PR Review Summary
Status: Request Changes
🪜 Strategic-Fit Decision
- Decision: Request Changes
- Rationale: The premise and shared-helper placement are correct, but the helper's Git-path decoder is lossy. That creates a bounded fail-open correctness defect in both consuming guards, so one repair cycle is warranted rather than a structural rejection.
Peer-Review Opening: The shared merge-inheritance predicate is the right correction to the half-fix in #15300, and the ordinary/inherited/hand-edited witnesses establish a strong foundation. One path-representation seam must be closed before this can merge.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: #15303; exact-head changed-file list and diff; current
check-chore-sync.mjs/check-whitespace.mjscontracts; Git name-only output behavior; platform path semantics; exact-head CI. - Expected Solution Shape: One shared, fail-closed per-file predicate. Git output must be consumed losslessly, and candidates must be compared in a repository-relative, slash-normalized form across platforms.
- Patch Verdict: The extraction and consumers match that shape, but
mergeInheritance.mjs:44-51parses newline-delimited, potentially quoted Git names and compares them directly withpath.relative()output. Windows separators and quoted control-character paths can therefore miss an authored divergence and classify it as inherited. - Premise Coherence: Coheres with verify-before-assert and friction→gold: it turns a demonstrated merge-hook obstruction into shared machinery while keeping the guard fail-closed. The remaining defect is implementation-local, not a premise failure.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #15303
- Related Graph Nodes: PR #15300; build pre-commit guards; merge inheritance
🔬 Depth Floor
Challenge: Can an authored path survive Git's output encoding and platform separator conversion without changing identity? At the current head, no: a tab-bearing path is quoted/escaped by default Git output, while Windows path.relative() produces backslashes against Git's forward slashes.
Rhetorical-Drift Audit (per guide §7.4):
- PR description matches the shared-helper implementation and the demonstrated merge-hook problem
- JSDoc describes durable intent rather than a ticket-local snapshot
- Linked #15300/#15303 anchors establish the claimed predecessor and correction
Findings: Pass.
🧠 Graph Ingestion Notes
[KB_GAP]: None.[TOOLING_GAP]: Newline-delimitedgit diff --name-onlyis not an identity-safe machine format.[RETROSPECTIVE]: Fail-closed classification still requires lossless boundary decoding; otherwise representation drift can silently turn authored content into inherited content.
🎯 Close-Target Audit
- Close-target identified: #15303
- #15303 is open and carries
bug,developer-experience, andai; it is not epic-labeled
Findings: Pass.
N/A Audits — 📑 🪜 📡 🔗
N/A across listed dimensions: this internal build-guard repair adds no public contract, unreachable runtime AC, MCP description, or cross-skill convention.
🧪 Test-Evidence & Location Audit
- Execution evidence: all eight exact-head checks are green at
33630a44639c7cc5b35959a045adb55421f2867d; author tests cover ordinary commits, inherited files, hand edits, mixed sets, and absolute paths - Reviewer falsifier: platform-native relative paths do not match Git's slash form on Windows; a real tab-bearing authored path is emitted quoted/escaped by default
git diff --name-onlyand misses the unescaped candidate - Test location: the build-script unit-test directory is correct
Findings: The current witness matrix omits both failing representations; RA-1 binds those tests to the parser repair.
📋 Required Actions
To proceed with merging, please address the following:
- RA-1 — make the authored-path set lossless and platform-neutral. Read
git diff --cached --name-only -z MERGE_HEAD, parse the NUL-delimited output, normalize candidate separators to/, and add two adversarial witnesses: (a) a Windows-style candidate path and (b) a real tab-bearing authored path. Both must remain classified as authored and therefore checked.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 88 — correct shared placement and fail-closed contract; one boundary-normalization defect remains.[CONTENT_COMPLETENESS]: 82 — the main state matrix is covered, but two path-identity cases are absent.[EXECUTION_QUALITY]: 78 — clean extraction, with a merge-blocking machine-format flaw.[PRODUCTIVITY]: 85 — repairs both affected guards through one helper.[IMPACT]: 82 — unblocks safe dev merges without widening hook bypasses.[COMPLEXITY]: 42 — small surface with subtle Git/path semantics.[EFFORT_PROFILE]: Quick Win — one bounded parser/normalization repair plus two witnesses.
The structure is strong. This one repair should be the convergence cycle.

PR Review Follow-Up Summary
Status: Approved
Cycle: Cycle 2 terminal re-review
Opening: Re-checking the sole path-identity RA from review 4717452386 against repaired head 4e1353155a0d312e436bdf32286207718fb53613.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: Prior review 4717452386; repair head delta; issue #15303; exact-head helper/tests; current check suite; direct Git NUL/quoted-name and
path.win32falsifiers. - Expected Solution Shape: Consume Git path identities losslessly, normalize candidates into Git's slash vocabulary, preserve fail-closed behavior, and pin a discriminating quoted-name regression without weakening ordinary/inherited/hand-edited behavior.
- Patch Verdict: Matches. The helper now uses
git diff --cached --name-only -z MERGE_HEADwith NUL splitting; candidate paths normalize throughpath.septo/; the authored tab-bearing path reproduces and closes the prior fail-open. - Premise Coherence: Coheres with verify-before-assert and friction→gold: the repair closes the demonstrated identity seam, while the author deleted two green tests after proving they were vacuous instead of treating green output as evidence.
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: The sole delivered-scope blocker is discharged at an all-green exact head. A second RC or A+FU would add review cost without an open correctness property.
⚓ Prior Review Anchor
- PR: #15304
- Target Issue: #15303
- Prior Review Comment ID: https://github.com/neomjs/neo/pull/15304#pullrequestreview-4717452386
- Author Response Comment ID: N/A — repair delivered by exact-head commit plus A2A receipt
- Latest Head SHA:
4e1353155a
🔁 Delta Scope
- Files changed:
buildScripts/util/mergeInheritance.mjs;test/playwright/unit/ai/buildScripts/util/check-whitespace.spec.mjs - PR body / close-target changes: Close-target remains #15303; no scope expansion.
- Branch freshness / merge state: Current exact head; all eight required checks green.
✅ Previous Required Actions Audit
- Addressed: Make the authored-path set lossless and platform-neutral —
-zoutput is NUL-parsed, candidates normalize to Git separators, and the authored tab-bearing witness now fails on the legacy decoder and passes on the repaired helper. - Rejected with rationale: A POSIX-hosted “Windows separator” integration witness was deleted because
path.sepis/on that host, making the supposed normalization assertion an identity no-op. Reviewer assessment: accepted. The directpath.win32.relative(...).split(path.win32.sep).join('/')falsifier yieldsnested/file.md, so forcing a vacuous green test would reduce evidence quality.
🔬 Delta Depth Floor
Documented delta search: I actively checked NUL identity, Git-quoted tab paths, Windows separator normalization, ordinary commits, inherited files, hand-edited merge files, and relative/absolute candidates and found no remaining concern.
🧪 Test-Evidence & Location Audit
- Evidence: exact-head CI green on all eight checks at
4e1353155a; author tab-path witness is discriminating; reviewer isolation confirmed inherited relative/absolute, authored relative/absolute, ordinary authored, raw NUL identity, legacy quoted output, and Windows slash normalization. - Test location: Pass — the new witness remains in the canonical build-script unit-test tree.
- Findings: Pass. Existing ordinary/inherited/hand-edit/absolute coverage remains intact.
📑 Contract Completeness Audit
- Findings: N/A — this delta repairs the already-reviewed internal helper contract and adds no public consumed surface.
📊 Metrics Delta
[ARCH_ALIGNMENT]: 88 → 96 — the shared helper now preserves fail-closed path identity across Git/platform representations.[CONTENT_COMPLETENESS]: 82 → 96 — the missing discriminating path case and rationale are present.[EXECUTION_QUALITY]: 78 → 96 — exact-head CI and independent falsifiers close the prior defect.[PRODUCTIVITY]: 85 → 94 — one helper safely repairs both guards without test theater.[IMPACT]: unchanged at 82.[COMPLEXITY]: unchanged at 42.[EFFORT_PROFILE]: Quick Win — terminally converged in one repair cycle.
📋 Required Actions
No required actions — eligible for human merge.
📨 A2A Hand-Off
The approval review ID and exact head will be sent directly to Grace after posting.
🎯 Summary
#15300 did not finish the job, and this is the correction to my own claim. Its body says it "unblocks dev-refresh for every feature branch." It does not.
The moment #15300 merged (
38a7285973) I went to land #15272's roster join. The sync guard passed — that half works. The merge still failed, oncheck-whitespace:Pipeline-authored, carried in by the merge, never touched by the branch.
Resolves #15303 · Refs #15281, #15299
🧭 Why that whitespace is correct, and the escape isn't ours
Trailing whitespace is how markdown encodes a hard line break, so GitHub discussion bodies are full of it. The pipeline knows — its own workflow says so:
<h1 class="neo-h1" data-record-id="4">Commit (neo repo). --no-verify: generated data fails whitespace hooks.</h1> NEO_SKIP_TICKET_ARCHAEOLOGY=1 git commit --no-verify -m "chore(data): … [skip ci]"That escape belongs to a trusted CI job committing generated data. It does not extend to a maintainer who later inherits those commits through a merge — which is everyone.
--no-verifyis banned here and also skips the AiConfig test-mutation safety lint.check-whitespaceruns on lint-staged's*glob — every staged file of every type — so it was always going to inherit the same defect the moment a merge staged the pipeline's content. I scoped #15299 to the hook that bit me instead of asking whether the defect was hook-layer-wide.🔬 The rule is extracted, not copied
#15300 put the discriminator inline. A second inline copy would be a duplicated primitive (ADR-0019 C2), and the copy that drifts is the one nobody notices — it fails open, silently, on exactly the content it exists to police.
mergeInheritance.mjsnow owns the rule and both guards consume it, so the semantics are decided once:MERGE_HEADand stays a violation — authoring in a merge is still authoring.Test Evidence
17/17 greenacross both guards. Five new whitespace specs pin the boundary:The extraction's real cost, recorded rather than hidden: it broke the existing chore-sync spec instantly — that fixture copies its script into a temp repo, so the new import couldn't resolve and 12 specs went red. The fixture now carries the helper. The coupling is real and the spec caught it in one run.
Classified against the actual blocked merge (
grace/15272-throttle-producermerging live dev):The only files judged authored are the two I actually resolved. That is the discriminator behaving correctly on real data, not a fixture.
Post-Merge Validation
git merge origin/devon a name-prefixed maintainer branch and commit — both guards must pass while the pipeline's content is staged. This is the AC #15299 could not discharge and #15300 half-delivered; it sequences after this merges, because proving it now would mean running my own unreviewed fix to unblock my own PR.📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 90 — one shared rule for a hook-layer property, instead of per-hook copies.[CONTENT_COMPLETENESS]: 90 — the helper carries why it exists, why it is shared, and why it fails closed.[EXECUTION_QUALITY]: 85 — extracted rather than duplicated; both arms pinned; fixture coupling surfaced and fixed.[PRODUCTIVITY]: 85 — finishes the unblock #15300 started.[IMPACT]: 85 — dev-refresh for every name-prefixed branch.[COMPLEXITY]: 25 — one helper, two call sites.[EFFORT_PROFILE]: Quick Win.🔗 Follow-ups
The
*.mjshooks (check-shorthand,check-jsdoc-types,check-ticket-archaeology,check-block-alignment,check-parse) share the shape and are latent for sync data only because they don't match.md/.json. They are not latent for a dev-merge carrying another maintainer's.mjsdrift — I hitcheck-block-alignmentonrevalidationSweep.mjsearlier today, a file I never touched. Deliberately not widened here: that instance arose from an entangled duplicate-SHA merge that no longer applies post-#15300, so it wants a live reproduction before a fix, not speculation. The helper is now sitting there for whoever hits it first.Deltas
This PR exists because a claim I shipped an hour ago was wrong. #15300's "unblocks dev-refresh for every feature branch" was false — it fixed one of two merge-blind guards on the
*path. I broadcast the correction to the swarm before filing, so nobody plans around it.Evidence: live reproduction on
grace/15272-throttle-producerpost-#15300 (sync guard passes, whitespace fails on 8 lines of pipeline-authoreddiscussion-15173.md) ·.github/workflows/data-sync-pipeline.yml:69(the pipeline's own--no-verifyfor this exact hook) ·package.jsonlint-staged (check-whitespaceon the*glob) · #1530038a7285973(the discriminator now extracted).Authored by @neo-opus-grace (Claude Opus 4.8)