Resolves #15196
Adds focused unit coverage for Neo.util.Style.compareStyles() across object deltas, missing inputs, string normalization, mixed input types, and input immutability. Runtime behavior is unchanged.
Evidence: L1 (unit contract coverage in the repository test harness); L1 required (test-only acceptance criteria with no external runtime effect). No residuals.
Deltas from ticket
None substantive. The test cases follow the existing test/playwright/unit/util/ sibling-spec structure.
Test Evidence
npm run test-unit -- test/playwright/unit/util/Style.spec.mjs in Node 24 / Debian trixie: 5 passed.
npm run test-unit: attempted after generating the required dist/parse5.mjs; exceeded the 6-minute local execution limit without reporting a test failure.
Neo.util.Style.compareStyles(): covered by test/playwright/unit/util/Style.spec.mjs.
Post-Merge Validation
Authored by Codex (GPT-5, Codex). Session 019f6601-f07e-7611-bddb-177183150143.
Pull request overview
Adds focused Playwright unit coverage to pin the existing Neo.util.Style.compareStyles() contract (object deltas, missing-side behavior, string normalization, mixed input types, and input immutability), without changing runtime behavior.
Changes:
- Introduces a new unit spec covering added/changed/removed style keys and the
null-for-removal delta shape.
- Covers missing-side semantics (both missing, old missing, new missing) including the historical “absent new style nulls all old keys” edge.
- Adds string normalization and mixed object/string input coverage.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
@neo-gpt-emmy (APPROVED) reviewed on 2026-07-15T19:50:36Z
Status: Approved
🪜 Strategic-Fit Decision
- Decision: Approve
- Rationale: This is the right bounded solution: it pins an existing core utility contract in the canonical unit-test location, covers the ticket ledger completely, and introduces no runtime or architectural churn.
Peer-Review Opening: Welcome to your first Neo PR, @stantheman0128 — this is a strong first contribution. You kept the change exactly inside the ticket boundary, made the cases easy to read, and supplied honest evidence about both the focused run and the local full-suite limit.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch:
#15196 and its Contract Ledger; the changed-file list; current dev versions of src/util/Style.mjs, src/core/Util.mjs, and src/vdom/Helper.mjs; sibling Json.spec.mjs / String.spec.mjs; and the historical #6859 fix.
- Expected Solution Shape: One isolated
test/playwright/unit/util/Style.spec.mjs using the canonical setup/import pattern, covering every compareStyles() branch and input immutability without changing runtime code or introducing shared-state/test-order coupling.
- Patch Verdict: Matches the expected shape exactly. The single-file diff covers added, changed, removed, unchanged, all missing-side branches, clone identity, string normalization, numeric/camelCase output, and both mixed-input orientations.
- Premise Coherence: Coheres with verify-before-assert: a historical runtime failure is converted into deterministic contract evidence, while the runtime boundary and unrelated Body/Brain surfaces remain untouched.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #15196
- Related Graph Nodes:
#6859, Neo.util.Style.compareStyles(), Neo.vdom.Helper.compareAttributes()
🔬 Depth Floor
Challenge (non-blocking): The missing-new-style regression case passes null, while the VDOM disappearance path commonly supplies undefined. Both values traverse the same !newStyle branch, and the repository history confirms this fixture would fail the original #6859 implementation because that branch built the removal delta but did not return it. An undefined case would mirror the production call shape more literally, but it would not increase current branch or regression coverage, so no contributor churn is requested.
I also actively looked for omitted control-flow branches, tautological assertions, input mutation, shared global state, and test-order coupling and found no concerns.
Rhetorical-Drift Audit: Pass — the PR describes a test-only contract guard with unchanged runtime behavior, and the entire diff is one focused spec.
Identity-Claim Audit: Pass — the Codex authorship footer is the contributor's own on-record bearer statement and includes its session anchor; it does not assert another maintainer's identity.
🧠 Graph Ingestion Notes
[KB_GAP]: None.
[TOOLING_GAP]: None in the delivered surface. The local full-suite time limit was disclosed transparently, and exact-head CI completed the full unit job successfully.
[RETROSPECTIVE]: A tightly bounded historical-regression spec is an effective contributor on-ramp: this PR preserves runtime scope while making the VDOM style-removal contract durable and reviewable.
N/A Audits — 📑 🪜 📡 🔗
N/A across listed dimensions: this test-only PR modifies no public/consumed API; its close-target ACs are fully covered by the static/unit L1 contract; and it touches no OpenAPI/MCP, skill, convention, or other cross-substrate surface.
🎯 Close-Target Audit
Findings: Pass — the newline-isolated Resolves #15196 reference is valid and does not over-close an epic.
🧪 Test-Evidence & Location Audit
Findings: Pass — assertions are independent expected values, every current branch is exercised, and no browser/component/whitebox layer would add unique evidence for this pure utility contract.
📋 Required Actions
No required actions — eligible for human merge.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 100 - Exact canonical placement and strict preservation of the test-only/runtime boundary.
[CONTENT_COMPLETENESS]: 98 - Every ticket AC and ledger row is represented; only the now-stale unchecked post-merge CI checkbox remains, and current CI already resolves it.
[EXECUTION_QUALITY]: 100 - Exact-head CI is green; assertions cover all branches, avoid tautology, and verify immutability and clone identity.
[PRODUCTIVITY]: 100 - The linked ticket is fully achieved in one focused file with no scope expansion.
[IMPACT]: 45 - Narrow test-only change, but it durably protects a core VDOM style-removal contract with a real regression history.
[COMPLEXITY]: 18 - Five straightforward deterministic cases in a 77-line isolated spec.
[EFFORT_PROFILE]: Quick Win - Small, high-confidence regression guard with meaningful core coverage.
Excellent first contribution: disciplined scope, readable evidence, and no unnecessary runtime churn. Approved — thank you, and welcome to Neo.
Resolves #15196
Adds focused unit coverage for
Neo.util.Style.compareStyles()across object deltas, missing inputs, string normalization, mixed input types, and input immutability. Runtime behavior is unchanged.Evidence: L1 (unit contract coverage in the repository test harness); L1 required (test-only acceptance criteria with no external runtime effect). No residuals.
Deltas from ticket
None substantive. The test cases follow the existing
test/playwright/unit/util/sibling-spec structure.Test Evidence
npm run test-unit -- test/playwright/unit/util/Style.spec.mjsin Node 24 / Debian trixie: 5 passed.npm run test-unit: attempted after generating the requireddist/parse5.mjs; exceeded the 6-minute local execution limit without reporting a test failure.Neo.util.Style.compareStyles(): covered bytest/playwright/unit/util/Style.spec.mjs.Post-Merge Validation
Authored by Codex (GPT-5, Codex). Session 019f6601-f07e-7611-bddb-177183150143.
Pull request overview
Adds focused Playwright unit coverage to pin the existing
Neo.util.Style.compareStyles()contract (object deltas, missing-side behavior, string normalization, mixed input types, and input immutability), without changing runtime behavior.Changes:
null-for-removal delta shape.💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
@neo-gpt-emmy(APPROVED) reviewed on 2026-07-15T19:50:36ZStatus: Approved
🪜 Strategic-Fit Decision
Peer-Review Opening: Welcome to your first Neo PR, @stantheman0128 — this is a strong first contribution. You kept the change exactly inside the ticket boundary, made the cases easy to read, and supplied honest evidence about both the focused run and the local full-suite limit.
🧭 Patch-Blind Premise Snapshot
#15196and its Contract Ledger; the changed-file list; currentdevversions ofsrc/util/Style.mjs,src/core/Util.mjs, andsrc/vdom/Helper.mjs; siblingJson.spec.mjs/String.spec.mjs; and the historical#6859fix.test/playwright/unit/util/Style.spec.mjsusing the canonical setup/import pattern, covering everycompareStyles()branch and input immutability without changing runtime code or introducing shared-state/test-order coupling.🕸️ Context & Graph Linking
#6859,Neo.util.Style.compareStyles(),Neo.vdom.Helper.compareAttributes()🔬 Depth Floor
Challenge (non-blocking): The missing-new-style regression case passes
null, while the VDOM disappearance path commonly suppliesundefined. Both values traverse the same!newStylebranch, and the repository history confirms this fixture would fail the original#6859implementation because that branch built the removal delta but did not return it. Anundefinedcase would mirror the production call shape more literally, but it would not increase current branch or regression coverage, so no contributor churn is requested.I also actively looked for omitted control-flow branches, tautological assertions, input mutation, shared global state, and test-order coupling and found no concerns.
Rhetorical-Drift Audit: Pass — the PR describes a test-only contract guard with unchanged runtime behavior, and the entire diff is one focused spec.
Identity-Claim Audit: Pass — the Codex authorship footer is the contributor's own on-record bearer statement and includes its session anchor; it does not assert another maintainer's identity.
🧠 Graph Ingestion Notes
[KB_GAP]: None.[TOOLING_GAP]: None in the delivered surface. The local full-suite time limit was disclosed transparently, and exact-head CI completed the full unit job successfully.[RETROSPECTIVE]: A tightly bounded historical-regression spec is an effective contributor on-ramp: this PR preserves runtime scope while making the VDOM style-removal contract durable and reviewable.N/A Audits — 📑 🪜 📡 🔗
N/A across listed dimensions: this test-only PR modifies no public/consumed API; its close-target ACs are fully covered by the static/unit L1 contract; and it touches no OpenAPI/MCP, skill, convention, or other cross-substrate surface.
🎯 Close-Target Audit
#15196.#15196is an enhancement/testing ticket and does not carry theepiclabel.Findings: Pass — the newline-isolated
Resolves #15196reference is valid and does not over-close an epic.🧪 Test-Evidence & Location Audit
d88a5329a1b2da47690c8eafcb4979a1e545fe12, including the complete unit job; GitHub exposes no separately designated required-check subset.git log --all -p -S"else if (!newStyle)" -- src/util/Style.mjsconfirmed that thenullfixture traverses and catches the historical missing-return defect just asundefineddoes.test/playwright/unit/util/Style.spec.mjsis the canonical util-unit location and follows sibling setup/import precedent.Findings: Pass — assertions are independent expected values, every current branch is exercised, and no browser/component/whitebox layer would add unique evidence for this pure utility contract.
📋 Required Actions
No required actions — eligible for human merge.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 100 - Exact canonical placement and strict preservation of the test-only/runtime boundary.[CONTENT_COMPLETENESS]: 98 - Every ticket AC and ledger row is represented; only the now-stale unchecked post-merge CI checkbox remains, and current CI already resolves it.[EXECUTION_QUALITY]: 100 - Exact-head CI is green; assertions cover all branches, avoid tautology, and verify immutability and clone identity.[PRODUCTIVITY]: 100 - The linked ticket is fully achieved in one focused file with no scope expansion.[IMPACT]: 45 - Narrow test-only change, but it durably protects a core VDOM style-removal contract with a real regression history.[COMPLEXITY]: 18 - Five straightforward deterministic cases in a 77-line isolated spec.[EFFORT_PROFILE]: Quick Win - Small, high-confidence regression guard with meaningful core coverage.Excellent first contribution: disciplined scope, readable evidence, and no unnecessary runtime churn. Approved — thank you, and welcome to Neo.