0.60.4
0.60.3 was tagged but never published: its publish run failed tests/keypad.test.ts on Linux. Off a Mac a Ctrl+C asks the page whether text is selected (getSelection), and the new ZNI-F001 test’s page had no getSelection; on the Mac the release was checked on, that branch is skipped. The test’s page now has one, and the pad’s tests pass with a Linux navigator. 0.60.4 is 0.60.3 with that test fixed.
A slow Herdr at start no longer leaves a session off the net
Section titled “A slow Herdr at start no longer leaves a session off the net”A main (the “sb 主塔台實體化” session) reloaded at load 30 to 50 and came back with no sb_* pane tokens and none of the joined-only tools (boss_status, board_set); other mains in the same workspace kept theirs, and intercom stayed connected. The start asks Herdr where the session runs (pane current, then the workspace list) before it joins; one of those calls timed out, and the session took the failure as an answer: it barred itself until the next reload.
- Only a definitive answer bars. A head workspace or a sub workspace bars for good, as before. A Herdr call that failed leaves the session unplaced, not barred: the boss gets one warning (“could not tell whether this is a sub workspace: …; it asks again”), and the check is asked again after 1 s, 2 s, 5 s, then every 15 s.
- The boss does not wait for the timer.
/bossand asubagentorsubagent_resumecall ask again at once (or share the ask already in flight) before they are refused. (No tool exists before the join:boss_promoteand the net tools are added by it.) - A failed join is retried too. A join that failed at start (intercom not connected within 15 s, no owner elected, or the second look at the pane failing before any channel exists) is retried by the same timers; before, only a
connectionorownerevent on the channel retried it, and a failure before the channel existed produced no event at all. A join that waiting cannot fix (pi-intercom not loaded, a tab id too long for a namespace, a broker withoutextension-bus-v1) is told once and not retried;/bosstries it again. - Once, and quietly. When a retry succeeds the normal start runs once (join, restore watch, opener and restore handling): no second join, no second “joined” note. The boss gets one info line when the session joined after retries, and each warning (the check’s, the join’s, a pane without
terminal_id) is told once per start. What the role record says is read at the first attempt only, so a retry does not forget the record a session wrote when/bossmade it main while the retry waited. A/new,/resume, or shutdown ends the old start’s retries (no timer outlives them, none keeps the process alive, and a failure of the old start’s join or check that comes late tells and arms nothing). - Two old edges closed with it. A check that answers after the session quit no longer joins it. A
/resumeinto a tower’s session file no longer keeps the bar of the member that was unplaced before, which let the tower’ssubagentcalls through.
Wire: none. New dependency seam joinRetryMs (the waits; the last repeats).
Zen: a card is never taken from you, and Enter presses the card’s button
Section titled “Zen: a card is never taken from you, and Enter presses the card’s button”Boss, on 0.60.2: 「terminal prompt 的 confirm 無法用 enter,確認也無法用 enter,然後我正在操作的時候,被強制切呼吸打斷,我覺得不該卡片已經跳出來了,還強制切回呼吸」「新進來的卡片也是,應該放在背景等候排隊,永遠不要打斷使用者正在進行的操作」. Asked how far Enter should go, he chose 「全部卡片都用 Enter」. Decision Z-D20 (docs/specs/2026-11-01-zen-view.md, Never interrupted, and Enter acts) supersedes parts of Z-D19 and the old “No default Allow”.
- A new card never takes the screen by itself. In 0.60.2 only the breathing circle held a card back: with a session for company, with the head’s whole conversation open (a wheel or swipe up on the circle, H, or the link), a card took the screen with the bowl. Now it queues everywhere. The cue says how many wait (under the head strip’s input, under the name on a session’s screen, on the head’s whole conversation); Enter, or a tap on the cue, takes the next one. The terminal layer stays as it is when a card arrives. The page’s reminder for a page nobody looks at stays, one per card. A card that resolves while it waits (answered in the terminal, the unit moved on) is never drawn, plays no bowl or knock, and leaves the count.
- A card on the screen is never replaced or pulled away. When its question ends while you read it (answered in the terminal, the unit’s next question, the unit gone or closed, a snapshot gap) the card stays with the question you were reading, every answer on it off and Already answered elsewhere (a failed unit keeps its error line and low bowl). Its one button, Back to the breath, takes the focus; Enter, Esc, and a tap close it, then the pause and the breath; the unit’s next question waits for Enter. The knock rings once; a question listed again by a later snapshot brings the card back to life with no second sound. Your own accepted answer still ends the card with its 1.2 s outcome and the pause. The 1.3 s inert card and the 20 s draft hold are gone, since nothing is drawn over a card and nothing waits to take a screen.
- Enter presses the primary control of every Zen card. When you take a card the focus lands on it: a dialog’s first choice (a forwarded dialog’s too), Open the terminal, Trust, Handle, Allow, Confirm, the pair card’s number field (Enter submits the number), a terminal step’s Run and a pane’s line. Enter never fires while a text field has the focus (the companion’s box, the head’s input, a card’s box, a terminal’s key sink), and a focused button keeps its own Enter. A held Enter is kept from the button it landed on.
- The key pad’s confirm takes Enter in Zen. The terminal layer’s Send Enter, Send Escape, and Send key confirms take the focus on the button that sends; Enter confirms. A repeating key, an Enter whose keydown began before the confirm showed, and Space confirm nothing. Standard and Geek keep the focus on Cancel; the pad is shared code and the difference is one flag, set only when the page’s view is Zen (the terminal card’s confirm in Zen’s card does the same).
- Second round (boss, 2026-11-06, 「永遠不要打斷」; review ZNI). Three rulings and ten review fixes, all in Zen:
- A terminal opened from a card never closes itself. The layer stays until you press Back to Zen (or Esc Esc): not at the unit’s first work (an armed terminal), not when a prompt’s own Enter is taken, not when a pane closes. A done step says so in a quiet line in the bar (「指令已送出,可以回到禪」, 「單位繼續工作了,可以回到禪」, 「這個窗格已關閉,可以回到禪」), and the card in the layer is put out, since a second Run would only send another Enter.
- A session for company that ends or loses control stays on the screen with a quiet 「已結束」 or 「已失去控制」, its log, its box read-only and its Send off (the composer’s own words say why), until you leave it: Esc, Back to the breath under its name, the palette, or
]. It used to turn into the breathing circle at the next snapshot. - A change of the server’s default view never switches a page that is showing Zen out of it. It applies at the next load, and at once to a page on Auto that is not in Zen. (The page you leave Zen on, or a view you pick, lets Auto follow the server again.)
- A typed key never reaches a confirm (ZNI-F001): in Zen’s terminal, a key that is typing while the key pad’s or the card’s confirm shows moves the focus to Cancel and is dropped, and the Enter that ends the line cancels. A double Ctrl+C, then
abcand Enter, confirms nothing. - Smaller: the knock rings once for a card, however many times a snapshot drops it and lists it again (F002); a revived card’s focus goes back to its first control, not to Maybe later (F003); on an ended wait or pair card Handle and the number field are off, the card does not say offline, and Enter closes it, also when the palette or the terminal layer was open over it (F004); a read-only dialog’s card has an Enter control, Open the terminal, and a
secret_drop’s is Maybe later (F005); a card that ends says This unit has left when its unit left the net or closed, not answered elsewhere (F007); the companion’s box no longer redraws the page on every keystroke (F009); the cue under a session’s name runs the whole width and balances its lines at 390 px (F010). The system reminder for a page nobody looks at stays one per waiting card, the ones behind a shown card too (F006: the spec said otherwise and is corrected). - Shared code touched outside Zen, with Standard and Geek unchanged:
confirmbar.ts(the typing rule is under Zen’senterflag),waitpanel.ts(update(on, ended), Handle off for an ended Zen card only),view.ts(a page showing Zen is held when the server’s default moves; a Standard or Geek page never is).
- Third round (boss rulings 2026-11-06; review ZNR, P0=P1=P2=0).
- A new version of the page waits for the breath. When the server’s build changes (a newer pi-straw-boss took the server over, as releasing 0.60.3 does to every open page), a page used to reload at once, Zen included: the card, the terminal layer, and any draft went. Standard and Geek still reload at once. A page showing Zen does not while a card, the terminal layer, a session for company, the head’s conversation or its unfolded input, the palette, or a menu is open (the pause after a card is not the breath yet): one quiet line at the foot (the page keeps that foot clear, so it covers nothing) says 「有新版本,回到呼吸時會更新」 / A new version is ready; it loads when you’re back at the breath, and the page reloads, once, when Zen is back on the breathing circle with nothing open (looked at every second), at once while the page is hidden, and when Zen is left. With nothing open it reloads at once, with no line.
- The confirm waits 400 ms in Zen (ZNR-F007). An Enter within 400 ms of the key pad’s or the card’s confirm showing confirms nothing, so the second tap of a double Enter cannot send what the first one asked about (
unread, an ending command), on top of the repeat, earlier-keydown, and typing guards. - Settings from a held page returns to Zen (ZNR-F004). A page the server’s default view moved away from while it showed Zen (the hold above) that opens the settings page shows Zen on leaving it, as the route row says. Leaving Zen itself or picking a view still lets Auto follow the server.
- The head’s conversation is not a session that ended (ZNR-F002). With the whole conversation open, a snapshot without
head(an older server, the demo) no longer makes it 「已結束」 then 「已失去控制」 with a dead second way back: it stays open, its box off, and Back to the breath and H work; the head’s return continues it. - A put-out step card says what the bar says (ZNR-F003). After a prompt’s own Enter was taken, the dimmed card in the layer says Sent., not that the command waits.
- Smaller: the low bowl still rings for a refused answer or a failed unit after a flap revived the card (the knock stays once per card: ZNR-F001); a card taken before the relay whose tool call then gains its dialog is the same question and becomes answerable, with no ended words and no knock (ZNR-F005); a
secret_drop’s 「請在終端機中回答。」 and a read-only dialog’s Open the terminal are centred, not pushed to the right edge; a session that lost control has a read-only box, as the ruling said “input off”; stale comments (ZNR-F006). - Shared code touched outside Zen, with Standard and Geek unchanged:
termcard.ts(a prompt card says Sent. before its owner hearstaken: Standard’s dock removes the card at once),viewface.tsandview.ts(release: only a leave releases the hold, which Standard and Geek pages never have),pagecore.ts(upgrade: Zen only),confirmbar.ts(the dwell is under Zen’senterflag).
- Demo.
&upgrade=<ms>on any state announces a new build that long after the page starts (once for the browser session).?zen=settled(the card’s question is answered elsewhere&settle=<ms>on, 6000 by default;&leftmakes the unit leave instead),?zen=idle&end=<ms>and&lost=<ms>(the companion’s session ends or loses control) and&box=<ms>on any state (a box’s question arrives that long after the page starts and queues behind whatever is shown).
Wire: none.
Zen: the head’s conversation fills the page
Section titled “Zen: the head’s conversation fills the page”Boss, on 0.60.2, with the head tower’s conversation open on a 1280 × 720 screen: the breathing circle shrank and a large empty gap stood between it and the lines; 「調整,讓對話填滿空白」. The gap was the mindfulness line’s room: it fades out while the strip is awake but keeps its place, so nothing moves when the lines come clear, and at 720 px that was 120 to 150 px, taken from the circle.
- The lines take the room. While the strip is awake (called back by a click or focus on the input, Enter, or H, or by a reply to something you sent; its lines clear or held) the page shows as many whole lines as the height allows, newest at the foot next to the input, older ones above, each still fading with its own age as designed. At 1280 × 720 with a long conversation that is about seven lines (it was three); 1920 × 1080 shows about fourteen. A line that does not fit is not cut in half: the oldest ones are simply not drawn, and the whole conversation is still the link, H, or a wheel or swipe up. The page keeps the last 24 lines (before, three; two on a phone).
- The circle gives way first, and alone. It keeps its size while the lines leave it room (a short conversation leaves the group centred as it was) and gives way before a line is dropped, down to 18 % of the screen’s height, never under 80 px and never over 160 px (108 px at a height of 600, 130 at 720, 160 from 890 up). The cue row (「N 張卡等 Enter…」) keeps its two rows of 44 px in every state, the input stays at the foot, 40 px stay under the header (the working-and-idle line), and the update line’s foot (
--zen-foot) is kept clear as before. - At rest nothing changes. The strip asleep, which is every visit’s start, after Esc, a tap on the blank space, or the focus leaving, and also once every line has faded, is the page it was: the circle, the mindfulness line, three lines (two on a phone or a window 560 px tall or less) in the same boxes, the folded hairline. The mindfulness line and the filled lines are never on at the same time (one thing in paper, Z-D15).
- Not changed. One focus, no boxes, vermilion for focus only, forced colours, reduced motion (the change of layout is at once), 44 px targets, the keys, and Standard and Geek.
- Demo.
&talk=<n>on?zen=head,head-open, orhead-history(0 to 40) fills the head’s history with that many earlier exchanges, to see a long conversation. - Checked. In a browser on the built demo at 1280 × 720, 1440 × 900, 1920 × 1080, 390 × 844, and 1280 × 600, in Traditional Chinese and English (before and after,
~/.local/share/sbd-review/zen-head-fill/; the boxes of each state are beside the pictures as*.geom.txt), with the computed style of each rule read back (flex,min-height,order,padding), and with the update line showing (&upgrade=3500).
Wire: none. Zen decision Z-D21 (docs/specs/2026-11-01-zen-view.md, docs/specs/2026-11-04-head-tower.md, Zen: the strip fills the page).
One ally card per device, however many teams it is in
Section titled “One ally card per device, however many teams it is in”Boss, from box trial C (observation O2): the box agent-tower-01 is in moldplan-center and agent-tower-team, and Standard showed an ally card for each team. A card is a device, so now it is one.
- One card, its teams named. A device (and each workspace of it) is one card on the map in Standard and Geek, on a phone too. A quiet line under the title names its teams, 「團隊:moldplan-center、agent-tower-team」 /
Teams: moldplan-center, agent-tower-team; the crown says teammate only. A device in one team looks as before (<team> · teammate, no line). - One status block, the device’s. Online when any team hears the device; the most urgent tower state of the online ones; the units of all its teams (a box reports each team only the units of that team’s project, so the card lists the union, each unit from its freshest report, stale per unit; units of a team that shows no workspace of the device and match none of its workspaces go to its first card); a label that stays put; a card none of whose teams hears the device reads
unknownwith no tabs, never another workspace’s state; a crash or trust notice told in either team shows once, and the page’s memory of a unit that ran after it is the device’s. A unit’s state word, last report, crash fold, stale and gone handling, and the unattended summary line are the same as in 0.60.2. - Team-scoped parts keep their team. A forwarded question on the card still says its team in its row (
in team <name> asks a question) and is answered as before; the card hosts one device’s questions whatever team they came on. A card’s teams are the teams whose presence lists its workspace plus those that show no workspace of the device, and a question is placed on a card of the team it came on when there is one. The Link panel’s role, remove, rotate and invite acts stay per team in the team’s card there; trust is per device. - Presentation only. No wire, holder or authority change;
summary().alliesis still per team. Zen ignores ally reports and is unchanged. The Link notices (header) still list a notice per team. - Demo.
?ally=takes a comma list (ask,reporttoo) and gainsteams, whose second team reports a different set of units:?ally=crashed,teams,?ally=idle,teams,?ally=mate,teams(an attended teammate in two teams).
Wire: none.