Unify native and WASM client views over platform follows

Merged
VA
2d ago
+7089-3520

Problem

Swarm status replacements retained retired payload allocations, a pending content snapshot blocked layout and status updates, and browser rendering still exposed a separate client view path.

Design

ClientViews is the swarm fold. SwarmClient follows the layout/open-view files, root children, every agent's LATEST status and the selected agents' ALL file records. Content starts at a snapshot's complete checked cursor. Promotion preserves its follow and segments; deselection drops content while retaining overview status.

The select loop drives bounded snapshot futures alongside demand and platform deliveries. Layout changes physically cancel obsolete snapshots; completion epochs fence a clear/reopen of the same agent. Status replacement retires the previous map key before publishing the new compact allocation.

WASM exposes the same ClientViewHandle through WasmClientViews; TS reexports it as ClientViews. Native and browser reads share the same followed instance, including file segments, full-width identities, overview attention and durability. Memory and IndexedDB use the existing Streams session through in-process platform I/O. Remote attach, credit and reconnect remain in the Rust platform pool.

Decisions

Streams and filesystem providers remain the only substrates. No new service, gateway, actor socket, client transport, journal or polling path is introduced. Files remain authoritative and the client rebuilds disposable views at snapshot plus cursor.

The generic provenance/hypothesis kernel is now named HypothesisClient / WasmHypothesisClient; its misleading old renderer name and manual file-view facade are removed, with callers repointed and no alias. Ordinary goal/model/plan projections are components of ClientViews.

The legacy headless wire adapter retains only outbox, cursors and operation-bound settlement evidence until #626 replaces its callers. It no longer owns a transcript, streaming tails, tool renderer or usage accumulator. Native plan rendering now follows files directly through ClientViews.

#626 owns the executable -p / --input-format jsonl binding and legacy wire-host deletion. Its current task_projection.rs extends the former ClientViews; integration must put that canonical file projection into this shared reducer and expose it through the same followed WASM handle. Retired ViewUpdate model/tool injection and the former renderer facade stay deleted.

Active membership uses the gc-agents #669 child status files: an archive request does not retire a child; only its settled Archived/Cancelled acknowledgement removes it. The shared child paths and status data are copied as the minimal common schema until #669 lands. The archive keeps .volumes/agents/<ref> history readable. Membership, status/content follows, view state and accounting retire together.

Initial membership is intersected with the root discovery deliveries before registration. Replaying the whole ready membership snapshot directly flooded the bounded control queue at 2,049 agents; the captured error was Storage("stream capacity exhausted"). Discovery already supplies wire backpressure. The held-delivery regression detects the former admission path deterministically, and a Loom model uses the real Streams synchronization shim, outbound queue and subscription/error dispatcher. Its negative control restores the snapshot burst.

Retirement removes a snapshot owner by BTreeMap lookup and immediately drops its provider future. Abort wakes drain only cancelled shells, before the next membership/layout event. It never rebuilds the outstanding queue. Cross-query goal bindings belong to standalone root selections and are not scanned on agent retirement.

Delete the separate queries state map. Models, goals and plans derive from the same agents[*].files selections as followed text. Ordinary file queries and swarm heads share one segmented index and metadata fold; followed WASM parity includes all three derived projections.

Deletions

Delete SwarmViews, the old wire-event transcript/tool/usage renderer, its direct model/tool update methods, the manual WASM file-view methods and the obsolete TS facade path. Replace their rendering regressions with canonical file-follow/reopen properties; preserve wire admission, JSONL, file-authority, checkpoint and cursor tests. Relative to the merged main base: +7081/-3520, net +3561 lines, including verification and browser coverage. No README changes.

Tests

All builds/checks run through bs.ps1; portable test binaries are reused directly. Native harness feature closure: tui,terminal,filesystem-local,native-execution,grpc,test-support,model-checking,search-http.

Latest reviewed-code regressions:

  • Client units/properties/controls: 26/26, 0.35 s.
  • Interests, held-discovery barrier, checked history and durability: 24/24, 0.63 s.
  • Swarm views, archive reclamation, query churn and controls: 21/21, 0.03 s.
  • Native command views over the shared file index: 11/11, 0.15 s.
  • 1k/2k scaling properties and nonlinear-work controls: 3/3, 1.30 s; allocations 211,900 -> 419,601, retained bytes charged by the same oracle.
  • Swarm scenarios including 10k: 6 scenarios, 4.67 s. The 10k case measured 1.15 s fixture seeding, 3.23 s live subscription/production, 0.13 s cold reopen. Added parent membership writes are included in seeding; no per-status membership scan is performed.
  • Paired snapshot cancellation at 2,048/4,096/8,192 outstanding requests: rebuild control 0.384/0.640/1.343 ms and 2,052/4,100/8,196 allocations; indexed removal 6.86/1.20/1.33 us and zero allocations at every size. Retirement properties and the requeue mutant: 3/3, 0.03 s. The target path is constructed before measurement.
  • Windows cross-checks: Streams 25.16 s; harness --lib --tests 1m02s. No native Windows build used.

Earlier checks of unchanged paths in this revision: Session/JSONL/outbox/journal 66/66 (0.31 s), model views 13/13 (0.04 s), file-query 21/21 (0.39 s), client-query 16/16 (0.03 s), task-volume 45/45 (0.23 s), swarm e2e 6/6 (0.09 s), native goal rendering 2/2 (1.42 s), plan scenario 1/1 (1.56 s).

  • Followed native/WASM handle parity, including model/goal/plan projections and both negative controls: 3/3, 0.06 s.

  • TS build/type contracts passed; focused TS client/query/memory/views/performance: 32/32, 0.884 s.

  • Fresh installed archive consumer: 40/40, 1.54 s. Chromium platform attach/reconnect and installed framework/demand/reload checks passed; warm reads allocate zero snapshots.

  • Pinned-nightly Linux ASAN fuzz: swarm views/membership 683 runs, file queries 1,707 runs, goals 2,098 runs (four seconds each).

  • Final discovery Loom model and snapshot-burst negative control: 2/2, <0.01 s, with RUSTFLAGS='--cfg acyclic_stream_loom'. The model starts with one queued registration and explores the competing drain and next registration through the real subscription dispatcher, Outbound mutex and Signal mutex. No preemption or schedule bounds are used. Earlier versions included unrelated setup/admission locks and exceeded the runtime bar; setup now precedes the modeled race.

  • Final native build completed in 1m48s; final Windows harness cross-check completed in 7.78 s. Final gate rc=0. Captured race log: /home/var/log/buildbox/2026-10-17T015409142Z-2170330.log; native regressions/scaling: 2026-10-17T020002788Z-2175766.log; browser/package/fuzz: 2026-10-17T020650307Z-2178701.log; final model/retirement/Windows: 2026-10-17T022106081Z-2191965.log.

Live steps

None. Fuzz qualification is Linux-only as directed; production Rust crates passed the Windows cross-check.

Follow-ups

After #626 lands, retire the remaining legacy wire/outbox adapter callers. README wording remains in the separate human-gated PR #770.

Live-membership admission follow-up

The same capacity race applied to a ready live provider tail, including existing initial members republishing before discovery. Live membership now uses a checked ALL follow on the existing multiplexed Streams session, from the active-files snapshot's complete cursor. The task-volume record-to-change fold is reused by both provider follows and session follows; no second decoder, retry loop, pending queue or protocol was added. Initial discovery and live membership both receive transport backpressure and yield into the same admission block; status registration is no longer duplicated across select branches.

Data-driven regressions hold session deliveries across 2,049 fresh agents or 2,049 republished initial statuses. Both require zero status admissions while delivery is held and exactly one status follow for every active agent after release. The real-shim Loom model separately explores hierarchy-snapshot and live-ALL membership delivery. Each has its own unpaced-admission negative control, using the same real Outbound/Signal locks and Pool dispatcher.

The command suite consumes main's new isolated local-runtime fixture. Every workspace and its execution journals use the fixture directory, with Linux fixtures in tmpfs; tests no longer contend on the user's shared state. This is a code-level isolation improvement, with no timeout or thread-limit change. The 10k live deadline stays at five seconds.

Latest live-membership validation (head 42d93b612, log 2026-10-17T025755810Z-2229710.log):

  • Full client commands: 100/100, 1.79 s (main's isolated fixture, no test-thread caps).

  • Interests, including fresh and republished 2,049-member held-delivery cases: 25/25, 0.69 s.

  • Unified swarm views/archive properties: 21/21, 0.09 s; task-volume: 45/45, 0.30 s.

  • Repointed merged tool-file oracle and its mutations: 1/1, 0.02 s; swarm properties: 6/6, 0.12 s; scaling: 3/3, 0.77 s.

  • Swarm scenarios: 6/6, 2.88 s; 10k phases: seed 0.518 s, live 2.002 s, cold reopen 0.116 s. The five-second live deadline is unchanged.

  • Discovery/live admission Loom models plus both bypass negative controls: 4/4, 0.01 s, using the real crate-local Streams synchronization shim.

  • Windows cross-checks at the final head passed: Streams 5.18 s; harness full --lib --tests 2m53s.

  • Final followed native/WASM parity (derived projections and both controls): 3/3, 0.06 s.

  • Final TS build/type contracts passed; focused client tests: 32/32, 0.929 s.

  • Final Chromium remote platform attach/reconnect passed; fresh installed package: 40/40, 1.78 s, plus framework and reload/demand browser checks.

  • Final pinned-nightly Linux ASAN fuzz passed: swarm/membership 466 runs, file queries 4,600 runs, goals 7,300 runs; each run took four seconds.

  • Combined final gate rc=0. Total 1,013.6 s includes native/Windows/WASM/nightly compilation after the main merge; every verification suite itself remained under ten seconds. No sleep, polling, deadline increase, test-thread cap, or coverage reduction was introduced.