Repository navigation
docs: design Huge Blue app-server inspection route - #21335
teamleaderleo wants to merge 1 commit into
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
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 |
|
Bead |
docs/design/huge-blue-app-server-inspection.md only existed in the unmerged #21335; the design lives in web/services/vms/README.md. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…every frame, jumps land, 250 ms card) (#22228) * test: prompt bookmarks persist in the acpmux session (red) Behavior tests for _acpmux/bookmark_get and _acpmux/bookmark_set before they exist: restart, prompt-only seqs, fork, transfer, peer forwarding, the pane relay's scope and params, and the minimap popover's store. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * acpmux: prompt bookmarks persist in the session _acpmux/bookmark_get and _acpmux/bookmark_set keep the thread minimap's marks in SessionMeta.bookmarks: seqs of the chat's user_message records, checked against its log and capped at 1000. A change logs a mux bookmarks record, as tags do, so attached panes hear it; the chat keeps its place in the session list. A fork carries the marks of the prompts it copies under its own seqs; a move carries them (the log keeps its seqs) and the source keeps none. Peers' chats forward to their owner. The pane relay allows both methods for a chat in the pane's scope with only sessionId, seq and bookmarked. The minimap's store reads them from acpmux, toggles optimistically with rollback, and imports this pane's old localStorage marks for the chat once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: thread minimap matches the Codex rail; bookmarks show and jump (red) Behavior tests for the rail's thresholds, hover magnification, card timing, keyboard focus, scrub, the bookmark dot and row button, and the bookmark steps, plus a WebKit motion test and the Swift action/page-event test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * cmux-next: thread minimap matches the Codex rail; bookmarks show and jump The rail now follows the Codex desktop app's measured behavior: it shows from 4 prompts with 48 px left of the column, 16 px in and centered, with 10 px x 36 px rows and 6 px ticks that scroll past 64 rows or 70% of the window. Hover magnifies the rows (26/20/14/10 px) in 160 ms on Codex's spring, the preview card opens after 250 ms (at once within 300 ms of a close, or on keyboard focus) and closes 100 ms after leaving. A click scrolls on cubic-bezier(0.35, 0.05, 0, 1) (~400 ms for ~650 px), landing the bubble 35 px below the top, and highlights it for 1400 ms; an unmounted target jumps. Dragging scrubs. Every row is a tab stop. Bookmarks show as a 2 px dot past the tick (a click on its spot toggles it), in the card, and in a new button on the prompt's own row. Previous and Next Bookmarked Prompt are palette actions with no default key; the turn steps keep Ctrl-Opt-Up/Down, now on Codex's 200 ms scroll curve. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * cmux-next: regenerate action exports for the bookmarked-prompt steps Generated by scripts/measure/export-action-surfaces.sh on the fleet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: concurrent bookmark sets log the kept marks; legacy marks wait for acpmux (red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * acpmux: log bookmark changes in order; keep legacy marks until acpmux holds them set_bookmark changes, logs and saves the marks under the chat's move lock, so concurrent sets log in the order they change the marks and a move begins before or after a change. The prompt check scans the log on a blocking thread. The pane forgets an old localStorage mark only once bookmark_set succeeds for it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: a clicked minimap row takes focus so Tab goes on from the rail WebKit does not focus a clicked button, so in the app Tab after a click left the rail for the transcript. Codex's rail (Chromium) focuses it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: focus a clicked minimap row so Tab goes on from the rail Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: read the minimap hover transition by seeking it, not by frame samples CI's headless WebKit paced frames unevenly, so a sample 40 ms into the transition could come long after it ended. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: regenerate action exports on the merged head Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(next): PR autofix at 568dba62ae7a - vp fmt webviews/test/ime-composition-keys.test.ts - cargo fmt in Native/OptChat/optchat-chief Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/38566033765 * chore: regenerate action exports after merging #20556's head Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: the minimap's card follows the app hover intent (red) Base's hover-intent and elevation tests now drive the rewritten rail (.acpmux-minimap__card, the rows' pointerenter/pointerleave), and the rail test pins the app hover intent (450 ms delay, warm 500 ms, gone as the pointer leaves unless it enters the card) instead of CardTiming's 250/300/100 ms. heavy --mem 3G bun test test/hover-intent-cards.test.tsx test/subtle-elevation.test.ts test/thread-minimap-rail.test.tsx (fail) the card follows the app's hover intent: it waits the hover delay, follows the pointer at once while warm, and goes as the pointer leaves thread-minimap-rail.test.tsx:210 expect(card()).toBeNull() after 400 ms: the card opened at 250 ms (fail) the minimap's turn preview waits the hover delay, then follows the pointer at once until the rail cools hover-intent-cards.test.tsx:117 expect(visible()).toBe(false) right after leaving: CardTiming keeps it 100 ms (fail) one subtle elevation scale > .lg-sheet casts --elevation-2 (base red, ledger.css untouched) The .acpmux-minimap__card casts --elevation-2 case passes (the merge already moved the card to it). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: the minimap's card follows the app hover intent The preview card now runs on ui/hoverIntent's useHoverIntent, as base's minimap did: the first waits the hover delay, the card then follows the pointer from row to row at once while the rail is warm, and it goes as the pointer leaves the rail (moving into the card, or back, keeps it). Keyboard focus still shows it at once; Escape dismisses it and focus-out closes it on that frame. cardTiming.ts and the CARD_* constants are gone. thread-bookmarks.test.tsx goes back to the PR's version: the merge took base's half, which drives the old rail's pointermove on two prompts. heavy --mem 3G bun test test/hover-intent-cards.test.tsx test/subtle-elevation.test.ts test/thread-minimap-rail.test.tsx 46 pass, 1 fail (.lg-sheet casts --elevation-2: base red, ledger.css untouched) heavy --mem 3G bun test test/thread-minimap-current.test.tsx test/thread-bookmarks.test.tsx test/thread-turn-keys.test.tsx test/hover-intent-parity.test.ts test/hover-row-sweep.test.ts test/thread-minimap-motion.test.ts 7 pass, 0 fail (browser lanes skipped locally) heavy --mem 4G bun run check: pass Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: regenerate action exports on the merged head export-action-surfaces.sh on 6cf54078 (fleet step a2d9f3a7): 961 actions (base's chat-identifier actions plus this PR's transcript actions). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: regenerate action exports on the merged head export-action-surfaces.sh on eec94827 (fleet step fa811efc): 963 actions (base's Music actions added). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * debug: a short seed of one-line turns for the thread minimap's density captures debug.agent_pane seed_rows fixture "short": one-line prompts answered "ok N", the same content as the Codex reference chat, so tick and highlight density compare like for like. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * cmux-next: regenerate action exports after merging feat-cmux-next Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: warm Vite before the minimap motion and Claude reasoning browser tests check-browser-test-lanes (#20733) requires warmViteServer after listen; claude-reasoning-default (#20592) landed without it and fails the base check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(next): PR autofix at 0f6b92945b0c - regenerated plans/cmux-next/action-surfaces.json - regenerated plans/cmux-next/actions.md Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/38683433717 * fix: a prompt's bookmark shows with the hover actions experiment at one The hover-actions experiment hides a prompt's action row unless it has Copy, versions or Edit; a prompt that can carry a mark keeps the row for its bookmark. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(next): PR autofix at a97cff790a52 - regenerated plans/cmux-next/action-surfaces.json - regenerated plans/cmux-next/actions.md Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/38694299706 * fix: a drag's click on the minimap stays swallowed until the next press The flag cleared on a 0 ms timer, which a slow frame could run between the pointerup and its click, so the drag's click jumped (CI web shard 2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * cmux-next: regenerate action exports after merging feat-cmux-next Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: the thread minimap's feel in a long chat, in Chromium (red) Jump landing for undrawn rows, the hover card's 250 ms, the band following the scroll on its own frame, and older turns loading without moving the band. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: the thread minimap lands, previews, tracks and holds like the Codex rail - A jump corrects its landing from the bubble while the rows it crossed measure. - The card opens 250 ms after the pointer reaches the rail (Codex's delayOpen). - The band of lit rows follows the scroll on the scroll's own frame, and counts the turns on screen as Codex's observer does (no turn below the view). - Older turns loading above the reader leave the band where it was on screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: settle skips a scroller with no layout; the rail's card tests at 250 ms; gallery rest, scrub and long-chat states Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style: format Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: a jump settles only on a bubble with a box to measure Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: review findings on the minimap feel - Older turns: the band reads the offset as the transcript will restore it, the keep-in-view scroll skips that commit, the hovered, focused, card and scrub rows follow their prompts, and a second page continues a running glide. - The band's first turn is Codex's: a prompt within 35 + 16 px of the top ends the turn above it, so a prompt just jumped to is the first lit. - A jump's landing correction ends on any input in the page; a pending turn step is tracked by its turn, not its offset. - The scroll listener runs in capture; the gallery's synthetic scrub cannot throw. - Tests: a scrolling rail taking 30 older turns, waits on frames instead of timers, a looser card window and one stray frame allowed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: the band reads the restored offset until the transcript's restoring scroll arrives Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(next): PR autofix at b030bd39f09d - regenerated plans/cmux-next/actions.md - regenerated cmux-tui/crates/cmux-app-host/generated/scopes.json Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39347840624 * fix: the band reads the transcript's placement; jumps end with their chat; the card closes on focus out and Escape; the rail fits a short pane - VirtualTranscript calls the rail once its placement pass has set the offset, so the band reads the restored place directly instead of guessing from a frame with no scroll event. - A running jump stops when the chat changes or the rail unmounts. - The card closes when focus leaves rail and card, and on Escape inside it. - The rail's height is capped by the transcript's own height. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: a press released off the minimap ends there; a chat switch stops a jump in its own commit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: the minimap card's Escape goes through ui/escapeDismiss, not a raw key handler (ui rules) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(next): PR autofix at a73c00f9cf02 - plans/cmux-next/action-surfaces.json - plans/cmux-next/actions.md Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39360464009 * chore(next): PR autofix at 3c3d0e0b6bcf - Packages/macOS/CmuxNext/ci-target-graph.json Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39364182964 * chore(next): PR autofix at 9d214de119ff - plans/cmux-next/action-surfaces.json - plans/cmux-next/actions.md Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39380161552 * chore(next): PR autofix at 6e9a03929633 - plans/cmux-next/action-surfaces.json - plans/cmux-next/actions.md - schemas/defaults/cmux-next.json - web/data/cmux-shortcuts.generated.json Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39386397629 * agents: fence native updates to the captured machine (#21389) * agents: expose machine platform capabilities * agents: document machine capability metadata * agents: model machine platform capabilities * agents: format machine platform metadata * agents: show machine platform metadata * cloud: preserve machine capability contract * test: cover cloud machine capabilities * cloud: expose capability operation checks * test: cover capability operation helpers * cloud: gate actions on provider capabilities * cloud: clarify capability refusal * cloud: keep capability gates within app size budget * agents: show machine capability summaries * agents: show machine capability summaries * test: cover agent capability summaries * cloud-server: type capability checks * cloud-server: centralize access gates * cloud-server: centralize access gates * cloud-server: carry machine capability metadata * docs: specify machine capability metadata * agents: exercise machine capability metadata * testdata: add machine capability fixtures * testdata: add machine capability fixtures * testdata: add machine capability fixtures * testdata: add machine capability fixtures * testdata: add machine capability fixtures * testdata: add machine capability fixtures * testdata: add machine capability fixtures * testdata: add machine capability fixtures * agents: sanitize machine metadata at ingress * agents: sanitize machine metadata at ingress * test: cover agent metadata sanitization * protocol: carry machine platform capabilities * protocol: carry machine platform capabilities * fix: restore provider runtime after upload truncation * style: format machine capability protocol * style: format provider runtime capability fields * style: fix provider snapshot indentation * protocol: retain provider metadata in machine catalog * protocol: map provider metadata into machine catalog * tests: update machine descriptors for provider metadata * tests: update machine descriptors for provider metadata * tests: update machine descriptors for provider metadata * tests: update machine descriptors for provider metadata * tests: update machine descriptors for provider metadata * tests: update machine descriptors for provider metadata * tests: update machine descriptors for provider metadata * tests: update machine descriptors for provider metadata * apps: reserve agent CLI provider family * test: enforce agent CLI provider ownership * agents: add verified read-only agent_cli owner * agents: cover read-only agent_cli owner projection * agents: register the read-only agent_cli owner * agents: defer App provider adapter until feature ownership extraction * agents: defer App provider adapter until feature ownership extraction * agents: keep App provider wiring within its module size boundary * agents: reproduce malformed machine capability crashes * agents: validate capability wire types before rendering * agents: specify cached harness inventory privacy and no-execution behavior * agents: expose cached harness inventory without health side effects Select only non-secret health fields and reject controls or machine selectors. Advertise the view in initialize so older daemons cannot silently execute a normal health request when a client expects a cache-only read. Cmux-Daemon-Tests: run * agents: retain prerelease and build metadata in cached inventory Cmux-Daemon-Tests: run * agents: negotiate cached inventory before sending health requests Keep initialize and the inventory request on one transport. Unsupported owners receive no health operation, and typed inventory decoding rejects legacy or noncached responses. Preserve pipelining for existing calls and enforce the documented frame limit before parsing complete replies. * machines: import platform type in provider runtime The hosted same-tree daemon build caught the missing import used by the machine catalog projection. Cmux-Daemon-Tests: run * test: specify trusted machine inventory routing Exercise same-owner feature negotiation, cache-only responses, missing owners and refusal of machine selectors, controls and untrusted clients before adding the daemon command. Cmux-Daemon-Tests: run * machines: read cached agent inventory through the native owner Add the agent-inventory-v1 daemon verb on trusted Unix connections. Negotiate harnessInventory on the exact owner socket before the cache-only health request, reject controls and machine selectors, bound per-daemon concurrency and serialize only non-secret DTO fields. Keep the conversations-only relay denied. Cmux-Daemon-Tests: run * test: unwrap successful provider snapshots before checking defaults The hosted workspace test build caught direct accesses to a nonexistent ResponseEnvelope.result field in the legacy-metadata regression. Match its ProviderResponse::Success payload instead. Also use the already-imported AtomicUsize in the inventory worker bound. Cmux-Daemon-Tests: run * agents: share the inventory wire model with native machine requests Move the cached observation DTO to the lower daemon protocol module, add the capability-gated AgentInventoryRequest and reuse that DTO in the direct acpmux reader. AgentPane now depends on Daemon, whose dependencies remain Compat and Wakeups; no cycle or app-target growth. Cmux-Daemon-Tests: run * chore(next): PR autofix at 48a59aac18e3 - regenerated Packages/macOS/CmuxNext/ci-target-graph.json Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39024598894 * test: repair machine metadata fixture construction The hosted workspace test build caught duplicate platform/capabilities assignments in MachineDescriptor fixtures and assignments intended for MachineDescriptor on ManagedMachineDescriptor. Remove the duplicate and wrongly typed pairs while preserving each descriptor's actual capabilities. Cmux-Daemon-Tests: run * test: reproduce false absence claims from partial agent inventory Cover partial caches, launcher uncertainty, presence-only auth evidence, watch removals and all three rendered layouts using FakeHost. Before the fix the focused suite executes 16 tests: 15 fail and the complete-inventory control passes. Command: bun test first-party-apps/agents/test/inventory.test.ts * agents: preserve unknown evidence in cached machine inventories Only an explicit complete:true inventory can establish missing CLIs. Preserve nullable installation and presence-only auth evidence, keep partial removals unknown, and show uncertain rows/cells without install or update actions in every layout. Empty account observations no longer imply signed out. Add translated uncertainty copy and regenerate synthetic preview fixtures and the app bundle. Focused regression: 15 failures and 1 control pass at 9863b7dc; all 16 pass after the fix. Full Agents suite: 27 passed, 297 assertions. Current Swift inventory suites also passed all 10 tests at 48a59aac. The repository-wide localization audit still reports errors in unchanged macOS catalogs; the Agents English/Japanese source-key and placeholder checks pass. * test: preserve inventory assertions during owner fixture cleanup Do not set a read timeout on the immediately closed cleanup wake socket (macOS returns EINVAL), and preserve the original assertion if the worker fails during panic cleanup. Real owner calls are already bounded and close their link; the fixture reads their EOF. Cmux-Daemon-Tests: run * apps: move injected capability handlers into their feature owner Move the request, error, handler protocol and family router from the executable App target to CmuxNextApps, preserving dispatch and refusal behavior. The App keeps its concrete handlers and channel wiring. Add a focused Apps test target, regenerate the target graph and import the feature at the remaining PageFactory use. The extraction removes 61 App-target lines and gives the agent inventory owner an injectable feature-level handler seam. Local Swift syntax, namespace, concurrency, graph freshness, App size and diff checks pass; hosted compilation and the new behavioral suite are pending. * docs: scope duplicate handler ownership to the in-process router Clarify the existing local dictionary replacement behavior without implying that a live provider registration may be taken over. * test: reproduce missing canonical machine identity in identify * machines: expose canonical owner identity in trusted daemon handshakes * sdk: preserve optional machine owner IDs in raw identify results * test: reproduce inventory refusal without a selected-owner fence * agents: fence native inventory reads to the selected machine owner * test: require inventory family evidence from cached executable and package * agents: project CLI family from the cached executable and package evidence * test: require an admitted read grant for agent CLI inventory * agents: serve scoped CLI inventory through admitted machine owner routes * test: use synthetic host labels in machine inventory fixtures * apps: give provider registration its own connection adapter Preserve captured-transport capability admission and legacy-family fallback without growing the already oversized DaemonConnection type. Update the wire-level registration test and the request documentation. * test(agents): reproduce wrong-platform install hints Exercise structured Linux metadata and unknown remote owners through the packed app. Keep legacy OS and recognized-platform controls. * fix(agents): choose install hints from the selected owner platform Prefer structured machine metadata, retain legacy OS compatibility, and keep unknown or unsupported systems unknown instead of offering Mac install commands. Record the current inventory owner/provider integration in the shared coordination lane. Regression: platform.test.ts goes from 3 behavioral failures and 2 controls to 5 passes. Full Agents suite: 32 passed, 340 assertions. * test(machines): define verified remote-catalog publication behavior Exercise the existing machine.list/get API, exact owner fencing, bounded metadata, ordered replacement, exclusive publication and connection expiry. Keep the local-only default as a control. * test(machines): use the resource module's error type Repair the fixture import before evaluating the behavioral catalog regression. * machines: project verified remote routes through the native catalog Accept bounded, sequenced publications on the verified local app's existing connection, fenced to this daemon's public ID. Keep the publication in that connection record so disconnect removes it atomically. Expose metadata through machine.list/get while retaining the native local identity and session owner. Reject competing publishers, local impersonation, stale replacement, unknown fields, commands, paths and nonlocal/agent-bound carriers. The app publisher is not wired yet. No new route, remote execution authority, owner reconnect, disk schema or credential delegation is introduced. * test(machines): cover SDK catalog decoding and retain outer disconnect denial Correct the expired native client's expected outer remote_denied refusal. Add a behavioral SDK regression for native platform/capability metadata and remote origins, preserving legacy records and strict malformed-field checks. * sdk: carry machine origins and owner capability metadata across resource clients Extend the authoritative MachineSnapshot contract and all seven ergonomic SDKs to preserve optional platform/capability metadata and Cloud, SSH and server origins. Keep legacy omission defaults and strict typed metadata. Extract the Rust and Zig machine models instead of growing oversized files; Zig retains a bounded capability table without allocation. Regenerate the app declaration and canonical SDK descriptors. Update the boundary guard to validate the exact remote metadata shape and add rejection coverage for command fields, arbitrary origins and an open platform schema. Document the native publication bridge; its app publisher remains unwired. Behavioral Python SDK regression: four assertion failures at 1552187f, then all three tests pass. Existing Python resource suite: 69 passed. Focused TS: three passed. Resource boundary guard suite: 34 passed. Native catalog tests: eight passed at 1552187f (f5d2957368a6c4fbd973f19d). Compiled SDK lanes pending. * test(java): preserve the SDK test runner executable bit * test(machines): require native owner metadata in the handshake The app must publish the owner's observed platform and machine capabilities, not infer them from a UI route, provider label or its own local system. * machines: publish admitted owner metadata from the app registry Observe existing native registry routes on the captured local connection. Fence snapshots to the owner and handshake epoch, preserve live lease sequences across temporary source loss, withdraw removed routes and discard stale acknowledgements. Bound catalog records and frames, and negotiate publication without a legacy fallback. Expose native platform and machine capabilities in trusted identify using the same snapshot helpers; regenerate all seven raw SDKs. Add deterministic publisher lifecycle and wire-contract coverage. * machines: verify the publication transport and avoid catalog panics Exercise actual connection negotiation, legacy refusal before write and owner mismatch propagation. Repair test-fixture compilation and remove three fallible expect sites from catalog projection and selection. Document event-driven publication and native owner metadata. * test(machines): expose policy readmission observation regression Extract the current registry projection unchanged from app composition and exercise it against a paired-server fixture. A blocked route must keep observing the policy that can readmit it. No host or connection is started by the fixture. * machines: keep blocked catalog routes observing readmission Read observable registry admission and carrier state before excluding blocked routes. This preserves the subscriptions needed when policy or a reconnect readmits the existing route, without opening a connection. Cover both policy and carrier invalidation. * test(machines): cover curated CLI and MCP catalog discovery Exercise read-only machine discovery, explicit metadata lookup and continued exclusion of session effects and arbitrary machine routing. Extract existing catalog tests instead of growing the large MCP test file. * test(machines): preserve CLI paths after catalog test extraction * machines: expose read-only catalog discovery to CLI and MCP Offer curated machine list/show and generate machine_list/machine_get from the existing operation catalog. Keep session effects and other-tool machine routing excluded. Share operation-aware route defaults between CLI and MCP so the catalog socket's session is not serialized as metadata, and resolve machine prefixes on the same connection with no ancestor fields. Extract the machine grammar instead of growing command.rs. Document the metadata-only contract and translate root discovery help in both native CLI locales. Add actual transport and route regression coverage. * machines: clarify catalog tool authority and repair fixture lints * test(machines): use an explicit name selector for reserved words * test: reproduce Swift catalog ancestor selector mismatch * fix: encode Swift catalog selectors for their operation * test: exercise catalog trust with real native owner connections * machines: exercise app discovery and scoped inventory through real server owners * test: use the catalog's read risk in the app journey fixture * test: retain owned app diagnostics for native journey failures * test: preserve new app runs across replacement host exit * fix: fence queued app runs from the outgoing host generation * style: terminate app dispatch match arm consistently * docs: distinguish machine catalog metadata from session authority * test: require negotiated metadata for strict provider v1 clients * machines: negotiate optional provider metadata per control generation * machines: reproduce strict native reader catalog incompatibility * machines: require reader opt-in for extended native catalogs * chore(next): PR autofix at 1938babb0ef6 - regenerated cmux-tui/crates/cmux-app-host/generated/cmux-app.d.ts Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39046739528 * tests: preserve native field validation in MCP catalog plans * sdk: expose machine reader options and reproduce missing wire opt-in * tests: format the SDK catalog wire regression for hosted Zig * sdk: serialize explicit machine catalog reads without changing defaults * tests: cover the extracted machine facade and typed invalid inputs * tests: reproduce strict identify reader compatibility and opt-in boundaries * tests: exercise identify through its native command handler * machines: negotiate owner identity metadata without changing legacy identify * tests: preserve identify callers and validate explicit metadata options * cloud: localize unavailable operation refusals * tests: capture bounded catalog withdrawal receipts on journey failures * tests: await the acknowledged withdrawn catalog instead of a fixed sequence * test(agents): reproduce stale and cross-owner inventory refreshes * test(agents): require explicit catalog discovery and local fallback controls * fix(agents): discover admitted owners and fence inventory refreshes * test(agents): reproduce missing cache-only inventory change feed * feat(agents): publish bounded cache-only inventory changes * test(agents): require owner-fenced native inventory watch leases * feat(agents): fence native cache watches to owner connection leases * test: reproduce inventory watch replacement cleanup race Correct the native watch fixture's writer construction and qualification warnings so the barrier-controlled socket replacement case can execute before changing cleanup behavior. * fix: fence inventory watches across socket replacement Detach old leases while changing the configured socket and close only that detached set outside the lock. Capture a monotonic internal socket epoch in every watch so a reused path cannot admit stale work. Preserve the native wire contract and the pre-fix barrier regression. * fix: document native inventory streams and guard handshake replies Declare the targeted watch events as control streams and document their payload/lifecycle. Keep moved agent-session emitters in their existing internal wire family. Replace the computed metadata reply subscript with a bounded lookup that fails malformed responses closed. Spec inventory and all32 checker tests pass after the previously observed missing-stream failure. Swift syntax, scoped conventions/size and crash ratchet pass; no crash baseline changed. Native watch Rust inputs are unchanged from the 25-case fleet pass at01418d27; final job cleanup remains pending. * test: preserve inventory lease events through tree resyncs Exercise native event decoding, DaemonStore side-event delivery behind a snapshot barrier, and EventInbox overflow. Inventory changed/ended events belong to the separate subscription; keep an unrelated unknown-event control. Regression only, before event-retention repair; fleet execution pending. * fix: retain native inventory lease events behind tree snapshots Classify the two targeted inventory lease notices as independent of workspace snapshots. Keep unrelated unknown events behind the existing tree barrier. EventInbox already retains unknown events; the new overflow cases preserve that control behavior. Regression be913d2e precedes this fix. Syntax, scoped conventions and size checks pass; exact fleet red/green execution remains pending the matching native artifact. No app-facing watch advertisement or new authority. * test: preserve exact native inventory watch revisions Exercise actual DaemonEvent wire decoding across UInt64 boundary values and malformed owner/lease/revision inputs. Require bounded lease-only side-event payloads and retain an unrelated numeric-event control. Regression only; no runtime RED claim before fleet execution. * feat: type native inventory watch requests and exact revisions Add separately capability-gated owner-fenced enable/disable requests and a directly decoded UInt64 receipt. Normalize targeted side events through validated owner/lease fields, preserving revisions as decimal text before generic JSON can round them and discarding diagnostics or malformed notices. Keep unrelated events unchanged. Revision regression8ddb7918 precedes this change. Add request framing and bounded real-connection bridge coverage for legacy refusal and exact UInt64 replies. Syntax, scoped conventions/size and crash ratchet pass; packet0 localization entries. Fleet runtime red/green remains pending matching artifact publication. App-facing subscriptions are not yet wired or advertised. * test: fence delayed inventory disable to its original lease Enable a new lease on the same native control connection after socket replacement, then deliver cleanup naming the retired lease. Assert idempotent no-op for stale cleanup, continued invalidations on the new lease, and successful conditional retirement of its exact ID. Regression only, before owner-side conditional disable. * fix: condition inventory cleanup on its captured lease Advertise agent-inventory-watch-fence-v1 and accept a canonical expected_watch_id only on disable. Atomically compare/remove only that client's matching lease; a stale ID or absent lease is an idempotent no-op, never a selector for another client. Keep the original explicit connection-wide disable. Managed Swift enable/disable requests require fencing support before starting and include the exact receipt ID on cleanup, with no unfenced fallback. Add cross-client, malformed-input and capability coverage. Regressionedd780 executes the missing conditional-disable assertion in the selected run and alone (jobdb37d30741c3eecdeda6d36e, failed100, no leaks). Spec inventory/32checker tests, scoped syntax/conventions/size and diff checks pass; runtime GREEN pending. * test: use the daemon JSON object case in the watch fixture Correct the connection fixture's assumed AppJSON accessor to pattern-match CmuxNextDaemon.JSONValue.object. Current lease-fenced wire assertions remain intact. The earlier904577 candidate stopped at this fixture compile error; it provided no runtime GREEN. Production sources and native inputs are unchanged. * test: consume admitted agent inventory invalidations Exercise the real Agents store in FakeHost: agent_cli.changed must re-discover/re-read admitted owners, ignore claimed event payload rows/selectors, and coalesce bursts while retaining a follow-up. The same focused Bun command executes13controls passed and3expected failures before the fix. Keep this regression before the implementation; advance the public branch with both after local GREEN. * fix: re-read admitted agent inventory on cache invalidations Subscribe to agent_cli.changed and ignore event payload rows, selectors, commands and job results. Re-discover/re-read current owners without live checks; coalesce an active batch and preserve a follow-up. Remove the unsupported watch payload listener and its proposed stream operation. Preserve stale-read, withdrawal and local-fallback fences across all three views. Regression154e9306 precedes this fix. The same focused Bun command first executes13pass/3expected failures, then passes all16original cases plus2refusal/removal cases. Full Agents suite50tests/416assertions, canonical bundle/check and manifest pass; existing execute-scope warning remains. Localization packet0entries/attention; global static baseline failures unchanged. Publish both commits together after local GREEN. App-facing native/provider invalidation production remains open; Agents is unbundled. * machines: bind inventory watch lifecycle to the ready control session Capture one manager per admitted native control transport, retain pending receipts for cancellation cleanup, and serialize conditional retirement before readmission. Failed cleanup cannot silently admit another lease. Add bounded bridge coverage for cancellation, owner refusal and reconnect. Extract handshake admission to keep DaemonConnection within its size ratchet. Runtime validation follows on the immutable hosted source; no end-to-end provider watch or Cloud journey is claimed. * test: reject cached inventory watch admission after control reconnect An old manager must not return its cached receipt after the original transport closes, even when the same canonical owner reconnects. Keep the new transport's live lease as the cleanup isolation control. * fix: refuse retired inventory watch transports before returning receipts Check the captured transport before cached admission and after pending admission. Recheck retirement when another caller starts a cleanup while an earlier cleanup await resumes. The preceding reconnect regression executes one expected cached-receipt failure with four passing controls on fleet job7c5042eb1d069c387c351d77. No reconnect or alternate-owner cleanup fallback is introduced. * machines: exercise watch manager admission refusal before native contact The new manager refuses an owner with only the older watch capability and an owner without canonical identity. Real bridge inspection confirms no watch operation is sent in either case. Production watch lifecycle at parent7c58329a passes all seven selected Swift suites, fleet job1d9ad29f7b992e9612c26052, including the preceding closed-transport regression. * test: revalidate app stream authority before each queued delivery Use the scripted host and an explicit queue barrier to hold the current process alive across grant, enabled, host-state and manifest changes. A saved subscription must not keep receiving events after those changes. The readable running host remains the positive delivery control. * apps: fence inventory invalidations to current readable demand Recheck install, manifest, grant and host state under the supervisor lock before queuing stream events. Keep fixed inventory invalidation out of the generic daemon event feed. Add opt-in inventory demand snapshots, targeted monotonic demand events, and a strict verified non-agent Unix provider ingress taking only the current demand sequence. Revoke, unsubscribe, host exit and provider replacement fence stale callbacks without supplying rows or selectors. The preceding real-host queue-barrier regression executes five expected authority failures with a passing running-host control, selected and alone, job b8b8381c06c4dd0c40a75d3a; no leaks. Current runtime validation follows. * fix: validate inventory invalidations at the apps request entry Move the strict frame check from cancel-request to try_handle, where the command discriminator and optional response shape are available. The prior candidate stopped during native compilation; no runtime result is attributed to it. Inventory and cancel-request behavioral gates will run on this corrected immutable source. * test: preserve the page relay role while proving its inventory refusal The generic verify helper sets role main. Set only the verified-app test fact in this fixture so the request actually originates from page_relay. Production inventory permission and demand behavior is unchanged. * apps: satisfy demand test lint and document inventory provider opt-in Add the two required test closure semicolons without suppressing warnings. Document the additive demand snapshot and fixed provider carrier in the owning module; legacy registration remains unchanged. Prior f85cfc62 runtime executes42 passing inventory cases with one invalid page-relay fixture failure, corrected in parent8859e57c. The queued8859 verification was cancelled before placement after these lint issues were known; the final exact source is the verification target. * machines: preserve source identity through side-event delivery Tag native event envelopes with the connection instance and retain their original control serial through the store, snapshots and inbox collapse. A new envelope subscription rejects unsequenced or unstamped delivery; existing event-only subscriptions remain compatible. Delegate typed wire execution and ready transport sequence projection to their resource owners without growing the connection type. Exact Swift files pass eight suites/28methods on immutable validation source2a74fd62 using its official matching published native tree eb966; job a4c6a87c47577e66e78cd436 is done/0/reset. This is component proof only. Current carrier Rust at parenta11bfff6 passes43inventory and140shared app cases. Current native/provider composition awaits its matching artifact and the production demand-to-watch bridge. * test: retain exact provider inventory demand sequences * apps: connect permissioned inventory demand to admitted machine watches * apps: validate inventory subscriptions through the native app journey * apps: fence provider callbacks and verify reconnect and lease retirement * test: reject stale registry admission after actor reconnect * apps: require the registry observed control transport for inventory admission * daemon: expose observable side event control admission * test: name disconnected control reason in stamp lifecycle fixture * test: recover explicit no-lease inventory admission refusals * machines: prove absent inventory leases before explicit admission retry * sdk: model native owner inventory events across generated wire layers * test(agents): reproduce duplicate and stale selected-owner job admission * fix(agents): bind job actions to one admitted pending request * test(core): pin agent update admission to the captured machine * feat(core): fence agent update calls to their captured machine --------- Co-authored-by: cmux-autofix[bot] <cmux-autofix[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * Use paired server identities for links (#21644) * test(server): expose missing pairing commands * test(server): reject missing idempotency values before mutation * Implement human-approved server enrollment in Rust * test(server): keep pairing links in the selected API environment * Keep pairing verification links on the selected API and fix isolated fixtures * Keep server enrollment coordination in its lane ledger * test(link): bind paired servers to their enrolled WireGuard identity * Use the enrolled server identity for an explicitly selected link * Dereference the protected key when checking a running link identity * Share link help and exercise enrolled traffic through real cmux processes * Report the exact encrypted-journey deadline and owned process logs * test(link): exit a refused encrypted dial while stdin remains open * Finish link dial after peer EOF with stdin still open --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * docs(web): point Huge Blue inspection comment at the vms README (#21952) docs/design/huge-blue-app-server-inspection.md only existed in the unmerged #21335; the design lives in web/services/vms/README.md. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * test(agent cursor): red: the name tag is a gray Liquid Glass capsule (pill gallery P1) User (Oct 20): 'more designs for tinted pill ... gray and liquid glassy, think about how Apple would design this'. Replaces the light-glass tag expectations: neutral gray translucent tint, continuous corners, light specular rim and top highlight, subtle shadow, dark text, gray dot. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * cmux-next agent cursor: the name tag is a gray Liquid Glass capsule (pill gallery P1) Neutral gray translucent tint (#D6D6D8 at 78%), continuous-corner capsule 22 pt tall, light specular rim, top highlight gradient, soft 1.5 pt shadow, dark label text and a gray dot; the typing caption uses the same material. No agent color anywhere in the tag. The overlay panel sits above Chromium's child windows, so it cannot blur the page; the tint stands in for the blur. No new animation: the tag still shows and hides through the existing Motion fades, so Reduce Motion and animation speed apply unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next tabs): a tab switch at rest walks no row of tabs (red: every switch runs the occlusion and full separator passes) TabSwitchWorkBudgetTests counts the strip's passes over every cell (TabStripRowPasses: occlusion, separators, frames) across 2N switches at 2, 10 and 30 tabs and expects none: the switch's cost must not grow with the tab count. Deterministic, where a timing gate on shared CI hosts is not (the same bench measured 0.4 ms on one fleet host and 29 ms on another). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * cmux-next tabs: a tab switch updates the two tabs it changes, not the row (tab-switch-rewrite) syncSelection walked every cell twice per switch: the full separator pass and the occlusion pass (TabOcclusion samples each cell's motion path). At rest no tab overlaps another and no mask is on, so occlusion runs only while a strip move is in flight (movesInFlight, cleared by the move's completion), and the separator rule is applied to the lines next to the old and new selected tab through a slot index built once per layout (TabSlotIndex), which reveal also reads. A multi-selection change keeps the full pass. TabStripSwitchSeparatorTests proves the lines equal a full pass after any switch order. Benches (fleet, aws-m4pro-5, same host A/B against a9439ce7ac3): TabSwitchPathBench apply p50 60 tabs 0.42 -> 0.31 ms, 30 tabs 0.21 -> 0.15 ms; strip separators 38 us -> 2.5 us at 60 tabs, constant. TabSwitchPathBench now prints the per-stage split (BenchSpans switch.*), and TabStripSelectionBench each strip step. scripts/cmux-next/tab-switch-matrix.py also reports each Chromium and WebKit page's own first frame after a switch (content_frame_ms). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Server: Add Server card: the Name/Team grid takes the card's width The fleet render at 39b0b0b23b5 still drew the Name field at its ideal width: the Grid sized to its cells, so maxWidth on a cell had nothing to fill. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Server: Add Server card: Name and Team as captioned full-width rows The Grid kept the Name field at its ideal width (the maxWidth frame sat outside the drawn card) and wrapped the Chief checkbox. Captions over the controls need no label column, so long labels in any language fit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: actions.md lists the transcript actions where the generator puts them (AgentTranscriptActionCatalog order) * test(next): pinned groups read as pinned; a group header's right-click is one flat menu (red) Lawrence 2026-10-20: Move to Top left a workspace under groups that were pinned (the Pinned band lists above the machine sections), but nothing showed they were pinned and Pin/Unpin could only pin. And the header's right-click opened the editor, whose More Group Actions row held the menu. Red: SidebarDocPinnedGroupTests (a Pinned-band group maps pinned), WorkspaceGroupFlatMenuTests (common rows top-level, no catch-all folder, every row in the palette), GroupPaletteDefaultTests (right-click shows the menu, editor rows without More). Design: plans/cmux-next/sidebar-ordering-DESIGN.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(next): pinned groups read as pinned and unpin; a group header's right-click is one flat menu Root cause (plans/cmux-next/sidebar-ordering-DESIGN.md): the groups Move to Top left a workspace under were pinned. Pin Group moves a group into the Pinned band, above every machine section, but SidebarDocSections mapped every document group with pinned: false, so no pin glyph showed and Pin/Unpin always pinned. A Pinned-band group now maps pinned (the header's pin, Unpin Group in the menu and editor), and Pin/Unpin toggles from what the sidebar shows. The header's right-click opens the group's menu at once (no editor, no More Group Actions row): Color, Set/Remove Icon, Pin/Unpin, Collapse All/Expand All/Collapse Others, Move to Top, Ungroup, Close Group, Delete Group and Close Other Groups are top-level; Move and Sort keep their lists. The editor offers Pin and Move to Top itself. New Workspace in Group, Pin/Unpin Group, Mark Read/Unread, Clear Notifications and Edit Group Config join the palette. Pin and Collapse rows read as the change they make. Strings in all 21 locales (19 need review). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(next): the flat group menu keeps 12 top-level rows ActionSurfaceParityTests.everyMenuKeepsAShortTopLevel (Lawrence 2026-10-01: at most 12 top-level rows) failed at 21. The rows Lawrence named stay top-level (New Workspace in Group, Rename, Color, Pin/Unpin, Collapse/Expand, Move to Top, Ungroup, Close Group) with Delete Group and Close Other Groups; Options ▸ takes icon, read state, collapse-all, config and Duplicate, and Move ▸ takes the group sorts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(next): Copy Group ID joins Options, so the group menu keeps 12 top-level rows Its one-row Copy folder showed inline as a 13th row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(next): regenerate action exports for the flat group menu Regenerated on the fleet (key a219-exports-820ba663b9c, scripts/measure/export-action-surfaces.sh). check-group-menus.py passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(next): TitleCoalescerTests takes mutating results before #expect (the pattern that broke CEFPumpScheduleTests) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: cmux-autofix[bot] <cmux-autofix[bot]@users.noreply.github.com> Co-authored-by: lawrencecchen <54008264+lawrencecchen@users.noreply.github.com>
|
Owned by projects-3f on cosmic-gray · session |
|
Closing as superseded by #21365 (merged 2026-10-18). That PR implemented slices 1 and 2 of this design plus the Cloud probe from slice 3 as |
Problem
Huge Blue/app-server inspection needs a read-only, typed visibility contract, but the current Run attach work is deliberately scoped to terminal ticket redemption. The existing SSH/session registry and cmux-tui trusted-carrier probes already provide the identity and enrollment facts needed for inspection.
Change
This draft PR records the follow-up design for issue #21332:
SSHHost/session identity;cloud.machine.list/cloud.machine.connect_infoand the trusted-carrier/enrollment probe where applicable;The implementation PR should follow this design once the owner of the app-server route confirms whether the inspection endpoint belongs on the Cloud app-server path or authenticated VM API path.
Validation
git diff --checkCloses #21332
Need help on this PR? Tag
@codesmith-botwith what you need.Summary by cubic
Adds a design document for a read-only Huge Blue app-server inspection route, defining four inspection states and the proposed response shape.
Design notes
SSHHost/session registry andcloud.machine.list/connect_infoinstead of introducing new credentials.Written for commit 619e067. Summary will update on new commits.