Repository navigation
feat: standby rows — a quit leaves live rows one arrival from open, for a day - #273
Merged
Merged
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Repository: olliegilbey/clave/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… the wire Plumbing only; nothing stamps it yet. A row whose agent ended with the session is STANDBY for a day (maintainer ruling, 2026-09-22): arrival opens it, where a dormant row waits for Alt+Enter. The host decides expiry against its own clock, because the bar has none. The stamp carries the tab the agent held, so a tab close that the agent's SessionEnd beat to the store can still be pruned. The record field is standby_stamp, not standby: the wire parity test caught the same name meaning two types.
Quitting zellij fires SessionEnd for every running agent, and the hook unbinds the tab. So the launch cannot read which rows were live. The hook now stamps a standby record at that SessionEnd, with the time and the tab. It stamps only when a tab was bound and the reason is `other` or absent; /exit, /clear, resume and logout stay dormant. The stamp clears on three events: - a bind (the row is live again); - a prune of the stamped tab (the human closed it, and SessionEnd reached the store before the prune); - a launch, when the stamp is older than 24 hours. A launch also drops the stamped tab, because zellij reuses tab ids across sessions. Tests: a_session_end_by_quit_stamps_standby_and_the_humans_own_end_does_not, a_standby_stamp_clears_on_bind_on_its_tabs_prune_and_on_expiry (watched red at the bind assertion first). Host lib 428 green; just gates green.
A row the last quit left live used to fall into the dormant block and wait for Alt+Enter, like any other dormant row. Ollie wants those rows to be easier to relaunch. - Rows render live, then standby, then dormant. A stale standby row cannot open, so it stays dormant. - The Alt+Up/Down ring now covers the live block and the standby rows. A walk, Alt+N or a click that lands on a standby row opens it at once. The cursor stays on that row, so a fast walk steps on to the next standby row before the opened tab takes focus. - The glyph is the half-filled circle (U+25D0) in the dormant ink. - The prune candidates and the witness settle include the stamped tab. When SessionEnd reaches the store before the prune, only the stamp still names the closed tab. Tests, each watched red first: standby_rows_sit_between_the_live_block_ and_the_dormant_block, a_walk_opens_each_standby_row_on_arrival_and_ skips_the_dormant_block, a_click_or_alt_n_on_a_standby_row_opens_it, only_the_executor_opens_a_standby_row (two models), a_closed_tab_prunes_the_standby_stamp_it_names, and the glyph table. Bar 308 green; just gates green.
The first cut stamped standby on reason `other` or no reason. A standby row opens when the human arrives on it, so a false stamp spawns an agent the human ended. A false dormant row costs one Alt+Enter. So only `other` stamps now. The QA drive's phase 5b fires SessionEnd by hand with no reason; that row now stays dormant, as the drive expects. Test: a_session_end_by_quit_stamps_standby_and_the_humans_own_end_does_not now lists no reason among the endings that do not stamp. Watched red first; host lib 428 green.
After the relaunch, 6c now also checks that every row bound before the quit (less the eager row) carries a standby stamp. A missing row means the quit's SessionEnd did not say `other`, or a bar pruned its tab while the session went down. Both are open measurements; this run settles them. After the beacon leg, one Alt+Down must bind exactly one more row, that row must have been on standby, and its bind must spend the stamp. The verdicts live in qa/lib.sh (standby_uuids, standby_expected_uuids, arrival_checks). The selftest makes a lost standby row, a quit that stamped nothing, an empty expectation and four wrong arrivals go red; script_hygiene.rs requires the readers there. Docs: standby row in UBIQUITOUS_LANGUAGE; FOOTGUNS "A launch cannot tell which rows were live"; README glyph, key and restart bullet with a generated status-standby icon; the QA-DRIVE 6c row.
`just mutants main` left two standby mutants alive: `<` to `<=` in Standby::live_at, and `*` to `+` in STANDBY_SECS. Nothing tested the exact 24-hour edge, and every test read the constant by name. The new tests pin both; the live_at flip was checked by hand to fail.
…s matching itself
- `just mutants` and `just mutants-file` pass `--jobs ${MUTANTS_JOBS:-4}`.
A serial run of 159 mutants took 23 minutes on a 12-core Mac.
- `remote-qa.sh qa-running` answered "running" with no drive alive: the
ssh shell's own command line held the pgrep pattern. Brackets in the
pattern stop the self-match. Measured on the devbox: it now answers
"finished" with no drive process.
QA run 33 (2026-09-23) failed 6c on both machines: of five agents running at a kill-session, one SessionEnd reached the store. The store seq went 75 to 80 across the relaunch on the box and the Mac alike, which leaves room for one hook write and no prune. So the other four rows were still bound when the launch ran, and it cleared them as dormant. A row still bound at the launch was live at the quit. The launch now stamps it before it clears the bind. /exit and a tab close unbind before the quit, so they stay dormant. A stamp SessionEnd already wrote keeps its own time. Test: a_launch_puts_every_row_still_bound_on_standby, watched red. Host lib 430 green; just gates green.
JetBrains Mono Nerd Font has no U+25D0, so the terminal drew the standby glyph from a fallback font, visibly larger than the dormant and live circles (Ollie's screenshot, 2026-09-23). nf-fa-adjust (U+F042) is in the bar's font at 600 units against 620 for the other two circles, and renders the same size. The README icon is regenerated from the same table.
Run 33 measured one hook write of five running agents (store seq 75 to 80 on both machines). FOOTGUNS records it beside the standby entry, and the QA ledger records runs 33 and 34.
The filled and hollow circles came from the base font, and the half circle from the Nerd Font icon set. They matched in size only in JetBrains Mono NF Mono (620 vs 600 units). Measured in the other Nerd Fonts installed here: FiraCode NF Mono 1080 vs 1200, and the non-Mono variants 620 vs 923 and 1080 vs 1800. The README asks only for a Nerd Font, so another install would see mismatched circles. The circles are now nf-fa-circle (U+F111), nf-fa-circle_o (U+F10C) and nf-fa-adjust (U+F042). All three are identical in every font measured. The glyph table test and the goldens pin the new code points. The README icons are regenerated. FOOTGUNS records the rule: glyphs that must match come from one set.
Ollie, 2026-09-23: an opened standby row went to the top of the live block. It must go where its frecency puts it. A row with no score ranks by its ordinal, and the new tab's birth touch minted a fresh top one. A walk is not a commitment, so it must not do that. - The bind of a standby row gives the tab the row's own ordinal. This overwrites a birth touch that landed first. - A birth touch that lands after that bind keeps the rank. touch_in now returns None when it mints nothing. - The quit's SessionEnd and the launch sweep carry the tab's ordinal into the row, the rule the prune already used (R2). Before this, a standby row came back ranked by an older prompt. A woken dormant row (Alt+Enter) is still a commitment and still goes to the top. Tests: both touch and bind arrival orders, the dormant contrast, the SessionEnd carry, the launch carry. The QA drive's arrival leg now checks that the tab kept the row's own rank, with a selftest case.
…inal just mutants over the rank change (since ea8cc0b) left two survivors in touch_in: '&&' to '||' in the keep guard, and the kept path's seq bump. The new test mints for a tab whose ordinal belongs to a row elsewhere, keeps for the tab's own agent at its own ordinal, and pins the bump. Rerun: 11 caught, 1 unviable, 0 missed.
…aunch The launch stamps every row still bound, because SessionEnd is lossy at a kill (QA run 33: one of five landed). It stamped `now`, the launch time, and the expiry pass after it used the same `now`. So a Monday launch after a Friday quit gave those rows a fresh day of standby, and a walk onto each spawned an agent. Found by the swarm review (correctness lane, confirmed by the verifier). The stamp now takes the store file's last write, read under the lock before the launch writes: the last moment the old session is known to have lived. It is a lower bound, so it errs toward dormant. Tests: the existing launch test now pins the stamp to a back-dated mtime; a new test back-dates the store past a day and sees the row come back dormant. Both were red before the fix. The Standby docs name both writers.
The host decided `standby` once, when it wrote the snapshot, and pushes only on change. An idle fleet writes nothing overnight, so a row past its 24 hours still read standby in the morning, and the first walk onto it spawned an agent. Found by the swarm review (correctness lane, confirmed by the verifier). The comments said the bar had no clock; it has one (`tick`, before every render and event). The wire now carries `standby_since`, the time the row went down, in place of the flag. One rule, `clave_types::standby_live`, serves the host's launch pass and the bar's `is_standby`. Tests: the bar's new clock test was red (the field did not exist); the standby row turns dormant at exactly 24 hours by `tick`. The clears test now also pins `standby_tab` on the snapshot, which nothing guarded (tests lane).
Swarm review, tests lane, confirmed by the verifier: - The hook's "no tab bound" case passed no reason, so the reason check alone kept it green. It now passes `other`, the quit's reason. Removing the tab check turns it red (checked by hand). - The standby fixture's uuid order matched its rank order, so deleting the standby block's sort kept every test green. The top-ranked row now has the later uuid. Deleting the sort turns three tests red (checked).
The devbox width flap is diagnosed and fixed (QA runs 30 to 35). Nine of eleven swarm-review lanes found what it left behind: - `width_deaf_reason`, a second copy of `width_effects`' gate ladder, with no test tying the two. It also logged `reason=owed` for every real ask, in the same render. - `own_tab_tiled_pane_count`, and the `panes=` and `client=` fields on the swap-width and load lines. Nothing reads them. - scripts/qa/width-probe.sh and width-probe-cli.sh. Nothing calls them. The swap-width line keeps `tab=` and `active=`, because phase 6c counts asks per tab. Tests, the wasm build and clippy are green; nothing that remains referenced the deleted items.
…the new glyphs Swarm review, staleness lane, confirmed by the verifier: - "Every other row comes back dormant" was untrue once standby landed. The justfile, qa-drive.sh, lib.sh, setup.rs and QA-DRIVE's "What it asserts" now name the standby rows and the arrival leg. - The glossary named SessionEnd as the only stamp writer; the launch stamps too (f1a0609). - QA-DRIVE claimed a `dev scenario` refusal that left with the restore. - A bar comment and the is_clave_binary doc named host callers that left with the restore. - The manual checklist and LEDGER D10 named the old circle code points.
Swarm review, staleness lane: lib.sh, qa-drive.sh and the FOOTGUNS entry said the quit's SessionEnd is the only writer. Since f1a0609 the launch also stamps every row still bound, because SessionEnd is lossy at a kill (QA run 33). Comment and prose only; the selftest is green.
Swarm review, guardrails lane: qa and drive started a second drive beside a running one, which force-pushed the checkout under it, restaged its sandbox and shared its log. Both verbs now refuse while qa-running would say running. Checked: bash -n, qa-running on the box (finished), script_hygiene green. Not fixed here: two worktrees still share the box's one sandbox. A plain clone is a main checkout, so it maps to clave-test whatever its directory (sandbox.rs key_for). The fix is a linked worktree per local worktree on the box, and it needs a launch to verify.
Ollie, 2026-09-23: "you are the one who kills." The old rule sent every sandbox kill to him, and each 6c relaunch cost a round trip.
Ollie saw opened standby rows hop in about 100 ms: bottom, top, then their own place. The new tab showed unranked before the store bound its agent; its bar's birth touch then gave it a fresh top ordinal and the opener's frecency; the bind then put the row's rank back. The bar now joins a tab to its row by the pane's launch command, `clave spawn <uuid>`, which zellij reports from the first frame (measured in the sandbox's list-panes). An exited pane joins nothing. The bar sends no birth touch for a standby row's tab, and none before its first snapshot, when it cannot tell that tab from a newborn. The host bind reset the rank for an expired stamp too; a row past its day is dormant, and waking one is a commitment. It now resets only for a live stamp. Tests: three bar tests failed first (the hop's exact order was the failure), the host rank test failed first on the expired case. The drive's arrival leg now checks that no birth touch reached the opened tab; the selftest proves that check goes red.
just mutants 7a0af62 left two survivors in spawned_agent's live-bind guard. This test fails under both (checked by hand).
QA-DRIVE.md's agent protocol was a run history with the steps buried in it, and still sent every kill to Ollie. It is now the loop that worked in runs 33 to 38: commit before staging, stage the Mac and the box in one message, the agent quits each sandbox at 6c and tears it down, one rerun for the known burst intermittent, fd sampling for changes that open tabs, then a ledger entry. A new section says how to add a drive check: a store trace, a verdict in lib.sh, a selftest case that proves it goes red. TESTING.md, CONTRIBUTING.md and the release runbook now carry the 2026-09-23 kill rule from AGENTS.md.
…s after the rebase
olliegilbey
force-pushed
the
feat/standby-rows
branch
from
September 23, 2026 11:13
41e0ffb to
84d9110
Compare
olliegilbey
added a commit
that referenced
this pull request
Sep 23, 2026
Workspace version, lockfile, README checkout line. The cut carries standby rows (#273): after a quit, the rows whose agent was live come back as standby for 24 hours, and an arrival opens one in place with no hop. It also carries the live-set restore removal (#271, breaking): a relaunch bakes one tab for the most recent row, and every other row waits dormant. Plus the frames-off width flap fix and the remote QA drive, both from #271. The tree under the bump is the one QA run 39 drove green on both machines (84d9110; git diff --stat 84d9110 dd40505 is empty).
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.
What changed
Standby rows. After a session quit, the rows whose agent was live come back as standby (◐) for 24 hours. Arriving on one (Alt+Up/Down, a click, Alt+N) opens it at once. Dormant rows (○) still need Alt+Enter. Stacks on #271.
other(a quit or a tab close). The hook is lossy at a kill-session (QA run 33: one of five landed), so the launch (clear_session_order) also stamps every row still bound, dated from the store's last write, not the launch. A tab close is pruned by the bar and leaves the row dormant.clave spawn <uuid>, which zellij reports from the first frame), and sends no birth touch for a standby row's tab.standby_since; the bar decides the 24 hours itself, because an idle fleet writes no snapshot for hours.Closes # (no issue was filed for standby rows)
Risk class(es) from the taxonomy (tick all that apply — they are cumulative):
config.kdl/layout.kdl/launch.kdl)PATH, doctor) → labelneeds-live-validationhost-untestableVerified automatically
cargo test --workspacecargo build -p clave-bar --target wasm32-wasip1cargo clippy --workspace --all-targets -- -D warningsbash scripts/qa/lib-selftest.shClass-specific evidence:
[Tab(1), Tab(2), Tab(3), Standby("u-s1")]); the host rank test failed first on the expired stamp.just mutants main: 153 tested, 9 missed, all known equivalents (run_*→Ok(()), a const-assert loop in clave-types,RowHeight::mode_atfrom feat!: remove the live-set restore; fix the frames-off width flap; the remote QA drive #271).just mutantsover the hop fix: 2 missed, both then covered by a test that fails under each (checked by hand).QA drive, live
Review lanes run
.claude/commands/fugu-review.md)coderabbit review --committed --base main)Findings DECLINED, with reasoning:
AgentRecord::unbindhelper for the three carry sites, a neutralquit: boolfor the SessionEnd reason, anamed_tabshelper, and evlog lines at the stamp sites: declined as churn, not defects.Could NOT be verified, and why
Live steps for the maintainer
Handoff and links
docs/dev/QA-DRIVE.md.