fix(build): pin image builds to a commit and tag by it — plus probe 1 of the resize finding #115
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/gateway-provenance"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes the loose end from #114: the live gateway could not be pinned because
nobody could say what was in it. Fixes the mechanism that produced that, then
uses it.
The mechanism
Both image build Jobs cloned
--depth 1 --branch mainand pushed a fixedopaque tag (
standalone-v13,standalone-v8). So an image recorded neitherwhat it was built from nor when — "v13" is not an answer — and rerunning
replaced the tag silently.
standalone-v13never existed in the registry atall, so the manifest had been edited to a tag that was never built while
something else was running.
Now both Jobs:
ref is worse than one that fails — the lesson
fire-build.shalreadylearned, applied to the two images it does not cover.
g-<sha12>/s-<sha12>), so the registry isself-describing and rebuilding the same commit is idempotent rather than a
silent tag move.
org.opencontainers.image.revisionas a label. A tag can bemoved; a label cannot.
crane config <ref>then answers the provenancequestion for any image, tagged or not — exactly what could not be answered
for the gateway this morning.
Used it
Built the gateway from
c9e35d78(current main) and rolled the cluster ontoit. Verified after the roll:
tag resolves to the pinned digest;
loginreturns 303; a viewer reachesice=connectedwith 129 frames and 22466 audio bytes — so the audio re-armfix still holds on a client bundle that now includes batches B and C.
This supersedes
sha256:63d6cfa7rather than reproducing it. Reproducingan unidentifiable image was never the goal; being able to say what is running
is. The DRIFT note in
stack.yamlis replaced by a real pin.Also: probe 1 of the resize/GPU finding, answered
No code change — the existing
[diag]counter was enough, so this cost a CDPsession rather than a lane cycle.
Cb.setViewport 854x590against a fresh worker with a live viewer:The renderer submits exactly one frame after the resize, then nothing. One
BeginFrame issued and never acked. So the renderer is not stuck upstream of
viz — a frame gets through; what dies is that single in-flight ack, dropped
when the Display was reconfigured underneath it.
This invalidates all three "third attempt" steps the finding proposed,
which is the useful part:
RenderWidgetHostView::SetSize") — it paints;awaiting_reconfigure_ack_waits for "the ack viz stillholds", and that ack no longer exists, so the wait cannot terminate. That is
why attempt 2 traded a crash for a freeze;
Stop()/Start(): the header's LIFECYCLE CONSTRAINT permits it only oncethe in-flight frame is known-drained, and viz clears
pending_frame_callback_only when the Display finishes the frame. Itnever finishes — so Stop/Start lands in precisely the forbidden window and
trips the same double-issue that aborted the GPU in attempt 1.
All three assumed the pre-resize frame completes eventually. It does not. The
finding now records where a fourth attempt should start instead — cheapest
being to invert attempt 2: hold the resize for the ack rather than holding
the ack-chain for the resize, which costs one frame of latency and needs no
viz internals.
Verification
make verify/make lint/lint-deploy-pinThe consistency check earned its keep: it caught this edit half-applied — env
set to
COMMITwhile the script still read$BRANCH, which would have failedat runtime.
Ran the finding's own cheapest next step against a fresh worker with a live viewer, driving Cb.setViewport over CDP. framesReceived: 600 -> 601 -> frozen at 601 for 30 s -> permanent death. The renderer submits exactly ONE frame after the resize and then nothing. The [diag] tick spanning the resize reads `issued=136 acked=135` where every one of the six before it was balanced (147/147, 148/148). So one BeginFrame was issued and never acked. The renderer is not stuck upstream of viz — a frame gets through. What dies is that single in-flight ack, dropped when the Display was reconfigured underneath it. This invalidates all three next steps the file proposed, which is the useful part: - probe 1's own hypothesis ("if the renderer is not painting, look at RenderWidgetHostView::SetSize") — it paints; - waiting longer: awaiting_reconfigure_ack_ waits for "the ack viz still holds", and that ack no longer exists, so the wait cannot terminate. That is why attempt 2 traded a crash for a freeze; - Stop()/Start(): the header's LIFECYCLE CONSTRAINT allows it only once the in-flight frame is known-drained, and viz clears pending_frame_callback_ only when the Display FINISHES the frame. It never finishes, so Stop/Start lands in precisely the forbidden window and trips the same double-issue that aborted the GPU in attempt 1. All three assumed the pre-resize frame completes eventually. It does not. Recorded where a fourth attempt should start instead — cheapest being to invert attempt 2: hold the RESIZE for the ack rather than holding the ack-chain for the resize, which costs one frame of latency and needs no viz internals. No code change. The next person gets a measured constraint instead of three plausible directions that are all closed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>