Daily-driver chat UX and fleet control plane - #59
Merged
Conversation
Boots a throwaway jevonsd on :13715 with temp state_dir and jevonsmcp-journey so live Grok journeys never hit the daily stream. make test-journey runs J1–J5; not part of make test. Co-Authored-By: Grok <noreply@x.ai>
Bump claudia to de7e55e (name-keyed EnsureAgent — no workdir session steal). agent_list/start use sessionDisplay so concurrent UUID-v7 peers no longer look identical. Hermetic regressions for same-workdir two-name isolation and same-name idempotency (🎯T86).
Tallness is full offsetHeight > 1.5 × collapsed-preview height after layout (tables/markdown no longer miss the gate). Measure only when the bubble is in the DOM. Latest user and assistant still auto-expand (T66); prior tall messages collapse (T77).
Master tip still had de7e55e; chat.go uses Parent. Pin 58cb7f5 so make bullseye builds again.
Re-apply jevons_agent_kill and lineage helpers after origin rebase.
AGENTS.md and journey README state preferred E2E net, distinct from make test, journey-or-exception, and Universe B port refusal. Hermetic go test ./scripts/journey-suite locks doctrine markers + J1–J10 inventory + dailyPort 13705 refusal. Achieve T101.
Hermetic check calls refuseDailyPort(dailyPort) and expects error — comment-only markers no longer keep the test green.
Owner: a user journey maps real interaction end-to-end and must talk to an agent; cache after green is OK. Clarify AGENTS + journey README; doctrine_test.go is explicitly not a journey. File T107; annotate T101.
Doc/inventory ratchets live in scripts/docratchet (prose ratchet, not journeys). Daily-port refusal is unit-tested in portguard. journey-suite has no unit tests — live E2E is make test-journey only.
Collapse measurement was repainting preview into the live body every stream frame, thrashing scrollHeight and leaving stick-to-bottom pinned at a stale mid-bubble offset (manual scroll bounced until seal). Skip collapse while a bubble is streaming; restore pin-guard + 120px slack + double-rAF; re-pin on seal/mermaid; end-sentinel IntersectionObserver when follow is armed but bottom left the viewport; overflow-anchor:none. Hermetic stream-scroll-test covers growth, scroll-up disarm, and free scroll after seal.
Close the control-plane dependency graph for complex fleet work: RHS who-started-whom tree with stable sibling sort, full registry list feed, event-driven agents.json refresh (fsnotify → agents_changed), mid-turn tool/fleet progress chrome, stuck-turn watchdog, NCA-named cross-tree kill deny, persona Build/Ship + fleet-spawn + impatience/RSI doctrine. Oracles: package tests (agents watch, lineage NCA, persona), UI suite (fleet-tree, attention, stream-scroll, collapse), journey J6b MCP reconnect + J8–J10 multi-agent paths on Universe B.
- T94: idle-bound stuck-watchdog; progress resets lastWorkingActivity; interrupt+status only after pure idle (no false-recover mid multi-agent). - T85: SweepDeadAgents / deadRecoveryPlan on list+send; rehydrate or clear. - T104 under fan-out: FleetStandingBrief on first jevons_agent_send; package TestEnsureFleetBriefInjectsOnce. - J8b-po-worker-lineage-fanout: PO+worker parent lineage + brief ack. - Reopen/re-achieve T108 only with skeptic-hardened evidence matrix.
SweepDeadAgents now runs through fleetSweepReg so tests inject hasProc&&!Alive without an OS process. Oracles assert Launch (AutoStart recover) and Stop (ephemeral clear / failed recover). agent_list and agent_send prepend FormatDeadAgentReport and notify the overseer so outage/recovery is not log-only.
Close T109 leaves without owner gates: journey step library (T102), journey doctrine/cache notes (T107), thread integrity on status (T33), tool-arg wire detail (T64), composer layout (T69/T70/T70.1), remove TMUX panel (T73), highlight.js (T74), user quotes (T75), dictation tidy (T80), GitHub path icon (T84), history redo Enter (T88), timestamp tooltips (T91). Hermetic batch-t109-test + package/journey oracles.
claudia 20464ce passes ACP session/update params through as Event.Raw so rawInput is not dropped by a narrow re-marshal. Bump go.mod and add TestToolCallDetailFromClaudiaPreservedParams (product-shaped params + regression guard that stripped re-marshal loses args). Re-achieve T64/T109.
Mid-stream freeze/bounce was still possible: flex-shrink let tall bubbles under-report scrollHeight, collapse measurement still painted through the live body on seal/expand, and end-sentinel IO only re-fires on transitions. - flex-shrink:0 on #messages children so scrollHeight tracks content - probe-based measureCollapse (no intermediate preview in live body) - expanded/latest paints full once; stream bubble ResizeObserver re-pins - pin-guard window + immediate post-paint pin on each stream frame - stronger hermetic stream-scroll oracle (working chrome + tables)
End-sentinel IntersectionObserver re-pinned whenever the bottom left the viewport while autoScroll was still true (within 120px slack). Wheel-up moved a few pixels then snapped back. Remove IO re-pin; growth follow stays on post-paint pin + stream ResizeObserver. Disarm on wheel/touch scroll-up. Hermetic wheel-up oracle asserts no snap-back.
- T34: Butler.PushEvent + jevons_event_push MCP (rehydrate, no silent fail) - T56: virtualise off-screen chat bodies (virt-shell + content-visibility) - T76: paste images → POST /api/images → [image:id] on the agent turn - T93/T95: target: filing aside + jevons_target_file + __TARGET_FILED__ auto-close - T99: cheap ThreadRoute continuation matcher on main send - T40: design note only (needs claudia connect-mode) — left open - Oracles: Go push/image/target-file tests; UI virtual-list + image-paste
Follow mode is sticky policy above the DOM, not nearBottom(120px): - Track: growth pins to true bottom (re-check before each pin) - Free: user owns scroll; stream growth never re-arms - Enter: send/boot/arrive at bottom (16px entry ε only) - Leave: wheel/touch/PageUp/scrollbar up (not layout clamps) - Bookkeeping ignores pin, virtualise, and history-prepend scroll noise Hermetic stream-scroll-test covers small leave mid-stream + re-enter.
After leave, geometry may re-enter Track only once the user has moved clear of ENTER_BOTTOM_EPS (~16px). Removes the residual mid-stream snag from leave → still-at-bottom scroll sensor → re-pin, without new policy layers. Explicit enter (send/boot) still arms immediately.
leaveTrackBottom only blocks geometry re-arm while still inside the entry band; a leave that already cleared it (e.g. jump to top) can re-enter on the next arrival. Amends the hysteresis so hermetic arrive-at-bottom still works.
When a prior latest reply collapses on a new request, height shrinks and Track re-pins; off-screen virt-shells that enter the viewport were not refreshed until the next user wheel (blank gap above the collapsed bubble). - scheduleVirtualize after latest-expansion height changes - virtualise on pin/bookkeeping scroll events too - rematerialise shell before collapsing a dematerialised prior latest - re-entrancy guard; keep expand toggle on dematerialise - hermetic: virtual-list collapse gap; collapse-test stubs virt for DOM asserts
When the textarea auto-grows, the flex messages viewport shrinks but scrollTop stayed fixed, so the bottom of the transcript slid under the composer. Bump messages.scrollTop by the growth delta (pure policy in composer_layout.js) and cover growth-without-cover with a hermetic unit test — no Playwright. Co-Authored-By: Grok <noreply@x.ai>
Add the thin vertical self-test slice: shared report schema, pack runner (HTTP + MCP), layout probe (JevonsProbe.snapshot), and three gradable packs (health-L1, composer-growth-L2, agents-parent-L1) for sites live|drill|ci. Drill site documented as docs-only ensure-isolate path (T110.4). Co-Authored-By: Grok <noreply@x.ai>
While an overseer turn is in flight, plain Enter enqueues the draft as a follow-up instead of interrupting. Only Control+Enter interjects. Queued items render above the composer with send-now/cancel; FIFO auto-drains on turn seal. Alt+Up/Down cycles queue before request history. Pure policy in web/scripts/send_queue.js + hermetic tests; wired into make test-web.
closeTargetAside and dismiss set status=done (not parked); stack() is open+parked only; archive()/archivedStack() keep completed asides discoverable. Manual park still shows as intentional chips. Hermetic: after file/close, stack excludes filing asides; archive lists them. Re-attests T95 auto-close as dismiss-from-chrome + focus main. Co-Authored-By: Grok jv-t95 <noreply@x.ai>
Pre-T95.1 auto-close used park(), so completed filing asides stayed in localStorage as parked chips after refresh. On deserialize/load, map purpose=file-target && status=parked → done; intentional manual parks unchanged.
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.
Summary
Ships the local week-of-use stack as v0.8.0: daily-driver chat UX (stick-to-bottom, virtualisation, collapse), multi-agent control plane from owner chat, journeys isolation, and related fleet/MCP work. Local master was 43 commits ahead of origin (squash-only → single PR).
Release notes (draft for the GitHub release)
Jevons v0.8.0 — daily-driver chat & fleet control plane
First release cut with the product in real daily use: long-stream chat that
stays readable, multi-agent work from the owner surface, and a clearer path
to keep the fleet honest under fan-out.
Added
jevons_event_pushinto threads with rehydrate / typed failure/api/images→[image:id]on the turntarget:filing asides (🎯T93/T95) +jevons_target_file; auto-close on__TARGET_FILED__Fixed
rawInputpreserved via claudia pin (T64 path; summariser still thin for nested MCP args)Changed
Install
brew upgrade marcelocantos/tap/jevons # or first time: brew install marcelocantos/tap/jevons brew services restart jevonsTest plan
go test -tags "sqlite_preupdate_hook sqlite_fts5" ./...(CI-identical)make test-webjevonsd --version