Repository navigation
fix(pixel): keep a passing show/hide proof across later passing checks of the same snapshot - #6754
Open
Lightheartdevs wants to merge 5 commits into
Open
Lightheartdevs wants to merge 5 commits into
Lightheartdevs wants to merge 5 commits into
Conversation
…s of the same snapshot Tower2 round 108 (website_create, integration e58f475): the transition assert-hidden(heading), click("#soldOutBtn"), assert-visible(heading) passed on snapshot f120c3cf. The model then inspected the same snapshot with assert-visible("h1"), click("#soldOutBtn"), assert-visible(heading). That plan passed, and #6740 did not mark it incomplete because the earlier proof covered the snapshot. The run guard still revoked the proof: it kept a proof only across passing plans with no click (#6626). The owner got "The requested show/hide interaction has not passed browser inspection." A passing inspection of the same snapshot now keeps the proof, with or without a click. Each inspection loads the unchanged snapshot again, so its passing steps cannot contradict the earlier transition. The proof now records each change it observed: the target, the control and the state after one click. A later passing plan that clicks that control once and then asserts that target in the other state is a failed test of the change, and it revokes the proof. A failed or incomplete receipt, page errors, another snapshot and another session still revoke it as before. The replay fixture holds the recorded create turn: owner message, model files and edits, publication receipts, inspection arguments and results, and the delivered text. On main every recorded inspection result and the delivered text are reproduced byte for byte. With this change the same replay delivers the verified preview. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y contradict it Review of #6754. The previous commit revoked a kept proof only when a later passing plan named the proved target and control with the same locators, clicked once from load, and asserted the other state. Two gaps followed: - Another locator for the same element kept the proof. After the round-108 proof, assert-hidden("#midnightCard"), click("#soldOutBtn"), assert-hidden("#midnightCard") passed at 1280 on a page where the click left the card hidden, and delivery said the check passed. Main said it had not passed. The model does switch locators between plans (round 108: role/name, then "#soldOutBtn"). - A proof whose change was seen only after a preparatory or second click recorded no changes, so no passing plan could revoke it. The check no longer depends on locators. After any click, each passing assertion must be in the state that every proved change produced, or name a proved target exactly in its proved state. Otherwise it may be a proved target left in the other state, and the proof is revoked. A proof without a one-click change is kept only across plans without a click. Plans without a click keep the proof as since #6626, and the round-108 later plan still keeps it. The proof now records only each changed locator and its result state; the control is no longer needed. A later click on another control that leaves an element hidden now revokes a reveal proof, as on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…exact targets Review of #6754 found later passing plans that showed a requested change failing while the proof survived: - a proof whose change followed a preparatory click (cookie banner) or a second click (toggle) recorded that change as caused by one click; - a later plan with two clicks compared a toggle's second-click state with the one-click proof; - after one click, any assertion in the proved state was accepted on any locator, so a card a self-hiding button never revealed, a summary a reveal never hid, or a panel a tab never replaced kept the proof. A proof now records a change only from a plan with exactly one click. A later plan with more than one click keeps nothing. With one click, each assertion must name a proved target exactly, before the click in its load state and after it in its proved state; anything else revokes, as main does for every clicked plan. Plans without a click keep the proof (#6626), and the tower2 round-108 shape, which re-asserted the proved heading, still keeps it. The simulated-page regression file checks every reviewer shape across the direct, tool_call and nested transports; against the previous head 53 of its and the matrix's cases fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…iewport Review of 2af6b12 found two false passes where the PR kept a proof that main revokes. Before the click, only a proved target named by the exact proved locator revoked, so an alias of that target already in its proved state (p#details, a heading role/name, "#details ", a conceal mirror, the second target of a two-change proof) kept the proof. The one click's locator was never checked, and the inspector clicks only rendered elements, so clicking the target of a reveal proof kept it too. In each case the later plan ran at another width, where the page already showed the target in its proved state at load, and its own receipt showed it. No locator rule can tell such an alias from the unrelated "h1" that the round 108 later plan asserted before its click. A proof now records its viewport, and a later plan with a click keeps it only at exactly that viewport, where the snapshot loads as the proof saw it; at any other viewport it revokes like main. Plans without a click are unchanged (#6626). Both round 108 inspections ran at 375x667, so the recorded replay still keeps its proof. Tests: section I of the multiclick file adds the review's false passes (CSS, role/name and click aliases, the conceal mirror and a two-change proof) on all three transports, and H3 shows a round-108-shaped plan at another viewport revoking. G2 runs the lifecycle faults against a one-click proof and a later plan that keeps it when nothing is wrong. The proof-shape matrix now runs each later plan at the proof's viewport, at the same width with another height, and at another width; the fault matrix checks click plans at the proof's viewport and adds a click at another viewport. The comments now state the rule the code applies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Sep 26, 2026
…08 replay The round-108 replay fixture and its tests carried identifiers of the qualification host and run. Replace them with neutral values without changing what the replay exercises: - rename the fixture to transition-proof-round108.json and drop the host name from the test names and comment; - rename the workspace directory to night-garden-site in the owner message, the exec, write, edit and read arguments and the publication receipts (the snapshot digest and siteId hash file names relative to the directory and their bytes, so every recorded receipt still validates); - use /home/user for the host workspace path of the exec cwd and the read; - use a neutral run ID, session ID and session key in the valid shapes; - remove the host, integration commit, run ID, session ID and timestamp from the evidence text, and say which values are neutralized. The recorded inspection results, the model-authored bytes, the answer and the delivered text are unchanged. On main's plugin code the two round-108 tests still fail where they did before (the later passing plan drops the proof); with this branch they pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Fleet round 108, website_create journey, on main + #6741 + #6747; the retention code is the same on main.
f120c3cfand inspected it at 375 withassert-hidden(heading "Midnight sold-out concert"),click("#soldOutBtn"),assert-visible(heading). The inspection passed as a show/hide transition.assert-visible("h1"),click("#soldOutBtn"),assert-visible(heading). This plan passed. It has a click but no transition.Root cause
The code is in
tool-loop-guard.mjs, inafterToolCall. A prior proof survived a later inspection only ifboundStaticPreviewInspectionaccepted it, and that check (#6626) required that no step is a click. The second plan passed, used the same snapshot and ran in the same session, but it contained a click. As a result:retainInteractionwas false.boundVisibilityInspectionreturned no new proof, because the plan is not a transition.state.workspaceVisibilityInspectionwas set toundefined.workspaceVisibilityInspectionPassed, which now failed, so the delivery reported the interaction as unverified.The later result was not classified as failed or incomplete. The retention rule simply discarded the proof. That rule also contradicted the prior-proof exemption in #6740.
Fix
A change seen only after a preparatory or second click is not recorded.
isErrorresultboundStaticPreviewInspectionis replaced bypreservesVisibilityInspection(proof, params, result, preview).Why the viewport
Before the click, no locator rule can tell the proved target under another name from an unrelated element. The round-108 later plan asserts
h1before its click, and an alias such asp#detailshas the same shape.At another width, the page may already show the target in its proved state at load. A plan that asserts it there under an alias passes, and its own receipt shows the change not happening. A click on the proved target works the same way, because the inspector clicks only rendered elements.
At the proof's viewport, the snapshot loads as the proof saw it. So these observations can pass only if they agree with the proof.
Review history
93df24d kept the proof unless the later plan re-asserted the target with byte-identical locators. Two reviews found two gaps: locator aliasing, and proofs whose change followed a preparatory click. fa45a29 replaced the rule with a locator-independent state rule.
fa45a29 accepted any assertion after the click that was in the proved state, on any locator. A review found pages where the requested change failed at the later width and the proof survived: a cookie banner, a toggle, two targets, tabs, and a self-hiding button. 2af6b12 fixed this in three ways:
2af6b12 still kept two shapes that main revokes. The review of 2af6b12 confirmed both on all three transports:
p#details,heading "Details","#details ",.promofor#promo(the conceal mirror), and the second target of a two-change proof.In each case the page showed the target at load at 375 but not at 800. The proof ran at 800 and the later plan at 375. The 2af6b12 comment and commit message also claimed a stricter before-click rule than the code applied.
3968252 binds a later plan with a click to the proof's viewport.
9748a99 (this head) is test-only. It removes host, run and session identifiers from the round-108 replay:
transition-proof-round108.json, and the test names and comment no longer name a host;night-garden-sitein the owner message, the tool arguments and the publication receipts;/home/user/...;The snapshot digest and siteId hash file names relative to the published directory and their bytes. All three recorded publication receipts (sha256, siteId, entrySha256, bytes) still match the replayed files. Plugin code is unchanged.
Behavior compared with main
assert-visible(p#details)alone at 375, and it keeps the proof on both main and this PR. This PR does not change that.Evidence
The replay fixture is
tests/transition-proof-round108.json, built from the recorded create turn. It contains:The workspace directory name, the host home directory, the run ID and the session identity are neutral values. Everything else is as recorded.
On main 6cba572, the replay reproduces two things byte for byte: the recorded tool output of all four inspections, and the recorded delivery ("The requested show/hide interaction has not passed browser inspection. ..."). With this change, the same replay delivers the verified preview ("Browser inspection passed for the submitted show/hide checks only; ..."). Both inspections ran at 375x667.
A read-only scan of the recorded qualification evidence (the portal observation files of rounds 100–114, all hosts) found 10 sessions with 31 inspection calls.
Tests
Round-108 replay (
inspection_transition_coverage.test.mjs), through the real guard and the real inspection tool: the recorded turn now delivers verified.Round-108 revocation replay: each of these still revokes the proof:
Simulated-page file (
transition_proof_retention_multiclick.test.mjs): the real guard, the real registered inspection tool, and a page state machine, so a plan passes only if the page behaves as asserted. Every case runs on the direct,tool_calland nested Tool Search transports.isError, republish and another session all revoke.Unit retention matrix (
preview_interaction_assurance.test.mjs, direct and Tool Search transports): the click faults now run at the proof's viewport, so the locator rules decide them. The newclick-other-viewportfault revokes.Proof-shape table (
preview_interaction_assurance.test.mjs): 23 later plans × 2 transports × 3 viewports, which is 138 tests. The viewports are the proof's 800x600, 800x720 and 1280x720.Red check (the updated test files run against 2af6b12): 36 of 301 fail.
click-other-viewport.With 3968252, the four affected files pass 339 of 339.
Reviewer files run against 3968252:
Red check after the scrub: the updated test files run against main 0a63258's plugin code. The four recorded inspection outputs still replay byte for byte. Both round-108 tests still fail where they did before the scrub: after the later plan, verification is
failedwhere the test expectspassed. G2 and H fail too.preview_interaction_assurance.test.mjsandcontrol_names_transition.test.mjsfail to importpreservesVisibilityInspection.Full Linux suite (
remote-js-test.sh):Overlap with open PRs
Checked with
git merge-treeagainst 3968252. 9748a99 edits only lines this PR adds:tool-loop-guard.mjs.preview_interaction_assurance.test.mjs.🤖 Generated with Claude Code