Repository navigation
feat(operator): adopt operator contract 1.14.0 and show why a draining run hasn't finished - #740
Conversation
…on the live run only
…ded card The stream owns the card's reason line while it paints there, so a list refresh no longer wipes the wait label or the checkout preparation headline.
…and release the reason line in one place Pin the owner marker and the wait selectors across modules, check fixture wait reasons against the vendored list, and cover backpressure, failure-label ownership and the attach-start release.
fro-bot
left a comment
There was a problem hiding this comment.
Verdict: PASS
I reviewed the full diff for src/, public/ and the CSS, and skimmed the test additions. I did not run the test suite, so the PR description's passing-checks claim is untested by me.
Blocking issues
None
Non-blocking concerns
- Exact-match contract pin (
src/gateway/operator-contract/version.ts,PINNED_CONTRACT_VERSIONinpublic/operator-stream.js). The bump from 1.13.0 to 1.14.0 is a hard cutover. A gateway older than fro-bot/agent v0.128.0 will fail the ready-frame version check. The PR description already says to deploy and roll back the dashboard and gateway together. This is an operational risk, not a code defect. Confirm the gateway pin bump is ready to land in the same window before merging. - Stale
waitReasonafter a reconnect.nextStreamStatekeepswaitReasonthrough a liveno-snapshotreset.getWaitReasonLabelonly requiresconnection === 'live'. The design assumes the gateway re-sends current status on (re)connect, so a stale reason would be replaced. That assumption sits in the gateway, so no test in this repo can confirm it. The PR's "Not verified" section already covers this. The post-deploy check on a real draining run should include a reconnect. - Security. No findings.
- Both parsers check the wire value against an allowlist (a
Setguard behind atypeofcheck) and accept it only onrunningframes. - The browser renders a dashboard-owned
Maplabel viatextContent, never the wire value. - The reason stays out of
RunSummary, the finished-run cache and the list. - The fixture harness additions (
approvalSettleHooks,pacedThenHeldStream) are dev-only. They clean up on abort, cancel andresetFixtureHarnessForTesting.
- Both parsers check the wire value against an allowlist (a
Missing tests
None. Coverage looks proportionate:
- the conformance, SSE reader and stream-core tests cover parsing, transient-state semantics and label precedence;
- the fixture-harness tests cover the three new scenarios;
- a run-index test covers the
data-reason-owner="stream"guard.
The one untested path is real-gateway emission, which the PR already calls out.
Risk assessment: LOW
The change is additive. Input goes through allowlists, rendering is textContent only, and there are no new credential, auth or write paths. The main exposure is the exact-match version coupling to the gateway, which is documented and handled by a paired deploy. The data-reason-owner change touches DOM shared between the list and the stream. Its release logic is centralized in releaseReasonLine and has dedicated tests.
Run Summary
| Field | Value |
|---|---|
| Event | pull_request |
| Repository | fro-bot/dashboard |
| Run ID | 40985646720 |
| Cache | hit |
| Session | ses_e75973d17ffeVRzQald5KOM2c6 |
fro-bot
left a comment
There was a problem hiding this comment.
Verdict: PASS
This is a re-review. The only new commit since my last review is 3bcec03, a merge of main into the branch. Between 072800c and 3bcec03 it changes one line, in .github/workflows/main.yaml. That line bumps the pinned npx impeccable from 4.7.0 to 4.8.0 in the Design Check step, and it comes from main, not from this PR. None of the files under src/, public/, web/src or test/ changed. The PR description also gained a sentence asking for a reconnect-during-drain check after deploy, which covers my earlier reconnect concern.
My earlier assessment still holds. I did not run the test suite.
Blocking issues
None
Non-blocking concerns
- Exact-match contract pin (
src/gateway/operator-contract/version.ts,PINNED_CONTRACT_VERSIONinpublic/operator-stream.js). A gateway older than fro-bot/agent v0.128.0 will fail the ready-frame version check. The PR documents the paired deploy and rollback. Confirm the gateway pin bump lands in the same window. - Reconnect behaviour depends on the gateway re-sending current status. No test in this repo can confirm that. The updated "Not verified" section now asks for a reconnect check during a real draining run, which is the right post-deploy check.
- Security: no findings. The wire value is checked against an allowlist in both parsers and accepted only on
runningframes. The browser renders a fixed label viatextContentand never the wire value.
Missing tests
None. The only untested path is emission from a real gateway, which the PR calls out.
Risk assessment: LOW
The change is additive. Input goes through allowlists, rendering is textContent only, and there are no new credential, auth or write paths. The main exposure is the exact-match gateway version coupling, which is documented and handled by a paired deploy.
Run Summary
| Field | Value |
|---|---|
| Event | pull_request |
| Repository | fro-bot/dashboard |
| Run ID | 40988971696 |
| Cache | hit |
| Session | ses_e75973d17ffeVRzQald5KOM2c6 |
Closes #729.
Adopts operator contract 1.14.0. A draining run's status frame can now say why the run hasn't finished yet, and the expanded card shows that reason on a quiet line under the repo name.
What changes
waitReasonwire type is vendored without the gateway-only helpers.waitReasononly on arunningstatus frame with a known value. Unknown values, or a reason on any other status, are dropped, and the frame itself is still kept.data-reason-owner="stream"), and a list refresh leaves that line alone. This also fixes a refresh wiping the checkout preparation headline.wait_reason_draining,wait_reason_with_approvalandwait_reason_unknown.Rollout
The contract version is an exact match, so this release only works against a gateway on contract 1.14.0. That means fro-bot/agent v0.128.0 or later. Deploy the dashboard and the gateway pin bump in the same window, and roll them back together.
Screenshots (fixture harness)
Verified
bun run check-typesandbun run lintpass, along with the web suite and the root suite.Not verified
/operator/healthforcontractVersion: "1.14.0"and watch a draining run, including a reconnect during the drain. The label should keep showing the last reason.