Skip to content

HAC-341: pre-freeze cleanup — framing, contrast, and one stale name - #28

Merged
qmarcelle merged 3 commits into
mainfrom
hac/341-prefreeze-cleanup
Aug 18, 2026
Merged

HAC-341: pre-freeze cleanup — framing, contrast, and one stale name#28
qmarcelle merged 3 commits into
mainfrom
hac/341-prefreeze-cleanup

Conversation

@qmarcelle

@qmarcelle qmarcelle commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

NO EVIDENCE SEMANTICS CHANGED. scene-manifest.json and experiments/** are 0 changes. The view model moves by exactly one label.

Correction. An earlier revision of this description claimed media/hac-334/** was untouched. That is no longer true, and the reason is worth recording: media/hac-334/bin/build-visual-model.mjs reads media/hac-341/evidence/view-model.json as its source for the cloud path, so renaming hop 6 propagated there. The visual-suite determinism gate caught it.

I diffed the visual model leaf by leaf before rebuilding: exactly two leaves differ, both the same label (assets[3].composition.path[5].label and assets[4].composition.layers[4].nodes[0]). No geometry, no colour, no evidence value moved. The two masters that draw them — IL-DIAG-011, IL-DIAG-012 — plus their PDFs and rasters were rebuilt, and the HAC-335 registry digests follow.

The colour token did not reach HAC-334; those masters carry resolved hex. A single source of truth means derived artifacts follow it — the correct response was to rebuild, not to special-case the gate.

Four surgical corrections from an external contract audit, plus cleanup. No redesign.

P1 — cloud L1 invited HAC-330/HAC-340 stitching

Cloud L1 rendered total 105 <= 130 beneath EXECUTED. The value is real — the protected target's own recorded bound — but an inequality against the same bound as the HAC-330 joint constraint, one proof-class switch away from 120 <= 130, can be chained by a fast reader into "same experiment, confirmed on cloud." That is precisely the reading the claim boundary denies and the one SB-06 works hardest to prevent.

The invariant moves to L2 → Protected mutation, with revision-before/after and an explicit note that it is not the HAC-330 joint bound. L1 now shows the packet's own caption — "Effect. Distinct from observation." — which reinforces the EXECUTED/OBSERVED distinction instead of competing with it.

The gate is semantic, not a blacklist. It asks where effect.invariant is consumed (via the renderCloud source region), so changing the number cannot evade it — and it also fails if the field stops rendering anywhere, because demoting evidence must not become deleting it.

P1 — light COUPLED under the contrast floor

Measured 4.01:1 against the sunken light surface, under the 4.5:1 floor for the 8.5–10px label and chip text that carries the state.

L on sunken on card
before 0.58 4.01 4.26 ❌
after 0.52 5.15 5.48 ✅

Hue and chroma unchanged, so the state still reads as the same blue. Dark peer was already ~8.6:1 and is untouched. Fixed at assets/tokens/colors.css so the storyboard inherits it. The gate pins the measured lightness and fails if hue or chroma move without a fresh browser measurement, or if the cockpit's re-declaration drifts from the token.

P2 — one name for the decision artifact

The adapter labelled hop 6 ALLOW + authorization receipt while the decision card and the storyboard both said ALLOW + receipt.

The longer phrase is not falsesrc/authorization/receipt.ts calls it exactly that, and the audit's original P0 reading was retracted on that basis. But two names for one artifact on one surface invites reading the longer one as a lifecycle state these packets never emitted. Rendered labels now agree. Prose describing the artifact is untouched, including the frozen HAC-333 factualBindings entry — the gate governs rendered labels, not descriptions.

P2 — architecture link, and documented limitations

Cloud L3 now links the existing IL-DIAG-012. No new architecture artifact, no storyboard reordering — seq.architecture already sits correctly at step 8. Deliberately not added to local L3: that asset is class B and would be a cross-class leak.

Both colour limitations are now documented in-repo rather than only in the PR trail: the shared Decision/Effect hue (the grammar has no ALLOW hue, and the only unused candidate is the forbidden authorization green), and the contrast measurement above.

Cleanup

Five orphaned capture PNGs from earlier passes removed — the manifest referenced only four. Only IL-COCK-013 changed dimensions (804 → 817, the new L2 section).

Verification

9 gates PASS · 437 tests · typecheck · build. 7 new negative proofs, all confirmed to fire: invariant returning to L1, invariant deleted rather than demoted, decision-hop label drift, authorization receipt reintroduced in a rendered surface, coupled lightness raised, hue/chroma changed without re-measure, cockpit drifting from the token.

Browser-verified on the branch at 1440×900: contrast 5.15:1, cloud L1 free of 105 <= 130, L2 carries it, L3 links architecture, local L3 does not, no console errors.

The full viewport/zoom/reduced-motion/keyboard matrix was already run on merged main and is treated as project evidence; the changed surfaces re-ran through the freshness and package gates, which forced the recapture.

Four surgical corrections from an external audit. No evidence semantics
changed; scene-manifest.json, media/hac-334 and experiments/ are untouched
and the view model moves by exactly one label.

Cloud L1 rendered `total 105 <= 130` beneath EXECUTED. The value is real —
the protected target's own recorded bound — but an inequality against the
same bound as the HAC-330 joint constraint, one proof-class switch away
from `120 <= 130`, can be chained by a fast reader into "same experiment,
confirmed on cloud". That is the reading the claim boundary denies and the
one SB-06 works hardest to prevent. The invariant moves to L2 under
Protected mutation, with a note that it is not the HAC-330 joint bound.
L1 now carries the packet's own caption, which reinforces the EXECUTED vs
OBSERVED distinction instead of competing with it.

The gate for that asks where `effect.invariant` is consumed rather than
blacklisting the current number, so changing the value cannot evade it —
and it also fails if the field stops being rendered anywhere, because
demoting evidence must not mean deleting it.

The adapter labelled hop 6 "ALLOW + authorization receipt" while the
decision card and the storyboard both said "ALLOW + receipt". The longer
phrase is not false — src/authorization/receipt.ts calls it exactly that —
but two names for one artifact on one surface invites reading the longer
one as a lifecycle state these packets never emitted. Rendered labels now
agree; prose describing the artifact is untouched, including the frozen
HAC-333 factualBindings entry.

Light COUPLED measured 4.01:1 against the sunken surface, under the 4.5:1
floor for the 8.5-10px label and chip text carrying it. L 0.52 measures
5.15:1 on sunken and 5.48:1 on card; hue and chroma unchanged, dark peer
(~8.6:1) untouched. Fixed at the token so the storyboard inherits it. The
gate pins the measured lightness and fails if hue or chroma move without a
fresh browser measurement, or if the cockpit drifts from the token.

Also: cloud L3 links the existing IL-DIAG-012 rather than authoring another
architecture artifact, and deliberately not from local L3 — that asset is
class B and would be a cross-class leak. Both colour limitations are now
documented in-repo rather than only in the PR trail.

Five orphaned capture PNGs from earlier passes removed; only IL-COCK-013
changed dimensions (804 -> 817, the new L2 section).

7 new negative proofs. 437 tests, 9 gates, typecheck, build.
Copilot AI lite review requested due to automatic review settings August 18, 2026 13:16
@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
interlock Ready Ready Preview Aug 18, 2026 1:28pm

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@codecov

codecov Bot commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

The visual-suite determinism gate caught this, which is what it is for.

media/hac-334/bin/build-visual-model.mjs reads
media/hac-341/evidence/view-model.json as its source for the cloud path, so
renaming hop 6 moved two leaves in the visual model — assets[3] path label
and assets[4] node — and the two masters that draw them, IL-DIAG-011 and
IL-DIAG-012. Their PDFs and rasters follow.

Diffed leaf by leaf before rebuilding: exactly two leaves differ, both the
same label. No geometry, no colour, no evidence value moved. The colour
token did not reach HAC-334 at all; those masters carry resolved hex.

So my earlier claim that media/hac-334 was untouched no longer holds, and
the correction is to say so rather than to special-case the gate. A single
source of truth means derived artifacts follow it.

Also: compare the token's parsed chroma and hue with a tolerance instead of
exact float equality (SonarCloud S1244).
@sonarqubecloud

Copy link
Copy Markdown

@qmarcelle
qmarcelle merged commit 5c04ed9 into main Aug 18, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants