Skip to content

[RSI, security] fix(kernel): keep the kernel stderr log owner-only - #2425

Merged
sethkarten merged 2 commits into
mainfrom
rsi/sec-band-85
Sep 17, 2026
Merged

sethkarten merged 2 commits into
mainfrom
rsi/sec-band-85

Conversation

@sethkarten

@sethkarten sethkarten commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

What

The kernel stderr log (kernel-stderr.log in the session artifact directory) was created world-readable (openSync(path, "a") default mode -> 0644) while every sibling artifact in the same private directory is owner-only: kernel-state.dill/kernel-state.json 0600, semantic-edges.jsonl 0600, rlm-subagent.json 0600, and the daemon journals use 0700 dirs + 0600 files. Kernel stderr can carry Python exception payloads and library warnings, so it belongs to the private set.

This creates the log owner-only (0600) and its directory owner-only (0700) when the kernel manager itself creates it, with fchmodSync on the opened descriptor so the exact bits hold despite the umask (and a pre-existing loose log is tightened on the next kernel start).

Why this shape

  • mkdirSync(dirname(path), { recursive: true, mode: 0o700 }) mirrors command-recovery-journal.ts, worker-recovery-journal.ts, and rlm-ledger.ts.
  • openSync(path, "a", 0o600) + fchmodSync mirrors auth-storage.ts's fchmod idiom; the stderr log is a persistent append fd with a byte budget, so the writeFileAtomicSync temp+rename pattern does not apply. The fd is closed if the fchmod fails (no leak window).
  • Rotation (renameSync to .old) preserves the mode, so rotated logs stay owner-only.

Tests

Extends the existing teardown test in test/repl-kernel-startup.test.ts (fake runtime that exits before ready, log path in a nested dir the manager creates) with two assertions: file mode 0600 and directory mode 0700. Both fail pre-fix (0644/0755) and pass post-fix; proven pre-fix by stashing the source change and rerunning (received 0o644 vs expected 0o600).

Validation

  • npm run check clean at the tip: biome, check:test-policy (vs origin/main), tsgo --noEmit, check:installer, check:browser-smoke.
  • npx vitest --run test/repl-kernel-startup.test.ts: 5/5.
  • Test-line budget: net test additions 2 vs 21 meaningful source additions.

Dedup

Complementary, not overlapping: #1249 (private-files.ts utility; covers session-manager/config/state-snapshot/agent-session storage; does not touch this log) and #2174 (kernel-env allowlist hunks in the same file, disjoint from openStderrLog; its docs explicitly keep the stderr log as-is). No bash.py guard-class overlap with #2373/#2384/#2390/#2395/#2413/#2415.


Note

Low Risk
Narrow filesystem permission change with tests; opening may fail if the process cannot chmod a log owned by another user.

Overview
Hardens permissions on kernel-stderr.log so it matches other private session artifacts (kernel state, semantic edges, etc.), since stderr can include Python exception payloads.

ReplKernelManager.openStderrLog now creates the log directory at 0700 and opens the log at 0600, with fchmodSync on the descriptor so mode holds under umask and existing loose files are tightened on the next open. Before rotation to .old, chmodSync runs so historical rotated logs are not left world-readable.

Startup tests gain shared fakeRuntime / withManager helpers plus assertions on file and directory modes, including a case that seeds an oversized 0644 log and expects rotation to produce 0600 on both the new file and .old.

Reviewed by Cursor Bugbot for commit fee75f1. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fix kernel stderr log permissions to be owner-only in ReplKernelManager

Sets the kernel stderr log directory to mode 0700 when newly created and keeps current and rotated log files at mode 0600 in repl-manager.ts. Before rotating an oversized existing log, the current file is tightened to 0600 so the renamed .old file retains restricted permissions. If fchmod fails on a log descriptor, the descriptor is closed and the operation fails.

  • Tests in repl-kernel-startup.test.ts verify the directory is 0700 and log files are 0600, including a case that tightens a pre-existing world-readable oversized log before rotation.
  • Behavioral Change: pre-existing stderr logs with looser permissions are now tightened to 0600 on open and before rotation; callers relying on group/world readability of these files will lose access.

Macroscope summarized fee75f1.

The kernel stderr log (session-artifacts/<id>/kernel-stderr.log) was created
world-readable (0644) while every sibling artifact in the same private
directory is owner-only (0600 files, 0700 dirs). Kernel stderr can carry
exception payloads and library warnings, so the log and its directory must
match the other private session artifacts.

Create both with owner-only bits: mode 0o700 for the directory and 0o600 for
the file, with fchmodSync on the opened descriptor to enforce the exact bits
despite the umask (and tighten a pre-existing loose log on next kernel start).
@github-actions

github-actions Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Prime Agent performance — completed

PR fee75f11 compared with main b6ac5d01.

Overall: 0 regressed · 1 improved · 39 no clear change.

Metric Main This PR Change
Cold startup 1,479.1 ms 1,379.2 ms ≈ -99.9 ms (-6.76%)
Warm startup 883.9 ms 794.9 ms ≈ -89.0 ms (-10.06%)
Installation 13.62 s 13.00 s ≈ -0.62 s (-4.56%)
Compressed release artifacts 72.48 MB 71.13 MB $\textcolor{#65816c}{\textsf{↓ -1.35 MB (-1.87\%)}}$
Installed footprint 577.63 MB 574.25 MB ≈ -3.38 MB (-0.59%)
Idle memory, summed RSS 1,169.97 MB 1,137.01 MB ≈ -32.96 MB (-2.82%)

Python runtime

Metric Main This PR Change
Python kernel startup 134.8 ms 134.9 ms ≈ +0.1 ms (+0.08%)
Python cell round trip 0.529 ms 0.496 ms ≈ -0.033 ms (-6.23%)
Empty bash command 11.7 ms 10.9 ms ≈ -0.8 ms (-6.48%)
Bash git status 18.1 ms 16.3 ms ≈ -1.8 ms (-9.93%)
Bash 32 KiB output 11.8 ms 11.2 ms ≈ -0.7 ms (-5.52%)
35 cells / 9 shell calls 169.0 ms 163.3 ms ≈ -5.7 ms (-3.36%)
Python interrupt to done 1.601 ms 1.513 ms ≈ -0.088 ms (-5.48%)
Python state snapshot 25.7 ms 25.5 ms ≈ -0.2 ms (-0.62%)
Python state restore 360.0 ms 356.9 ms ≈ -3.1 ms (-0.86%)
Python idle RSS 34.52 MB 35.95 MB ≈ +1.43 MB (+4.15%)
Python RSS after pandas workload 96.59 MB 97.99 MB ≈ +1.40 MB (+1.45%)

UI interactions

Metric Main This PR Change
Resume large session (cold) 4,012.5 ms 3,602.6 ms ≈ -409.9 ms (-10.21%)
CPU, resume large session 6,520.0 ms 5,970.0 ms ≈ -550.0 ms (-8.44%)
Switch into large session 5,396.0 ms 5,329.2 ms ≈ -66.8 ms (-1.24%)
CPU, switch into large session 9,550.0 ms 9,530.0 ms ≈ -20.0 ms (-0.21%)
Open agents view from a session 165.5 ms 160.4 ms ≈ -5.2 ms (-3.12%)
CPU, open agents view 330.0 ms 360.0 ms ≈ +30.0 ms (+9.09%)
Full agents roster, many sessions 4.46 s 4.45 s ≈ -0.0043 s (-0.10%)
CPU, full agents roster 3.19 s 2.77 s ≈ -0.42 s (-13.17%)
Open another session from agents view 2,688.1 ms 2,640.5 ms ≈ -47.6 ms (-1.77%)
CPU, open from agents view 2,860.0 ms 2,680.0 ms ≈ -180.0 ms (-6.29%)
Reopen resident large session 615.7 ms 566.5 ms ≈ -49.2 ms (-7.99%)
CPU, reopen resident session 1,040.0 ms 960.0 ms ≈ -80.0 ms (-7.69%)
Open subagent session at depth 6 21,187.3 ms 20,777.1 ms ≈ -410.2 ms (-1.94%)
CPU, open subagent at depth 6 10,760.0 ms 9,700.0 ms ≈ -1,060.0 ms (-9.85%)
Open chain parent from agents view 4,047.9 ms 3,817.3 ms ≈ -230.7 ms (-5.70%)
CPU, open chain parent 4,060.0 ms 3,590.0 ms ≈ -470.0 ms (-11.58%)
Scheduled catalog, first request 2,029.3 ms 1,964.0 ms ≈ -65.2 ms (-3.21%)
CPU, scheduled catalog 3,340.0 ms 3,350.0 ms ≈ +10.0 ms (+0.30%)
Scheduled catalog, repeated request 1,243.1 ms 1,210.1 ms ≈ -33.0 ms (-2.65%)
CPU, repeated catalog 1,680.0 ms 1,680.0 ms ≈ +0.0 ms (+0.00%)
Cold worker with three catalog scans 1,629.2 ms 1,666.5 ms ≈ +37.3 ms (+2.29%)
CPU, cold worker and scans 4,470.0 ms 4,360.0 ms ≈ -110.0 ms (-2.46%)
UI memory after interactions 2,678.68 MB 2,585.61 MB ≈ -93.07 MB (-3.47%)

Sandbox cost: ~$0.1419 — no inference calls.
Run, logs, and downloadable raw results

Methodology and samples

Main resolved at 2026-09-16T23:46:40.168225+00:00. Harness b6ac5d01.
Linux x64, 4 vCPU, 8 GB RAM, 20 GB disk; region us.
Image: node:24-bookworm@sha256:be23f54a88d34e8824c741b19b91064094f92c1c97b194144bfc8b50d67258e2.
Stock tools, skills, daemon, and Python bootstrap enabled; fresh homes and a fixed Git fixture.
Onboarding is dismissed; the editor starts without a selected model or submitted prompt.
Medians shown. Arrows require a 20% timing/memory change plus absolute floors and IQR.
These practical noise floors are not a statistical significance test.
Cold means stopped Prime processes; OS filesystem caches are not flushed.
No model requests or credentials. Installation excludes build/setup time.
Installer tarballs use loopback; npm/Python downloads use the network with fresh caches.
Artifact size counts release tarballs; footprint after first use includes registry packages.
MB is decimal. Summed RSS can double-count shared pages; PSS is recorded when available.
Provisioning, setup, and build durations are recorded separately in the raw results.
Kernel probes use the installed JSONL runtime, outside the TUI/TypeScript host.
Per trial: 50 Python cells, 5 calls per shell case, and one 35-cell mix (9 git status calls).
Cell/shell values are batch means; other runtime timings are single operations.
State fixture: a 10,000-row × 8-column integer DataFrame and a 10,000-integer list.
Restore runs in a fresh kernel, including pandas imports; kernel startup is excluded.
Kernel RSS covers the isolated Python process; loaded RSS follows the pandas workload.
UI trials use a fresh fixture set: 194 top-level sessions including one ~40 MB transcript,
40 ledger fan-out children, and a 6-deep subagent chain (~46 spawn edges).
Large fixtures hold 1,999 complete triples (~5 MB JSONL); medium 119; subagents 399 each.
Interactions: cold --resume of a large session, warm /resume switch, left-arrow to agents view,
roster settle with many saved sessions, search-and-open of another large session,
reattaching to that resident session, opening the chain parent, and drilling to depth 6.
Readiness is the rendered transcript tail plus a confirmed editor echo.
CPU metrics sum utime+stime across the whole benchmark-user process tree per interaction.
UI memory sums RSS after the interactions; PTY byte counts are in the raw results.
A separate catalog fixture has 2,300 sessions, 2,298 edges, and 13 paused scheduled-job owners.
Catalog timings cover first/repeated reads and cold worker creation under three pending scans.
All expected jobs and owner metadata are checked; worker readiness excludes TUI rendering.
Costs estimate full sandbox lifetimes at configured rates, including setup and build.
Budget target: $1; not a billing cap. Performance changes are informational.
Failed or incomplete execution fails the workflow; saved artifacts remain available.
Each side stops a phase after 2 identical consecutive failures.
Skipped trials are not attempted samples. Warm startup requires a successful cold launch.

Metric Main successful/attempted PR successful/attempted Main spread PR spread
Cold startup 10/10 10/10 IQR 43.3 ms IQR 90.5 ms
Warm startup 10/10 10/10 IQR 31.7 ms IQR 16.9 ms
Installation 3/3 3/3 range 0.12 s range 0.26 s
Compressed release artifacts 1/1 1/1 — —
Installed footprint 1/1 1/1 — —
Idle memory, summed RSS 10/10 10/10 IQR 65.87 MB IQR 134.09 MB
Python kernel startup 10/10 10/10 IQR 8.3 ms IQR 6.6 ms
Python cell round trip 10/10 10/10 IQR 0.060 ms IQR 0.028 ms
Empty bash command 10/10 10/10 IQR 1.5 ms IQR 0.4 ms
Bash git status 10/10 10/10 IQR 2.4 ms IQR 0.7 ms
Bash 32 KiB output 10/10 10/10 IQR 0.9 ms IQR 0.4 ms
35 cells / 9 shell calls 10/10 10/10 IQR 16.9 ms IQR 8.5 ms
Python interrupt to done 10/10 10/10 IQR 0.111 ms IQR 0.062 ms
Python state snapshot 10/10 10/10 IQR 3.4 ms IQR 2.1 ms
Python state restore 10/10 10/10 IQR 37.6 ms IQR 16.3 ms
Python idle RSS 10/10 10/10 IQR 4.65 MB IQR 2.27 MB
Python RSS after pandas workload 10/10 10/10 IQR 5.51 MB IQR 2.31 MB
Resume large session (cold) 3/3 3/3 range 940.0 ms range 454.3 ms
CPU, resume large session 3/3 3/3 range 930.0 ms range 810.0 ms
Switch into large session 3/3 3/3 range 516.8 ms range 327.5 ms
CPU, switch into large session 3/3 3/3 range 760.0 ms range 1,060.0 ms
Open agents view from a session 3/3 3/3 range 17.4 ms range 11.4 ms
CPU, open agents view 3/3 3/3 range 20.0 ms range 70.0 ms
Full agents roster, many sessions 3/3 3/3 range 0.0097 s range 0.009 s
CPU, full agents roster 3/3 3/3 range 0.55 s range 0.55 s
Open another session from agents view 3/3 3/3 range 195.3 ms range 169.1 ms
CPU, open from agents view 3/3 3/3 range 580.0 ms range 360.0 ms
Reopen resident large session 3/3 3/3 range 112.6 ms range 74.8 ms
CPU, reopen resident session 3/3 3/3 range 340.0 ms range 180.0 ms
Open subagent session at depth 6 3/3 3/3 range 732.1 ms range 2,322.5 ms
CPU, open subagent at depth 6 3/3 3/3 range 560.0 ms range 140.0 ms
Open chain parent from agents view 3/3 3/3 range 69.7 ms range 130.1 ms
CPU, open chain parent 3/3 3/3 range 110.0 ms range 350.0 ms
Scheduled catalog, first request 3/3 3/3 range 117.2 ms range 414.5 ms
CPU, scheduled catalog 3/3 3/3 range 250.0 ms range 930.0 ms
Scheduled catalog, repeated request 3/3 3/3 range 134.8 ms range 97.0 ms
CPU, repeated catalog 3/3 3/3 range 180.0 ms range 120.0 ms
Cold worker with three catalog scans 3/3 3/3 range 66.7 ms range 226.1 ms
CPU, cold worker and scans 3/3 3/3 range 330.0 ms range 600.0 ms
UI memory after interactions 3/3 3/3 range 85.50 MB range 89.09 MB

Comment thread packages/coding-agent/src/core/kernel/repl-manager.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c023913. Configure here.

Comment thread packages/coding-agent/src/core/kernel/repl-manager.ts
Rotating an oversized kernel stderr log renamed it to `.old` before any
chmod, so a pre-existing world-readable (0644) log kept those bits and its
historical exception payloads stayed readable by other users. Only the new
current file was tightened.

chmod the log to KERNEL_STDERR_LOG_MODE immediately before the rename. The
path is known to exist (statSync just succeeded), a chmod failure lands in
the existing rotation catch and keeps appending instead, and on Windows the
chmod clears the read-only bit so the rename still proceeds.

Cover it with a regression test that pre-creates an oversized 0644 log and
asserts the rotated file is 0600. The failing-start tests now share
fakeRuntime/withManager helpers to keep the added coverage line-neutral.
@sethkarten
sethkarten enabled auto-merge (squash) September 17, 2026 21:20
@sethkarten
sethkarten requested a review from xeophon September 17, 2026 21:21
@sethkarten
sethkarten merged commit b6d955a into main Sep 17, 2026
44 checks passed
@sethkarten
sethkarten deleted the rsi/sec-band-85 branch September 17, 2026 23:44
kevinjosethomas added a commit that referenced this pull request Sep 27, 2026
… (TS #2372/#2423/#2500/#2471/#2478/#2425 parity) (#2744)

ea5abd1bbe1bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).
snimu added a commit that referenced this pull request Sep 30, 2026
* pa-daemon: supervisor.rs split 1/8 - the routing concern moves out of src/supervisor.rs (#2877)

8a7ea9d8784dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: mouse/touch clicks on the core surfaces - click-to-expand condensed runs and tool cards, click-to-place-caret in the prompt bar, click-to-open rows in the agents view, picker row select (#2865)

b3fa6b4ebbe1merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* release: split Linux debug info into optional decoder (Option C) (#2844)

d4ff407544d3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-types/pa-cli/pa-tui: daemon incident forensics — prime-agent incident CLI + agents-view incident notices (TS #2406 port) (#2866)

068259acae6fmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 2/8 - the client-connection concern moves out of src/supervisor.rs (#2878)

3f8b85f25dc2merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: free the side-question registry entry before the cancelled event queues (one registry hold for removal and terminal emit) - closes the same-id restart flake (#2887)

18f6b7fb6f34merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): O(1) catalog fold search-text cap + 64 KiB fold reads (#2879)

* perf(pa-daemon): keep the catalog fold's search-text cap as an O(1) running count

The roster fold re-counted the capped search corpus for every user/
assistant message (the cap guard plus the append's two counts), an
O(messages x 64KiB) walk per session: the cold-scan split shows this
guard is the single largest cold-scan stage (~40% at every fixture
tier). The accumulator now carries the corpus char count in lockstep
with the one writer, so the guard and the append read the counter and
the fold stays O(messages). Row bytes are unchanged: the counter is
kept exact by construction and covered by lockstep and legacy-mirror
tests; the stale-manifest row audit and the 100/1000/4096 fixture
checksums stay identical.

* perf(pa-daemon): batch the roster fold's reads into 64 KiB fills

The fold read grown session files through the default 8 KiB BufReader,
one read syscall per 8 KiB: the strace census counts 6.6k reads on a
1,000-file cold scan (27k at 4,096) where ~one fill per file suffices.
A 64 KiB buffer keeps the line semantics, folded bytes, and resume
cursor exactly - only the syscall chunking changes.

* test(pa-daemon): name every corpus-mutation path the search-text counter rides

The orchestrator review asked the lockstep matrix to enumerate the
paths, not just the happy append: fresh fold, the resume copy a grown
file folds into (clone_for_resume travels the counter with the
corpus), the torn-tail snapshot fold (the durable accumulator stays
untouched; the cap bounds the snapshot arm too), and a rewritten
file's fresh re-fold. Eviction drops the counter with the corpus and
store_state keeps them whole - both cannot desync.

---------

Co-authored-by: perf-catalog-cold-fast <agent@local>

* perf(pa-core): batch kernel venv Python skill installs into one uv invocation (#2884)

* perf(pa-core): batch kernel venv Python skill installs into one uv invocation

The fresh-install kernel venv bootstrap installs every missing Python skill
with its own `uv pip install --editable` child process; each call pays a
process plus PEP 517 build-backend startup for a metadata-only editable
install (measured on the venv-boot lane VM: nine serial installs 1.85s vs one
batched invocation 0.37s, warm uv cache, same VM; the skills phase is the
dominant local cost of the bootstrap, ~1.9s of a ~2.4s span).

Missing skills now go into ONE uv invocation; a batch failure falls back to
the per-skill loop, so a broken skill still costs only its own warning and
never blocks the rest. Installed-skill carry-over, the shared-cache version
file, per-skill warnings, and the venv identity contract are unchanged.

* test(pa-core): fix skill-sync test closure lifetime and fmt

The warning-sink closure needs 'static: share the vector through
Arc<Mutex<Vec<String>>> and lock for the assertion. Formatting follows
cargo fmt.

* test(pa-core): one log line per fake-uv invocation; clippy clean

The fake uv logged printf per argument, so the invocation-count asserts
counted args; printf the joined "$*" as a single line. Move the unix
PermissionsExt import above the statements and close the sink push with
a semicolon (clippy items-after-statements / semicolon-if-nothing-
returned).

* test(pa-core): match the skill path, not the --editable flag

"--editable" contains "edit", so the not-reinstalled assertion needs the
package path.

* pa-core: park the tool abort watcher on the signal (per-tool-call 100Hz wake leak) (#2880)

ToolDefinitionBridge::execute spawned a watcher task per tool call that
polled signal.is_aborted() every 10ms and exited only on abort; a normal
(non-aborted) call never aborts, so every completed tool call left a
100 Hz wake-up loop running for the worker's lifetime. A 45-min 4-vCPU
idle profile (one kernel cell executed) measured the worker's tokio
thread at a constant 104.4 voluntary wake-ups/s for the whole horizon
(pa-core probe, thread-level /proc counters). Await the watch channel
directly instead: abort latency drops from up-to-10ms to immediate, and
an uninterrupted call parks with zero wake-ups. Abort semantics, tool
cancellation, and the loop contract are unchanged.

Lane: hillclimb-cpu-creep (cpu axis, long-horizon resident profile).

* perf(kernel): defer websearch httpx import to first call - first tool cell 17ms -> 2ms (#2888)

Module-level 'import httpx' put its full import chain (~15ms in-kernel) on
every kernel bootstrap cell, in every session, even when no search runs.
Import it inside _fetch_serper on first call instead. A module-level
find_spec guard keeps the import-time contract byte-identical: when httpx
is absent, importing websearch still raises ModuleNotFoundError('No module
named \'httpx\''), so the kernel's unavailable-skill stub and its message
are unchanged. No Rust, API, wire, or behavior change; the first websearch
call pays the import once.

Co-authored-by: perf-kernel-cell-fast <lane@hillclimb>

* perf(pa-core): adopt the retained window one-copy - move the trees in, drop the raw duplicate (#2890)

* pa-daemon: summary scalars from one borrowed walk, not the materialized fold

session_summary folded the whole retained window into a Vec<Value> on
every read (attach, get_state, roster pushes, list rows) just to read
three scalars: the newest message timestamp, the summed assistant usage,
and the window's message count. At session scale that fold is the
majority of the summary's cost and half the retained-window folds an
attach pays (handle_attach's snapshot fold is the other).

SessionFile::messages now delegates to one shared windowed walk
(walk_message_values): message rows borrow their persisted message,
custom_message rows rejoin in their wire form, and a compaction window
prepends its summary message with the retained count counted in a
borrowing pass. The materialized fold keeps its exact sequence (same
keeping-flip semantics on message-bearing rows, same summary-first
order) and drops the doubled clones the old retained loop paid.

scan_message_scalars walks the same sequence for the summary scalars:
the reverse find_map timestamp (last positioned value, not the
maximum), the assistant usage sums in fold order, and the message
count. session_summary consumes the scan instead of the Vec, so every
summary surface derives from the same walk the fold uses - the two can
never disagree. Golden equivalence tests pin the scan against the old
full-clone extraction across window shapes (non-monotonic timestamps,
custom rows carrying usage, kept id on message/non-bearing/missing
rows, stacked compactions, empty session, degenerate rows), and boundary
tests pin the fold's exact windowed sequence.

* perf(pa-core): adopt the retained window one-copy - move the trees in, drop the raw duplicate

The worker-rss census (bench hillclimb record 20260926-183300) measured
five resident copies of the retained window on the 10MiB canonical
fixture; three were derivable duplicates: SessionManager::adopt_window
cloned the walk's typed trees into file_entries (B) while the window kept
its original (C1, wire-identical) plus the raw JSONL lines (C2,
10.48MiB) - ~29.5MiB of wire-equivalent duplication in the loaded
worker, whose same-build RSS band is 182.5-217.9MiB (p50 207.6).

- WindowedSessionStore::take_retained hands the typed rows AND raw lines
  to the owning manager in one move; a detached window keeps its
  snapshot/settings/metadata surfaces (goal state, refinement history,
  git state, append-time stats) and asserts that its transcript context
  comes from the manager.
- SessionManager::adopt_window adopts the trees by move (no to_vec).
- SessionManager::active_context builds from file_entries with the SAME
  window settings overlay gate as the old window.context() - the served
  context is unchanged; the manager's own append_child_usage_attribution
  fold is the one-copy authority for live rows.
- ensure_full_history re-arms the detached copies (historical hydration
  restores bodies, exactly like a fresh walk).

Oracles: adopted-context byte parity vs an un-adopted window (cold+warm),
detached-window lookups + should_panic context, live-appends-vs-full-
reopen byte parity incl. an in-window attribution target; existing
manager/window/byte-parity tests now ride the adopt path.

* fix: adopt_window takes the window by mut (take_retained borrows mutably); tests serialize the context field tuple (SessionContext is not Serialize) and fully-qualify AgentMessage

* fmt: rustfmt on the new window-scan tests

* fix(tests): reference opens first in the cold pass (the adopted open warms the sidecar); compaction_count is the file-level tally (fixture carries a sibling compaction); the retained assistant row needs the required api/stopReason fields or it degrades to Unknown

* fix: clippy default_trait_access in the scan equivalence test

* fix: clippy default-trait-access in tests (JsonMap::default / MessageWindowScalars::default; the latter is a lint fix on the folded attach-path tests so this lane's gates run green - their lane must carry the same fix on their branch)

* fmt: wrap the scan default assert to 100 cols

* perf(pa-daemon): collapse fresh-create session-file writes into one durable write (#2892)

* pa-daemon: fresh-create single durable write (spawn admission)

The fresh-path create collapsed its session-file durability from three
sync'd writes (a header-only rewrite, a second rewrite for the prefix +
active state, and a persist_entry name append) into ONE rewrite that
assembles the prefix, the state, and the session name in memory first.
The dropped header-only intermediate has no reader: the durable create
stays pathless until the create succeeds, so no replay, scan, or
registration consumes the file mid-create. The final bytes are identical
to the sequential writes (same entries, same order; the name's line is
the exact persist_entry construction via append_session_info).

Measured on the spawn-latency VM (hillclimb lane perf-spawn-admission-fast,
bench record 20260926-204300): each admission pays ~7 serialized
durability round trips; the fresh-write class costs ~38-45ms/op in the
degraded host regime (0.3ms quiet) - the collapse removes two of the
three writes on the child-create leg. In-crate oracles: the single write
matches the legacy sequence's masked bytes; the folded name lands once;
a failed write leaves no session file; a legacy crash orphan neither
blocks the create nor bleeds into the new file.

* pa-daemon: split the create-collapse tests into their own file

create.rs grew past the ~800 LoC guidance with the in-file test module; the tests move to worker/create_collapse_tests.rs via #[path] (still a child of the create module, so the module-private append_creation_prefix stays reachable). No product change.

---------

Co-authored-by: perf-spawn-admission-fast <lane@hillclimb.local>

* perf(pa-tui): handoff exits break the run loop this iteration - chat->agents 119ms -> 67ms (#2893)

The terminal loop's exit-key break only left the input-drain loop, so the
handoff fell into the select below it and parked on the 50ms idle tick
before the loop-tail exit check ran — measured as ~50ms of added latency
on every chat -> agents view switch (strace: the key is handled in ~0.1ms,
the teardown starts on the next tick wake ~51ms later; the code's own
comment already demanded the teardown run "this iteration").

A handoff (agents-back, /resume, the scoped view, /resume <selector>)
now breaks the outer loop immediately: the next surface's mount clears
the alt screen, so the tail pass paints nothing the user can see. A
non-handoff exit (/exit, /quit) keeps the tail pass — its frame gate
paints the final chat frame the exit's main-screen flush shows — and
headless runs keep the tail pass so captured frame sequences stay
identical.

* perf(pa-daemon): borrow message content as RawValue - kill the second full catalog parse, cold -25% (#2882)

Co-authored-by: perf-catalog-second-parse-fast <hillclimb@local>

* pa-daemon: agent_engine.rs split 1/11 - the tests concern moves out of src/agent_engine.rs (#2889)

51bd18583e17merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-cli/pa-daemon): tighten the two cold-open connect-probe grids from 25ms to 5ms (#2891)

Cold-open boot-floor decomposition at 7064d039a (bench hillclimb record
20260926-194800-startup-boot-floor-decompose) measured two pure-wait
probe grids on every cold launch, each quantized 0-25ms (mean ~12.5ms):

- ensure_daemon_running_with polls the freshly spawned supervisor's
  socket every 25ms; a cold supervisor binds ~39ms after spawn.
- probe_worker_socket polls a freshly forked session worker's socket
  every WORKER_CONNECT_BACKOFF_MS=25ms; the worker binds ~1-3ms after
  the fork.

Both grids tighten to 5ms. Timing-only: probes, 30s budgets, auth floor,
and all error paths are unchanged; wire and user-visible behavior are
identical (TS polls at 25ms in both places - the deliberate divergence
is the perf port's, flagged for review).

* perf(pa-tui): return the first-frame heap of a resumed transcript; store settled messages rows once (#2895)

* perf(pa-tui): return the first-frame heap of a resumed transcript; drop settled messages duplicate block-cache copy

* test(pa-tui): settled messages keep no block-cache copy; streaming keeps its replay cache

---------

Co-authored-by: perf-tui-memory-fast <perf-tui-memory-fast@hillclimb.local>

* perf(pa-daemon): zero-copy relay for routed responses - share the payload bytes, splice the client id (#2897)

* pa-daemon: relay routed responses by bytes - supervisor splices the client id onto the worker line

* fmt: the two supervisor.rs forms CI rustfmt wants

* perf: the cross-process runtime-ready probe memo - on-disk, same identity key, damage-aware (#2881)

* pa-core: the cross-process runtime-ready probe memo (on-disk, same identity key)

* pa-core: fix the xproc memo commit's test-module paths and escape damage

* pa-core: rustfmt the cross-process memo

* pa-core: clippy fixes for the cross-process memo tests

* pa-core: move the memo-walk helper to test-mod scope (clippy items-after-statements)

* pa-core: fix the disk-memo oracles (missing-dir semantics, fallback sequence) and serialize the memo-state tests

* pa-core: the disk-memo repair-to-verified-content hits (oracle fix)

* pa-core: the live closure-freeze allowlist covers the real runtime's stdlib imports (18 modules found on first live run)

* pa-tui: agents-view summary rows drop the model mix; the inactive line bills the descendant aggregate (operator directive) (#2894)

9168514c8384merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs facade cut SS3 - the adoption/register concern byte-moves into supervisor/adoption.rs (#2901)

450cf50aeb31merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): share client-event payloads on the supervisor broadcast (Arc) - sup CPU -60% at N=100 (#2896)

* perf(pa-daemon): share client-event payloads on the supervisor broadcast (Arc)

Baseline at origin/rust 7064d039a on the concurrent-io lane: supervisor CPU
per append_custom_message is Theta(N) in resident sessions - 536us/append at
N=1 rising to ~2636us at N=100 live sessions (a+21us*N fits all four N and
both trials), because every session event (2 per append: message_start +
message_end, each carrying the full message payload) is published on the one
daemon-wide tokio broadcast channel, and every connected client's event arm
wakes, deep-clones the (ClientRouting, Value) frame, locks its attached-list
mutex, checks, and discards. Aggregate daemon CPU for equal per-session
traffic is Theta(N^2).

Share the payload instead of cloning it per receiver: the channel carries
(ClientRouting, Arc<Value>). Nothing else changes - same channel, same ring
capacity, same routing decisions in the same recv order, same wire frames
(write_line serializes from the shared Value; the worker-side EventPump
already shares its frames this way via Arc<OutboundFrame>). The per-receiver
cost for a non-matching connection drops from a full serde_json::Value deep
clone to an atomic refcount bump.

Measured on the 16c/32GB ubuntu:22.04 VM (hillclimb-perf-concurrent-io):
same-vm ABBA at N in {1,100} follows in the lane record; the claim is
daemon CPU per session event, not wall latency (append wall is
fsync-dominated on the measurement host).

* fix(pa-daemon): wrap the two missed client-event send sites + test compile

- supervisor.rs shutdown-signal daemon_closing broadcast and the
  supervisor_roster.rs RosterSubscribers push missed the Arc wrap; both
  now share the payload like every other events.send site.
- Test fixtures compile against the shared-payload channel: the roster
  drain helper derefs back to owned Values (tests keep comparing Values),
  and the daemon_closing assert compares through the Arc.

* fix(pa-daemon): compile + rustfmt the shared-payload channel's test helpers

- supervisor_roster_seed tests' drain helper takes the Arc-typed receiver
  and derefs back to owned Values (same pattern as supervisor_roster).
- rustfmt the Arc-wrapped send sites (line-width wrap only, no semantics).
No product behavior changes: whitespace + cfg(test) code only.

* style(pa-daemon): rustfmt the seed-test drain helper + clippy semicolon

One-liner receiver type per rustfmt, trailing semicolon per
clippy::semicolon_if_nothing_returned. cfg(test)-only change.

* pa-core: anchor compaction summaries to kept-tail state and stop re-summarizing file lists (TS #2385) (#2768)

a1c236c05df8merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-tui): the bang-during-streaming-turn e2e gates the mock's turn end on the ack bang, not a wall clock - every awaited state is causal or terminal, closing the two-channel load red (red-bang-stream-flush-20260926-1) (#2904)

a02c3aa25cdamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai/pa-daemon: the faux repeat-last knob + the goal-recovery e2e opts in and pins the exhaustion race deterministically - closes red-goal-recovery-faux-exhaustion-20260926-1 (#2902)

1e236ad703efmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the inline pickers' selection wash reads off the surface (operator directive) (#2908)

c7a54e058c31merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): return the supervisor relay and catalog-scan heap to the OS (#2899)

The supervisor process relays every routed worker response through a
serde_json Value tree (from_slice in the worker-frame reader, a
DaemonResponse through the pending-reply channel, response_line to the
client write) and the saved-session catalog scan folds a parse tree per
file line; both phases free their trees when the phase ends, but nothing
in the supervisor process ever returned the freed pages, so a grown
session relay (a ~9.5MiB get_messages wire leaves +71MiB resident; a
routed attach adds +42MiB more) and every grown catalog scan stayed at
the arena high-water for the daemon lifetime.

Mirror the merged #2872 session-memory pattern on the two daemon-side
phase boundaries: write_line reports the serialized byte count and the
client write loop trims when a routed line carried >=1MiB (the frame is
out and the tree is dropped first), and the saved-session scan trims at
its join (the per-line trees are folded and freed inside the blocking
task; the per-file cached scan states are live cache and stay
untouched). Allocator plumbing only - no data, protocol, wire, or
behavior changes; non-glibc/Linux builds are no-ops via
pa_types::memory_release.

Co-authored-by: perf-daemon-rss-fast <hillclimb@prime-intellect.local>

* perf(pa-tui): stream the exit/suspend main-screen flush - zero exit RSS spike, byte-identical output (#2913)

* perf(pa-tui): stream the exit flush in bounded chunks - the inline repaint never materializes the whole frame

* pa-tui: fmt + the flush errors doc (gate nits)

* pa-tui: fmt + the flush errors doc (gate nits)

* perf(pa-core): serialize same-process auth-lock holders - first-turn slow-class 50% to 12% (#2915)

The TS product runs acquireLockSyncWithRetry on a single thread, so the
10x20ms retry only ever fires against another process. The Rust engine is
threaded: two worker threads racing AuthStorage::create on a fresh
session's first turn (model-resolution registry build vs a concurrent
auth read, strace-verified: openat O_CREAT|O_EXCL -> EEXIST within 47us,
loser clock_nanosleeps the full 20ms) pay the TS retry sleep against each
other, a ~20ms first-turn latency class in 4/6 msgsettle trials.

A process-local mutex keyed by the auth document path serializes
same-process callers for the microseconds the small read/modify/write
holds. The file protocol, staleness judgment, and retry semantics are
untouched: a foreign holder (another process) still surfaces WouldBlock
and still takes the 10x20ms retry. The mutex is a leaf (the locked
section performs only the document's own fs ops plus the caller's
callback; no callback re-enters with_lock), and poisoning is recovered
because the file protocol is the correctness mechanism.

Co-authored-by: perf-model-resolve-cache-fast <hillclimb@prime-intellect.ai>

* perf(pa-daemon): per-session subscriber registry - send-time attached check, sup CPU -20% at N=100 (#2914)

* perf(pa-daemon): share client-event payloads on the supervisor broadcast (Arc)

Baseline at origin/rust 7064d039a on the concurrent-io lane: supervisor CPU
per append_custom_message is Theta(N) in resident sessions - 536us/append at
N=1 rising to ~2636us at N=100 live sessions (a+21us*N fits all four N and
both trials), because every session event (2 per append: message_start +
message_end, each carrying the full message payload) is published on the one
daemon-wide tokio broadcast channel, and every connected client's event arm
wakes, deep-clones the (ClientRouting, Value) frame, locks its attached-list
mutex, checks, and discards. Aggregate daemon CPU for equal per-session
traffic is Theta(N^2).

Share the payload instead of cloning it per receiver: the channel carries
(ClientRouting, Arc<Value>). Nothing else changes - same channel, same ring
capacity, same routing decisions in the same recv order, same wire frames
(write_line serializes from the shared Value; the worker-side EventPump
already shares its frames this way via Arc<OutboundFrame>). The per-receiver
cost for a non-matching connection drops from a full serde_json::Value deep
clone to an atomic refcount bump.

Measured on the 16c/32GB ubuntu:22.04 VM (hillclimb-perf-concurrent-io):
same-vm ABBA at N in {1,100} follows in the lane record; the claim is
daemon CPU per session event, not wall latency (append wall is
fsync-dominated on the measurement host).

* fix(pa-daemon): wrap the two missed client-event send sites + test compile

- supervisor.rs shutdown-signal daemon_closing broadcast and the
  supervisor_roster.rs RosterSubscribers push missed the Arc wrap; both
  now share the payload like every other events.send site.
- Test fixtures compile against the shared-payload channel: the roster
  drain helper derefs back to owned Values (tests keep comparing Values),
  and the daemon_closing assert compares through the Arc.

* fix(pa-daemon): compile + rustfmt the shared-payload channel's test helpers

- supervisor_roster_seed tests' drain helper takes the Arc-typed receiver
  and derefs back to owned Values (same pattern as supervisor_roster).
- rustfmt the Arc-wrapped send sites (line-width wrap only, no semantics).
No product behavior changes: whitespace + cfg(test) code only.

* style(pa-daemon): rustfmt the seed-test drain helper + clippy semicolon

One-liner receiver type per rustfmt, trailing semicolon per
clippy::semicolon_if_nothing_returned. cfg(test)-only change.

* pa-daemon: per-session subscriber registry - session events resolve delivery at publish time (TS handleWorkerFrame parity)

TS evaluates the attached predicate in the same synchronous pass that
writes the socket (daemon-supervisor.ts handleWorkerFrame l.6353; attach
flips the flag and writes session_attached in one tick, l.5586->l.5608).
The Rust ring evaluated it at RECV time in every connection event arm - a
superset in the attach/detach race window TS cannot produce (an event
published before an attach could still land after it, duplicating a row
the attach snapshot already carried).

Session events now route through a supervisor-side subscriber index
(session id -> connection id -> bounded per-connection queue): publish
enqueues to the attached set under one lock, unattached connections
never wake (the ~5.9us/session/append wakeup floor at N=100 from the
concurrent-io lane), per-(session,connection) order stays publish order,
and a full queue drops with a one-line-per-stall-cycle log (finding 4a
visibility). Broadcast / BroadcastExcept / RosterSubscribers keep the
ring; ClientRouting::AttachedSession is removed so a stale session-event
publish fails at compile time. Session events without an active session
id are dropped (TS l.6296 !activeSessionId guard), not broadcast.

The dormant supervisor/clients.rs split copy carries the same change
(re-homing at the fold will take one of the two).

* pa-daemon: fmt + clippy fixes for the subscriber registry (if-let for the single-pattern session-event relay)

* pa-daemon: fix the registry idempotency test - drain the delivered frame before the post-detach empty check

* pa-daemon: rustfmt the registry rebind call and the idempotency assert

* pa-daemon: rustfmt the registry call sites exactly as rustfmt asks

* pa-daemon: convert the zero-copy splice arm's attach push to the subscriber registry

#2897's raw-splice attach family added a SECOND attach-success push site on
the tip's routing.rs; it arrived through the fold with the old vec
semantics (the pre-fold grep could not have seen it). Same conversion as
the typed arm: registry + session list in one attach() call, the registry
insertion is the delivery boundary.

* pa-tui: the operator's touch follow-ups - the card click opens the card, the follow hint re-derives at the mode exit, the prompt bar's indicators paint on the bar (#2911)

0c526d534fcamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai: the codex dead-callback tests stage the registered port checked, not blind (settle-race hardening) (#2906)

c38824288cf2merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli: the first-run login frames render the TS login dialog (frame-parity r3) (#2845)

11365e57484dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 1/14 - the heartbeats concern moves out of src/session_ui.rs (#2886)

9f1cfc73550amerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the hover affordance - ?1003 any-event tracking delivers the buttonless motion, the hovered clickable card row brightens (muted to the theme fg, dim to muted) (#2918)

d81f3d2c7c07merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-ai/pa-agent): StreamingJsonAccumulator - stop re-parsing streamed tool-call JSON on every delta (TS #2783 port) (#2912)

dbec3a6eb0b7merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge); optional lane gate evidence: gate_1790470828_1252847 GREEN.

* pa-daemon: agent_engine.rs split 3/11 - the artifacts concern moves out of src/agent_engine.rs (#2905)

95e10f8ea95emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 2/14 - the stream concern moves out of src/session_ui.rs (#2920)

6aecfb087453merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 5/14 - the auth concern moves out of src/session_ui.rs (#2923)

70abcc702d14merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-cli/pa-daemon: implement the RPC stdio mode over the in-process session engine (TS modes/rpc parity, stub S5) (#2801)

25b657908b38merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 2/8 R2 (remediation) - the client-connection cut actually lands on the facade (#2885)

21304589206amerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli: the agents-view e2e settles its daemon-driven rows by synchronization, not a timing budget (AgentsStep::WaitRender - the registered ranked-hits render/data-arrival race closes by construction) (#2910)

f22938c1e0aamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-tui): packed cached entry layouts - scroll retention RSS -42%, byte-identical output (#2921)

* perf(pa-tui): store cached entry layouts packed - byte-exact rows, one blob + dense span records

The transcript layout cache retains every visited entry's rendered rows
for the process lifetime. A 2600-key scroll walk over the canonical 10MiB
session retained 5,428 entries' rows as 604k fragment-sized spans holding
5.2MB of text (+64.6MB heap, fully retained after return-to-tail; the
tui-scroll-retain census: 8.3 spans/line, content capacity already
exact, 44% line-buffer slack, per-span Vec/String chunk overhead the
retained mass). Merging adjacent same-style spans would shrink the
storage but changes the exit-flush inline scrollback's ANSI bytes
(per-span SGR re-emission; the exit flush is the TS-parity-frozen
output), so the cache stores the same rows packed instead: one content
blob plus dense (offset, len, style) records, expanded byte-exactly on
read - only the intersecting row range is expanded, so a frame inside a
huge entry pays its visible rows, never the whole row set. The pad
entry's own 109k-span row set (the resumed ready-state footprint) packs
the same way.

* perf(pa-tui): exact pack blob capacity + size-gated post-pack trim

The pack's blob grew by String doubling (2x capacity: 33.6MB held for a
17.45MB row set at 40MiB); the first pass now sizes it exactly. A huge
entry's rendered rows are the transcript's biggest single transient and
the pack just freed them - the freed pages only return to the OS when
the allocator's trim can reach them (the 40MiB ready RSS measured
bimodal 181/205 on the same build); the pack now returns them
immediately, gated at 8192 rows so ordinary entries never pay a trim.

* fix(pa-tui): EntryRows::is_empty for the touch surface's shows-tail peek (fold resolution completion)

The #2911 fold introduced the empty-section peek (a window that exactly
ends on the final chat entry re-checks whether any non-empty section
remains before declaring shows-tail); its section source is the
EntryRows handle since the packing fold, which needs the is_empty form.

* test(pa-tui): fix the pack tests' clippy findings (untyped Vec::new, shadowed view helper)

* test(pa-tui): drop the pack test closure's unused mut

---------

Co-authored-by: perf-tui-scroll-retain-fast <perf-tui-scroll-retain-fast@hillclimb.local>

* pa-daemon: agent_engine.rs split 2/11 - the config concern moves out of src/agent_engine.rs (#2909)

07cbb0febb74merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 4/11 - the model concern moves out of src/agent_engine.rs (#2907)

5c530e66cef9merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 3/14 - the queue concern moves out of src/session_ui.rs (#2900)

e673275046dfmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 7/8 - the update/restart concern moves out of src/supervisor.rs (#2903)

268c1fba26c0merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli: dock panel exits restore the dock's own group, not the prompt bar (operator ruling 2026-09-26) (#2864)

a12c2847335bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 5/11 - the goalcore concern moves out of src/agent_engine.rs (#2924)

c95a239b9eb3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-tui): handoff drains park on observed input, not a fixed wait - chat-to-agents -79% (#2916)

* perf(pa-tui): a handoff drain consumes buffered input instead of parking on the idle window

The chat->agents handoff teardown pays the enhanced_keys drain's fixed 50ms
DRAIN_IDLE poll on every switch (chat->agents measured 67ms p50 at #2893,
~50ms of it this window). The idle window guards a kitty key release that
lands after raw mode is off - a leak that is unreachable on a handoff: raw
mode stays on (the adopting surface's reader takes the same tty) and every
surface's dispatch drops release events (input::filter_enhanced_key_events,
TS tui.ts). The handoff now consumes what the terminal has already written
with zero-timeout polls and returns as soon as the buffer is observed empty;
only when input IS flowing does it fall through to the bounded drain, so a
burst around a handoff is coalesced exactly like before. True exits (drain,
drain_for_exit) keep the TS drainInput(1000, 50) contract untouched. Adds a
real-pty e2e that arms the kitty protocol, injects the handoff trigger's
release in flight, and audits the byte stream (no visible release, no
post-exit kitty flags, no echo after the restore).

* test(pa-cli): fix the kitty-release e2e gate lints (fmt shape, unit let-binding, unused import)

* test(pa-cli): the kitty-release mock supervisor serves every connection in turn

The chat surface holds one daemon connection and the agents view opens its own after the handoff; a single-accept mock refused the second (the first run of the e2e failed on exactly that: connection refused at run_agents_view connect).

* test(pa-cli): qualify the mock supervisor connection handler call

* test(pa-cli): handle the listener incoming result in the mock supervisor

* test(pa-cli): the kitty-release editor probe waits for the painted cell

The frame paints typed cells as styled positioned cells (escape bytes between characters), so the two-byte zz needle never appears; wait for the painted z cell instead.

* test(pa-cli): the kitty-release harness reaps the pty child on panic paths too

* test(pa-cli): the kitty-release exit drives the CSI-u escape form

With disambiguate armed a kitty terminal encodes its Esc presses as CSI 27 u; the raw lone ESC byte is the legacy form the reader arms its meta-wrapper hold for. Drive the realistic encoding and separate the exit key from the release injection.

* fix(pa-tui): the handoff drain's bounded phase runs on the budget the zero-timeout loop left

The zero-timeout consume loop can spend the whole DRAIN_MAX under
continuous input before falling through to drain_until_idle, which
then started a fresh budget - the handoff could block nearly two
seconds, past the documented one-second hard cap. The bounded phase
now runs on what remains of the original budget (Macroscope thread
PRRT_kwDOSXZbXs6mWWqM).

* perf(pa-daemon): borrow the catalog fold metadata and single-open the scan - cold scan -7%, syscalls -22% (#2919)

* perf(pa-daemon): borrow the catalog fold's entry metadata, kill the per-line tail Vec

The post-#2879/#2882 cold roster scan still typed-parsed every line into
owned strings and materialized `Value` trees for fields the fold reads
once or discards: 3 `String` allocations per line (type, id, timestamp)
plus a `Value` tree per message row (role, provider, model, timestamp) and
per session_info/state/model_change/thinking_level row. The resume tail
added one `Vec` allocation per line sized line.len()+17 to keep 16 bytes.

Both costs are gone without changing a row byte:

- SessionInfoEntry's scalar fields borrow as `Cow<str>` (zero-copy when
  unescaped, owned fallback identical to the old String), its object
  fields ride raw spans like #2882's content: each arm parses back only
  the span it reads, with exactly `Value::as_str`/`as_u64` semantics
  (present-and-string/number, absent and non-string both read None, the
  model_change abort arm keeps its exact two-step None).
- advance_tail copies inside the fixed 16-byte window: the same bytes
  (a rolling-reference lockstep test pins the old Vec semantics), no
  per-line allocation.

Differential ground truth: the new in-tree shape matrix pins every
borrowed read to the full-parse Value read per row (escaped scalars,
non-string roles/timestamps, null/absent/whitespace names, hidden/sleep
states, abort shapes) and folds the accepted rows end to end against the
legacy full-parse reference fold; the VM census ran the same differential
over 177,798 real fixture lines (100/1000/4096 tiers) with zero
divergence in acceptance, fields, or fold states both directions.

* perf(pa-daemon): share one open between the roster header gate and the fold

The roster scan opened every file twice: the bounded header gate opened,
read its first line, and closed, then the fold opened the same path again
for the scan — an openat+close per file per scan (plus the second
metadata read the fold always paid). The gate now reads the first line
from the same fresh handle the fold rewinds and scans, so one open serves
both.

The TOCTOU the double-open carried is disclosed: with two opens, a
rename/replace landing between them judged one file and folded another;
the shared handle pins the judgment and the fold to the same inode —
the fold's cursor, generation, and certification re-stat now read the
file the gate judged, never a replacement that raced in between.

The listing stat (`stats.mtime`, the `modified` fallback of last resort)
is read lazily now: the fold only reaches it when a row has neither
message timestamps nor a parseable header timestamp, so the eager
per-file stat the scan always paid serves only the rows that read it.
The `or_else` chain keeps its order and its None semantics (the
existing fallback tests pin every arm of the chain).

* pa-daemon: fmt + clippy for the catalog fold lane (test-import move, lockstep test polish, matrix lint allows)

* pa-daemon: supervisor.rs split 4/8 - the saved-session concern moves out of src/supervisor.rs (#2883)

9f9146b74371merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the #2921 review follow-ups - RowPack::pack refuses unrepresentable entries, the huge-entry trim drops the expanded rows first (fold of rust 9b62f26af) (#2925)

df34ea19dbb3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 10/14 - the bash concern moves out of src/session_ui.rs (#2928)

481b2f28553cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* skills/prime-intellect: sync vendored sandbox docs to the VM-only surface (TS #2456 doc half) (#2751)

a4e997e2e803merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* fix(pa-cli): remove the duplicated restore_dock_focus initializer the #2751 squash double-applied

The #2751 squash (1a9fd16b9) landed the heal rider line onto a tip that
already carried the identical line from #2925 (e6e7a26e4) - the squash
applied the stale pre-fold diff, duplicating the field (E0062). This
restores the fixture to the parent 84dbb51e0 state (exactly one field).
The label rider and the docs in the same squash are intended and stay.

* pa-daemon: agent_engine.rs split 7/11 - the SessionEngine trait impl moves out whole (#2926)

2b07a22bd1d3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core + runtime: the harness-digest family - IDF-ranked digest/search, state-fingerprint staleness, newest-only digest contexts, validated kernel harness writes (TS #2392/#2400/#2394/#2463 parity) (#2750)

bff9fa6ff122merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* fix(pa-cli): the kitty handoff e2e fixture initializes restore_dock_focus (#2927)

962ff3097575merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 7/14 - the settings concern moves out of src/session_ui.rs (#2930)

fd71eaf2dfeamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 6/14 - the model-picker concern moves out of src/session_ui.rs (#2929)

2038abcf5754merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon/pa-cli: ACP model and effort pickers - configOptions at session/new, session/set_config_option, config_option_update (TS #2455) (#2758)

fd977cb13ee6merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core): consolidate auth-lock reads - 36 lock cycles per first turn to 2, settings mutex closes the unmasked stall class (#2932)

* perf(pa-core): consolidate auth-document reads through a validated cache

* perf(pa-core): serialize same-process settings-lock holders (the #2915 pattern)

The auth read-through cache on this lane unmasks a pre-existing stall:
two worker threads racing the same settings.json pay the full TS
10x20ms retry sleep against each other (strace-verified: mkdir
attempts 11us apart, the loser clock_nanosleeps the full 20ms; the
paired census shows same-process overlapping settings acquisitions 2
on the base and 5 with the auth cache, sleep20 1 vs 2, and the timing
legs pay a ~20ms-class stall on 3/6 fresh turns vs 0/6 base). The
auth-lock cycles 150-300us same-process serialization was pacing the
threads apart by accident; that masking is not a mechanism to keep.

TS runs its synchronous settings lock single-threaded, so same-process
settings contention is a Rust-port artifact, the exact class #2915
ruled on for the auth lock: a process-local mutex keyed by the
document path serializes same-process callers for the microseconds
the small read/modify/write holds. The file protocol, staleness
judgment, and retry semantics are untouched: a foreign holder
(another process) still surfaces WouldBlock and still takes the
10x20ms retry. The mutex is a leaf (the locked section performs only
the document's own filesystem operations plus the caller's update
callback; no settings callback re-enters with_lock - every callback
is a pure JSON transform), and poisoning is recovered because the
file protocol is the correctness mechanism.

---------

Co-authored-by: perf-auth-lock-fast <hillclimb@prime-intellect.ai>

* perf(pa-daemon): zero-copy worker response path - routed msgs -17%, attach -22%, worker RSS -20% (#2935)

* perf(pa-daemon): zero-copy worker response handoff - serialize the line from the borrowed trees, write the frame without re-buffering the payload

* fmt(pa-types): the segments test write_frame call in the form CI rustfmt wants

* fmt(pa-daemon): the response-path call forms CI rustfmt wants (VM cargo fmt at the exact head)

* fix(pa-daemon): restore the response_line TS-key-order test the new-test insert orphaned (clippy empty_line_after_doc_comments was the symptom)

* fmt(pa-daemon): the restored test doc comment indent

* fmt(pa-daemon): single trailing newline at file end

---------

Co-authored-by: wc <wc@fleet.local>

* pa-daemon: agent_engine.rs split 6/11 - the Turn types move out of src/agent_engine.rs (#2931)

b2ca4deea5afmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): batch the queue-checkpoint journal pair - 4 syncs per warm turn to 2, crash window strictly narrowed (#2936)

* perf(pa-daemon): batch the queue-checkpoint journal pair into one durable append

The queue checkpoint (prompt/steer/follow-up admission, turn settle, queue
mutations) appends two records to the worker recovery journal - the queue
snapshot and the busy/operation verdict - as two separate open+write+fsync
cycles, paying two journal flushes per checkpoint. Both records describe
one atomic checkpoint, and the busy verdict must never publish over a
snapshot that did not persist, so the pair can ride ONE open+write+fsync:
the batch is all-or-nothing durable, the on-disk line order matches the
sequential form exactly (snapshot first, then the verdict), and an
unchanged verdict keeps appending the snapshot alone.

Measured on the warm-turn admission path (the wave-5 warm-durable-append
decomposition): the two journal fsyncs sit inside the TUI-ack-to-user-row
phase together with the session append's fdatasync; batching removes one
of the three durable syncs per warm turn without weakening any durability
guarantee (the session append's per-row fdatasync is untouched).

* test: rustfmt the batched-checkpoint test call sites (gate fmt finding)

* fix(pa-tui): the exit watchdog holds fire while the flush drains - healthy slow drains no longer truncate scrollback, TS-convergent (#2937)

* perf(pa-tui): the exit guard holds its force-quit while the exit path drains - slow terminals keep the whole scrollback flush

On a terminal that consumes the exit flush slowly (a laggy ssh at
~0.5-2MB/s), the flush of a large transcript outlasts the 1500ms
FORCE_QUIT_AFTER_MS deadline that arms at the second Ctrl+C, and the
watchdog fires mid-flush: strace shows its restore writes winning the
pty FIFO race at a flush-chunk boundary, exit_group(0) landing while the
writer still holds ~64-82% of the transcript (40k rows: 8.74MB flush
truncated to 1.5-3.1MB), 'shutdown stalled; forced exit.' printing on a
healthy drain, and the restore bytes queueing mid-stream behind the
flushed rows. TS has no watchdog at all (its handleCtrlC second press
runs the async shutdown, and slow writes simply wait), so both the
message and the truncation are port-only.

The guard becomes drain-aware: the flush writer reports progress per
completed 32KiB chunk (view.rs FlushSink), the release tail and the
resume hint report theirs, and the watchdog holds its fire while
progress landed within EXIT_PROGRESS_GRACE_MS (500ms) - the hard 1500ms
ceiling stays for the silent case (the wedged loop the guard was built
for). Flush chunks shrink 256KiB -> 32KiB so a drain of at least
~65KB/s completes chunks inside the grace window; the flush byte stream
is unchanged (the exit-flush lane's byte-identity oracle). The truncated
scrollback contract is restored on slow drains: the flush completes
byte-identically, the release tail lands after the last row, and the
message prints only for a genuinely stalled drain.

The exit-guard unit tests grow the hold/fire decision table; a new
real-pty e2e (pa-cli slow_drain_exit_guard_e2e, the kitty-release
harness pattern) drives the real chat surface over a paced pty master
and asserts both sides: a draining terminal flushes the whole
transcript with no forced exit, and a stalled drain still fires.

Rider (disclosed): kitty_release_handoff_e2e grows the restore_dock_focus
field the #2916 squash dropped from its fold-time heal - the tip's
pa-cli test target does not compile without it.

* test(pa-cli): the slow-drain e2e asserts the forced fire structurally

The re-executed test binary's libtest harness captures stderr per
test, so the watchdog's 'shutdown stalled' line never reaches the pty
in the harness child (the real binary writes it to fd 2 - the lane's
VM bench legs assert it there). The stalled-drain leg instead asserts
the forced exit structurally: the forced restore's own alt-screen
leave lands on top of the exit path's (a clean exit leaves it exactly
once), the flush never reaches the transcript tail (one copy of the
last user row, the startup viewport's), and the process dies with the
guard's exit code inside the stall window. Harness needles use the
user-message rows (assistant rows carry per-word SGR spans) and the
post-exit drain reads the pty's kernel-held bytes before asserting.

* fmt: the slow-drain e2e needles and the watchdog's progress read

* clippy: doc backticks + checked Duration subtraction in the guard tests; the e2e's needle check takes the direct is_none

---------

Co-authored-by: perf-slowdrain-exitguard-fast <lane@hillclimb.local>

* perf(pa-core): consolidate settings-lock reads - 32 lock cycles per first turn to 2 (#2941)

* pa-ai/pa-core/pa-cli/pa-tui: grok-4.7 on every serving surface (TS #2505) + Claude Code 2.1.281 + Anthropic subscription ban-risk warning (TS #2645) + one owner for the Prime team header, retry failed !command credentials (TS #2497) (#2755)

7373eb471670merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-cli): the interactive_daemon_e2e wedge root-kill - PDEATHSIG + orphan sweep + the 300s headless wall (#2942)

dbed1170fa2bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli/pa-daemon: session opens wait through a daemon update restart (TS #2391) + the failed-restart hint (TS #2515) (#2763)

e7a84e749089merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): the all-idle compaction fires like TS and rides the TS compact sync class - journals bounded (#2944)

* perf(pa-daemon): settle-tail compact consolidation - the all-idle compaction fires like TS and rides the TS compact sync class

The worker recovery journal's all-idle gate ran BEFORE the record insert,
so a single-session journal's own busy admission record blocked every
settle's compaction: the compact never fired on the dominant shape and
the journal grew append-only for the session's lifetime (TS computes the
gate POST-insert and compacts at every changed-idle record). The gate now
matches TS, bounding the file.

Where the compact fires, its temp sync_all was a sync class TS's compact
does not pay (TS worker-recovery-journal: writeFileSync + renameSync, no
fsync; the command journal's writeFileAtomicSync counterpart does carry
fsync). The Finalize seam now encodes the sync class per owner: RetryBusy
keeps its fsync (command journal), Synced keeps the Rust-native
terminal-compaction journal's belt, and Bare is the TS worker shape -
temp write + rename, no fsync. Durability is owned by the append path
(the fresh-write class is untouched): the compacted form holds only
records the append path already made durable, so a lost compact falls
back to the append-only history, which replays identically.

* test-only rustfmt of the new test call site (the gate's one fmt finding)

* runtime/kernel: vendored-runtime hardening + kernel stderr owner-only (TS #2372/#2423/#2500/#2471/#2478/#2425 parity) (#2744)

ea5abd1bbe1bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 11/14 - the prompt submit pipeline moves out of src/session_ui.rs (#2943)

3bafbc007b74merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-tui): 8-byte packed span records with per-pack style table - scroll retention -7.5MB, byte-identical output (#2939)

* perf(pa-tui): denser packed span records - style table + derived offsets (8B/span), byte-exact range expansion

* test(pa-tui): rustfmt the exhaustive row-pack range oracle

* fix(pa-tui): clippy - if-let style dedup + drop redundant test clones

* pa-tui: fix the submit-outlived-by-switch idle-gate race - the turn-end watermark restarts with the mounted stream (#2945)

c661290b1b77merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: hold spawn-name reservations until admission is durable; collect returns cancelled envelopes for just-deleted targets (TS #2396 + #2388 F4) (#2757)

18aa772bd3b2merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai/pa-core/pa-daemon: codex stale-chain retry after metadata (TS #2374) + safety failures permanent (TS #2472) + quota park until reset with auto-resume (TS #2375) (#2761)

dc9892ffbc1emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-tui): the headless settle bound names its stuck member in 60s - defense-in-depth inside the wedge wall (#2949)

The interactive_daemon_e2e exit-gate wedge family is root-killed
upstream (#2945: the turn-end watermark restarts with the mounted
stream) and the harness carries the 300s wall (#2942). This closes the
remaining gap: the headless settle was the run loop's only unbounded
wait on the product side — a settle member that never drains parked the
run forever with no failure name (TS exits the process at shutdown and
lets in-flight work dangle, so the settle has no TS counterpart).

The gate's twelve settle members are now snapshotted (HeadlessSettle:
settled() is the old gate exactly; blockers() names them), and after
the plan completes a stuck member fails the run within
HEADLESS_SETTLE_TIMEOUT_MS (60s) with the member named — e.g. 'a turn
still active' — instead of waiting out the harness's 300s wall with a
generic timeout. Green settles are milliseconds after HeadlessDone
(the suite's green wall is ~15s; the last submit's own ack bound is
10s), and terminal runs never arm the bound (HeadlessDone exists only
on the headless harness; a live terminal ends the run on
exit_requested + the exit guard).

Proven end-to-end by the lane's matrix: the wedge converted to a 98.4s
attributable red naming the latched member (the bound-only diagnostic
arm), and the full candidate stayed clean at 30/30 interleaved trials
vs 3/30 wedges at the lane parent (record
20260927-085200-interaction-exit-gate-hang-remediation, bench
hillclimb).

* perf(pa-daemon/rpc): warm the model registry at RPC session boot - first get_available_models 1170.6ms to 58.9ms (#2953)

TS session boot resolves the initial model through refreshAvailableModels
(model-resolver.ts), which also fetches the live Prime Inference catalog
in the background and caches it on disk; the daemon worker fires the same
fire-and-forget refresh from its create path (worker/create.rs). The RPC
mode hosts the session in-process with no create command, so nothing
warmed the caches: an integration's FIRST get_available_models call paid
the whole awaited refresh chain on its response path (measured 812-1296ms
on the bench VM; the 15s fetch-timeout worst case on a degraded network)
while the same command on the daemon and ACP surfaces answers from the
validated snapshot. Mirror the daemon worker boot spawn: the caches warm
during the session's first turn, and the first call serves the same
snapshot. Write behavior is unchanged: the same cache files, the same
write-on-fetch-success conditions, the same cadence (hour-gated catalog
refresh, 5-min private-authorization TTL), only started at boot.

Co-authored-by: perf-rpc-models-persist <lane@hillclimb>

* pa-tui: session_ui.rs split 4/14 - the share concern moves out of src/session_ui.rs (#2922)

b0d72b29a700merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 8/11 - the turn-execution impl moves out (#2934)

a59d3389dfbamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 5/8 - the worker-lifecycle concern moves out of src/supervisor.rs (#2956)

205f4d0f469cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 8/14 - the sessions concern moves out of src/session_ui.rs (#2957)

7d19e9832120merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 6/8 - the signals concern moves out (#2960)

a6562bc252efmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 10/11 - the lifecycle concern moves out of src/agent_engine.rs (#2962)

17d3573c5a58merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 12/14 - the keys concern moves out of src/session_ui.rs (#2958)

bc6b7d82cb0bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 11/11 - the facade trim: the last product free fns move out; the file ends as the composition root (#2964)

1fe6a6791030merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 8/8 - the facade trim: the notes concern moves out, the test battery re-homes (#2963)

8a5274baa0d9merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 9/14 - the panels concern moves out of src/session_ui.rs (#2961)

377eda9ded15merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 13/14 - the apply concern moves out of src/session_ui.rs (#2965)

c10a44e407cdmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: cap kernel host-request cell source at 2 KiB (the TS #2475 port) (#2966)

96f689fc38femerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the /model picker resolves by provider, never the first same-id catalog entry (fixes the operator report) (#2967)

24411964739emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 14/14 - the facade trim: the file ends as the composition root (#2968)

60cbb4fbb642merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core): the oauth refresh leaves the auth lock - fetch under single-flight, hold-sum 396ms to 0.09ms (#2971)

An expired stored OAuth credential refreshes its token inside
AuthStorageBackend::with_lock: the OAuthIntegration seam is synchronous
by contract, so the network round trip runs under the document lock AND
under the process mutex that spans the whole critical section, stalling
every other same-process auth read and write for the fetch (the RPC
cycle_model path measured 194-201ms auth.json.lock holds per switch on
the bench VM; the assembly read pays one ~0.2ms cycle, the switch pays
the fetch).

The TS product holds its own lock across the same await
(refreshOAuthTokenWithLock -> withLockAsync), but its single-threaded
runtime never blocks other work on it; this engine is threaded, so the
port narrows the lock scope instead: load-then-lock. The document loads
through the consolidated read arm, the token fetch runs outside every
lock behind a per-provider single-flight gate (the in-process
serialization TS gets from its single-threaded runtime, with the expiry
re-checked under the gate so a second caller never spends a single-use
refresh token after the first flight landed), and the write re-enters
the same locked read-modify-write protocol - now held only for the
re-read, insert, and atomic write, and skipping the write entirely when
a peer refreshed while the fetch ran. File protocol, read results, and
every resolution outcome are unchanged.

* pa-daemon: the supervisor roster broadcasts only on content change (the TS #2481 port P3) (#2974)

054553b8ca12merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-cli/pa-tui: prime-agent update - the TS->Rust migration path (uninstall TS, install Rust, sessions preserved) (#2981)

739ed7f7d015merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core/pa-daemon): a settled RLM child releases its kernel at the settle park - ~27MB reclaimed per settled child, TS #2483 port (#2983)

* perf(pa-core/pa-daemon): a settled RLM child releases its kernel at settle - snapshot-flushing stop_kernel, revivable (TS #2483)

The rust port of the stale perf PR #2483's inline arm (the supersession
analysis: the not-superseded claim - settled children hold a worker and
a kernel until parent close; nothing at the tip releases them; the
daemon-mode whole-worker passivation stays deferred to the orchestrator):

- IpythonKernelProvisioner::stop_kernel (TS s…
snimu added a commit that referenced this pull request Sep 30, 2026
* perf(kernel): defer websearch httpx import to first call - first tool cell 17ms -> 2ms (#2888)

Module-level 'import httpx' put its full import chain (~15ms in-kernel) on
every kernel bootstrap cell, in every session, even when no search runs.
Import it inside _fetch_serper on first call instead. A module-level
find_spec guard keeps the import-time contract byte-identical: when httpx
is absent, importing websearch still raises ModuleNotFoundError('No module
named \'httpx\''), so the kernel's unavailable-skill stub and its message
are unchanged. No Rust, API, wire, or behavior change; the first websearch
call pays the import once.

Co-authored-by: perf-kernel-cell-fast <lane@hillclimb>

* perf(pa-core): adopt the retained window one-copy - move the trees in, drop the raw duplicate (#2890)

* pa-daemon: summary scalars from one borrowed walk, not the materialized fold

session_summary folded the whole retained window into a Vec<Value> on
every read (attach, get_state, roster pushes, list rows) just to read
three scalars: the newest message timestamp, the summed assistant usage,
and the window's message count. At session scale that fold is the
majority of the summary's cost and half the retained-window folds an
attach pays (handle_attach's snapshot fold is the other).

SessionFile::messages now delegates to one shared windowed walk
(walk_message_values): message rows borrow their persisted message,
custom_message rows rejoin in their wire form, and a compaction window
prepends its summary message with the retained count counted in a
borrowing pass. The materialized fold keeps its exact sequence (same
keeping-flip semantics on message-bearing rows, same summary-first
order) and drops the doubled clones the old retained loop paid.

scan_message_scalars walks the same sequence for the summary scalars:
the reverse find_map timestamp (last positioned value, not the
maximum), the assistant usage sums in fold order, and the message
count. session_summary consumes the scan instead of the Vec, so every
summary surface derives from the same walk the fold uses - the two can
never disagree. Golden equivalence tests pin the scan against the old
full-clone extraction across window shapes (non-monotonic timestamps,
custom rows carrying usage, kept id on message/non-bearing/missing
rows, stacked compactions, empty session, degenerate rows), and boundary
tests pin the fold's exact windowed sequence.

* perf(pa-core): adopt the retained window one-copy - move the trees in, drop the raw duplicate

The worker-rss census (bench hillclimb record 20260926-183300) measured
five resident copies of the retained window on the 10MiB canonical
fixture; three were derivable duplicates: SessionManager::adopt_window
cloned the walk's typed trees into file_entries (B) while the window kept
its original (C1, wire-identical) plus the raw JSONL lines (C2,
10.48MiB) - ~29.5MiB of wire-equivalent duplication in the loaded
worker, whose same-build RSS band is 182.5-217.9MiB (p50 207.6).

- WindowedSessionStore::take_retained hands the typed rows AND raw lines
  to the owning manager in one move; a detached window keeps its
  snapshot/settings/metadata surfaces (goal state, refinement history,
  git state, append-time stats) and asserts that its transcript context
  comes from the manager.
- SessionManager::adopt_window adopts the trees by move (no to_vec).
- SessionManager::active_context builds from file_entries with the SAME
  window settings overlay gate as the old window.context() - the served
  context is unchanged; the manager's own append_child_usage_attribution
  fold is the one-copy authority for live rows.
- ensure_full_history re-arms the detached copies (historical hydration
  restores bodies, exactly like a fresh walk).

Oracles: adopted-context byte parity vs an un-adopted window (cold+warm),
detached-window lookups + should_panic context, live-appends-vs-full-
reopen byte parity incl. an in-window attribution target; existing
manager/window/byte-parity tests now ride the adopt path.

* fix: adopt_window takes the window by mut (take_retained borrows mutably); tests serialize the context field tuple (SessionContext is not Serialize) and fully-qualify AgentMessage

* fmt: rustfmt on the new window-scan tests

* fix(tests): reference opens first in the cold pass (the adopted open warms the sidecar); compaction_count is the file-level tally (fixture carries a sibling compaction); the retained assistant row needs the required api/stopReason fields or it degrades to Unknown

* fix: clippy default_trait_access in the scan equivalence test

* fix: clippy default-trait-access in tests (JsonMap::default / MessageWindowScalars::default; the latter is a lint fix on the folded attach-path tests so this lane's gates run green - their lane must carry the same fix on their branch)

* fmt: wrap the scan default assert to 100 cols

* perf(pa-daemon): collapse fresh-create session-file writes into one durable write (#2892)

* pa-daemon: fresh-create single durable write (spawn admission)

The fresh-path create collapsed its session-file durability from three
sync'd writes (a header-only rewrite, a second rewrite for the prefix +
active state, and a persist_entry name append) into ONE rewrite that
assembles the prefix, the state, and the session name in memory first.
The dropped header-only intermediate has no reader: the durable create
stays pathless until the create succeeds, so no replay, scan, or
registration consumes the file mid-create. The final bytes are identical
to the sequential writes (same entries, same order; the name's line is
the exact persist_entry construction via append_session_info).

Measured on the spawn-latency VM (hillclimb lane perf-spawn-admission-fast,
bench record 20260926-204300): each admission pays ~7 serialized
durability round trips; the fresh-write class costs ~38-45ms/op in the
degraded host regime (0.3ms quiet) - the collapse removes two of the
three writes on the child-create leg. In-crate oracles: the single write
matches the legacy sequence's masked bytes; the folded name lands once;
a failed write leaves no session file; a legacy crash orphan neither
blocks the create nor bleeds into the new file.

* pa-daemon: split the create-collapse tests into their own file

create.rs grew past the ~800 LoC guidance with the in-file test module; the tests move to worker/create_collapse_tests.rs via #[path] (still a child of the create module, so the module-private append_creation_prefix stays reachable). No product change.

---------

Co-authored-by: perf-spawn-admission-fast <lane@hillclimb.local>

* perf(pa-tui): handoff exits break the run loop this iteration - chat->agents 119ms -> 67ms (#2893)

The terminal loop's exit-key break only left the input-drain loop, so the
handoff fell into the select below it and parked on the 50ms idle tick
before the loop-tail exit check ran — measured as ~50ms of added latency
on every chat -> agents view switch (strace: the key is handled in ~0.1ms,
the teardown starts on the next tick wake ~51ms later; the code's own
comment already demanded the teardown run "this iteration").

A handoff (agents-back, /resume, the scoped view, /resume <selector>)
now breaks the outer loop immediately: the next surface's mount clears
the alt screen, so the tail pass paints nothing the user can see. A
non-handoff exit (/exit, /quit) keeps the tail pass — its frame gate
paints the final chat frame the exit's main-screen flush shows — and
headless runs keep the tail pass so captured frame sequences stay
identical.

* perf(pa-daemon): borrow message content as RawValue - kill the second full catalog parse, cold -25% (#2882)

Co-authored-by: perf-catalog-second-parse-fast <hillclimb@local>

* pa-daemon: agent_engine.rs split 1/11 - the tests concern moves out of src/agent_engine.rs (#2889)

51bd18583e17merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-cli/pa-daemon): tighten the two cold-open connect-probe grids from 25ms to 5ms (#2891)

Cold-open boot-floor decomposition at 7064d039a (bench hillclimb record
20260926-194800-startup-boot-floor-decompose) measured two pure-wait
probe grids on every cold launch, each quantized 0-25ms (mean ~12.5ms):

- ensure_daemon_running_with polls the freshly spawned supervisor's
  socket every 25ms; a cold supervisor binds ~39ms after spawn.
- probe_worker_socket polls a freshly forked session worker's socket
  every WORKER_CONNECT_BACKOFF_MS=25ms; the worker binds ~1-3ms after
  the fork.

Both grids tighten to 5ms. Timing-only: probes, 30s budgets, auth floor,
and all error paths are unchanged; wire and user-visible behavior are
identical (TS polls at 25ms in both places - the deliberate divergence
is the perf port's, flagged for review).

* perf(pa-tui): return the first-frame heap of a resumed transcript; store settled messages rows once (#2895)

* perf(pa-tui): return the first-frame heap of a resumed transcript; drop settled messages duplicate block-cache copy

* test(pa-tui): settled messages keep no block-cache copy; streaming keeps its replay cache

---------

Co-authored-by: perf-tui-memory-fast <perf-tui-memory-fast@hillclimb.local>

* perf(pa-daemon): zero-copy relay for routed responses - share the payload bytes, splice the client id (#2897)

* pa-daemon: relay routed responses by bytes - supervisor splices the client id onto the worker line

* fmt: the two supervisor.rs forms CI rustfmt wants

* perf: the cross-process runtime-ready probe memo - on-disk, same identity key, damage-aware (#2881)

* pa-core: the cross-process runtime-ready probe memo (on-disk, same identity key)

* pa-core: fix the xproc memo commit's test-module paths and escape damage

* pa-core: rustfmt the cross-process memo

* pa-core: clippy fixes for the cross-process memo tests

* pa-core: move the memo-walk helper to test-mod scope (clippy items-after-statements)

* pa-core: fix the disk-memo oracles (missing-dir semantics, fallback sequence) and serialize the memo-state tests

* pa-core: the disk-memo repair-to-verified-content hits (oracle fix)

* pa-core: the live closure-freeze allowlist covers the real runtime's stdlib imports (18 modules found on first live run)

* pa-tui: agents-view summary rows drop the model mix; the inactive line bills the descendant aggregate (operator directive) (#2894)

9168514c8384merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs facade cut SS3 - the adoption/register concern byte-moves into supervisor/adoption.rs (#2901)

450cf50aeb31merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): share client-event payloads on the supervisor broadcast (Arc) - sup CPU -60% at N=100 (#2896)

* perf(pa-daemon): share client-event payloads on the supervisor broadcast (Arc)

Baseline at origin/rust 7064d039a on the concurrent-io lane: supervisor CPU
per append_custom_message is Theta(N) in resident sessions - 536us/append at
N=1 rising to ~2636us at N=100 live sessions (a+21us*N fits all four N and
both trials), because every session event (2 per append: message_start +
message_end, each carrying the full message payload) is published on the one
daemon-wide tokio broadcast channel, and every connected client's event arm
wakes, deep-clones the (ClientRouting, Value) frame, locks its attached-list
mutex, checks, and discards. Aggregate daemon CPU for equal per-session
traffic is Theta(N^2).

Share the payload instead of cloning it per receiver: the channel carries
(ClientRouting, Arc<Value>). Nothing else changes - same channel, same ring
capacity, same routing decisions in the same recv order, same wire frames
(write_line serializes from the shared Value; the worker-side EventPump
already shares its frames this way via Arc<OutboundFrame>). The per-receiver
cost for a non-matching connection drops from a full serde_json::Value deep
clone to an atomic refcount bump.

Measured on the 16c/32GB ubuntu:22.04 VM (hillclimb-perf-concurrent-io):
same-vm ABBA at N in {1,100} follows in the lane record; the claim is
daemon CPU per session event, not wall latency (append wall is
fsync-dominated on the measurement host).

* fix(pa-daemon): wrap the two missed client-event send sites + test compile

- supervisor.rs shutdown-signal daemon_closing broadcast and the
  supervisor_roster.rs RosterSubscribers push missed the Arc wrap; both
  now share the payload like every other events.send site.
- Test fixtures compile against the shared-payload channel: the roster
  drain helper derefs back to owned Values (tests keep comparing Values),
  and the daemon_closing assert compares through the Arc.

* fix(pa-daemon): compile + rustfmt the shared-payload channel's test helpers

- supervisor_roster_seed tests' drain helper takes the Arc-typed receiver
  and derefs back to owned Values (same pattern as supervisor_roster).
- rustfmt the Arc-wrapped send sites (line-width wrap only, no semantics).
No product behavior changes: whitespace + cfg(test) code only.

* style(pa-daemon): rustfmt the seed-test drain helper + clippy semicolon

One-liner receiver type per rustfmt, trailing semicolon per
clippy::semicolon_if_nothing_returned. cfg(test)-only change.

* pa-core: anchor compaction summaries to kept-tail state and stop re-summarizing file lists (TS #2385) (#2768)

a1c236c05df8merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-tui): the bang-during-streaming-turn e2e gates the mock's turn end on the ack bang, not a wall clock - every awaited state is causal or terminal, closing the two-channel load red (red-bang-stream-flush-20260926-1) (#2904)

a02c3aa25cdamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai/pa-daemon: the faux repeat-last knob + the goal-recovery e2e opts in and pins the exhaustion race deterministically - closes red-goal-recovery-faux-exhaustion-20260926-1 (#2902)

1e236ad703efmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the inline pickers' selection wash reads off the surface (operator directive) (#2908)

c7a54e058c31merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): return the supervisor relay and catalog-scan heap to the OS (#2899)

The supervisor process relays every routed worker response through a
serde_json Value tree (from_slice in the worker-frame reader, a
DaemonResponse through the pending-reply channel, response_line to the
client write) and the saved-session catalog scan folds a parse tree per
file line; both phases free their trees when the phase ends, but nothing
in the supervisor process ever returned the freed pages, so a grown
session relay (a ~9.5MiB get_messages wire leaves +71MiB resident; a
routed attach adds +42MiB more) and every grown catalog scan stayed at
the arena high-water for the daemon lifetime.

Mirror the merged #2872 session-memory pattern on the two daemon-side
phase boundaries: write_line reports the serialized byte count and the
client write loop trims when a routed line carried >=1MiB (the frame is
out and the tree is dropped first), and the saved-session scan trims at
its join (the per-line trees are folded and freed inside the blocking
task; the per-file cached scan states are live cache and stay
untouched). Allocator plumbing only - no data, protocol, wire, or
behavior changes; non-glibc/Linux builds are no-ops via
pa_types::memory_release.

Co-authored-by: perf-daemon-rss-fast <hillclimb@prime-intellect.local>

* perf(pa-tui): stream the exit/suspend main-screen flush - zero exit RSS spike, byte-identical output (#2913)

* perf(pa-tui): stream the exit flush in bounded chunks - the inline repaint never materializes the whole frame

* pa-tui: fmt + the flush errors doc (gate nits)

* pa-tui: fmt + the flush errors doc (gate nits)

* perf(pa-core): serialize same-process auth-lock holders - first-turn slow-class 50% to 12% (#2915)

The TS product runs acquireLockSyncWithRetry on a single thread, so the
10x20ms retry only ever fires against another process. The Rust engine is
threaded: two worker threads racing AuthStorage::create on a fresh
session's first turn (model-resolution registry build vs a concurrent
auth read, strace-verified: openat O_CREAT|O_EXCL -> EEXIST within 47us,
loser clock_nanosleeps the full 20ms) pay the TS retry sleep against each
other, a ~20ms first-turn latency class in 4/6 msgsettle trials.

A process-local mutex keyed by the auth document path serializes
same-process callers for the microseconds the small read/modify/write
holds. The file protocol, staleness judgment, and retry semantics are
untouched: a foreign holder (another process) still surfaces WouldBlock
and still takes the 10x20ms retry. The mutex is a leaf (the locked
section performs only the document's own fs ops plus the caller's
callback; no callback re-enters with_lock), and poisoning is recovered
because the file protocol is the correctness mechanism.

Co-authored-by: perf-model-resolve-cache-fast <hillclimb@prime-intellect.ai>

* perf(pa-daemon): per-session subscriber registry - send-time attached check, sup CPU -20% at N=100 (#2914)

* perf(pa-daemon): share client-event payloads on the supervisor broadcast (Arc)

Baseline at origin/rust 7064d039a on the concurrent-io lane: supervisor CPU
per append_custom_message is Theta(N) in resident sessions - 536us/append at
N=1 rising to ~2636us at N=100 live sessions (a+21us*N fits all four N and
both trials), because every session event (2 per append: message_start +
message_end, each carrying the full message payload) is published on the one
daemon-wide tokio broadcast channel, and every connected client's event arm
wakes, deep-clones the (ClientRouting, Value) frame, locks its attached-list
mutex, checks, and discards. Aggregate daemon CPU for equal per-session
traffic is Theta(N^2).

Share the payload instead of cloning it per receiver: the channel carries
(ClientRouting, Arc<Value>). Nothing else changes - same channel, same ring
capacity, same routing decisions in the same recv order, same wire frames
(write_line serializes from the shared Value; the worker-side EventPump
already shares its frames this way via Arc<OutboundFrame>). The per-receiver
cost for a non-matching connection drops from a full serde_json::Value deep
clone to an atomic refcount bump.

Measured on the 16c/32GB ubuntu:22.04 VM (hillclimb-perf-concurrent-io):
same-vm ABBA at N in {1,100} follows in the lane record; the claim is
daemon CPU per session event, not wall latency (append wall is
fsync-dominated on the measurement host).

* fix(pa-daemon): wrap the two missed client-event send sites + test compile

- supervisor.rs shutdown-signal daemon_closing broadcast and the
  supervisor_roster.rs RosterSubscribers push missed the Arc wrap; both
  now share the payload like every other events.send site.
- Test fixtures compile against the shared-payload channel: the roster
  drain helper derefs back to owned Values (tests keep comparing Values),
  and the daemon_closing assert compares through the Arc.

* fix(pa-daemon): compile + rustfmt the shared-payload channel's test helpers

- supervisor_roster_seed tests' drain helper takes the Arc-typed receiver
  and derefs back to owned Values (same pattern as supervisor_roster).
- rustfmt the Arc-wrapped send sites (line-width wrap only, no semantics).
No product behavior changes: whitespace + cfg(test) code only.

* style(pa-daemon): rustfmt the seed-test drain helper + clippy semicolon

One-liner receiver type per rustfmt, trailing semicolon per
clippy::semicolon_if_nothing_returned. cfg(test)-only change.

* pa-daemon: per-session subscriber registry - session events resolve delivery at publish time (TS handleWorkerFrame parity)

TS evaluates the attached predicate in the same synchronous pass that
writes the socket (daemon-supervisor.ts handleWorkerFrame l.6353; attach
flips the flag and writes session_attached in one tick, l.5586->l.5608).
The Rust ring evaluated it at RECV time in every connection event arm - a
superset in the attach/detach race window TS cannot produce (an event
published before an attach could still land after it, duplicating a row
the attach snapshot already carried).

Session events now route through a supervisor-side subscriber index
(session id -> connection id -> bounded per-connection queue): publish
enqueues to the attached set under one lock, unattached connections
never wake (the ~5.9us/session/append wakeup floor at N=100 from the
concurrent-io lane), per-(session,connection) order stays publish order,
and a full queue drops with a one-line-per-stall-cycle log (finding 4a
visibility). Broadcast / BroadcastExcept / RosterSubscribers keep the
ring; ClientRouting::AttachedSession is removed so a stale session-event
publish fails at compile time. Session events without an active session
id are dropped (TS l.6296 !activeSessionId guard), not broadcast.

The dormant supervisor/clients.rs split copy carries the same change
(re-homing at the fold will take one of the two).

* pa-daemon: fmt + clippy fixes for the subscriber registry (if-let for the single-pattern session-event relay)

* pa-daemon: fix the registry idempotency test - drain the delivered frame before the post-detach empty check

* pa-daemon: rustfmt the registry rebind call and the idempotency assert

* pa-daemon: rustfmt the registry call sites exactly as rustfmt asks

* pa-daemon: convert the zero-copy splice arm's attach push to the subscriber registry

#2897's raw-splice attach family added a SECOND attach-success push site on
the tip's routing.rs; it arrived through the fold with the old vec
semantics (the pre-fold grep could not have seen it). Same conversion as
the typed arm: registry + session list in one attach() call, the registry
insertion is the delivery boundary.

* pa-tui: the operator's touch follow-ups - the card click opens the card, the follow hint re-derives at the mode exit, the prompt bar's indicators paint on the bar (#2911)

0c526d534fcamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai: the codex dead-callback tests stage the registered port checked, not blind (settle-race hardening) (#2906)

c38824288cf2merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli: the first-run login frames render the TS login dialog (frame-parity r3) (#2845)

11365e57484dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 1/14 - the heartbeats concern moves out of src/session_ui.rs (#2886)

9f1cfc73550amerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the hover affordance - ?1003 any-event tracking delivers the buttonless motion, the hovered clickable card row brightens (muted to the theme fg, dim to muted) (#2918)

d81f3d2c7c07merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-ai/pa-agent): StreamingJsonAccumulator - stop re-parsing streamed tool-call JSON on every delta (TS #2783 port) (#2912)

dbec3a6eb0b7merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge); optional lane gate evidence: gate_1790470828_1252847 GREEN.

* pa-daemon: agent_engine.rs split 3/11 - the artifacts concern moves out of src/agent_engine.rs (#2905)

95e10f8ea95emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 2/14 - the stream concern moves out of src/session_ui.rs (#2920)

6aecfb087453merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 5/14 - the auth concern moves out of src/session_ui.rs (#2923)

70abcc702d14merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-cli/pa-daemon: implement the RPC stdio mode over the in-process session engine (TS modes/rpc parity, stub S5) (#2801)

25b657908b38merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 2/8 R2 (remediation) - the client-connection cut actually lands on the facade (#2885)

21304589206amerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli: the agents-view e2e settles its daemon-driven rows by synchronization, not a timing budget (AgentsStep::WaitRender - the registered ranked-hits render/data-arrival race closes by construction) (#2910)

f22938c1e0aamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-tui): packed cached entry layouts - scroll retention RSS -42%, byte-identical output (#2921)

* perf(pa-tui): store cached entry layouts packed - byte-exact rows, one blob + dense span records

The transcript layout cache retains every visited entry's rendered rows
for the process lifetime. A 2600-key scroll walk over the canonical 10MiB
session retained 5,428 entries' rows as 604k fragment-sized spans holding
5.2MB of text (+64.6MB heap, fully retained after return-to-tail; the
tui-scroll-retain census: 8.3 spans/line, content capacity already
exact, 44% line-buffer slack, per-span Vec/String chunk overhead the
retained mass). Merging adjacent same-style spans would shrink the
storage but changes the exit-flush inline scrollback's ANSI bytes
(per-span SGR re-emission; the exit flush is the TS-parity-frozen
output), so the cache stores the same rows packed instead: one content
blob plus dense (offset, len, style) records, expanded byte-exactly on
read - only the intersecting row range is expanded, so a frame inside a
huge entry pays its visible rows, never the whole row set. The pad
entry's own 109k-span row set (the resumed ready-state footprint) packs
the same way.

* perf(pa-tui): exact pack blob capacity + size-gated post-pack trim

The pack's blob grew by String doubling (2x capacity: 33.6MB held for a
17.45MB row set at 40MiB); the first pass now sizes it exactly. A huge
entry's rendered rows are the transcript's biggest single transient and
the pack just freed them - the freed pages only return to the OS when
the allocator's trim can reach them (the 40MiB ready RSS measured
bimodal 181/205 on the same build); the pack now returns them
immediately, gated at 8192 rows so ordinary entries never pay a trim.

* fix(pa-tui): EntryRows::is_empty for the touch surface's shows-tail peek (fold resolution completion)

The #2911 fold introduced the empty-section peek (a window that exactly
ends on the final chat entry re-checks whether any non-empty section
remains before declaring shows-tail); its section source is the
EntryRows handle since the packing fold, which needs the is_empty form.

* test(pa-tui): fix the pack tests' clippy findings (untyped Vec::new, shadowed view helper)

* test(pa-tui): drop the pack test closure's unused mut

---------

Co-authored-by: perf-tui-scroll-retain-fast <perf-tui-scroll-retain-fast@hillclimb.local>

* pa-daemon: agent_engine.rs split 2/11 - the config concern moves out of src/agent_engine.rs (#2909)

07cbb0febb74merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 4/11 - the model concern moves out of src/agent_engine.rs (#2907)

5c530e66cef9merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 3/14 - the queue concern moves out of src/session_ui.rs (#2900)

e673275046dfmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 7/8 - the update/restart concern moves out of src/supervisor.rs (#2903)

268c1fba26c0merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli: dock panel exits restore the dock's own group, not the prompt bar (operator ruling 2026-09-26) (#2864)

a12c2847335bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 5/11 - the goalcore concern moves out of src/agent_engine.rs (#2924)

c95a239b9eb3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-tui): handoff drains park on observed input, not a fixed wait - chat-to-agents -79% (#2916)

* perf(pa-tui): a handoff drain consumes buffered input instead of parking on the idle window

The chat->agents handoff teardown pays the enhanced_keys drain's fixed 50ms
DRAIN_IDLE poll on every switch (chat->agents measured 67ms p50 at #2893,
~50ms of it this window). The idle window guards a kitty key release that
lands after raw mode is off - a leak that is unreachable on a handoff: raw
mode stays on (the adopting surface's reader takes the same tty) and every
surface's dispatch drops release events (input::filter_enhanced_key_events,
TS tui.ts). The handoff now consumes what the terminal has already written
with zero-timeout polls and returns as soon as the buffer is observed empty;
only when input IS flowing does it fall through to the bounded drain, so a
burst around a handoff is coalesced exactly like before. True exits (drain,
drain_for_exit) keep the TS drainInput(1000, 50) contract untouched. Adds a
real-pty e2e that arms the kitty protocol, injects the handoff trigger's
release in flight, and audits the byte stream (no visible release, no
post-exit kitty flags, no echo after the restore).

* test(pa-cli): fix the kitty-release e2e gate lints (fmt shape, unit let-binding, unused import)

* test(pa-cli): the kitty-release mock supervisor serves every connection in turn

The chat surface holds one daemon connection and the agents view opens its own after the handoff; a single-accept mock refused the second (the first run of the e2e failed on exactly that: connection refused at run_agents_view connect).

* test(pa-cli): qualify the mock supervisor connection handler call

* test(pa-cli): handle the listener incoming result in the mock supervisor

* test(pa-cli): the kitty-release editor probe waits for the painted cell

The frame paints typed cells as styled positioned cells (escape bytes between characters), so the two-byte zz needle never appears; wait for the painted z cell instead.

* test(pa-cli): the kitty-release harness reaps the pty child on panic paths too

* test(pa-cli): the kitty-release exit drives the CSI-u escape form

With disambiguate armed a kitty terminal encodes its Esc presses as CSI 27 u; the raw lone ESC byte is the legacy form the reader arms its meta-wrapper hold for. Drive the realistic encoding and separate the exit key from the release injection.

* fix(pa-tui): the handoff drain's bounded phase runs on the budget the zero-timeout loop left

The zero-timeout consume loop can spend the whole DRAIN_MAX under
continuous input before falling through to drain_until_idle, which
then started a fresh budget - the handoff could block nearly two
seconds, past the documented one-second hard cap. The bounded phase
now runs on what remains of the original budget (Macroscope thread
PRRT_kwDOSXZbXs6mWWqM).

* perf(pa-daemon): borrow the catalog fold metadata and single-open the scan - cold scan -7%, syscalls -22% (#2919)

* perf(pa-daemon): borrow the catalog fold's entry metadata, kill the per-line tail Vec

The post-#2879/#2882 cold roster scan still typed-parsed every line into
owned strings and materialized `Value` trees for fields the fold reads
once or discards: 3 `String` allocations per line (type, id, timestamp)
plus a `Value` tree per message row (role, provider, model, timestamp) and
per session_info/state/model_change/thinking_level row. The resume tail
added one `Vec` allocation per line sized line.len()+17 to keep 16 bytes.

Both costs are gone without changing a row byte:

- SessionInfoEntry's scalar fields borrow as `Cow<str>` (zero-copy when
  unescaped, owned fallback identical to the old String), its object
  fields ride raw spans like #2882's content: each arm parses back only
  the span it reads, with exactly `Value::as_str`/`as_u64` semantics
  (present-and-string/number, absent and non-string both read None, the
  model_change abort arm keeps its exact two-step None).
- advance_tail copies inside the fixed 16-byte window: the same bytes
  (a rolling-reference lockstep test pins the old Vec semantics), no
  per-line allocation.

Differential ground truth: the new in-tree shape matrix pins every
borrowed read to the full-parse Value read per row (escaped scalars,
non-string roles/timestamps, null/absent/whitespace names, hidden/sleep
states, abort shapes) and folds the accepted rows end to end against the
legacy full-parse reference fold; the VM census ran the same differential
over 177,798 real fixture lines (100/1000/4096 tiers) with zero
divergence in acceptance, fields, or fold states both directions.

* perf(pa-daemon): share one open between the roster header gate and the fold

The roster scan opened every file twice: the bounded header gate opened,
read its first line, and closed, then the fold opened the same path again
for the scan — an openat+close per file per scan (plus the second
metadata read the fold always paid). The gate now reads the first line
from the same fresh handle the fold rewinds and scans, so one open serves
both.

The TOCTOU the double-open carried is disclosed: with two opens, a
rename/replace landing between them judged one file and folded another;
the shared handle pins the judgment and the fold to the same inode —
the fold's cursor, generation, and certification re-stat now read the
file the gate judged, never a replacement that raced in between.

The listing stat (`stats.mtime`, the `modified` fallback of last resort)
is read lazily now: the fold only reaches it when a row has neither
message timestamps nor a parseable header timestamp, so the eager
per-file stat the scan always paid serves only the rows that read it.
The `or_else` chain keeps its order and its None semantics (the
existing fallback tests pin every arm of the chain).

* pa-daemon: fmt + clippy for the catalog fold lane (test-import move, lockstep test polish, matrix lint allows)

* pa-daemon: supervisor.rs split 4/8 - the saved-session concern moves out of src/supervisor.rs (#2883)

9f9146b74371merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the #2921 review follow-ups - RowPack::pack refuses unrepresentable entries, the huge-entry trim drops the expanded rows first (fold of rust 9b62f26af) (#2925)

df34ea19dbb3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 10/14 - the bash concern moves out of src/session_ui.rs (#2928)

481b2f28553cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* skills/prime-intellect: sync vendored sandbox docs to the VM-only surface (TS #2456 doc half) (#2751)

a4e997e2e803merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* fix(pa-cli): remove the duplicated restore_dock_focus initializer the #2751 squash double-applied

The #2751 squash (1a9fd16b9) landed the heal rider line onto a tip that
already carried the identical line from #2925 (e6e7a26e4) - the squash
applied the stale pre-fold diff, duplicating the field (E0062). This
restores the fixture to the parent 84dbb51e0 state (exactly one field).
The label rider and the docs in the same squash are intended and stay.

* pa-daemon: agent_engine.rs split 7/11 - the SessionEngine trait impl moves out whole (#2926)

2b07a22bd1d3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core + runtime: the harness-digest family - IDF-ranked digest/search, state-fingerprint staleness, newest-only digest contexts, validated kernel harness writes (TS #2392/#2400/#2394/#2463 parity) (#2750)

bff9fa6ff122merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* fix(pa-cli): the kitty handoff e2e fixture initializes restore_dock_focus (#2927)

962ff3097575merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 7/14 - the settings concern moves out of src/session_ui.rs (#2930)

fd71eaf2dfeamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 6/14 - the model-picker concern moves out of src/session_ui.rs (#2929)

2038abcf5754merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon/pa-cli: ACP model and effort pickers - configOptions at session/new, session/set_config_option, config_option_update (TS #2455) (#2758)

fd977cb13ee6merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core): consolidate auth-lock reads - 36 lock cycles per first turn to 2, settings mutex closes the unmasked stall class (#2932)

* perf(pa-core): consolidate auth-document reads through a validated cache

* perf(pa-core): serialize same-process settings-lock holders (the #2915 pattern)

The auth read-through cache on this lane unmasks a pre-existing stall:
two worker threads racing the same settings.json pay the full TS
10x20ms retry sleep against each other (strace-verified: mkdir
attempts 11us apart, the loser clock_nanosleeps the full 20ms; the
paired census shows same-process overlapping settings acquisitions 2
on the base and 5 with the auth cache, sleep20 1 vs 2, and the timing
legs pay a ~20ms-class stall on 3/6 fresh turns vs 0/6 base). The
auth-lock cycles 150-300us same-process serialization was pacing the
threads apart by accident; that masking is not a mechanism to keep.

TS runs its synchronous settings lock single-threaded, so same-process
settings contention is a Rust-port artifact, the exact class #2915
ruled on for the auth lock: a process-local mutex keyed by the
document path serializes same-process callers for the microseconds
the small read/modify/write holds. The file protocol, staleness
judgment, and retry semantics are untouched: a foreign holder
(another process) still surfaces WouldBlock and still takes the
10x20ms retry. The mutex is a leaf (the locked section performs only
the document's own filesystem operations plus the caller's update
callback; no settings callback re-enters with_lock - every callback
is a pure JSON transform), and poisoning is recovered because the
file protocol is the correctness mechanism.

---------

Co-authored-by: perf-auth-lock-fast <hillclimb@prime-intellect.ai>

* perf(pa-daemon): zero-copy worker response path - routed msgs -17%, attach -22%, worker RSS -20% (#2935)

* perf(pa-daemon): zero-copy worker response handoff - serialize the line from the borrowed trees, write the frame without re-buffering the payload

* fmt(pa-types): the segments test write_frame call in the form CI rustfmt wants

* fmt(pa-daemon): the response-path call forms CI rustfmt wants (VM cargo fmt at the exact head)

* fix(pa-daemon): restore the response_line TS-key-order test the new-test insert orphaned (clippy empty_line_after_doc_comments was the symptom)

* fmt(pa-daemon): the restored test doc comment indent

* fmt(pa-daemon): single trailing newline at file end

---------

Co-authored-by: wc <wc@fleet.local>

* pa-daemon: agent_engine.rs split 6/11 - the Turn types move out of src/agent_engine.rs (#2931)

b2ca4deea5afmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): batch the queue-checkpoint journal pair - 4 syncs per warm turn to 2, crash window strictly narrowed (#2936)

* perf(pa-daemon): batch the queue-checkpoint journal pair into one durable append

The queue checkpoint (prompt/steer/follow-up admission, turn settle, queue
mutations) appends two records to the worker recovery journal - the queue
snapshot and the busy/operation verdict - as two separate open+write+fsync
cycles, paying two journal flushes per checkpoint. Both records describe
one atomic checkpoint, and the busy verdict must never publish over a
snapshot that did not persist, so the pair can ride ONE open+write+fsync:
the batch is all-or-nothing durable, the on-disk line order matches the
sequential form exactly (snapshot first, then the verdict), and an
unchanged verdict keeps appending the snapshot alone.

Measured on the warm-turn admission path (the wave-5 warm-durable-append
decomposition): the two journal fsyncs sit inside the TUI-ack-to-user-row
phase together with the session append's fdatasync; batching removes one
of the three durable syncs per warm turn without weakening any durability
guarantee (the session append's per-row fdatasync is untouched).

* test: rustfmt the batched-checkpoint test call sites (gate fmt finding)

* fix(pa-tui): the exit watchdog holds fire while the flush drains - healthy slow drains no longer truncate scrollback, TS-convergent (#2937)

* perf(pa-tui): the exit guard holds its force-quit while the exit path drains - slow terminals keep the whole scrollback flush

On a terminal that consumes the exit flush slowly (a laggy ssh at
~0.5-2MB/s), the flush of a large transcript outlasts the 1500ms
FORCE_QUIT_AFTER_MS deadline that arms at the second Ctrl+C, and the
watchdog fires mid-flush: strace shows its restore writes winning the
pty FIFO race at a flush-chunk boundary, exit_group(0) landing while the
writer still holds ~64-82% of the transcript (40k rows: 8.74MB flush
truncated to 1.5-3.1MB), 'shutdown stalled; forced exit.' printing on a
healthy drain, and the restore bytes queueing mid-stream behind the
flushed rows. TS has no watchdog at all (its handleCtrlC second press
runs the async shutdown, and slow writes simply wait), so both the
message and the truncation are port-only.

The guard becomes drain-aware: the flush writer reports progress per
completed 32KiB chunk (view.rs FlushSink), the release tail and the
resume hint report theirs, and the watchdog holds its fire while
progress landed within EXIT_PROGRESS_GRACE_MS (500ms) - the hard 1500ms
ceiling stays for the silent case (the wedged loop the guard was built
for). Flush chunks shrink 256KiB -> 32KiB so a drain of at least
~65KB/s completes chunks inside the grace window; the flush byte stream
is unchanged (the exit-flush lane's byte-identity oracle). The truncated
scrollback contract is restored on slow drains: the flush completes
byte-identically, the release tail lands after the last row, and the
message prints only for a genuinely stalled drain.

The exit-guard unit tests grow the hold/fire decision table; a new
real-pty e2e (pa-cli slow_drain_exit_guard_e2e, the kitty-release
harness pattern) drives the real chat surface over a paced pty master
and asserts both sides: a draining terminal flushes the whole
transcript with no forced exit, and a stalled drain still fires.

Rider (disclosed): kitty_release_handoff_e2e grows the restore_dock_focus
field the #2916 squash dropped from its fold-time heal - the tip's
pa-cli test target does not compile without it.

* test(pa-cli): the slow-drain e2e asserts the forced fire structurally

The re-executed test binary's libtest harness captures stderr per
test, so the watchdog's 'shutdown stalled' line never reaches the pty
in the harness child (the real binary writes it to fd 2 - the lane's
VM bench legs assert it there). The stalled-drain leg instead asserts
the forced exit structurally: the forced restore's own alt-screen
leave lands on top of the exit path's (a clean exit leaves it exactly
once), the flush never reaches the transcript tail (one copy of the
last user row, the startup viewport's), and the process dies with the
guard's exit code inside the stall window. Harness needles use the
user-message rows (assistant rows carry per-word SGR spans) and the
post-exit drain reads the pty's kernel-held bytes before asserting.

* fmt: the slow-drain e2e needles and the watchdog's progress read

* clippy: doc backticks + checked Duration subtraction in the guard tests; the e2e's needle check takes the direct is_none

---------

Co-authored-by: perf-slowdrain-exitguard-fast <lane@hillclimb.local>

* perf(pa-core): consolidate settings-lock reads - 32 lock cycles per first turn to 2 (#2941)

* pa-ai/pa-core/pa-cli/pa-tui: grok-4.7 on every serving surface (TS #2505) + Claude Code 2.1.281 + Anthropic subscription ban-risk warning (TS #2645) + one owner for the Prime team header, retry failed !command credentials (TS #2497) (#2755)

7373eb471670merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-cli): the interactive_daemon_e2e wedge root-kill - PDEATHSIG + orphan sweep + the 300s headless wall (#2942)

dbed1170fa2bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli/pa-daemon: session opens wait through a daemon update restart (TS #2391) + the failed-restart hint (TS #2515) (#2763)

e7a84e749089merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): the all-idle compaction fires like TS and rides the TS compact sync class - journals bounded (#2944)

* perf(pa-daemon): settle-tail compact consolidation - the all-idle compaction fires like TS and rides the TS compact sync class

The worker recovery journal's all-idle gate ran BEFORE the record insert,
so a single-session journal's own busy admission record blocked every
settle's compaction: the compact never fired on the dominant shape and
the journal grew append-only for the session's lifetime (TS computes the
gate POST-insert and compacts at every changed-idle record). The gate now
matches TS, bounding the file.

Where the compact fires, its temp sync_all was a sync class TS's compact
does not pay (TS worker-recovery-journal: writeFileSync + renameSync, no
fsync; the command journal's writeFileAtomicSync counterpart does carry
fsync). The Finalize seam now encodes the sync class per owner: RetryBusy
keeps its fsync (command journal), Synced keeps the Rust-native
terminal-compaction journal's belt, and Bare is the TS worker shape -
temp write + rename, no fsync. Durability is owned by the append path
(the fresh-write class is untouched): the compacted form holds only
records the append path already made durable, so a lost compact falls
back to the append-only history, which replays identically.

* test-only rustfmt of the new test call site (the gate's one fmt finding)

* runtime/kernel: vendored-runtime hardening + kernel stderr owner-only (TS #2372/#2423/#2500/#2471/#2478/#2425 parity) (#2744)

ea5abd1bbe1bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 11/14 - the prompt submit pipeline moves out of src/session_ui.rs (#2943)

3bafbc007b74merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-tui): 8-byte packed span records with per-pack style table - scroll retention -7.5MB, byte-identical output (#2939)

* perf(pa-tui): denser packed span records - style table + derived offsets (8B/span), byte-exact range expansion

* test(pa-tui): rustfmt the exhaustive row-pack range oracle

* fix(pa-tui): clippy - if-let style dedup + drop redundant test clones

* pa-tui: fix the submit-outlived-by-switch idle-gate race - the turn-end watermark restarts with the mounted stream (#2945)

c661290b1b77merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: hold spawn-name reservations until admission is durable; collect returns cancelled envelopes for just-deleted targets (TS #2396 + #2388 F4) (#2757)

18aa772bd3b2merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai/pa-core/pa-daemon: codex stale-chain retry after metadata (TS #2374) + safety failures permanent (TS #2472) + quota park until reset with auto-resume (TS #2375) (#2761)

dc9892ffbc1emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-tui): the headless settle bound names its stuck member in 60s - defense-in-depth inside the wedge wall (#2949)

The interactive_daemon_e2e exit-gate wedge family is root-killed
upstream (#2945: the turn-end watermark restarts with the mounted
stream) and the harness carries the 300s wall (#2942). This closes the
remaining gap: the headless settle was the run loop's only unbounded
wait on the product side — a settle member that never drains parked the
run forever with no failure name (TS exits the process at shutdown and
lets in-flight work dangle, so the settle has no TS counterpart).

The gate's twelve settle members are now snapshotted (HeadlessSettle:
settled() is the old gate exactly; blockers() names them), and after
the plan completes a stuck member fails the run within
HEADLESS_SETTLE_TIMEOUT_MS (60s) with the member named — e.g. 'a turn
still active' — instead of waiting out the harness's 300s wall with a
generic timeout. Green settles are milliseconds after HeadlessDone
(the suite's green wall is ~15s; the last submit's own ack bound is
10s), and terminal runs never arm the bound (HeadlessDone exists only
on the headless harness; a live terminal ends the run on
exit_requested + the exit guard).

Proven end-to-end by the lane's matrix: the wedge converted to a 98.4s
attributable red naming the latched member (the bound-only diagnostic
arm), and the full candidate stayed clean at 30/30 interleaved trials
vs 3/30 wedges at the lane parent (record
20260927-085200-interaction-exit-gate-hang-remediation, bench
hillclimb).

* perf(pa-daemon/rpc): warm the model registry at RPC session boot - first get_available_models 1170.6ms to 58.9ms (#2953)

TS session boot resolves the initial model through refreshAvailableModels
(model-resolver.ts), which also fetches the live Prime Inference catalog
in the background and caches it on disk; the daemon worker fires the same
fire-and-forget refresh from its create path (worker/create.rs). The RPC
mode hosts the session in-process with no create command, so nothing
warmed the caches: an integration's FIRST get_available_models call paid
the whole awaited refresh chain on its response path (measured 812-1296ms
on the bench VM; the 15s fetch-timeout worst case on a degraded network)
while the same command on the daemon and ACP surfaces answers from the
validated snapshot. Mirror the daemon worker boot spawn: the caches warm
during the session's first turn, and the first call serves the same
snapshot. Write behavior is unchanged: the same cache files, the same
write-on-fetch-success conditions, the same cadence (hour-gated catalog
refresh, 5-min private-authorization TTL), only started at boot.

Co-authored-by: perf-rpc-models-persist <lane@hillclimb>

* pa-tui: session_ui.rs split 4/14 - the share concern moves out of src/session_ui.rs (#2922)

b0d72b29a700merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 8/11 - the turn-execution impl moves out (#2934)

a59d3389dfbamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 5/8 - the worker-lifecycle concern moves out of src/supervisor.rs (#2956)

205f4d0f469cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 8/14 - the sessions concern moves out of src/session_ui.rs (#2957)

7d19e9832120merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 6/8 - the signals concern moves out (#2960)

a6562bc252efmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 10/11 - the lifecycle concern moves out of src/agent_engine.rs (#2962)

17d3573c5a58merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 12/14 - the keys concern moves out of src/session_ui.rs (#2958)

bc6b7d82cb0bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 11/11 - the facade trim: the last product free fns move out; the file ends as the composition root (#2964)

1fe6a6791030merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 8/8 - the facade trim: the notes concern moves out, the test battery re-homes (#2963)

8a5274baa0d9merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 9/14 - the panels concern moves out of src/session_ui.rs (#2961)

377eda9ded15merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 13/14 - the apply concern moves out of src/session_ui.rs (#2965)

c10a44e407cdmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: cap kernel host-request cell source at 2 KiB (the TS #2475 port) (#2966)

96f689fc38femerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the /model picker resolves by provider, never the first same-id catalog entry (fixes the operator report) (#2967)

24411964739emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 14/14 - the facade trim: the file ends as the composition root (#2968)

60cbb4fbb642merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core): the oauth refresh leaves the auth lock - fetch under single-flight, hold-sum 396ms to 0.09ms (#2971)

An expired stored OAuth credential refreshes its token inside
AuthStorageBackend::with_lock: the OAuthIntegration seam is synchronous
by contract, so the network round trip runs under the document lock AND
under the process mutex that spans the whole critical section, stalling
every other same-process auth read and write for the fetch (the RPC
cycle_model path measured 194-201ms auth.json.lock holds per switch on
the bench VM; the assembly read pays one ~0.2ms cycle, the switch pays
the fetch).

The TS product holds its own lock across the same await
(refreshOAuthTokenWithLock -> withLockAsync), but its single-threaded
runtime never blocks other work on it; this engine is threaded, so the
port narrows the lock scope instead: load-then-lock. The document loads
through the consolidated read arm, the token fetch runs outside every
lock behind a per-provider single-flight gate (the in-process
serialization TS gets from its single-threaded runtime, with the expiry
re-checked under the gate so a second caller never spends a single-use
refresh token after the first flight landed), and the write re-enters
the same locked read-modify-write protocol - now held only for the
re-read, insert, and atomic write, and skipping the write entirely when
a peer refreshed while the fetch ran. File protocol, read results, and
every resolution outcome are unchanged.

* pa-daemon: the supervisor roster broadcasts only on content change (the TS #2481 port P3) (#2974)

054553b8ca12merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-cli/pa-tui: prime-agent update - the TS->Rust migration path (uninstall TS, install Rust, sessions preserved) (#2981)

739ed7f7d015merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core/pa-daemon): a settled RLM child releases its kernel at the settle park - ~27MB reclaimed per settled child, TS #2483 port (#2983)

* perf(pa-core/pa-daemon): a settled RLM child releases its kernel at settle - snapshot-flushing stop_kernel, revivable (TS #2483)

The rust port of the stale perf PR #2483's inline arm (the supersession
analysis: the not-superseded claim - settled children hold a worker and
a kernel until parent close; nothing at the tip releases them; the
daemon-mode whole-worker passivation stays deferred to the orchestrator):

- IpythonKernelProvisioner::stop_kernel (TS stopKernel): shuts the owned
  kernel down with a final namespace snapshot WITHOUT marking the
  provisioner disposed; a kernel still starting up is joined first and
  shut down the same way (the TS managerPromise arm). The stop records a
  pending-stop gate (TS pendingStop) that the next start_kernel_impl
  awaits before reading the snapshot back, so a follow-up turn's fresh
  boot revives the flushed namespace instead of racing the flush; a
  completed stop awaits instantly and each stop supersedes the previous
  (a clonable watch receiver: multiple revival waiters gate on it).
- The session engine gains stop_kernel_snapshot (the TS
  stopKernel({snapshot:true}) seam beside dispose_kernel), and the
  SessionEngine trait gains release_settled_child_kernel (default no-op):
  the AgentSessionEngine arm evaluates the canPassivateSettledSession
  gates engine-side - no unsettled descendants (has_unsettled_rlm_work),
  no registered cron/heartbeat jobs (a worker-wired probe over the shared
  cron store) - then fires the per-build release probe (a weak
  provisioner reference, the background-bash-probe adoption pattern,
  cleared on retire/close).
- The turn runner's park arm fires it best-effort when the worker core
  proves the parent-owned, unattached, unqueued idle state (rlm_depth>0,
  no attached clients, not compacting, no lane work - the park arm's
  own construction). The divergence the port discloses: rust children
  are worker processes (the parent has no in-process reach and the wire
  is frozen), so the release triggers at the child's own idle park
  instead of the TS parent's run-settle hook - the same revivability
  semantics (the next kernel use boots fresh from the flushed snapshot),
  and the roster/collect surfaces are untouched by design.

Tests: the provisioner stop flushes the snapshot and the next ensure
revives the namespace (live-kernel, ambient-venv-gated); the park arm's
policy matrix (a parent-owned child releases, a root/attached/compacting
session stays resident); the engine gates (a registered-jobs probe
defers the release, the probe fires otherwise).

* test(pa-daemon): the park-arm release test waits on observable readiness (the review advisories)

Two BUGBOT test advisories on the first review: the park-arm test's
bounded poll used fixed sleeps (a retry-to-green readiness wrapper). The
recording engine now notifies on every release fire, so the test waits
for the observable readiness - the notification is the pass condition,
the bounded timeout is only the failure bound for the positive arm and
the absence bound for the gated arms (no fixed sleep ever makes a pass).

The commit also lands the VM's cargo fmt output on the touched files
(the first commit's hand-written formatting failed the review's fmt
pre-flight: the lane builds on the VM only, and the formatted sources
must sync back before every commit).

* perf(pa-core): provider auth answers once per provider - the #2479 memoization ports, per-model probe -66% (#2973)

* perf(pa-core): provider auth answers once per provider and the private PI authorization cache parses once per file identity (TS #2479)

The rust port of the four unclaimed mechanisms of the stale perf PR #2479
(the supersession analysis: the rest of that PR's premise landed via
#2932's storage read-cache):

- get_available's per-model has_configured_auth becomes a per-provider
  memo: the catalog walks hundreds of models over a few dozen providers
  and each probe rebuilds the provider's auth-source candidates, while a
  same-registry probe is stable by construction (&self, no mutation
  between models). TS getAvailable's authByProvider map.
- get_rlm_searchable_models' per-model get_auth_status becomes the same
  per-provider memo (TS _authenticatedRlmModels' selectableByProvider).
- read_private_prime_authorization_cache serves from a process-wide
  stat-identity snapshot (dev/ino/mtime_ns/len, the TS
  CatalogFileIdentity) while the file is unchanged; the port builds a
  fresh registry per resolution touchpoint (the TS session kept one
  long-lived registry), so the parse would otherwise re-run on every
  resolution. Only a successful parse bracketed by one identity is
  pinned, a failed read unpins (retries), and the write path's atomic
  rename supersedes (new identity).
- AuthStorage memoizes auth-source candidates keyed by the hashed
  material itself (TS authCandidateMemos): reuse skips only the SHA-256
  work, env values are deliberately re-read on every call, command
  values resolve before the memo, and stale checks run against the
  memoized candidate (candidates are immutable).

Tests: the per-provider status memo gates one stale provider across all
its models while a second authed provider keeps its models; the
private-cache snapshot pins stable parses, re-parses rewrites, and never
pins a failed read or resurrects a deleted file; the candidate memos
supersede exactly when the hashed material changes (a stale marking from
an old value never gates a changed one).

* test(pa-core): the stale-provider memo test asserts the tip's stale-aware has_auth

The memo regression test claimed a stale-marked provider's models stay in
get_available ("stale is only the searchable-set's gate") - but
AuthStorage::has_auth is stale-aware at the tip (available_candidate
skips candidates matching a marked stale token), so get_available gates
the stale provider too, and the tip's get_rlm_searchable_models gates it
twice over. The memo preserves exactly those semantics; assert them: the
stale provider is gated across all its models from BOTH sets, and a second
authed provider keeps its models. Discovered by the full-suite fleet gate
(gate_1790546015_945232) - the lane's local legs had not run the test
suite; the three other gate reds (kernel_restore_guards x2,
tui_prime_login_escape) are SOLO-GREEN on the exact head content
(co-scheduling class, the standing family from gate_1790531716).

* test(pa-core): behavior-focused …
snimu added a commit that referenced this pull request Sep 30, 2026
* pa-types/pa-cli/pa-tui: daemon incident forensics — prime-agent incident CLI + agents-view incident notices (TS #2406 port) (#2866)

068259acae6fmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 2/8 - the client-connection concern moves out of src/supervisor.rs (#2878)

3f8b85f25dc2merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: free the side-question registry entry before the cancelled event queues (one registry hold for removal and terminal emit) - closes the same-id restart flake (#2887)

18f6b7fb6f34merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): O(1) catalog fold search-text cap + 64 KiB fold reads (#2879)

* perf(pa-daemon): keep the catalog fold's search-text cap as an O(1) running count

The roster fold re-counted the capped search corpus for every user/
assistant message (the cap guard plus the append's two counts), an
O(messages x 64KiB) walk per session: the cold-scan split shows this
guard is the single largest cold-scan stage (~40% at every fixture
tier). The accumulator now carries the corpus char count in lockstep
with the one writer, so the guard and the append read the counter and
the fold stays O(messages). Row bytes are unchanged: the counter is
kept exact by construction and covered by lockstep and legacy-mirror
tests; the stale-manifest row audit and the 100/1000/4096 fixture
checksums stay identical.

* perf(pa-daemon): batch the roster fold's reads into 64 KiB fills

The fold read grown session files through the default 8 KiB BufReader,
one read syscall per 8 KiB: the strace census counts 6.6k reads on a
1,000-file cold scan (27k at 4,096) where ~one fill per file suffices.
A 64 KiB buffer keeps the line semantics, folded bytes, and resume
cursor exactly - only the syscall chunking changes.

* test(pa-daemon): name every corpus-mutation path the search-text counter rides

The orchestrator review asked the lockstep matrix to enumerate the
paths, not just the happy append: fresh fold, the resume copy a grown
file folds into (clone_for_resume travels the counter with the
corpus), the torn-tail snapshot fold (the durable accumulator stays
untouched; the cap bounds the snapshot arm too), and a rewritten
file's fresh re-fold. Eviction drops the counter with the corpus and
store_state keeps them whole - both cannot desync.

---------

Co-authored-by: perf-catalog-cold-fast <agent@local>

* perf(pa-core): batch kernel venv Python skill installs into one uv invocation (#2884)

* perf(pa-core): batch kernel venv Python skill installs into one uv invocation

The fresh-install kernel venv bootstrap installs every missing Python skill
with its own `uv pip install --editable` child process; each call pays a
process plus PEP 517 build-backend startup for a metadata-only editable
install (measured on the venv-boot lane VM: nine serial installs 1.85s vs one
batched invocation 0.37s, warm uv cache, same VM; the skills phase is the
dominant local cost of the bootstrap, ~1.9s of a ~2.4s span).

Missing skills now go into ONE uv invocation; a batch failure falls back to
the per-skill loop, so a broken skill still costs only its own warning and
never blocks the rest. Installed-skill carry-over, the shared-cache version
file, per-skill warnings, and the venv identity contract are unchanged.

* test(pa-core): fix skill-sync test closure lifetime and fmt

The warning-sink closure needs 'static: share the vector through
Arc<Mutex<Vec<String>>> and lock for the assertion. Formatting follows
cargo fmt.

* test(pa-core): one log line per fake-uv invocation; clippy clean

The fake uv logged printf per argument, so the invocation-count asserts
counted args; printf the joined "$*" as a single line. Move the unix
PermissionsExt import above the statements and close the sink push with
a semicolon (clippy items-after-statements / semicolon-if-nothing-
returned).

* test(pa-core): match the skill path, not the --editable flag

"--editable" contains "edit", so the not-reinstalled assertion needs the
package path.

* pa-core: park the tool abort watcher on the signal (per-tool-call 100Hz wake leak) (#2880)

ToolDefinitionBridge::execute spawned a watcher task per tool call that
polled signal.is_aborted() every 10ms and exited only on abort; a normal
(non-aborted) call never aborts, so every completed tool call left a
100 Hz wake-up loop running for the worker's lifetime. A 45-min 4-vCPU
idle profile (one kernel cell executed) measured the worker's tokio
thread at a constant 104.4 voluntary wake-ups/s for the whole horizon
(pa-core probe, thread-level /proc counters). Await the watch channel
directly instead: abort latency drops from up-to-10ms to immediate, and
an uninterrupted call parks with zero wake-ups. Abort semantics, tool
cancellation, and the loop contract are unchanged.

Lane: hillclimb-cpu-creep (cpu axis, long-horizon resident profile).

* perf(kernel): defer websearch httpx import to first call - first tool cell 17ms -> 2ms (#2888)

Module-level 'import httpx' put its full import chain (~15ms in-kernel) on
every kernel bootstrap cell, in every session, even when no search runs.
Import it inside _fetch_serper on first call instead. A module-level
find_spec guard keeps the import-time contract byte-identical: when httpx
is absent, importing websearch still raises ModuleNotFoundError('No module
named \'httpx\''), so the kernel's unavailable-skill stub and its message
are unchanged. No Rust, API, wire, or behavior change; the first websearch
call pays the import once.

Co-authored-by: perf-kernel-cell-fast <lane@hillclimb>

* perf(pa-core): adopt the retained window one-copy - move the trees in, drop the raw duplicate (#2890)

* pa-daemon: summary scalars from one borrowed walk, not the materialized fold

session_summary folded the whole retained window into a Vec<Value> on
every read (attach, get_state, roster pushes, list rows) just to read
three scalars: the newest message timestamp, the summed assistant usage,
and the window's message count. At session scale that fold is the
majority of the summary's cost and half the retained-window folds an
attach pays (handle_attach's snapshot fold is the other).

SessionFile::messages now delegates to one shared windowed walk
(walk_message_values): message rows borrow their persisted message,
custom_message rows rejoin in their wire form, and a compaction window
prepends its summary message with the retained count counted in a
borrowing pass. The materialized fold keeps its exact sequence (same
keeping-flip semantics on message-bearing rows, same summary-first
order) and drops the doubled clones the old retained loop paid.

scan_message_scalars walks the same sequence for the summary scalars:
the reverse find_map timestamp (last positioned value, not the
maximum), the assistant usage sums in fold order, and the message
count. session_summary consumes the scan instead of the Vec, so every
summary surface derives from the same walk the fold uses - the two can
never disagree. Golden equivalence tests pin the scan against the old
full-clone extraction across window shapes (non-monotonic timestamps,
custom rows carrying usage, kept id on message/non-bearing/missing
rows, stacked compactions, empty session, degenerate rows), and boundary
tests pin the fold's exact windowed sequence.

* perf(pa-core): adopt the retained window one-copy - move the trees in, drop the raw duplicate

The worker-rss census (bench hillclimb record 20260926-183300) measured
five resident copies of the retained window on the 10MiB canonical
fixture; three were derivable duplicates: SessionManager::adopt_window
cloned the walk's typed trees into file_entries (B) while the window kept
its original (C1, wire-identical) plus the raw JSONL lines (C2,
10.48MiB) - ~29.5MiB of wire-equivalent duplication in the loaded
worker, whose same-build RSS band is 182.5-217.9MiB (p50 207.6).

- WindowedSessionStore::take_retained hands the typed rows AND raw lines
  to the owning manager in one move; a detached window keeps its
  snapshot/settings/metadata surfaces (goal state, refinement history,
  git state, append-time stats) and asserts that its transcript context
  comes from the manager.
- SessionManager::adopt_window adopts the trees by move (no to_vec).
- SessionManager::active_context builds from file_entries with the SAME
  window settings overlay gate as the old window.context() - the served
  context is unchanged; the manager's own append_child_usage_attribution
  fold is the one-copy authority for live rows.
- ensure_full_history re-arms the detached copies (historical hydration
  restores bodies, exactly like a fresh walk).

Oracles: adopted-context byte parity vs an un-adopted window (cold+warm),
detached-window lookups + should_panic context, live-appends-vs-full-
reopen byte parity incl. an in-window attribution target; existing
manager/window/byte-parity tests now ride the adopt path.

* fix: adopt_window takes the window by mut (take_retained borrows mutably); tests serialize the context field tuple (SessionContext is not Serialize) and fully-qualify AgentMessage

* fmt: rustfmt on the new window-scan tests

* fix(tests): reference opens first in the cold pass (the adopted open warms the sidecar); compaction_count is the file-level tally (fixture carries a sibling compaction); the retained assistant row needs the required api/stopReason fields or it degrades to Unknown

* fix: clippy default_trait_access in the scan equivalence test

* fix: clippy default-trait-access in tests (JsonMap::default / MessageWindowScalars::default; the latter is a lint fix on the folded attach-path tests so this lane's gates run green - their lane must carry the same fix on their branch)

* fmt: wrap the scan default assert to 100 cols

* perf(pa-daemon): collapse fresh-create session-file writes into one durable write (#2892)

* pa-daemon: fresh-create single durable write (spawn admission)

The fresh-path create collapsed its session-file durability from three
sync'd writes (a header-only rewrite, a second rewrite for the prefix +
active state, and a persist_entry name append) into ONE rewrite that
assembles the prefix, the state, and the session name in memory first.
The dropped header-only intermediate has no reader: the durable create
stays pathless until the create succeeds, so no replay, scan, or
registration consumes the file mid-create. The final bytes are identical
to the sequential writes (same entries, same order; the name's line is
the exact persist_entry construction via append_session_info).

Measured on the spawn-latency VM (hillclimb lane perf-spawn-admission-fast,
bench record 20260926-204300): each admission pays ~7 serialized
durability round trips; the fresh-write class costs ~38-45ms/op in the
degraded host regime (0.3ms quiet) - the collapse removes two of the
three writes on the child-create leg. In-crate oracles: the single write
matches the legacy sequence's masked bytes; the folded name lands once;
a failed write leaves no session file; a legacy crash orphan neither
blocks the create nor bleeds into the new file.

* pa-daemon: split the create-collapse tests into their own file

create.rs grew past the ~800 LoC guidance with the in-file test module; the tests move to worker/create_collapse_tests.rs via #[path] (still a child of the create module, so the module-private append_creation_prefix stays reachable). No product change.

---------

Co-authored-by: perf-spawn-admission-fast <lane@hillclimb.local>

* perf(pa-tui): handoff exits break the run loop this iteration - chat->agents 119ms -> 67ms (#2893)

The terminal loop's exit-key break only left the input-drain loop, so the
handoff fell into the select below it and parked on the 50ms idle tick
before the loop-tail exit check ran — measured as ~50ms of added latency
on every chat -> agents view switch (strace: the key is handled in ~0.1ms,
the teardown starts on the next tick wake ~51ms later; the code's own
comment already demanded the teardown run "this iteration").

A handoff (agents-back, /resume, the scoped view, /resume <selector>)
now breaks the outer loop immediately: the next surface's mount clears
the alt screen, so the tail pass paints nothing the user can see. A
non-handoff exit (/exit, /quit) keeps the tail pass — its frame gate
paints the final chat frame the exit's main-screen flush shows — and
headless runs keep the tail pass so captured frame sequences stay
identical.

* perf(pa-daemon): borrow message content as RawValue - kill the second full catalog parse, cold -25% (#2882)

Co-authored-by: perf-catalog-second-parse-fast <hillclimb@local>

* pa-daemon: agent_engine.rs split 1/11 - the tests concern moves out of src/agent_engine.rs (#2889)

51bd18583e17merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-cli/pa-daemon): tighten the two cold-open connect-probe grids from 25ms to 5ms (#2891)

Cold-open boot-floor decomposition at 7064d039a (bench hillclimb record
20260926-194800-startup-boot-floor-decompose) measured two pure-wait
probe grids on every cold launch, each quantized 0-25ms (mean ~12.5ms):

- ensure_daemon_running_with polls the freshly spawned supervisor's
  socket every 25ms; a cold supervisor binds ~39ms after spawn.
- probe_worker_socket polls a freshly forked session worker's socket
  every WORKER_CONNECT_BACKOFF_MS=25ms; the worker binds ~1-3ms after
  the fork.

Both grids tighten to 5ms. Timing-only: probes, 30s budgets, auth floor,
and all error paths are unchanged; wire and user-visible behavior are
identical (TS polls at 25ms in both places - the deliberate divergence
is the perf port's, flagged for review).

* perf(pa-tui): return the first-frame heap of a resumed transcript; store settled messages rows once (#2895)

* perf(pa-tui): return the first-frame heap of a resumed transcript; drop settled messages duplicate block-cache copy

* test(pa-tui): settled messages keep no block-cache copy; streaming keeps its replay cache

---------

Co-authored-by: perf-tui-memory-fast <perf-tui-memory-fast@hillclimb.local>

* perf(pa-daemon): zero-copy relay for routed responses - share the payload bytes, splice the client id (#2897)

* pa-daemon: relay routed responses by bytes - supervisor splices the client id onto the worker line

* fmt: the two supervisor.rs forms CI rustfmt wants

* perf: the cross-process runtime-ready probe memo - on-disk, same identity key, damage-aware (#2881)

* pa-core: the cross-process runtime-ready probe memo (on-disk, same identity key)

* pa-core: fix the xproc memo commit's test-module paths and escape damage

* pa-core: rustfmt the cross-process memo

* pa-core: clippy fixes for the cross-process memo tests

* pa-core: move the memo-walk helper to test-mod scope (clippy items-after-statements)

* pa-core: fix the disk-memo oracles (missing-dir semantics, fallback sequence) and serialize the memo-state tests

* pa-core: the disk-memo repair-to-verified-content hits (oracle fix)

* pa-core: the live closure-freeze allowlist covers the real runtime's stdlib imports (18 modules found on first live run)

* pa-tui: agents-view summary rows drop the model mix; the inactive line bills the descendant aggregate (operator directive) (#2894)

9168514c8384merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs facade cut SS3 - the adoption/register concern byte-moves into supervisor/adoption.rs (#2901)

450cf50aeb31merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): share client-event payloads on the supervisor broadcast (Arc) - sup CPU -60% at N=100 (#2896)

* perf(pa-daemon): share client-event payloads on the supervisor broadcast (Arc)

Baseline at origin/rust 7064d039a on the concurrent-io lane: supervisor CPU
per append_custom_message is Theta(N) in resident sessions - 536us/append at
N=1 rising to ~2636us at N=100 live sessions (a+21us*N fits all four N and
both trials), because every session event (2 per append: message_start +
message_end, each carrying the full message payload) is published on the one
daemon-wide tokio broadcast channel, and every connected client's event arm
wakes, deep-clones the (ClientRouting, Value) frame, locks its attached-list
mutex, checks, and discards. Aggregate daemon CPU for equal per-session
traffic is Theta(N^2).

Share the payload instead of cloning it per receiver: the channel carries
(ClientRouting, Arc<Value>). Nothing else changes - same channel, same ring
capacity, same routing decisions in the same recv order, same wire frames
(write_line serializes from the shared Value; the worker-side EventPump
already shares its frames this way via Arc<OutboundFrame>). The per-receiver
cost for a non-matching connection drops from a full serde_json::Value deep
clone to an atomic refcount bump.

Measured on the 16c/32GB ubuntu:22.04 VM (hillclimb-perf-concurrent-io):
same-vm ABBA at N in {1,100} follows in the lane record; the claim is
daemon CPU per session event, not wall latency (append wall is
fsync-dominated on the measurement host).

* fix(pa-daemon): wrap the two missed client-event send sites + test compile

- supervisor.rs shutdown-signal daemon_closing broadcast and the
  supervisor_roster.rs RosterSubscribers push missed the Arc wrap; both
  now share the payload like every other events.send site.
- Test fixtures compile against the shared-payload channel: the roster
  drain helper derefs back to owned Values (tests keep comparing Values),
  and the daemon_closing assert compares through the Arc.

* fix(pa-daemon): compile + rustfmt the shared-payload channel's test helpers

- supervisor_roster_seed tests' drain helper takes the Arc-typed receiver
  and derefs back to owned Values (same pattern as supervisor_roster).
- rustfmt the Arc-wrapped send sites (line-width wrap only, no semantics).
No product behavior changes: whitespace + cfg(test) code only.

* style(pa-daemon): rustfmt the seed-test drain helper + clippy semicolon

One-liner receiver type per rustfmt, trailing semicolon per
clippy::semicolon_if_nothing_returned. cfg(test)-only change.

* pa-core: anchor compaction summaries to kept-tail state and stop re-summarizing file lists (TS #2385) (#2768)

a1c236c05df8merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-tui): the bang-during-streaming-turn e2e gates the mock's turn end on the ack bang, not a wall clock - every awaited state is causal or terminal, closing the two-channel load red (red-bang-stream-flush-20260926-1) (#2904)

a02c3aa25cdamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai/pa-daemon: the faux repeat-last knob + the goal-recovery e2e opts in and pins the exhaustion race deterministically - closes red-goal-recovery-faux-exhaustion-20260926-1 (#2902)

1e236ad703efmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the inline pickers' selection wash reads off the surface (operator directive) (#2908)

c7a54e058c31merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): return the supervisor relay and catalog-scan heap to the OS (#2899)

The supervisor process relays every routed worker response through a
serde_json Value tree (from_slice in the worker-frame reader, a
DaemonResponse through the pending-reply channel, response_line to the
client write) and the saved-session catalog scan folds a parse tree per
file line; both phases free their trees when the phase ends, but nothing
in the supervisor process ever returned the freed pages, so a grown
session relay (a ~9.5MiB get_messages wire leaves +71MiB resident; a
routed attach adds +42MiB more) and every grown catalog scan stayed at
the arena high-water for the daemon lifetime.

Mirror the merged #2872 session-memory pattern on the two daemon-side
phase boundaries: write_line reports the serialized byte count and the
client write loop trims when a routed line carried >=1MiB (the frame is
out and the tree is dropped first), and the saved-session scan trims at
its join (the per-line trees are folded and freed inside the blocking
task; the per-file cached scan states are live cache and stay
untouched). Allocator plumbing only - no data, protocol, wire, or
behavior changes; non-glibc/Linux builds are no-ops via
pa_types::memory_release.

Co-authored-by: perf-daemon-rss-fast <hillclimb@prime-intellect.local>

* perf(pa-tui): stream the exit/suspend main-screen flush - zero exit RSS spike, byte-identical output (#2913)

* perf(pa-tui): stream the exit flush in bounded chunks - the inline repaint never materializes the whole frame

* pa-tui: fmt + the flush errors doc (gate nits)

* pa-tui: fmt + the flush errors doc (gate nits)

* perf(pa-core): serialize same-process auth-lock holders - first-turn slow-class 50% to 12% (#2915)

The TS product runs acquireLockSyncWithRetry on a single thread, so the
10x20ms retry only ever fires against another process. The Rust engine is
threaded: two worker threads racing AuthStorage::create on a fresh
session's first turn (model-resolution registry build vs a concurrent
auth read, strace-verified: openat O_CREAT|O_EXCL -> EEXIST within 47us,
loser clock_nanosleeps the full 20ms) pay the TS retry sleep against each
other, a ~20ms first-turn latency class in 4/6 msgsettle trials.

A process-local mutex keyed by the auth document path serializes
same-process callers for the microseconds the small read/modify/write
holds. The file protocol, staleness judgment, and retry semantics are
untouched: a foreign holder (another process) still surfaces WouldBlock
and still takes the 10x20ms retry. The mutex is a leaf (the locked
section performs only the document's own fs ops plus the caller's
callback; no callback re-enters with_lock), and poisoning is recovered
because the file protocol is the correctness mechanism.

Co-authored-by: perf-model-resolve-cache-fast <hillclimb@prime-intellect.ai>

* perf(pa-daemon): per-session subscriber registry - send-time attached check, sup CPU -20% at N=100 (#2914)

* perf(pa-daemon): share client-event payloads on the supervisor broadcast (Arc)

Baseline at origin/rust 7064d039a on the concurrent-io lane: supervisor CPU
per append_custom_message is Theta(N) in resident sessions - 536us/append at
N=1 rising to ~2636us at N=100 live sessions (a+21us*N fits all four N and
both trials), because every session event (2 per append: message_start +
message_end, each carrying the full message payload) is published on the one
daemon-wide tokio broadcast channel, and every connected client's event arm
wakes, deep-clones the (ClientRouting, Value) frame, locks its attached-list
mutex, checks, and discards. Aggregate daemon CPU for equal per-session
traffic is Theta(N^2).

Share the payload instead of cloning it per receiver: the channel carries
(ClientRouting, Arc<Value>). Nothing else changes - same channel, same ring
capacity, same routing decisions in the same recv order, same wire frames
(write_line serializes from the shared Value; the worker-side EventPump
already shares its frames this way via Arc<OutboundFrame>). The per-receiver
cost for a non-matching connection drops from a full serde_json::Value deep
clone to an atomic refcount bump.

Measured on the 16c/32GB ubuntu:22.04 VM (hillclimb-perf-concurrent-io):
same-vm ABBA at N in {1,100} follows in the lane record; the claim is
daemon CPU per session event, not wall latency (append wall is
fsync-dominated on the measurement host).

* fix(pa-daemon): wrap the two missed client-event send sites + test compile

- supervisor.rs shutdown-signal daemon_closing broadcast and the
  supervisor_roster.rs RosterSubscribers push missed the Arc wrap; both
  now share the payload like every other events.send site.
- Test fixtures compile against the shared-payload channel: the roster
  drain helper derefs back to owned Values (tests keep comparing Values),
  and the daemon_closing assert compares through the Arc.

* fix(pa-daemon): compile + rustfmt the shared-payload channel's test helpers

- supervisor_roster_seed tests' drain helper takes the Arc-typed receiver
  and derefs back to owned Values (same pattern as supervisor_roster).
- rustfmt the Arc-wrapped send sites (line-width wrap only, no semantics).
No product behavior changes: whitespace + cfg(test) code only.

* style(pa-daemon): rustfmt the seed-test drain helper + clippy semicolon

One-liner receiver type per rustfmt, trailing semicolon per
clippy::semicolon_if_nothing_returned. cfg(test)-only change.

* pa-daemon: per-session subscriber registry - session events resolve delivery at publish time (TS handleWorkerFrame parity)

TS evaluates the attached predicate in the same synchronous pass that
writes the socket (daemon-supervisor.ts handleWorkerFrame l.6353; attach
flips the flag and writes session_attached in one tick, l.5586->l.5608).
The Rust ring evaluated it at RECV time in every connection event arm - a
superset in the attach/detach race window TS cannot produce (an event
published before an attach could still land after it, duplicating a row
the attach snapshot already carried).

Session events now route through a supervisor-side subscriber index
(session id -> connection id -> bounded per-connection queue): publish
enqueues to the attached set under one lock, unattached connections
never wake (the ~5.9us/session/append wakeup floor at N=100 from the
concurrent-io lane), per-(session,connection) order stays publish order,
and a full queue drops with a one-line-per-stall-cycle log (finding 4a
visibility). Broadcast / BroadcastExcept / RosterSubscribers keep the
ring; ClientRouting::AttachedSession is removed so a stale session-event
publish fails at compile time. Session events without an active session
id are dropped (TS l.6296 !activeSessionId guard), not broadcast.

The dormant supervisor/clients.rs split copy carries the same change
(re-homing at the fold will take one of the two).

* pa-daemon: fmt + clippy fixes for the subscriber registry (if-let for the single-pattern session-event relay)

* pa-daemon: fix the registry idempotency test - drain the delivered frame before the post-detach empty check

* pa-daemon: rustfmt the registry rebind call and the idempotency assert

* pa-daemon: rustfmt the registry call sites exactly as rustfmt asks

* pa-daemon: convert the zero-copy splice arm's attach push to the subscriber registry

#2897's raw-splice attach family added a SECOND attach-success push site on
the tip's routing.rs; it arrived through the fold with the old vec
semantics (the pre-fold grep could not have seen it). Same conversion as
the typed arm: registry + session list in one attach() call, the registry
insertion is the delivery boundary.

* pa-tui: the operator's touch follow-ups - the card click opens the card, the follow hint re-derives at the mode exit, the prompt bar's indicators paint on the bar (#2911)

0c526d534fcamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai: the codex dead-callback tests stage the registered port checked, not blind (settle-race hardening) (#2906)

c38824288cf2merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli: the first-run login frames render the TS login dialog (frame-parity r3) (#2845)

11365e57484dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 1/14 - the heartbeats concern moves out of src/session_ui.rs (#2886)

9f1cfc73550amerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the hover affordance - ?1003 any-event tracking delivers the buttonless motion, the hovered clickable card row brightens (muted to the theme fg, dim to muted) (#2918)

d81f3d2c7c07merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-ai/pa-agent): StreamingJsonAccumulator - stop re-parsing streamed tool-call JSON on every delta (TS #2783 port) (#2912)

dbec3a6eb0b7merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge); optional lane gate evidence: gate_1790470828_1252847 GREEN.

* pa-daemon: agent_engine.rs split 3/11 - the artifacts concern moves out of src/agent_engine.rs (#2905)

95e10f8ea95emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 2/14 - the stream concern moves out of src/session_ui.rs (#2920)

6aecfb087453merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 5/14 - the auth concern moves out of src/session_ui.rs (#2923)

70abcc702d14merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-cli/pa-daemon: implement the RPC stdio mode over the in-process session engine (TS modes/rpc parity, stub S5) (#2801)

25b657908b38merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 2/8 R2 (remediation) - the client-connection cut actually lands on the facade (#2885)

21304589206amerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli: the agents-view e2e settles its daemon-driven rows by synchronization, not a timing budget (AgentsStep::WaitRender - the registered ranked-hits render/data-arrival race closes by construction) (#2910)

f22938c1e0aamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-tui): packed cached entry layouts - scroll retention RSS -42%, byte-identical output (#2921)

* perf(pa-tui): store cached entry layouts packed - byte-exact rows, one blob + dense span records

The transcript layout cache retains every visited entry's rendered rows
for the process lifetime. A 2600-key scroll walk over the canonical 10MiB
session retained 5,428 entries' rows as 604k fragment-sized spans holding
5.2MB of text (+64.6MB heap, fully retained after return-to-tail; the
tui-scroll-retain census: 8.3 spans/line, content capacity already
exact, 44% line-buffer slack, per-span Vec/String chunk overhead the
retained mass). Merging adjacent same-style spans would shrink the
storage but changes the exit-flush inline scrollback's ANSI bytes
(per-span SGR re-emission; the exit flush is the TS-parity-frozen
output), so the cache stores the same rows packed instead: one content
blob plus dense (offset, len, style) records, expanded byte-exactly on
read - only the intersecting row range is expanded, so a frame inside a
huge entry pays its visible rows, never the whole row set. The pad
entry's own 109k-span row set (the resumed ready-state footprint) packs
the same way.

* perf(pa-tui): exact pack blob capacity + size-gated post-pack trim

The pack's blob grew by String doubling (2x capacity: 33.6MB held for a
17.45MB row set at 40MiB); the first pass now sizes it exactly. A huge
entry's rendered rows are the transcript's biggest single transient and
the pack just freed them - the freed pages only return to the OS when
the allocator's trim can reach them (the 40MiB ready RSS measured
bimodal 181/205 on the same build); the pack now returns them
immediately, gated at 8192 rows so ordinary entries never pay a trim.

* fix(pa-tui): EntryRows::is_empty for the touch surface's shows-tail peek (fold resolution completion)

The #2911 fold introduced the empty-section peek (a window that exactly
ends on the final chat entry re-checks whether any non-empty section
remains before declaring shows-tail); its section source is the
EntryRows handle since the packing fold, which needs the is_empty form.

* test(pa-tui): fix the pack tests' clippy findings (untyped Vec::new, shadowed view helper)

* test(pa-tui): drop the pack test closure's unused mut

---------

Co-authored-by: perf-tui-scroll-retain-fast <perf-tui-scroll-retain-fast@hillclimb.local>

* pa-daemon: agent_engine.rs split 2/11 - the config concern moves out of src/agent_engine.rs (#2909)

07cbb0febb74merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 4/11 - the model concern moves out of src/agent_engine.rs (#2907)

5c530e66cef9merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 3/14 - the queue concern moves out of src/session_ui.rs (#2900)

e673275046dfmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 7/8 - the update/restart concern moves out of src/supervisor.rs (#2903)

268c1fba26c0merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli: dock panel exits restore the dock's own group, not the prompt bar (operator ruling 2026-09-26) (#2864)

a12c2847335bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 5/11 - the goalcore concern moves out of src/agent_engine.rs (#2924)

c95a239b9eb3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-tui): handoff drains park on observed input, not a fixed wait - chat-to-agents -79% (#2916)

* perf(pa-tui): a handoff drain consumes buffered input instead of parking on the idle window

The chat->agents handoff teardown pays the enhanced_keys drain's fixed 50ms
DRAIN_IDLE poll on every switch (chat->agents measured 67ms p50 at #2893,
~50ms of it this window). The idle window guards a kitty key release that
lands after raw mode is off - a leak that is unreachable on a handoff: raw
mode stays on (the adopting surface's reader takes the same tty) and every
surface's dispatch drops release events (input::filter_enhanced_key_events,
TS tui.ts). The handoff now consumes what the terminal has already written
with zero-timeout polls and returns as soon as the buffer is observed empty;
only when input IS flowing does it fall through to the bounded drain, so a
burst around a handoff is coalesced exactly like before. True exits (drain,
drain_for_exit) keep the TS drainInput(1000, 50) contract untouched. Adds a
real-pty e2e that arms the kitty protocol, injects the handoff trigger's
release in flight, and audits the byte stream (no visible release, no
post-exit kitty flags, no echo after the restore).

* test(pa-cli): fix the kitty-release e2e gate lints (fmt shape, unit let-binding, unused import)

* test(pa-cli): the kitty-release mock supervisor serves every connection in turn

The chat surface holds one daemon connection and the agents view opens its own after the handoff; a single-accept mock refused the second (the first run of the e2e failed on exactly that: connection refused at run_agents_view connect).

* test(pa-cli): qualify the mock supervisor connection handler call

* test(pa-cli): handle the listener incoming result in the mock supervisor

* test(pa-cli): the kitty-release editor probe waits for the painted cell

The frame paints typed cells as styled positioned cells (escape bytes between characters), so the two-byte zz needle never appears; wait for the painted z cell instead.

* test(pa-cli): the kitty-release harness reaps the pty child on panic paths too

* test(pa-cli): the kitty-release exit drives the CSI-u escape form

With disambiguate armed a kitty terminal encodes its Esc presses as CSI 27 u; the raw lone ESC byte is the legacy form the reader arms its meta-wrapper hold for. Drive the realistic encoding and separate the exit key from the release injection.

* fix(pa-tui): the handoff drain's bounded phase runs on the budget the zero-timeout loop left

The zero-timeout consume loop can spend the whole DRAIN_MAX under
continuous input before falling through to drain_until_idle, which
then started a fresh budget - the handoff could block nearly two
seconds, past the documented one-second hard cap. The bounded phase
now runs on what remains of the original budget (Macroscope thread
PRRT_kwDOSXZbXs6mWWqM).

* perf(pa-daemon): borrow the catalog fold metadata and single-open the scan - cold scan -7%, syscalls -22% (#2919)

* perf(pa-daemon): borrow the catalog fold's entry metadata, kill the per-line tail Vec

The post-#2879/#2882 cold roster scan still typed-parsed every line into
owned strings and materialized `Value` trees for fields the fold reads
once or discards: 3 `String` allocations per line (type, id, timestamp)
plus a `Value` tree per message row (role, provider, model, timestamp) and
per session_info/state/model_change/thinking_level row. The resume tail
added one `Vec` allocation per line sized line.len()+17 to keep 16 bytes.

Both costs are gone without changing a row byte:

- SessionInfoEntry's scalar fields borrow as `Cow<str>` (zero-copy when
  unescaped, owned fallback identical to the old String), its object
  fields ride raw spans like #2882's content: each arm parses back only
  the span it reads, with exactly `Value::as_str`/`as_u64` semantics
  (present-and-string/number, absent and non-string both read None, the
  model_change abort arm keeps its exact two-step None).
- advance_tail copies inside the fixed 16-byte window: the same bytes
  (a rolling-reference lockstep test pins the old Vec semantics), no
  per-line allocation.

Differential ground truth: the new in-tree shape matrix pins every
borrowed read to the full-parse Value read per row (escaped scalars,
non-string roles/timestamps, null/absent/whitespace names, hidden/sleep
states, abort shapes) and folds the accepted rows end to end against the
legacy full-parse reference fold; the VM census ran the same differential
over 177,798 real fixture lines (100/1000/4096 tiers) with zero
divergence in acceptance, fields, or fold states both directions.

* perf(pa-daemon): share one open between the roster header gate and the fold

The roster scan opened every file twice: the bounded header gate opened,
read its first line, and closed, then the fold opened the same path again
for the scan — an openat+close per file per scan (plus the second
metadata read the fold always paid). The gate now reads the first line
from the same fresh handle the fold rewinds and scans, so one open serves
both.

The TOCTOU the double-open carried is disclosed: with two opens, a
rename/replace landing between them judged one file and folded another;
the shared handle pins the judgment and the fold to the same inode —
the fold's cursor, generation, and certification re-stat now read the
file the gate judged, never a replacement that raced in between.

The listing stat (`stats.mtime`, the `modified` fallback of last resort)
is read lazily now: the fold only reaches it when a row has neither
message timestamps nor a parseable header timestamp, so the eager
per-file stat the scan always paid serves only the rows that read it.
The `or_else` chain keeps its order and its None semantics (the
existing fallback tests pin every arm of the chain).

* pa-daemon: fmt + clippy for the catalog fold lane (test-import move, lockstep test polish, matrix lint allows)

* pa-daemon: supervisor.rs split 4/8 - the saved-session concern moves out of src/supervisor.rs (#2883)

9f9146b74371merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the #2921 review follow-ups - RowPack::pack refuses unrepresentable entries, the huge-entry trim drops the expanded rows first (fold of rust 9b62f26af) (#2925)

df34ea19dbb3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 10/14 - the bash concern moves out of src/session_ui.rs (#2928)

481b2f28553cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* skills/prime-intellect: sync vendored sandbox docs to the VM-only surface (TS #2456 doc half) (#2751)

a4e997e2e803merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* fix(pa-cli): remove the duplicated restore_dock_focus initializer the #2751 squash double-applied

The #2751 squash (1a9fd16b9) landed the heal rider line onto a tip that
already carried the identical line from #2925 (e6e7a26e4) - the squash
applied the stale pre-fold diff, duplicating the field (E0062). This
restores the fixture to the parent 84dbb51e0 state (exactly one field).
The label rider and the docs in the same squash are intended and stay.

* pa-daemon: agent_engine.rs split 7/11 - the SessionEngine trait impl moves out whole (#2926)

2b07a22bd1d3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core + runtime: the harness-digest family - IDF-ranked digest/search, state-fingerprint staleness, newest-only digest contexts, validated kernel harness writes (TS #2392/#2400/#2394/#2463 parity) (#2750)

bff9fa6ff122merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* fix(pa-cli): the kitty handoff e2e fixture initializes restore_dock_focus (#2927)

962ff3097575merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 7/14 - the settings concern moves out of src/session_ui.rs (#2930)

fd71eaf2dfeamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 6/14 - the model-picker concern moves out of src/session_ui.rs (#2929)

2038abcf5754merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon/pa-cli: ACP model and effort pickers - configOptions at session/new, session/set_config_option, config_option_update (TS #2455) (#2758)

fd977cb13ee6merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core): consolidate auth-lock reads - 36 lock cycles per first turn to 2, settings mutex closes the unmasked stall class (#2932)

* perf(pa-core): consolidate auth-document reads through a validated cache

* perf(pa-core): serialize same-process settings-lock holders (the #2915 pattern)

The auth read-through cache on this lane unmasks a pre-existing stall:
two worker threads racing the same settings.json pay the full TS
10x20ms retry sleep against each other (strace-verified: mkdir
attempts 11us apart, the loser clock_nanosleeps the full 20ms; the
paired census shows same-process overlapping settings acquisitions 2
on the base and 5 with the auth cache, sleep20 1 vs 2, and the timing
legs pay a ~20ms-class stall on 3/6 fresh turns vs 0/6 base). The
auth-lock cycles 150-300us same-process serialization was pacing the
threads apart by accident; that masking is not a mechanism to keep.

TS runs its synchronous settings lock single-threaded, so same-process
settings contention is a Rust-port artifact, the exact class #2915
ruled on for the auth lock: a process-local mutex keyed by the
document path serializes same-process callers for the microseconds
the small read/modify/write holds. The file protocol, staleness
judgment, and retry semantics are untouched: a foreign holder
(another process) still surfaces WouldBlock and still takes the
10x20ms retry. The mutex is a leaf (the locked section performs only
the document's own filesystem operations plus the caller's update
callback; no settings callback re-enters with_lock - every callback
is a pure JSON transform), and poisoning is recovered because the
file protocol is the correctness mechanism.

---------

Co-authored-by: perf-auth-lock-fast <hillclimb@prime-intellect.ai>

* perf(pa-daemon): zero-copy worker response path - routed msgs -17%, attach -22%, worker RSS -20% (#2935)

* perf(pa-daemon): zero-copy worker response handoff - serialize the line from the borrowed trees, write the frame without re-buffering the payload

* fmt(pa-types): the segments test write_frame call in the form CI rustfmt wants

* fmt(pa-daemon): the response-path call forms CI rustfmt wants (VM cargo fmt at the exact head)

* fix(pa-daemon): restore the response_line TS-key-order test the new-test insert orphaned (clippy empty_line_after_doc_comments was the symptom)

* fmt(pa-daemon): the restored test doc comment indent

* fmt(pa-daemon): single trailing newline at file end

---------

Co-authored-by: wc <wc@fleet.local>

* pa-daemon: agent_engine.rs split 6/11 - the Turn types move out of src/agent_engine.rs (#2931)

b2ca4deea5afmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): batch the queue-checkpoint journal pair - 4 syncs per warm turn to 2, crash window strictly narrowed (#2936)

* perf(pa-daemon): batch the queue-checkpoint journal pair into one durable append

The queue checkpoint (prompt/steer/follow-up admission, turn settle, queue
mutations) appends two records to the worker recovery journal - the queue
snapshot and the busy/operation verdict - as two separate open+write+fsync
cycles, paying two journal flushes per checkpoint. Both records describe
one atomic checkpoint, and the busy verdict must never publish over a
snapshot that did not persist, so the pair can ride ONE open+write+fsync:
the batch is all-or-nothing durable, the on-disk line order matches the
sequential form exactly (snapshot first, then the verdict), and an
unchanged verdict keeps appending the snapshot alone.

Measured on the warm-turn admission path (the wave-5 warm-durable-append
decomposition): the two journal fsyncs sit inside the TUI-ack-to-user-row
phase together with the session append's fdatasync; batching removes one
of the three durable syncs per warm turn without weakening any durability
guarantee (the session append's per-row fdatasync is untouched).

* test: rustfmt the batched-checkpoint test call sites (gate fmt finding)

* fix(pa-tui): the exit watchdog holds fire while the flush drains - healthy slow drains no longer truncate scrollback, TS-convergent (#2937)

* perf(pa-tui): the exit guard holds its force-quit while the exit path drains - slow terminals keep the whole scrollback flush

On a terminal that consumes the exit flush slowly (a laggy ssh at
~0.5-2MB/s), the flush of a large transcript outlasts the 1500ms
FORCE_QUIT_AFTER_MS deadline that arms at the second Ctrl+C, and the
watchdog fires mid-flush: strace shows its restore writes winning the
pty FIFO race at a flush-chunk boundary, exit_group(0) landing while the
writer still holds ~64-82% of the transcript (40k rows: 8.74MB flush
truncated to 1.5-3.1MB), 'shutdown stalled; forced exit.' printing on a
healthy drain, and the restore bytes queueing mid-stream behind the
flushed rows. TS has no watchdog at all (its handleCtrlC second press
runs the async shutdown, and slow writes simply wait), so both the
message and the truncation are port-only.

The guard becomes drain-aware: the flush writer reports progress per
completed 32KiB chunk (view.rs FlushSink), the release tail and the
resume hint report theirs, and the watchdog holds its fire while
progress landed within EXIT_PROGRESS_GRACE_MS (500ms) - the hard 1500ms
ceiling stays for the silent case (the wedged loop the guard was built
for). Flush chunks shrink 256KiB -> 32KiB so a drain of at least
~65KB/s completes chunks inside the grace window; the flush byte stream
is unchanged (the exit-flush lane's byte-identity oracle). The truncated
scrollback contract is restored on slow drains: the flush completes
byte-identically, the release tail lands after the last row, and the
message prints only for a genuinely stalled drain.

The exit-guard unit tests grow the hold/fire decision table; a new
real-pty e2e (pa-cli slow_drain_exit_guard_e2e, the kitty-release
harness pattern) drives the real chat surface over a paced pty master
and asserts both sides: a draining terminal flushes the whole
transcript with no forced exit, and a stalled drain still fires.

Rider (disclosed): kitty_release_handoff_e2e grows the restore_dock_focus
field the #2916 squash dropped from its fold-time heal - the tip's
pa-cli test target does not compile without it.

* test(pa-cli): the slow-drain e2e asserts the forced fire structurally

The re-executed test binary's libtest harness captures stderr per
test, so the watchdog's 'shutdown stalled' line never reaches the pty
in the harness child (the real binary writes it to fd 2 - the lane's
VM bench legs assert it there). The stalled-drain leg instead asserts
the forced exit structurally: the forced restore's own alt-screen
leave lands on top of the exit path's (a clean exit leaves it exactly
once), the flush never reaches the transcript tail (one copy of the
last user row, the startup viewport's), and the process dies with the
guard's exit code inside the stall window. Harness needles use the
user-message rows (assistant rows carry per-word SGR spans) and the
post-exit drain reads the pty's kernel-held bytes before asserting.

* fmt: the slow-drain e2e needles and the watchdog's progress read

* clippy: doc backticks + checked Duration subtraction in the guard tests; the e2e's needle check takes the direct is_none

---------

Co-authored-by: perf-slowdrain-exitguard-fast <lane@hillclimb.local>

* perf(pa-core): consolidate settings-lock reads - 32 lock cycles per first turn to 2 (#2941)

* pa-ai/pa-core/pa-cli/pa-tui: grok-4.7 on every serving surface (TS #2505) + Claude Code 2.1.281 + Anthropic subscription ban-risk warning (TS #2645) + one owner for the Prime team header, retry failed !command credentials (TS #2497) (#2755)

7373eb471670merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-cli): the interactive_daemon_e2e wedge root-kill - PDEATHSIG + orphan sweep + the 300s headless wall (#2942)

dbed1170fa2bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli/pa-daemon: session opens wait through a daemon update restart (TS #2391) + the failed-restart hint (TS #2515) (#2763)

e7a84e749089merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): the all-idle compaction fires like TS and rides the TS compact sync class - journals bounded (#2944)

* perf(pa-daemon): settle-tail compact consolidation - the all-idle compaction fires like TS and rides the TS compact sync class

The worker recovery journal's all-idle gate ran BEFORE the record insert,
so a single-session journal's own busy admission record blocked every
settle's compaction: the compact never fired on the dominant shape and
the journal grew append-only for the session's lifetime (TS computes the
gate POST-insert and compacts at every changed-idle record). The gate now
matches TS, bounding the file.

Where the compact fires, its temp sync_all was a sync class TS's compact
does not pay (TS worker-recovery-journal: writeFileSync + renameSync, no
fsync; the command journal's writeFileAtomicSync counterpart does carry
fsync). The Finalize seam now encodes the sync class per owner: RetryBusy
keeps its fsync (command journal), Synced keeps the Rust-native
terminal-compaction journal's belt, and Bare is the TS worker shape -
temp write + rename, no fsync. Durability is owned by the append path
(the fresh-write class is untouched): the compacted form holds only
records the append path already made durable, so a lost compact falls
back to the append-only history, which replays identically.

* test-only rustfmt of the new test call site (the gate's one fmt finding)

* runtime/kernel: vendored-runtime hardening + kernel stderr owner-only (TS #2372/#2423/#2500/#2471/#2478/#2425 parity) (#2744)

ea5abd1bbe1bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 11/14 - the prompt submit pipeline moves out of src/session_ui.rs (#2943)

3bafbc007b74merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-tui): 8-byte packed span records with per-pack style table - scroll retention -7.5MB, byte-identical output (#2939)

* perf(pa-tui): denser packed span records - style table + derived offsets (8B/span), byte-exact range expansion

* test(pa-tui): rustfmt the exhaustive row-pack range oracle

* fix(pa-tui): clippy - if-let style dedup + drop redundant test clones

* pa-tui: fix the submit-outlived-by-switch idle-gate race - the turn-end watermark restarts with the mounted stream (#2945)

c661290b1b77merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: hold spawn-name reservations until admission is durable; collect returns cancelled envelopes for just-deleted targets (TS #2396 + #2388 F4) (#2757)

18aa772bd3b2merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai/pa-core/pa-daemon: codex stale-chain retry after metadata (TS #2374) + safety failures permanent (TS #2472) + quota park until reset with auto-resume (TS #2375) (#2761)

dc9892ffbc1emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-tui): the headless settle bound names its stuck member in 60s - defense-in-depth inside the wedge wall (#2949)

The interactive_daemon_e2e exit-gate wedge family is root-killed
upstream (#2945: the turn-end watermark restarts with the mounted
stream) and the harness carries the 300s wall (#2942). This closes the
remaining gap: the headless settle was the run loop's only unbounded
wait on the product side — a settle member that never drains parked the
run forever with no failure name (TS exits the process at shutdown and
lets in-flight work dangle, so the settle has no TS counterpart).

The gate's twelve settle members are now snapshotted (HeadlessSettle:
settled() is the old gate exactly; blockers() names them), and after
the plan completes a stuck member fails the run within
HEADLESS_SETTLE_TIMEOUT_MS (60s) with the member named — e.g. 'a turn
still active' — instead of waiting out the harness's 300s wall with a
generic timeout. Green settles are milliseconds after HeadlessDone
(the suite's green wall is ~15s; the last submit's own ack bound is
10s), and terminal runs never arm the bound (HeadlessDone exists only
on the headless harness; a live terminal ends the run on
exit_requested + the exit guard).

Proven end-to-end by the lane's matrix: the wedge converted to a 98.4s
attributable red naming the latched member (the bound-only diagnostic
arm), and the full candidate stayed clean at 30/30 interleaved trials
vs 3/30 wedges at the lane parent (record
20260927-085200-interaction-exit-gate-hang-remediation, bench
hillclimb).

* perf(pa-daemon/rpc): warm the model registry at RPC session boot - first get_available_models 1170.6ms to 58.9ms (#2953)

TS session boot resolves the initial model through refreshAvailableModels
(model-resolver.ts), which also fetches the live Prime Inference catalog
in the background and caches it on disk; the daemon worker fires the same
fire-and-forget refresh from its create path (worker/create.rs). The RPC
mode hosts the session in-process with no create command, so nothing
warmed the caches: an integration's FIRST get_available_models call paid
the whole awaited refresh chain on its response path (measured 812-1296ms
on the bench VM; the 15s fetch-timeout worst case on a degraded network)
while the same command on the daemon and ACP surfaces answers from the
validated snapshot. Mirror the daemon worker boot spawn: the caches warm
during the session's first turn, and the first call serves the same
snapshot. Write behavior is unchanged: the same cache files, the same
write-on-fetch-success conditions, the same cadence (hour-gated catalog
refresh, 5-min private-authorization TTL), only started at boot.

Co-authored-by: perf-rpc-models-persist <lane@hillclimb>

* pa-tui: session_ui.rs split 4/14 - the share concern moves out of src/session_ui.rs (#2922)

b0d72b29a700merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 8/11 - the turn-execution impl moves out (#2934)

a59d3389dfbamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 5/8 - the worker-lifecycle concern moves out of src/supervisor.rs (#2956)

205f4d0f469cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 8/14 - the sessions concern moves out of src/session_ui.rs (#2957)

7d19e9832120merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 6/8 - the signals concern moves out (#2960)

a6562bc252efmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 10/11 - the lifecycle concern moves out of src/agent_engine.rs (#2962)

17d3573c5a58merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 12/14 - the keys concern moves out of src/session_ui.rs (#2958)

bc6b7d82cb0bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 11/11 - the facade trim: the last product free fns move out; the file ends as the composition root (#2964)

1fe6a6791030merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 8/8 - the facade trim: the notes concern moves out, the test battery re-homes (#2963)

8a5274baa0d9merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 9/14 - the panels concern moves out of src/session_ui.rs (#2961)

377eda9ded15merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 13/14 - the apply concern moves out of src/session_ui.rs (#2965)

c10a44e407cdmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: cap kernel host-request cell source at 2 KiB (the TS #2475 port) (#2966)

96f689fc38femerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the /model picker resolves by provider, never the first same-id catalog entry (fixes the operator report) (#2967)

24411964739emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 14/14 - the facade trim: the file ends as the composition root (#2968)

60cbb4fbb642merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core): the oauth refresh leaves the auth lock - fetch under single-flight, hold-sum 396ms to 0.09ms (#2971)

An expired stored OAuth credential refreshes its token inside
AuthStorageBackend::with_lock: the OAuthIntegration seam is synchronous
by contract, so the network round trip runs under the document lock AND
under the process mutex that spans the whole critical section, stalling
every other same-process auth read and write for the fetch (the RPC
cycle_model path measured 194-201ms auth.json.lock holds per switch on
the bench VM; the assembly read pays one ~0.2ms cycle, the switch pays
the fetch).

The TS product holds its own lock across the same await
(refreshOAuthTokenWithLock -> withLockAsync), but its single-threaded
runtime never blocks other work on it; this engine is threaded, so the
port narrows the lock scope instead: load-then-lock. The document loads
through the consolidated read arm, the token fetch runs outside every
lock behind a per-provider single-flight gate (the in-process
serialization TS gets from its single-threaded runtime, with the expiry
re-checked under the gate so a second caller never spends a single-use
refresh token after the first flight landed), and the write re-enters
the same locked read-modify-write protocol - now held only for the
re-read, insert, and atomic write, and skipping the write entirely when
a peer refreshed while the fetch ran. File protocol, read results, and
every resolution outcome are unchanged.

* pa-daemon: the supervisor roster broadcasts only on content change (the TS #2481 port P3) (#2974)

054553b8ca12merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-cli/pa-tui: prime-agent update - the TS->Rust migration path (uninstall TS, install Rust, sessions preserved) (#2981)

739ed7f7d015merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core/pa-daemon): a settled RLM child releases its kernel at the settle park - ~27MB reclaimed per settled child, TS #2483 port (#2983)

* perf(pa-core/pa-daemon): a settled RLM child releases its kernel at settle - snapshot-flushing stop_kernel, revivable (TS #2483)

The rust port of the stale perf PR #2483's inline arm (the supersession
analysis: the not-superseded claim - settled children hold a worker and
a kernel until parent close; nothing at the tip releases them; the
daemon-mode whole-worker passivation stays deferred to the orchestrator):

- IpythonKernelProvisioner::stop_kernel (TS stopKernel): shuts the owned
  kernel down with a final namespace snapshot WITHOUT marking the
  provisioner disposed; a kernel still starting up is joined first and
  shut down the same way (the TS managerPromise arm). The stop records a
  pending-stop gate (TS pendingStop) that the next start_kernel_impl
  awaits before reading the snapshot back, so a follow-up turn's fresh
  boot revives the flushed namespace instead of racing the flush; a
  completed stop awaits instantly and each stop supersedes the previous
  (a clonable watch receiver: multiple revival waiters gate on it).
- The session engine gains stop_kernel_snapshot (the TS
  stopKernel({snapshot:true}) seam beside dispose_kernel), and the
  SessionEngine trait gains release_settled_child_kernel (default no-op):
  the AgentSessionEngine arm eval…
snimu added a commit that referenced this pull request Oct 2, 2026
* perf(pa-tui): handoff exits break the run loop this iteration - chat->agents 119ms -> 67ms (#2893)

The terminal loop's exit-key break only left the input-drain loop, so the
handoff fell into the select below it and parked on the 50ms idle tick
before the loop-tail exit check ran — measured as ~50ms of added latency
on every chat -> agents view switch (strace: the key is handled in ~0.1ms,
the teardown starts on the next tick wake ~51ms later; the code's own
comment already demanded the teardown run "this iteration").

A handoff (agents-back, /resume, the scoped view, /resume <selector>)
now breaks the outer loop immediately: the next surface's mount clears
the alt screen, so the tail pass paints nothing the user can see. A
non-handoff exit (/exit, /quit) keeps the tail pass — its frame gate
paints the final chat frame the exit's main-screen flush shows — and
headless runs keep the tail pass so captured frame sequences stay
identical.

* perf(pa-daemon): borrow message content as RawValue - kill the second full catalog parse, cold -25% (#2882)

Co-authored-by: perf-catalog-second-parse-fast <hillclimb@local>

* pa-daemon: agent_engine.rs split 1/11 - the tests concern moves out of src/agent_engine.rs (#2889)

51bd18583e17merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-cli/pa-daemon): tighten the two cold-open connect-probe grids from 25ms to 5ms (#2891)

Cold-open boot-floor decomposition at 7064d039a (bench hillclimb record
20260926-194800-startup-boot-floor-decompose) measured two pure-wait
probe grids on every cold launch, each quantized 0-25ms (mean ~12.5ms):

- ensure_daemon_running_with polls the freshly spawned supervisor's
  socket every 25ms; a cold supervisor binds ~39ms after spawn.
- probe_worker_socket polls a freshly forked session worker's socket
  every WORKER_CONNECT_BACKOFF_MS=25ms; the worker binds ~1-3ms after
  the fork.

Both grids tighten to 5ms. Timing-only: probes, 30s budgets, auth floor,
and all error paths are unchanged; wire and user-visible behavior are
identical (TS polls at 25ms in both places - the deliberate divergence
is the perf port's, flagged for review).

* perf(pa-tui): return the first-frame heap of a resumed transcript; store settled messages rows once (#2895)

* perf(pa-tui): return the first-frame heap of a resumed transcript; drop settled messages duplicate block-cache copy

* test(pa-tui): settled messages keep no block-cache copy; streaming keeps its replay cache

---------

Co-authored-by: perf-tui-memory-fast <perf-tui-memory-fast@hillclimb.local>

* perf(pa-daemon): zero-copy relay for routed responses - share the payload bytes, splice the client id (#2897)

* pa-daemon: relay routed responses by bytes - supervisor splices the client id onto the worker line

* fmt: the two supervisor.rs forms CI rustfmt wants

* perf: the cross-process runtime-ready probe memo - on-disk, same identity key, damage-aware (#2881)

* pa-core: the cross-process runtime-ready probe memo (on-disk, same identity key)

* pa-core: fix the xproc memo commit's test-module paths and escape damage

* pa-core: rustfmt the cross-process memo

* pa-core: clippy fixes for the cross-process memo tests

* pa-core: move the memo-walk helper to test-mod scope (clippy items-after-statements)

* pa-core: fix the disk-memo oracles (missing-dir semantics, fallback sequence) and serialize the memo-state tests

* pa-core: the disk-memo repair-to-verified-content hits (oracle fix)

* pa-core: the live closure-freeze allowlist covers the real runtime's stdlib imports (18 modules found on first live run)

* pa-tui: agents-view summary rows drop the model mix; the inactive line bills the descendant aggregate (operator directive) (#2894)

9168514c8384merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs facade cut SS3 - the adoption/register concern byte-moves into supervisor/adoption.rs (#2901)

450cf50aeb31merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): share client-event payloads on the supervisor broadcast (Arc) - sup CPU -60% at N=100 (#2896)

* perf(pa-daemon): share client-event payloads on the supervisor broadcast (Arc)

Baseline at origin/rust 7064d039a on the concurrent-io lane: supervisor CPU
per append_custom_message is Theta(N) in resident sessions - 536us/append at
N=1 rising to ~2636us at N=100 live sessions (a+21us*N fits all four N and
both trials), because every session event (2 per append: message_start +
message_end, each carrying the full message payload) is published on the one
daemon-wide tokio broadcast channel, and every connected client's event arm
wakes, deep-clones the (ClientRouting, Value) frame, locks its attached-list
mutex, checks, and discards. Aggregate daemon CPU for equal per-session
traffic is Theta(N^2).

Share the payload instead of cloning it per receiver: the channel carries
(ClientRouting, Arc<Value>). Nothing else changes - same channel, same ring
capacity, same routing decisions in the same recv order, same wire frames
(write_line serializes from the shared Value; the worker-side EventPump
already shares its frames this way via Arc<OutboundFrame>). The per-receiver
cost for a non-matching connection drops from a full serde_json::Value deep
clone to an atomic refcount bump.

Measured on the 16c/32GB ubuntu:22.04 VM (hillclimb-perf-concurrent-io):
same-vm ABBA at N in {1,100} follows in the lane record; the claim is
daemon CPU per session event, not wall latency (append wall is
fsync-dominated on the measurement host).

* fix(pa-daemon): wrap the two missed client-event send sites + test compile

- supervisor.rs shutdown-signal daemon_closing broadcast and the
  supervisor_roster.rs RosterSubscribers push missed the Arc wrap; both
  now share the payload like every other events.send site.
- Test fixtures compile against the shared-payload channel: the roster
  drain helper derefs back to owned Values (tests keep comparing Values),
  and the daemon_closing assert compares through the Arc.

* fix(pa-daemon): compile + rustfmt the shared-payload channel's test helpers

- supervisor_roster_seed tests' drain helper takes the Arc-typed receiver
  and derefs back to owned Values (same pattern as supervisor_roster).
- rustfmt the Arc-wrapped send sites (line-width wrap only, no semantics).
No product behavior changes: whitespace + cfg(test) code only.

* style(pa-daemon): rustfmt the seed-test drain helper + clippy semicolon

One-liner receiver type per rustfmt, trailing semicolon per
clippy::semicolon_if_nothing_returned. cfg(test)-only change.

* pa-core: anchor compaction summaries to kept-tail state and stop re-summarizing file lists (TS #2385) (#2768)

a1c236c05df8merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-tui): the bang-during-streaming-turn e2e gates the mock's turn end on the ack bang, not a wall clock - every awaited state is causal or terminal, closing the two-channel load red (red-bang-stream-flush-20260926-1) (#2904)

a02c3aa25cdamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai/pa-daemon: the faux repeat-last knob + the goal-recovery e2e opts in and pins the exhaustion race deterministically - closes red-goal-recovery-faux-exhaustion-20260926-1 (#2902)

1e236ad703efmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the inline pickers' selection wash reads off the surface (operator directive) (#2908)

c7a54e058c31merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): return the supervisor relay and catalog-scan heap to the OS (#2899)

The supervisor process relays every routed worker response through a
serde_json Value tree (from_slice in the worker-frame reader, a
DaemonResponse through the pending-reply channel, response_line to the
client write) and the saved-session catalog scan folds a parse tree per
file line; both phases free their trees when the phase ends, but nothing
in the supervisor process ever returned the freed pages, so a grown
session relay (a ~9.5MiB get_messages wire leaves +71MiB resident; a
routed attach adds +42MiB more) and every grown catalog scan stayed at
the arena high-water for the daemon lifetime.

Mirror the merged #2872 session-memory pattern on the two daemon-side
phase boundaries: write_line reports the serialized byte count and the
client write loop trims when a routed line carried >=1MiB (the frame is
out and the tree is dropped first), and the saved-session scan trims at
its join (the per-line trees are folded and freed inside the blocking
task; the per-file cached scan states are live cache and stay
untouched). Allocator plumbing only - no data, protocol, wire, or
behavior changes; non-glibc/Linux builds are no-ops via
pa_types::memory_release.

Co-authored-by: perf-daemon-rss-fast <hillclimb@prime-intellect.local>

* perf(pa-tui): stream the exit/suspend main-screen flush - zero exit RSS spike, byte-identical output (#2913)

* perf(pa-tui): stream the exit flush in bounded chunks - the inline repaint never materializes the whole frame

* pa-tui: fmt + the flush errors doc (gate nits)

* pa-tui: fmt + the flush errors doc (gate nits)

* perf(pa-core): serialize same-process auth-lock holders - first-turn slow-class 50% to 12% (#2915)

The TS product runs acquireLockSyncWithRetry on a single thread, so the
10x20ms retry only ever fires against another process. The Rust engine is
threaded: two worker threads racing AuthStorage::create on a fresh
session's first turn (model-resolution registry build vs a concurrent
auth read, strace-verified: openat O_CREAT|O_EXCL -> EEXIST within 47us,
loser clock_nanosleeps the full 20ms) pay the TS retry sleep against each
other, a ~20ms first-turn latency class in 4/6 msgsettle trials.

A process-local mutex keyed by the auth document path serializes
same-process callers for the microseconds the small read/modify/write
holds. The file protocol, staleness judgment, and retry semantics are
untouched: a foreign holder (another process) still surfaces WouldBlock
and still takes the 10x20ms retry. The mutex is a leaf (the locked
section performs only the document's own fs ops plus the caller's
callback; no callback re-enters with_lock), and poisoning is recovered
because the file protocol is the correctness mechanism.

Co-authored-by: perf-model-resolve-cache-fast <hillclimb@prime-intellect.ai>

* perf(pa-daemon): per-session subscriber registry - send-time attached check, sup CPU -20% at N=100 (#2914)

* perf(pa-daemon): share client-event payloads on the supervisor broadcast (Arc)

Baseline at origin/rust 7064d039a on the concurrent-io lane: supervisor CPU
per append_custom_message is Theta(N) in resident sessions - 536us/append at
N=1 rising to ~2636us at N=100 live sessions (a+21us*N fits all four N and
both trials), because every session event (2 per append: message_start +
message_end, each carrying the full message payload) is published on the one
daemon-wide tokio broadcast channel, and every connected client's event arm
wakes, deep-clones the (ClientRouting, Value) frame, locks its attached-list
mutex, checks, and discards. Aggregate daemon CPU for equal per-session
traffic is Theta(N^2).

Share the payload instead of cloning it per receiver: the channel carries
(ClientRouting, Arc<Value>). Nothing else changes - same channel, same ring
capacity, same routing decisions in the same recv order, same wire frames
(write_line serializes from the shared Value; the worker-side EventPump
already shares its frames this way via Arc<OutboundFrame>). The per-receiver
cost for a non-matching connection drops from a full serde_json::Value deep
clone to an atomic refcount bump.

Measured on the 16c/32GB ubuntu:22.04 VM (hillclimb-perf-concurrent-io):
same-vm ABBA at N in {1,100} follows in the lane record; the claim is
daemon CPU per session event, not wall latency (append wall is
fsync-dominated on the measurement host).

* fix(pa-daemon): wrap the two missed client-event send sites + test compile

- supervisor.rs shutdown-signal daemon_closing broadcast and the
  supervisor_roster.rs RosterSubscribers push missed the Arc wrap; both
  now share the payload like every other events.send site.
- Test fixtures compile against the shared-payload channel: the roster
  drain helper derefs back to owned Values (tests keep comparing Values),
  and the daemon_closing assert compares through the Arc.

* fix(pa-daemon): compile + rustfmt the shared-payload channel's test helpers

- supervisor_roster_seed tests' drain helper takes the Arc-typed receiver
  and derefs back to owned Values (same pattern as supervisor_roster).
- rustfmt the Arc-wrapped send sites (line-width wrap only, no semantics).
No product behavior changes: whitespace + cfg(test) code only.

* style(pa-daemon): rustfmt the seed-test drain helper + clippy semicolon

One-liner receiver type per rustfmt, trailing semicolon per
clippy::semicolon_if_nothing_returned. cfg(test)-only change.

* pa-daemon: per-session subscriber registry - session events resolve delivery at publish time (TS handleWorkerFrame parity)

TS evaluates the attached predicate in the same synchronous pass that
writes the socket (daemon-supervisor.ts handleWorkerFrame l.6353; attach
flips the flag and writes session_attached in one tick, l.5586->l.5608).
The Rust ring evaluated it at RECV time in every connection event arm - a
superset in the attach/detach race window TS cannot produce (an event
published before an attach could still land after it, duplicating a row
the attach snapshot already carried).

Session events now route through a supervisor-side subscriber index
(session id -> connection id -> bounded per-connection queue): publish
enqueues to the attached set under one lock, unattached connections
never wake (the ~5.9us/session/append wakeup floor at N=100 from the
concurrent-io lane), per-(session,connection) order stays publish order,
and a full queue drops with a one-line-per-stall-cycle log (finding 4a
visibility). Broadcast / BroadcastExcept / RosterSubscribers keep the
ring; ClientRouting::AttachedSession is removed so a stale session-event
publish fails at compile time. Session events without an active session
id are dropped (TS l.6296 !activeSessionId guard), not broadcast.

The dormant supervisor/clients.rs split copy carries the same change
(re-homing at the fold will take one of the two).

* pa-daemon: fmt + clippy fixes for the subscriber registry (if-let for the single-pattern session-event relay)

* pa-daemon: fix the registry idempotency test - drain the delivered frame before the post-detach empty check

* pa-daemon: rustfmt the registry rebind call and the idempotency assert

* pa-daemon: rustfmt the registry call sites exactly as rustfmt asks

* pa-daemon: convert the zero-copy splice arm's attach push to the subscriber registry

#2897's raw-splice attach family added a SECOND attach-success push site on
the tip's routing.rs; it arrived through the fold with the old vec
semantics (the pre-fold grep could not have seen it). Same conversion as
the typed arm: registry + session list in one attach() call, the registry
insertion is the delivery boundary.

* pa-tui: the operator's touch follow-ups - the card click opens the card, the follow hint re-derives at the mode exit, the prompt bar's indicators paint on the bar (#2911)

0c526d534fcamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai: the codex dead-callback tests stage the registered port checked, not blind (settle-race hardening) (#2906)

c38824288cf2merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli: the first-run login frames render the TS login dialog (frame-parity r3) (#2845)

11365e57484dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 1/14 - the heartbeats concern moves out of src/session_ui.rs (#2886)

9f1cfc73550amerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the hover affordance - ?1003 any-event tracking delivers the buttonless motion, the hovered clickable card row brightens (muted to the theme fg, dim to muted) (#2918)

d81f3d2c7c07merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-ai/pa-agent): StreamingJsonAccumulator - stop re-parsing streamed tool-call JSON on every delta (TS #2783 port) (#2912)

dbec3a6eb0b7merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge); optional lane gate evidence: gate_1790470828_1252847 GREEN.

* pa-daemon: agent_engine.rs split 3/11 - the artifacts concern moves out of src/agent_engine.rs (#2905)

95e10f8ea95emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 2/14 - the stream concern moves out of src/session_ui.rs (#2920)

6aecfb087453merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 5/14 - the auth concern moves out of src/session_ui.rs (#2923)

70abcc702d14merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-cli/pa-daemon: implement the RPC stdio mode over the in-process session engine (TS modes/rpc parity, stub S5) (#2801)

25b657908b38merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 2/8 R2 (remediation) - the client-connection cut actually lands on the facade (#2885)

21304589206amerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli: the agents-view e2e settles its daemon-driven rows by synchronization, not a timing budget (AgentsStep::WaitRender - the registered ranked-hits render/data-arrival race closes by construction) (#2910)

f22938c1e0aamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-tui): packed cached entry layouts - scroll retention RSS -42%, byte-identical output (#2921)

* perf(pa-tui): store cached entry layouts packed - byte-exact rows, one blob + dense span records

The transcript layout cache retains every visited entry's rendered rows
for the process lifetime. A 2600-key scroll walk over the canonical 10MiB
session retained 5,428 entries' rows as 604k fragment-sized spans holding
5.2MB of text (+64.6MB heap, fully retained after return-to-tail; the
tui-scroll-retain census: 8.3 spans/line, content capacity already
exact, 44% line-buffer slack, per-span Vec/String chunk overhead the
retained mass). Merging adjacent same-style spans would shrink the
storage but changes the exit-flush inline scrollback's ANSI bytes
(per-span SGR re-emission; the exit flush is the TS-parity-frozen
output), so the cache stores the same rows packed instead: one content
blob plus dense (offset, len, style) records, expanded byte-exactly on
read - only the intersecting row range is expanded, so a frame inside a
huge entry pays its visible rows, never the whole row set. The pad
entry's own 109k-span row set (the resumed ready-state footprint) packs
the same way.

* perf(pa-tui): exact pack blob capacity + size-gated post-pack trim

The pack's blob grew by String doubling (2x capacity: 33.6MB held for a
17.45MB row set at 40MiB); the first pass now sizes it exactly. A huge
entry's rendered rows are the transcript's biggest single transient and
the pack just freed them - the freed pages only return to the OS when
the allocator's trim can reach them (the 40MiB ready RSS measured
bimodal 181/205 on the same build); the pack now returns them
immediately, gated at 8192 rows so ordinary entries never pay a trim.

* fix(pa-tui): EntryRows::is_empty for the touch surface's shows-tail peek (fold resolution completion)

The #2911 fold introduced the empty-section peek (a window that exactly
ends on the final chat entry re-checks whether any non-empty section
remains before declaring shows-tail); its section source is the
EntryRows handle since the packing fold, which needs the is_empty form.

* test(pa-tui): fix the pack tests' clippy findings (untyped Vec::new, shadowed view helper)

* test(pa-tui): drop the pack test closure's unused mut

---------

Co-authored-by: perf-tui-scroll-retain-fast <perf-tui-scroll-retain-fast@hillclimb.local>

* pa-daemon: agent_engine.rs split 2/11 - the config concern moves out of src/agent_engine.rs (#2909)

07cbb0febb74merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 4/11 - the model concern moves out of src/agent_engine.rs (#2907)

5c530e66cef9merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 3/14 - the queue concern moves out of src/session_ui.rs (#2900)

e673275046dfmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 7/8 - the update/restart concern moves out of src/supervisor.rs (#2903)

268c1fba26c0merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli: dock panel exits restore the dock's own group, not the prompt bar (operator ruling 2026-09-26) (#2864)

a12c2847335bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 5/11 - the goalcore concern moves out of src/agent_engine.rs (#2924)

c95a239b9eb3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-tui): handoff drains park on observed input, not a fixed wait - chat-to-agents -79% (#2916)

* perf(pa-tui): a handoff drain consumes buffered input instead of parking on the idle window

The chat->agents handoff teardown pays the enhanced_keys drain's fixed 50ms
DRAIN_IDLE poll on every switch (chat->agents measured 67ms p50 at #2893,
~50ms of it this window). The idle window guards a kitty key release that
lands after raw mode is off - a leak that is unreachable on a handoff: raw
mode stays on (the adopting surface's reader takes the same tty) and every
surface's dispatch drops release events (input::filter_enhanced_key_events,
TS tui.ts). The handoff now consumes what the terminal has already written
with zero-timeout polls and returns as soon as the buffer is observed empty;
only when input IS flowing does it fall through to the bounded drain, so a
burst around a handoff is coalesced exactly like before. True exits (drain,
drain_for_exit) keep the TS drainInput(1000, 50) contract untouched. Adds a
real-pty e2e that arms the kitty protocol, injects the handoff trigger's
release in flight, and audits the byte stream (no visible release, no
post-exit kitty flags, no echo after the restore).

* test(pa-cli): fix the kitty-release e2e gate lints (fmt shape, unit let-binding, unused import)

* test(pa-cli): the kitty-release mock supervisor serves every connection in turn

The chat surface holds one daemon connection and the agents view opens its own after the handoff; a single-accept mock refused the second (the first run of the e2e failed on exactly that: connection refused at run_agents_view connect).

* test(pa-cli): qualify the mock supervisor connection handler call

* test(pa-cli): handle the listener incoming result in the mock supervisor

* test(pa-cli): the kitty-release editor probe waits for the painted cell

The frame paints typed cells as styled positioned cells (escape bytes between characters), so the two-byte zz needle never appears; wait for the painted z cell instead.

* test(pa-cli): the kitty-release harness reaps the pty child on panic paths too

* test(pa-cli): the kitty-release exit drives the CSI-u escape form

With disambiguate armed a kitty terminal encodes its Esc presses as CSI 27 u; the raw lone ESC byte is the legacy form the reader arms its meta-wrapper hold for. Drive the realistic encoding and separate the exit key from the release injection.

* fix(pa-tui): the handoff drain's bounded phase runs on the budget the zero-timeout loop left

The zero-timeout consume loop can spend the whole DRAIN_MAX under
continuous input before falling through to drain_until_idle, which
then started a fresh budget - the handoff could block nearly two
seconds, past the documented one-second hard cap. The bounded phase
now runs on what remains of the original budget (Macroscope thread
PRRT_kwDOSXZbXs6mWWqM).

* perf(pa-daemon): borrow the catalog fold metadata and single-open the scan - cold scan -7%, syscalls -22% (#2919)

* perf(pa-daemon): borrow the catalog fold's entry metadata, kill the per-line tail Vec

The post-#2879/#2882 cold roster scan still typed-parsed every line into
owned strings and materialized `Value` trees for fields the fold reads
once or discards: 3 `String` allocations per line (type, id, timestamp)
plus a `Value` tree per message row (role, provider, model, timestamp) and
per session_info/state/model_change/thinking_level row. The resume tail
added one `Vec` allocation per line sized line.len()+17 to keep 16 bytes.

Both costs are gone without changing a row byte:

- SessionInfoEntry's scalar fields borrow as `Cow<str>` (zero-copy when
  unescaped, owned fallback identical to the old String), its object
  fields ride raw spans like #2882's content: each arm parses back only
  the span it reads, with exactly `Value::as_str`/`as_u64` semantics
  (present-and-string/number, absent and non-string both read None, the
  model_change abort arm keeps its exact two-step None).
- advance_tail copies inside the fixed 16-byte window: the same bytes
  (a rolling-reference lockstep test pins the old Vec semantics), no
  per-line allocation.

Differential ground truth: the new in-tree shape matrix pins every
borrowed read to the full-parse Value read per row (escaped scalars,
non-string roles/timestamps, null/absent/whitespace names, hidden/sleep
states, abort shapes) and folds the accepted rows end to end against the
legacy full-parse reference fold; the VM census ran the same differential
over 177,798 real fixture lines (100/1000/4096 tiers) with zero
divergence in acceptance, fields, or fold states both directions.

* perf(pa-daemon): share one open between the roster header gate and the fold

The roster scan opened every file twice: the bounded header gate opened,
read its first line, and closed, then the fold opened the same path again
for the scan — an openat+close per file per scan (plus the second
metadata read the fold always paid). The gate now reads the first line
from the same fresh handle the fold rewinds and scans, so one open serves
both.

The TOCTOU the double-open carried is disclosed: with two opens, a
rename/replace landing between them judged one file and folded another;
the shared handle pins the judgment and the fold to the same inode —
the fold's cursor, generation, and certification re-stat now read the
file the gate judged, never a replacement that raced in between.

The listing stat (`stats.mtime`, the `modified` fallback of last resort)
is read lazily now: the fold only reaches it when a row has neither
message timestamps nor a parseable header timestamp, so the eager
per-file stat the scan always paid serves only the rows that read it.
The `or_else` chain keeps its order and its None semantics (the
existing fallback tests pin every arm of the chain).

* pa-daemon: fmt + clippy for the catalog fold lane (test-import move, lockstep test polish, matrix lint allows)

* pa-daemon: supervisor.rs split 4/8 - the saved-session concern moves out of src/supervisor.rs (#2883)

9f9146b74371merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the #2921 review follow-ups - RowPack::pack refuses unrepresentable entries, the huge-entry trim drops the expanded rows first (fold of rust 9b62f26af) (#2925)

df34ea19dbb3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 10/14 - the bash concern moves out of src/session_ui.rs (#2928)

481b2f28553cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* skills/prime-intellect: sync vendored sandbox docs to the VM-only surface (TS #2456 doc half) (#2751)

a4e997e2e803merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* fix(pa-cli): remove the duplicated restore_dock_focus initializer the #2751 squash double-applied

The #2751 squash (1a9fd16b9) landed the heal rider line onto a tip that
already carried the identical line from #2925 (e6e7a26e4) - the squash
applied the stale pre-fold diff, duplicating the field (E0062). This
restores the fixture to the parent 84dbb51e0 state (exactly one field).
The label rider and the docs in the same squash are intended and stay.

* pa-daemon: agent_engine.rs split 7/11 - the SessionEngine trait impl moves out whole (#2926)

2b07a22bd1d3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core + runtime: the harness-digest family - IDF-ranked digest/search, state-fingerprint staleness, newest-only digest contexts, validated kernel harness writes (TS #2392/#2400/#2394/#2463 parity) (#2750)

bff9fa6ff122merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* fix(pa-cli): the kitty handoff e2e fixture initializes restore_dock_focus (#2927)

962ff3097575merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 7/14 - the settings concern moves out of src/session_ui.rs (#2930)

fd71eaf2dfeamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 6/14 - the model-picker concern moves out of src/session_ui.rs (#2929)

2038abcf5754merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon/pa-cli: ACP model and effort pickers - configOptions at session/new, session/set_config_option, config_option_update (TS #2455) (#2758)

fd977cb13ee6merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core): consolidate auth-lock reads - 36 lock cycles per first turn to 2, settings mutex closes the unmasked stall class (#2932)

* perf(pa-core): consolidate auth-document reads through a validated cache

* perf(pa-core): serialize same-process settings-lock holders (the #2915 pattern)

The auth read-through cache on this lane unmasks a pre-existing stall:
two worker threads racing the same settings.json pay the full TS
10x20ms retry sleep against each other (strace-verified: mkdir
attempts 11us apart, the loser clock_nanosleeps the full 20ms; the
paired census shows same-process overlapping settings acquisitions 2
on the base and 5 with the auth cache, sleep20 1 vs 2, and the timing
legs pay a ~20ms-class stall on 3/6 fresh turns vs 0/6 base). The
auth-lock cycles 150-300us same-process serialization was pacing the
threads apart by accident; that masking is not a mechanism to keep.

TS runs its synchronous settings lock single-threaded, so same-process
settings contention is a Rust-port artifact, the exact class #2915
ruled on for the auth lock: a process-local mutex keyed by the
document path serializes same-process callers for the microseconds
the small read/modify/write holds. The file protocol, staleness
judgment, and retry semantics are untouched: a foreign holder
(another process) still surfaces WouldBlock and still takes the
10x20ms retry. The mutex is a leaf (the locked section performs only
the document's own filesystem operations plus the caller's update
callback; no settings callback re-enters with_lock - every callback
is a pure JSON transform), and poisoning is recovered because the
file protocol is the correctness mechanism.

---------

Co-authored-by: perf-auth-lock-fast <hillclimb@prime-intellect.ai>

* perf(pa-daemon): zero-copy worker response path - routed msgs -17%, attach -22%, worker RSS -20% (#2935)

* perf(pa-daemon): zero-copy worker response handoff - serialize the line from the borrowed trees, write the frame without re-buffering the payload

* fmt(pa-types): the segments test write_frame call in the form CI rustfmt wants

* fmt(pa-daemon): the response-path call forms CI rustfmt wants (VM cargo fmt at the exact head)

* fix(pa-daemon): restore the response_line TS-key-order test the new-test insert orphaned (clippy empty_line_after_doc_comments was the symptom)

* fmt(pa-daemon): the restored test doc comment indent

* fmt(pa-daemon): single trailing newline at file end

---------

Co-authored-by: wc <wc@fleet.local>

* pa-daemon: agent_engine.rs split 6/11 - the Turn types move out of src/agent_engine.rs (#2931)

b2ca4deea5afmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): batch the queue-checkpoint journal pair - 4 syncs per warm turn to 2, crash window strictly narrowed (#2936)

* perf(pa-daemon): batch the queue-checkpoint journal pair into one durable append

The queue checkpoint (prompt/steer/follow-up admission, turn settle, queue
mutations) appends two records to the worker recovery journal - the queue
snapshot and the busy/operation verdict - as two separate open+write+fsync
cycles, paying two journal flushes per checkpoint. Both records describe
one atomic checkpoint, and the busy verdict must never publish over a
snapshot that did not persist, so the pair can ride ONE open+write+fsync:
the batch is all-or-nothing durable, the on-disk line order matches the
sequential form exactly (snapshot first, then the verdict), and an
unchanged verdict keeps appending the snapshot alone.

Measured on the warm-turn admission path (the wave-5 warm-durable-append
decomposition): the two journal fsyncs sit inside the TUI-ack-to-user-row
phase together with the session append's fdatasync; batching removes one
of the three durable syncs per warm turn without weakening any durability
guarantee (the session append's per-row fdatasync is untouched).

* test: rustfmt the batched-checkpoint test call sites (gate fmt finding)

* fix(pa-tui): the exit watchdog holds fire while the flush drains - healthy slow drains no longer truncate scrollback, TS-convergent (#2937)

* perf(pa-tui): the exit guard holds its force-quit while the exit path drains - slow terminals keep the whole scrollback flush

On a terminal that consumes the exit flush slowly (a laggy ssh at
~0.5-2MB/s), the flush of a large transcript outlasts the 1500ms
FORCE_QUIT_AFTER_MS deadline that arms at the second Ctrl+C, and the
watchdog fires mid-flush: strace shows its restore writes winning the
pty FIFO race at a flush-chunk boundary, exit_group(0) landing while the
writer still holds ~64-82% of the transcript (40k rows: 8.74MB flush
truncated to 1.5-3.1MB), 'shutdown stalled; forced exit.' printing on a
healthy drain, and the restore bytes queueing mid-stream behind the
flushed rows. TS has no watchdog at all (its handleCtrlC second press
runs the async shutdown, and slow writes simply wait), so both the
message and the truncation are port-only.

The guard becomes drain-aware: the flush writer reports progress per
completed 32KiB chunk (view.rs FlushSink), the release tail and the
resume hint report theirs, and the watchdog holds its fire while
progress landed within EXIT_PROGRESS_GRACE_MS (500ms) - the hard 1500ms
ceiling stays for the silent case (the wedged loop the guard was built
for). Flush chunks shrink 256KiB -> 32KiB so a drain of at least
~65KB/s completes chunks inside the grace window; the flush byte stream
is unchanged (the exit-flush lane's byte-identity oracle). The truncated
scrollback contract is restored on slow drains: the flush completes
byte-identically, the release tail lands after the last row, and the
message prints only for a genuinely stalled drain.

The exit-guard unit tests grow the hold/fire decision table; a new
real-pty e2e (pa-cli slow_drain_exit_guard_e2e, the kitty-release
harness pattern) drives the real chat surface over a paced pty master
and asserts both sides: a draining terminal flushes the whole
transcript with no forced exit, and a stalled drain still fires.

Rider (disclosed): kitty_release_handoff_e2e grows the restore_dock_focus
field the #2916 squash dropped from its fold-time heal - the tip's
pa-cli test target does not compile without it.

* test(pa-cli): the slow-drain e2e asserts the forced fire structurally

The re-executed test binary's libtest harness captures stderr per
test, so the watchdog's 'shutdown stalled' line never reaches the pty
in the harness child (the real binary writes it to fd 2 - the lane's
VM bench legs assert it there). The stalled-drain leg instead asserts
the forced exit structurally: the forced restore's own alt-screen
leave lands on top of the exit path's (a clean exit leaves it exactly
once), the flush never reaches the transcript tail (one copy of the
last user row, the startup viewport's), and the process dies with the
guard's exit code inside the stall window. Harness needles use the
user-message rows (assistant rows carry per-word SGR spans) and the
post-exit drain reads the pty's kernel-held bytes before asserting.

* fmt: the slow-drain e2e needles and the watchdog's progress read

* clippy: doc backticks + checked Duration subtraction in the guard tests; the e2e's needle check takes the direct is_none

---------

Co-authored-by: perf-slowdrain-exitguard-fast <lane@hillclimb.local>

* perf(pa-core): consolidate settings-lock reads - 32 lock cycles per first turn to 2 (#2941)

* pa-ai/pa-core/pa-cli/pa-tui: grok-4.7 on every serving surface (TS #2505) + Claude Code 2.1.281 + Anthropic subscription ban-risk warning (TS #2645) + one owner for the Prime team header, retry failed !command credentials (TS #2497) (#2755)

7373eb471670merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-cli): the interactive_daemon_e2e wedge root-kill - PDEATHSIG + orphan sweep + the 300s headless wall (#2942)

dbed1170fa2bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli/pa-daemon: session opens wait through a daemon update restart (TS #2391) + the failed-restart hint (TS #2515) (#2763)

e7a84e749089merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): the all-idle compaction fires like TS and rides the TS compact sync class - journals bounded (#2944)

* perf(pa-daemon): settle-tail compact consolidation - the all-idle compaction fires like TS and rides the TS compact sync class

The worker recovery journal's all-idle gate ran BEFORE the record insert,
so a single-session journal's own busy admission record blocked every
settle's compaction: the compact never fired on the dominant shape and
the journal grew append-only for the session's lifetime (TS computes the
gate POST-insert and compacts at every changed-idle record). The gate now
matches TS, bounding the file.

Where the compact fires, its temp sync_all was a sync class TS's compact
does not pay (TS worker-recovery-journal: writeFileSync + renameSync, no
fsync; the command journal's writeFileAtomicSync counterpart does carry
fsync). The Finalize seam now encodes the sync class per owner: RetryBusy
keeps its fsync (command journal), Synced keeps the Rust-native
terminal-compaction journal's belt, and Bare is the TS worker shape -
temp write + rename, no fsync. Durability is owned by the append path
(the fresh-write class is untouched): the compacted form holds only
records the append path already made durable, so a lost compact falls
back to the append-only history, which replays identically.

* test-only rustfmt of the new test call site (the gate's one fmt finding)

* runtime/kernel: vendored-runtime hardening + kernel stderr owner-only (TS #2372/#2423/#2500/#2471/#2478/#2425 parity) (#2744)

ea5abd1bbe1bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 11/14 - the prompt submit pipeline moves out of src/session_ui.rs (#2943)

3bafbc007b74merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-tui): 8-byte packed span records with per-pack style table - scroll retention -7.5MB, byte-identical output (#2939)

* perf(pa-tui): denser packed span records - style table + derived offsets (8B/span), byte-exact range expansion

* test(pa-tui): rustfmt the exhaustive row-pack range oracle

* fix(pa-tui): clippy - if-let style dedup + drop redundant test clones

* pa-tui: fix the submit-outlived-by-switch idle-gate race - the turn-end watermark restarts with the mounted stream (#2945)

c661290b1b77merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: hold spawn-name reservations until admission is durable; collect returns cancelled envelopes for just-deleted targets (TS #2396 + #2388 F4) (#2757)

18aa772bd3b2merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai/pa-core/pa-daemon: codex stale-chain retry after metadata (TS #2374) + safety failures permanent (TS #2472) + quota park until reset with auto-resume (TS #2375) (#2761)

dc9892ffbc1emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-tui): the headless settle bound names its stuck member in 60s - defense-in-depth inside the wedge wall (#2949)

The interactive_daemon_e2e exit-gate wedge family is root-killed
upstream (#2945: the turn-end watermark restarts with the mounted
stream) and the harness carries the 300s wall (#2942). This closes the
remaining gap: the headless settle was the run loop's only unbounded
wait on the product side — a settle member that never drains parked the
run forever with no failure name (TS exits the process at shutdown and
lets in-flight work dangle, so the settle has no TS counterpart).

The gate's twelve settle members are now snapshotted (HeadlessSettle:
settled() is the old gate exactly; blockers() names them), and after
the plan completes a stuck member fails the run within
HEADLESS_SETTLE_TIMEOUT_MS (60s) with the member named — e.g. 'a turn
still active' — instead of waiting out the harness's 300s wall with a
generic timeout. Green settles are milliseconds after HeadlessDone
(the suite's green wall is ~15s; the last submit's own ack bound is
10s), and terminal runs never arm the bound (HeadlessDone exists only
on the headless harness; a live terminal ends the run on
exit_requested + the exit guard).

Proven end-to-end by the lane's matrix: the wedge converted to a 98.4s
attributable red naming the latched member (the bound-only diagnostic
arm), and the full candidate stayed clean at 30/30 interleaved trials
vs 3/30 wedges at the lane parent (record
20260927-085200-interaction-exit-gate-hang-remediation, bench
hillclimb).

* perf(pa-daemon/rpc): warm the model registry at RPC session boot - first get_available_models 1170.6ms to 58.9ms (#2953)

TS session boot resolves the initial model through refreshAvailableModels
(model-resolver.ts), which also fetches the live Prime Inference catalog
in the background and caches it on disk; the daemon worker fires the same
fire-and-forget refresh from its create path (worker/create.rs). The RPC
mode hosts the session in-process with no create command, so nothing
warmed the caches: an integration's FIRST get_available_models call paid
the whole awaited refresh chain on its response path (measured 812-1296ms
on the bench VM; the 15s fetch-timeout worst case on a degraded network)
while the same command on the daemon and ACP surfaces answers from the
validated snapshot. Mirror the daemon worker boot spawn: the caches warm
during the session's first turn, and the first call serves the same
snapshot. Write behavior is unchanged: the same cache files, the same
write-on-fetch-success conditions, the same cadence (hour-gated catalog
refresh, 5-min private-authorization TTL), only started at boot.

Co-authored-by: perf-rpc-models-persist <lane@hillclimb>

* pa-tui: session_ui.rs split 4/14 - the share concern moves out of src/session_ui.rs (#2922)

b0d72b29a700merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 8/11 - the turn-execution impl moves out (#2934)

a59d3389dfbamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 5/8 - the worker-lifecycle concern moves out of src/supervisor.rs (#2956)

205f4d0f469cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 8/14 - the sessions concern moves out of src/session_ui.rs (#2957)

7d19e9832120merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 6/8 - the signals concern moves out (#2960)

a6562bc252efmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 10/11 - the lifecycle concern moves out of src/agent_engine.rs (#2962)

17d3573c5a58merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 12/14 - the keys concern moves out of src/session_ui.rs (#2958)

bc6b7d82cb0bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 11/11 - the facade trim: the last product free fns move out; the file ends as the composition root (#2964)

1fe6a6791030merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 8/8 - the facade trim: the notes concern moves out, the test battery re-homes (#2963)

8a5274baa0d9merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 9/14 - the panels concern moves out of src/session_ui.rs (#2961)

377eda9ded15merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 13/14 - the apply concern moves out of src/session_ui.rs (#2965)

c10a44e407cdmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: cap kernel host-request cell source at 2 KiB (the TS #2475 port) (#2966)

96f689fc38femerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the /model picker resolves by provider, never the first same-id catalog entry (fixes the operator report) (#2967)

24411964739emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 14/14 - the facade trim: the file ends as the composition root (#2968)

60cbb4fbb642merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core): the oauth refresh leaves the auth lock - fetch under single-flight, hold-sum 396ms to 0.09ms (#2971)

An expired stored OAuth credential refreshes its token inside
AuthStorageBackend::with_lock: the OAuthIntegration seam is synchronous
by contract, so the network round trip runs under the document lock AND
under the process mutex that spans the whole critical section, stalling
every other same-process auth read and write for the fetch (the RPC
cycle_model path measured 194-201ms auth.json.lock holds per switch on
the bench VM; the assembly read pays one ~0.2ms cycle, the switch pays
the fetch).

The TS product holds its own lock across the same await
(refreshOAuthTokenWithLock -> withLockAsync), but its single-threaded
runtime never blocks other work on it; this engine is threaded, so the
port narrows the lock scope instead: load-then-lock. The document loads
through the consolidated read arm, the token fetch runs outside every
lock behind a per-provider single-flight gate (the in-process
serialization TS gets from its single-threaded runtime, with the expiry
re-checked under the gate so a second caller never spends a single-use
refresh token after the first flight landed), and the write re-enters
the same locked read-modify-write protocol - now held only for the
re-read, insert, and atomic write, and skipping the write entirely when
a peer refreshed while the fetch ran. File protocol, read results, and
every resolution outcome are unchanged.

* pa-daemon: the supervisor roster broadcasts only on content change (the TS #2481 port P3) (#2974)

054553b8ca12merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-cli/pa-tui: prime-agent update - the TS->Rust migration path (uninstall TS, install Rust, sessions preserved) (#2981)

739ed7f7d015merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core/pa-daemon): a settled RLM child releases its kernel at the settle park - ~27MB reclaimed per settled child, TS #2483 port (#2983)

* perf(pa-core/pa-daemon): a settled RLM child releases its kernel at settle - snapshot-flushing stop_kernel, revivable (TS #2483)

The rust port of the stale perf PR #2483's inline arm (the supersession
analysis: the not-superseded claim - settled children hold a worker and
a kernel until parent close; nothing at the tip releases them; the
daemon-mode whole-worker passivation stays deferred to the orchestrator):

- IpythonKernelProvisioner::stop_kernel (TS stopKernel): shuts the owned
  kernel down with a final namespace snapshot WITHOUT marking the
  provisioner disposed; a kernel still starting up is joined first and
  shut down the same way (the TS managerPromise arm). The stop records a
  pending-stop gate (TS pendingStop) that the next start_kernel_impl
  awaits before reading the snapshot back, so a follow-up turn's fresh
  boot revives the flushed namespace instead of racing the flush; a
  completed stop awaits instantly and each stop supersedes the previous
  (a clonable watch receiver: multiple revival waiters gate on it).
- The session engine gains stop_kernel_snapshot (the TS
  stopKernel({snapshot:true}) seam beside dispose_kernel), and the
  SessionEngine trait gains release_settled_child_kernel (default no-op):
  the AgentSessionEngine arm evaluates the canPassivateSettledSession
  gates engine-side - no unsettled descendants (has_unsettled_rlm_work),
  no registered cron/heartbeat jobs (a worker-wired probe over the shared
  cron store) - then fires the per-build release probe (a weak
  provisioner reference, the background-bash-probe adoption pattern,
  cleared on retire/close).
- The turn runner's park arm fires it best-effort when the worker core
  proves the parent-owned, unattached, unqueued idle state (rlm_depth>0,
  no attached clients, not compacting, no lane work - the park arm's
  own construction). The divergence the port discloses: rust children
  are worker processes (the parent has no in-process reach and the wire
  is frozen), so the release triggers at the child's own idle park
  instead of the TS parent's run-settle hook - the same revivability
  semantics (the next kernel use boots fresh from the flushed snapshot),
  and the roster/collect surfaces are untouched by design.

Tests: the provisioner stop flushes the snapshot and the next ensure
revives the namespace (live-kernel, ambient-venv-gated); the park arm's
policy matrix (a parent-owned child releases, a root/attached/compacting
session stays resident); the engine gates (a registered-jobs probe
defers the release, the probe fires otherwise).

* test(pa-daemon): the park-arm release test waits on observable readiness (the review advisories)

Two BUGBOT test advisories on the first review: the park-arm test's
bounded poll used fixed sleeps (a retry-to-green readiness wrapper). The
recording engine now notifies on every release fire, so the test waits
for the observable readiness - the notification is the pass condition,
the bounded timeout is only the failure bound for the positive arm and
the absence bound for the gated arms (no fixed sleep ever makes a pass).

The commit also lands the VM's cargo fmt output on the touched files
(the first commit's hand-written formatting failed the review's fmt
pre-flight: the lane builds on the VM only, and the formatted sources
must sync back before every commit).

* perf(pa-core): provider auth answers once per provider - the #2479 memoization ports, per-model probe -66% (#2973)

* perf(pa-core): provider auth answers once per provider and the private PI authorization cache parses once per file identity (TS #2479)

The rust port of the four unclaimed mechanisms of the stale perf PR #2479
(the supersession analysis: the rest of that PR's premise landed via
#2932's storage read-cache):

- get_available's per-model has_configured_auth becomes a per-provider
  memo: the catalog walks hundreds of models over a few dozen providers
  and each probe rebuilds the provider's auth-source candidates, while a
  same-registry probe is stable by construction (&self, no mutation
  between models). TS getAvailable's authByProvider map.
- get_rlm_searchable_models' per-model get_auth_status becomes the same
  per-provider memo (TS _authenticatedRlmModels' selectableByProvider).
- read_private_prime_authorization_cache serves from a process-wide
  stat-identity snapshot (dev/ino/mtime_ns/len, the TS
  CatalogFileIdentity) while the file is unchanged; the port builds a
  fresh registry per resolution touchpoint (the TS session kept one
  long-lived registry), so the parse would otherwise re-run on every
  resolution. Only a successful parse bracketed by one identity is
  pinned, a failed read unpins (retries), and the write path's atomic
  rename supersedes (new identity).
- AuthStorage memoizes auth-source candidates keyed by the hashed
  material itself (TS authCandidateMemos): reuse skips only the SHA-256
  work, env values are deliberately re-read on every call, command
  values resolve before the memo, and stale checks run against the
  memoized candidate (candidates are immutable).

Tests: the per-provider status memo gates one stale provider across all
its models while a second authed provider keeps its models; the
private-cache snapshot pins stable parses, re-parses rewrites, and never
pins a failed read or resurrects a deleted file; the candidate memos
supersede exactly when the hashed material changes (a stale marking from
an old value never gates a changed one).

* test(pa-core): the stale-provider memo test asserts the tip's stale-aware has_auth

The memo regression test claimed a stale-marked provider's models stay in
get_available ("stale is only the searchable-set's gate") - but
AuthStorage::has_auth is stale-aware at the tip (available_candidate
skips candidates matching a marked stale token), so get_available gates
the stale provider too, and the tip's get_rlm_searchable_models gates it
twice over. The memo preserves exactly those semantics; assert them: the
stale provider is gated across all its models from BOTH sets, and a second
authed provider keeps its models. Discovered by the full-suite fleet gate
(gate_1790546015_945232) - the lane's local legs had not run the test
suite; the three other gate reds (kernel_restore_guards x2,
tui_prime_login_escape) are SOLO-GREEN on the exact head content
(co-scheduling class, the standing family from gate_1790531716).

* test(pa-core): behavior-focused wording in the candidate-memo test comments (the review advisory)

The BUGBOT history-narration advisory asked for comments that state the
current behavior rather than the sequence of edits: the env-change arm
now says what the memo key does (a changed value changes the key, so the
rebuilt candidate's value fingerprint differs from the stale token's) and
the return arm says the marked material's candidate re-serves when its
value returns.

* pa-cli/docs: the update fetch source flips to the official domain at the rust-to-main merge (#2984)

309dd96b1f96merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: agents_view.rs split stages 1-2 - the test mass re-homes + the delete concern moves out (#2985)

bd221cb5e70amerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): saved_session_context reads windowed-first - worker resume CPU -140ms, the parse signature (#2969)

* perf(pa-daemon): windowed-first saved_session_context - the create-path model restore reads the windowed store (restored_settings + has_thinking_level) instead of full-parsing the session history; open_windowed's full-open fallback keeps unsupported/malformed files identical; differential oracle keeps the pre-change full-parse reader as the reference across no-boundary/in-window/model-only-before/thinking-only-before/malformed-prefix fixture classes

* perf(pa-daemon): address the Bugbot findings on the windowed saved_session_context - comments describe current behavior only, the oracle helper returns the owned TempDir so fixture scratch trees clean up at test scope end

---------

Co-authored-by: perf-launch-open-fast <hillclimb@primeintellect.ai>

* pa-core: compact_session.rs split - the tests re-home + the summarization, anchor-selection, and boundary cuts (#2987)

f43aebc9c50dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: agents_view.rs split stage 3 - the render concern moves out (#2988)

03a6fcc07793merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* install: the Rust port takes over the prime-agent keyword - clean TS daemon shutdown, config preserved (#2972)

737e52dc7695merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: the scheduling catalog fans out per-worker (the TS port P4) (#2979)

1e78bb715fddmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: agents_view.rs split stage 4 - the open + incident concerns move out (#2991)

0ef076a06131merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: session_store.rs split - the index, read, write, view, info, tests children (#2990)

7b58b0acb457merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: agents_view.rs split stage 5 - the data + input concerns move out; the file ends as the composition root (#2992)

cadb8b4f33d6merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* docs: the README becomes the Rust product's own; the port-process docs are removed (#2993)

fe891d188ad0merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: snapshot.rs split stages 1-2 - the test mass re-homes + the tool-fold concern moves out (#2995)

eaa4b672f2f8merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: snapshot.rs split stage 3 - the decoder concern moves out; the file ends as the composition root (#2996)

1564648986edmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: rlm_children.rs split - the composition root (host, lifecycle, usage, registry, tests) (#2997)

4ee722d403b6merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: interactive.rs split - the tests, onboarding, headless, render, reconnect, run children (#2998)

d592a0672d5dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): share the open's artifacts + skip the depth scan's full parse (cold-open-residual) (#2970)

5b75513ff7fbmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: every session-exit route restores the terminal - the kitty-mode leak into the shell is fixed (#3001)

8f84a46233cdmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-cli: the family-seeding e2e spawns pin the daemon's session dir (the flash e2e's seeded-family red) (#3003)

c54ff2a09a84merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: undo the condensed activity runs - the collapse mode becomes details mode minus thinking blocks (#2999)

a6d8414d818cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-cli: print_boundary.rs split - the 4 stages: events, compaction_arms, autorefine, tests (#2989)

2292af8f1cefmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: bash_view.rs split - under 1,000 lines (#3008)

15d9c1a659efmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: auth_panel.rs split - under 1,000 lines (#3009)

8c3061a5db29merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pi…
snimu added a commit that referenced this pull request Oct 2, 2026
* pa-tui: session_ui.rs split 10/14 - the bash concern moves out of src/session_ui.rs (#2928)

481b2f28553cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* skills/prime-intellect: sync vendored sandbox docs to the VM-only surface (TS #2456 doc half) (#2751)

a4e997e2e803merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* fix(pa-cli): remove the duplicated restore_dock_focus initializer the #2751 squash double-applied

The #2751 squash (1a9fd16b9) landed the heal rider line onto a tip that
already carried the identical line from #2925 (e6e7a26e4) - the squash
applied the stale pre-fold diff, duplicating the field (E0062). This
restores the fixture to the parent 84dbb51e0 state (exactly one field).
The label rider and the docs in the same squash are intended and stay.

* pa-daemon: agent_engine.rs split 7/11 - the SessionEngine trait impl moves out whole (#2926)

2b07a22bd1d3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core + runtime: the harness-digest family - IDF-ranked digest/search, state-fingerprint staleness, newest-only digest contexts, validated kernel harness writes (TS #2392/#2400/#2394/#2463 parity) (#2750)

bff9fa6ff122merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* fix(pa-cli): the kitty handoff e2e fixture initializes restore_dock_focus (#2927)

962ff3097575merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 7/14 - the settings concern moves out of src/session_ui.rs (#2930)

fd71eaf2dfeamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 6/14 - the model-picker concern moves out of src/session_ui.rs (#2929)

2038abcf5754merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon/pa-cli: ACP model and effort pickers - configOptions at session/new, session/set_config_option, config_option_update (TS #2455) (#2758)

fd977cb13ee6merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core): consolidate auth-lock reads - 36 lock cycles per first turn to 2, settings mutex closes the unmasked stall class (#2932)

* perf(pa-core): consolidate auth-document reads through a validated cache

* perf(pa-core): serialize same-process settings-lock holders (the #2915 pattern)

The auth read-through cache on this lane unmasks a pre-existing stall:
two worker threads racing the same settings.json pay the full TS
10x20ms retry sleep against each other (strace-verified: mkdir
attempts 11us apart, the loser clock_nanosleeps the full 20ms; the
paired census shows same-process overlapping settings acquisitions 2
on the base and 5 with the auth cache, sleep20 1 vs 2, and the timing
legs pay a ~20ms-class stall on 3/6 fresh turns vs 0/6 base). The
auth-lock cycles 150-300us same-process serialization was pacing the
threads apart by accident; that masking is not a mechanism to keep.

TS runs its synchronous settings lock single-threaded, so same-process
settings contention is a Rust-port artifact, the exact class #2915
ruled on for the auth lock: a process-local mutex keyed by the
document path serializes same-process callers for the microseconds
the small read/modify/write holds. The file protocol, staleness
judgment, and retry semantics are untouched: a foreign holder
(another process) still surfaces WouldBlock and still takes the
10x20ms retry. The mutex is a leaf (the locked section performs only
the document's own filesystem operations plus the caller's update
callback; no settings callback re-enters with_lock - every callback
is a pure JSON transform), and poisoning is recovered because the
file protocol is the correctness mechanism.

---------

Co-authored-by: perf-auth-lock-fast <hillclimb@prime-intellect.ai>

* perf(pa-daemon): zero-copy worker response path - routed msgs -17%, attach -22%, worker RSS -20% (#2935)

* perf(pa-daemon): zero-copy worker response handoff - serialize the line from the borrowed trees, write the frame without re-buffering the payload

* fmt(pa-types): the segments test write_frame call in the form CI rustfmt wants

* fmt(pa-daemon): the response-path call forms CI rustfmt wants (VM cargo fmt at the exact head)

* fix(pa-daemon): restore the response_line TS-key-order test the new-test insert orphaned (clippy empty_line_after_doc_comments was the symptom)

* fmt(pa-daemon): the restored test doc comment indent

* fmt(pa-daemon): single trailing newline at file end

---------

Co-authored-by: wc <wc@fleet.local>

* pa-daemon: agent_engine.rs split 6/11 - the Turn types move out of src/agent_engine.rs (#2931)

b2ca4deea5afmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): batch the queue-checkpoint journal pair - 4 syncs per warm turn to 2, crash window strictly narrowed (#2936)

* perf(pa-daemon): batch the queue-checkpoint journal pair into one durable append

The queue checkpoint (prompt/steer/follow-up admission, turn settle, queue
mutations) appends two records to the worker recovery journal - the queue
snapshot and the busy/operation verdict - as two separate open+write+fsync
cycles, paying two journal flushes per checkpoint. Both records describe
one atomic checkpoint, and the busy verdict must never publish over a
snapshot that did not persist, so the pair can ride ONE open+write+fsync:
the batch is all-or-nothing durable, the on-disk line order matches the
sequential form exactly (snapshot first, then the verdict), and an
unchanged verdict keeps appending the snapshot alone.

Measured on the warm-turn admission path (the wave-5 warm-durable-append
decomposition): the two journal fsyncs sit inside the TUI-ack-to-user-row
phase together with the session append's fdatasync; batching removes one
of the three durable syncs per warm turn without weakening any durability
guarantee (the session append's per-row fdatasync is untouched).

* test: rustfmt the batched-checkpoint test call sites (gate fmt finding)

* fix(pa-tui): the exit watchdog holds fire while the flush drains - healthy slow drains no longer truncate scrollback, TS-convergent (#2937)

* perf(pa-tui): the exit guard holds its force-quit while the exit path drains - slow terminals keep the whole scrollback flush

On a terminal that consumes the exit flush slowly (a laggy ssh at
~0.5-2MB/s), the flush of a large transcript outlasts the 1500ms
FORCE_QUIT_AFTER_MS deadline that arms at the second Ctrl+C, and the
watchdog fires mid-flush: strace shows its restore writes winning the
pty FIFO race at a flush-chunk boundary, exit_group(0) landing while the
writer still holds ~64-82% of the transcript (40k rows: 8.74MB flush
truncated to 1.5-3.1MB), 'shutdown stalled; forced exit.' printing on a
healthy drain, and the restore bytes queueing mid-stream behind the
flushed rows. TS has no watchdog at all (its handleCtrlC second press
runs the async shutdown, and slow writes simply wait), so both the
message and the truncation are port-only.

The guard becomes drain-aware: the flush writer reports progress per
completed 32KiB chunk (view.rs FlushSink), the release tail and the
resume hint report theirs, and the watchdog holds its fire while
progress landed within EXIT_PROGRESS_GRACE_MS (500ms) - the hard 1500ms
ceiling stays for the silent case (the wedged loop the guard was built
for). Flush chunks shrink 256KiB -> 32KiB so a drain of at least
~65KB/s completes chunks inside the grace window; the flush byte stream
is unchanged (the exit-flush lane's byte-identity oracle). The truncated
scrollback contract is restored on slow drains: the flush completes
byte-identically, the release tail lands after the last row, and the
message prints only for a genuinely stalled drain.

The exit-guard unit tests grow the hold/fire decision table; a new
real-pty e2e (pa-cli slow_drain_exit_guard_e2e, the kitty-release
harness pattern) drives the real chat surface over a paced pty master
and asserts both sides: a draining terminal flushes the whole
transcript with no forced exit, and a stalled drain still fires.

Rider (disclosed): kitty_release_handoff_e2e grows the restore_dock_focus
field the #2916 squash dropped from its fold-time heal - the tip's
pa-cli test target does not compile without it.

* test(pa-cli): the slow-drain e2e asserts the forced fire structurally

The re-executed test binary's libtest harness captures stderr per
test, so the watchdog's 'shutdown stalled' line never reaches the pty
in the harness child (the real binary writes it to fd 2 - the lane's
VM bench legs assert it there). The stalled-drain leg instead asserts
the forced exit structurally: the forced restore's own alt-screen
leave lands on top of the exit path's (a clean exit leaves it exactly
once), the flush never reaches the transcript tail (one copy of the
last user row, the startup viewport's), and the process dies with the
guard's exit code inside the stall window. Harness needles use the
user-message rows (assistant rows carry per-word SGR spans) and the
post-exit drain reads the pty's kernel-held bytes before asserting.

* fmt: the slow-drain e2e needles and the watchdog's progress read

* clippy: doc backticks + checked Duration subtraction in the guard tests; the e2e's needle check takes the direct is_none

---------

Co-authored-by: perf-slowdrain-exitguard-fast <lane@hillclimb.local>

* perf(pa-core): consolidate settings-lock reads - 32 lock cycles per first turn to 2 (#2941)

* pa-ai/pa-core/pa-cli/pa-tui: grok-4.7 on every serving surface (TS #2505) + Claude Code 2.1.281 + Anthropic subscription ban-risk warning (TS #2645) + one owner for the Prime team header, retry failed !command credentials (TS #2497) (#2755)

7373eb471670merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-cli): the interactive_daemon_e2e wedge root-kill - PDEATHSIG + orphan sweep + the 300s headless wall (#2942)

dbed1170fa2bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-cli/pa-daemon: session opens wait through a daemon update restart (TS #2391) + the failed-restart hint (TS #2515) (#2763)

e7a84e749089merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): the all-idle compaction fires like TS and rides the TS compact sync class - journals bounded (#2944)

* perf(pa-daemon): settle-tail compact consolidation - the all-idle compaction fires like TS and rides the TS compact sync class

The worker recovery journal's all-idle gate ran BEFORE the record insert,
so a single-session journal's own busy admission record blocked every
settle's compaction: the compact never fired on the dominant shape and
the journal grew append-only for the session's lifetime (TS computes the
gate POST-insert and compacts at every changed-idle record). The gate now
matches TS, bounding the file.

Where the compact fires, its temp sync_all was a sync class TS's compact
does not pay (TS worker-recovery-journal: writeFileSync + renameSync, no
fsync; the command journal's writeFileAtomicSync counterpart does carry
fsync). The Finalize seam now encodes the sync class per owner: RetryBusy
keeps its fsync (command journal), Synced keeps the Rust-native
terminal-compaction journal's belt, and Bare is the TS worker shape -
temp write + rename, no fsync. Durability is owned by the append path
(the fresh-write class is untouched): the compacted form holds only
records the append path already made durable, so a lost compact falls
back to the append-only history, which replays identically.

* test-only rustfmt of the new test call site (the gate's one fmt finding)

* runtime/kernel: vendored-runtime hardening + kernel stderr owner-only (TS #2372/#2423/#2500/#2471/#2478/#2425 parity) (#2744)

ea5abd1bbe1bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 11/14 - the prompt submit pipeline moves out of src/session_ui.rs (#2943)

3bafbc007b74merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-tui): 8-byte packed span records with per-pack style table - scroll retention -7.5MB, byte-identical output (#2939)

* perf(pa-tui): denser packed span records - style table + derived offsets (8B/span), byte-exact range expansion

* test(pa-tui): rustfmt the exhaustive row-pack range oracle

* fix(pa-tui): clippy - if-let style dedup + drop redundant test clones

* pa-tui: fix the submit-outlived-by-switch idle-gate race - the turn-end watermark restarts with the mounted stream (#2945)

c661290b1b77merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: hold spawn-name reservations until admission is durable; collect returns cancelled envelopes for just-deleted targets (TS #2396 + #2388 F4) (#2757)

18aa772bd3b2merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai/pa-core/pa-daemon: codex stale-chain retry after metadata (TS #2374) + safety failures permanent (TS #2472) + quota park until reset with auto-resume (TS #2375) (#2761)

dc9892ffbc1emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-tui): the headless settle bound names its stuck member in 60s - defense-in-depth inside the wedge wall (#2949)

The interactive_daemon_e2e exit-gate wedge family is root-killed
upstream (#2945: the turn-end watermark restarts with the mounted
stream) and the harness carries the 300s wall (#2942). This closes the
remaining gap: the headless settle was the run loop's only unbounded
wait on the product side — a settle member that never drains parked the
run forever with no failure name (TS exits the process at shutdown and
lets in-flight work dangle, so the settle has no TS counterpart).

The gate's twelve settle members are now snapshotted (HeadlessSettle:
settled() is the old gate exactly; blockers() names them), and after
the plan completes a stuck member fails the run within
HEADLESS_SETTLE_TIMEOUT_MS (60s) with the member named — e.g. 'a turn
still active' — instead of waiting out the harness's 300s wall with a
generic timeout. Green settles are milliseconds after HeadlessDone
(the suite's green wall is ~15s; the last submit's own ack bound is
10s), and terminal runs never arm the bound (HeadlessDone exists only
on the headless harness; a live terminal ends the run on
exit_requested + the exit guard).

Proven end-to-end by the lane's matrix: the wedge converted to a 98.4s
attributable red naming the latched member (the bound-only diagnostic
arm), and the full candidate stayed clean at 30/30 interleaved trials
vs 3/30 wedges at the lane parent (record
20260927-085200-interaction-exit-gate-hang-remediation, bench
hillclimb).

* perf(pa-daemon/rpc): warm the model registry at RPC session boot - first get_available_models 1170.6ms to 58.9ms (#2953)

TS session boot resolves the initial model through refreshAvailableModels
(model-resolver.ts), which also fetches the live Prime Inference catalog
in the background and caches it on disk; the daemon worker fires the same
fire-and-forget refresh from its create path (worker/create.rs). The RPC
mode hosts the session in-process with no create command, so nothing
warmed the caches: an integration's FIRST get_available_models call paid
the whole awaited refresh chain on its response path (measured 812-1296ms
on the bench VM; the 15s fetch-timeout worst case on a degraded network)
while the same command on the daemon and ACP surfaces answers from the
validated snapshot. Mirror the daemon worker boot spawn: the caches warm
during the session's first turn, and the first call serves the same
snapshot. Write behavior is unchanged: the same cache files, the same
write-on-fetch-success conditions, the same cadence (hour-gated catalog
refresh, 5-min private-authorization TTL), only started at boot.

Co-authored-by: perf-rpc-models-persist <lane@hillclimb>

* pa-tui: session_ui.rs split 4/14 - the share concern moves out of src/session_ui.rs (#2922)

b0d72b29a700merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 8/11 - the turn-execution impl moves out (#2934)

a59d3389dfbamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 5/8 - the worker-lifecycle concern moves out of src/supervisor.rs (#2956)

205f4d0f469cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 8/14 - the sessions concern moves out of src/session_ui.rs (#2957)

7d19e9832120merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 6/8 - the signals concern moves out (#2960)

a6562bc252efmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 10/11 - the lifecycle concern moves out of src/agent_engine.rs (#2962)

17d3573c5a58merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 12/14 - the keys concern moves out of src/session_ui.rs (#2958)

bc6b7d82cb0bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine.rs split 11/11 - the facade trim: the last product free fns move out; the file ends as the composition root (#2964)

1fe6a6791030merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor.rs split 8/8 - the facade trim: the notes concern moves out, the test battery re-homes (#2963)

8a5274baa0d9merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 9/14 - the panels concern moves out of src/session_ui.rs (#2961)

377eda9ded15merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 13/14 - the apply concern moves out of src/session_ui.rs (#2965)

c10a44e407cdmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: cap kernel host-request cell source at 2 KiB (the TS #2475 port) (#2966)

96f689fc38femerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the /model picker resolves by provider, never the first same-id catalog entry (fixes the operator report) (#2967)

24411964739emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: session_ui.rs split 14/14 - the facade trim: the file ends as the composition root (#2968)

60cbb4fbb642merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core): the oauth refresh leaves the auth lock - fetch under single-flight, hold-sum 396ms to 0.09ms (#2971)

An expired stored OAuth credential refreshes its token inside
AuthStorageBackend::with_lock: the OAuthIntegration seam is synchronous
by contract, so the network round trip runs under the document lock AND
under the process mutex that spans the whole critical section, stalling
every other same-process auth read and write for the fetch (the RPC
cycle_model path measured 194-201ms auth.json.lock holds per switch on
the bench VM; the assembly read pays one ~0.2ms cycle, the switch pays
the fetch).

The TS product holds its own lock across the same await
(refreshOAuthTokenWithLock -> withLockAsync), but its single-threaded
runtime never blocks other work on it; this engine is threaded, so the
port narrows the lock scope instead: load-then-lock. The document loads
through the consolidated read arm, the token fetch runs outside every
lock behind a per-provider single-flight gate (the in-process
serialization TS gets from its single-threaded runtime, with the expiry
re-checked under the gate so a second caller never spends a single-use
refresh token after the first flight landed), and the write re-enters
the same locked read-modify-write protocol - now held only for the
re-read, insert, and atomic write, and skipping the write entirely when
a peer refreshed while the fetch ran. File protocol, read results, and
every resolution outcome are unchanged.

* pa-daemon: the supervisor roster broadcasts only on content change (the TS #2481 port P3) (#2974)

054553b8ca12merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-cli/pa-tui: prime-agent update - the TS->Rust migration path (uninstall TS, install Rust, sessions preserved) (#2981)

739ed7f7d015merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core/pa-daemon): a settled RLM child releases its kernel at the settle park - ~27MB reclaimed per settled child, TS #2483 port (#2983)

* perf(pa-core/pa-daemon): a settled RLM child releases its kernel at settle - snapshot-flushing stop_kernel, revivable (TS #2483)

The rust port of the stale perf PR #2483's inline arm (the supersession
analysis: the not-superseded claim - settled children hold a worker and
a kernel until parent close; nothing at the tip releases them; the
daemon-mode whole-worker passivation stays deferred to the orchestrator):

- IpythonKernelProvisioner::stop_kernel (TS stopKernel): shuts the owned
  kernel down with a final namespace snapshot WITHOUT marking the
  provisioner disposed; a kernel still starting up is joined first and
  shut down the same way (the TS managerPromise arm). The stop records a
  pending-stop gate (TS pendingStop) that the next start_kernel_impl
  awaits before reading the snapshot back, so a follow-up turn's fresh
  boot revives the flushed namespace instead of racing the flush; a
  completed stop awaits instantly and each stop supersedes the previous
  (a clonable watch receiver: multiple revival waiters gate on it).
- The session engine gains stop_kernel_snapshot (the TS
  stopKernel({snapshot:true}) seam beside dispose_kernel), and the
  SessionEngine trait gains release_settled_child_kernel (default no-op):
  the AgentSessionEngine arm evaluates the canPassivateSettledSession
  gates engine-side - no unsettled descendants (has_unsettled_rlm_work),
  no registered cron/heartbeat jobs (a worker-wired probe over the shared
  cron store) - then fires the per-build release probe (a weak
  provisioner reference, the background-bash-probe adoption pattern,
  cleared on retire/close).
- The turn runner's park arm fires it best-effort when the worker core
  proves the parent-owned, unattached, unqueued idle state (rlm_depth>0,
  no attached clients, not compacting, no lane work - the park arm's
  own construction). The divergence the port discloses: rust children
  are worker processes (the parent has no in-process reach and the wire
  is frozen), so the release triggers at the child's own idle park
  instead of the TS parent's run-settle hook - the same revivability
  semantics (the next kernel use boots fresh from the flushed snapshot),
  and the roster/collect surfaces are untouched by design.

Tests: the provisioner stop flushes the snapshot and the next ensure
revives the namespace (live-kernel, ambient-venv-gated); the park arm's
policy matrix (a parent-owned child releases, a root/attached/compacting
session stays resident); the engine gates (a registered-jobs probe
defers the release, the probe fires otherwise).

* test(pa-daemon): the park-arm release test waits on observable readiness (the review advisories)

Two BUGBOT test advisories on the first review: the park-arm test's
bounded poll used fixed sleeps (a retry-to-green readiness wrapper). The
recording engine now notifies on every release fire, so the test waits
for the observable readiness - the notification is the pass condition,
the bounded timeout is only the failure bound for the positive arm and
the absence bound for the gated arms (no fixed sleep ever makes a pass).

The commit also lands the VM's cargo fmt output on the touched files
(the first commit's hand-written formatting failed the review's fmt
pre-flight: the lane builds on the VM only, and the formatted sources
must sync back before every commit).

* perf(pa-core): provider auth answers once per provider - the #2479 memoization ports, per-model probe -66% (#2973)

* perf(pa-core): provider auth answers once per provider and the private PI authorization cache parses once per file identity (TS #2479)

The rust port of the four unclaimed mechanisms of the stale perf PR #2479
(the supersession analysis: the rest of that PR's premise landed via
#2932's storage read-cache):

- get_available's per-model has_configured_auth becomes a per-provider
  memo: the catalog walks hundreds of models over a few dozen providers
  and each probe rebuilds the provider's auth-source candidates, while a
  same-registry probe is stable by construction (&self, no mutation
  between models). TS getAvailable's authByProvider map.
- get_rlm_searchable_models' per-model get_auth_status becomes the same
  per-provider memo (TS _authenticatedRlmModels' selectableByProvider).
- read_private_prime_authorization_cache serves from a process-wide
  stat-identity snapshot (dev/ino/mtime_ns/len, the TS
  CatalogFileIdentity) while the file is unchanged; the port builds a
  fresh registry per resolution touchpoint (the TS session kept one
  long-lived registry), so the parse would otherwise re-run on every
  resolution. Only a successful parse bracketed by one identity is
  pinned, a failed read unpins (retries), and the write path's atomic
  rename supersedes (new identity).
- AuthStorage memoizes auth-source candidates keyed by the hashed
  material itself (TS authCandidateMemos): reuse skips only the SHA-256
  work, env values are deliberately re-read on every call, command
  values resolve before the memo, and stale checks run against the
  memoized candidate (candidates are immutable).

Tests: the per-provider status memo gates one stale provider across all
its models while a second authed provider keeps its models; the
private-cache snapshot pins stable parses, re-parses rewrites, and never
pins a failed read or resurrects a deleted file; the candidate memos
supersede exactly when the hashed material changes (a stale marking from
an old value never gates a changed one).

* test(pa-core): the stale-provider memo test asserts the tip's stale-aware has_auth

The memo regression test claimed a stale-marked provider's models stay in
get_available ("stale is only the searchable-set's gate") - but
AuthStorage::has_auth is stale-aware at the tip (available_candidate
skips candidates matching a marked stale token), so get_available gates
the stale provider too, and the tip's get_rlm_searchable_models gates it
twice over. The memo preserves exactly those semantics; assert them: the
stale provider is gated across all its models from BOTH sets, and a second
authed provider keeps its models. Discovered by the full-suite fleet gate
(gate_1790546015_945232) - the lane's local legs had not run the test
suite; the three other gate reds (kernel_restore_guards x2,
tui_prime_login_escape) are SOLO-GREEN on the exact head content
(co-scheduling class, the standing family from gate_1790531716).

* test(pa-core): behavior-focused wording in the candidate-memo test comments (the review advisory)

The BUGBOT history-narration advisory asked for comments that state the
current behavior rather than the sequence of edits: the env-change arm
now says what the memo key does (a changed value changes the key, so the
rebuilt candidate's value fingerprint differs from the stale token's) and
the return arm says the marked material's candidate re-serves when its
value returns.

* pa-cli/docs: the update fetch source flips to the official domain at the rust-to-main merge (#2984)

309dd96b1f96merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: agents_view.rs split stages 1-2 - the test mass re-homes + the delete concern moves out (#2985)

bd221cb5e70amerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): saved_session_context reads windowed-first - worker resume CPU -140ms, the parse signature (#2969)

* perf(pa-daemon): windowed-first saved_session_context - the create-path model restore reads the windowed store (restored_settings + has_thinking_level) instead of full-parsing the session history; open_windowed's full-open fallback keeps unsupported/malformed files identical; differential oracle keeps the pre-change full-parse reader as the reference across no-boundary/in-window/model-only-before/thinking-only-before/malformed-prefix fixture classes

* perf(pa-daemon): address the Bugbot findings on the windowed saved_session_context - comments describe current behavior only, the oracle helper returns the owned TempDir so fixture scratch trees clean up at test scope end

---------

Co-authored-by: perf-launch-open-fast <hillclimb@primeintellect.ai>

* ci: unify workflows under .github/ + port the vouch gate

The staged-copy era ends (operator-authorized workflow-scope push):
.github/workflows/ is the one home for workflow files.

- ci.yml: the staged windows-cross/windows/deny jobs promoted from
  ci/workflows/ci.yml as the windows job set (the deny job pinned to the
  live continuous.yml shape: cargo-deny --all-features --workspace check
  advisories licenses, the `make deny` mirror); ci/workflows/ deleted
  entirely (benchmark.yml goes with it - it needed self-hosted
  `prime-sandbox` runner labels no registered runner carries; the wave
  stays runnable via `make perf-wave`).
- ci.yml + codebase-health.yml: the contributor-trust gate ported from
  main (mitchellh/vouch/action/check-user@v1, allow-fail): push events
  always allowed, PR authors must be bot/collaborator/vouched - every
  job keys on the trust output, so unvouched PRs never bill a minute.
  The vouched list resolves from the repo default branch's
  .github/VOUCHED.td (main) - nothing local on this branch.
- contribution-gate.yml ported VERBATIM from main: unvouched PRs and
  issues auto-close (check-pr/check-issue) - the admin-spam killer.
- CONTRIBUTING.md ported from main (vouched-contributor policy; the
  TS-repo-only sections adapted to this branch) + the PR template gains
  main's vouch line.
- Makefile: actionlint lints all five live workflow files;
  activate-workflows removed (obsolete). Stale staging references in
  docs/ and the battery scripts made truthful.

* pa-core: compact_session.rs split - the tests re-home + the summarization, anchor-selection, and boundary cuts (#2987)

f43aebc9c50dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: agents_view.rs split stage 3 - the render concern moves out (#2988)

03a6fcc07793merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* install: the Rust port takes over the prime-agent keyword - clean TS daemon shutdown, config preserved (#2972)

737e52dc7695merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: the scheduling catalog fans out per-worker (the TS port P4) (#2979)

1e78bb715fddmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: agents_view.rs split stage 4 - the open + incident concerns move out (#2991)

0ef076a06131merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: session_store.rs split - the index, read, write, view, info, tests children (#2990)

7b58b0acb457merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: agents_view.rs split stage 5 - the data + input concerns move out; the file ends as the composition root (#2992)

cadb8b4f33d6merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* docs: the README becomes the Rust product's own; the port-process docs are removed (#2993)

fe891d188ad0merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: snapshot.rs split stages 1-2 - the test mass re-homes + the tool-fold concern moves out (#2995)

eaa4b672f2f8merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: snapshot.rs split stage 3 - the decoder concern moves out; the file ends as the composition root (#2996)

1564648986edmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: rlm_children.rs split - the composition root (host, lifecycle, usage, registry, tests) (#2997)

4ee722d403b6merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: interactive.rs split - the tests, onboarding, headless, render, reconnect, run children (#2998)

d592a0672d5dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): share the open's artifacts + skip the depth scan's full parse (cold-open-residual) (#2970)

5b75513ff7fbmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: every session-exit route restores the terminal - the kitty-mode leak into the shell is fixed (#3001)

8f84a46233cdmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-cli: the family-seeding e2e spawns pin the daemon's session dir (the flash e2e's seeded-family red) (#3003)

c54ff2a09a84merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: undo the condensed activity runs - the collapse mode becomes details mode minus thinking blocks (#2999)

a6d8414d818cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* ci+pa-types: the first real windows runs surface tip cfg-hygiene gaps - unix-gate the pa-types sites the cross-check flagged (the #2833 pattern, zero unix behavior change): terminal.rs unix imports + the non-linux OLCUC arm, memory_release trim param, process.rs the redundant unsafe on the safe winapi wrapper; drop dangling pointers to the tip-deleted port-process docs (windows-readiness.md/installer-ci-design.md) from ci.yml/continuous.yml

* pa-cli: print_boundary.rs split - the 4 stages: events, compaction_arms, autorefine, tests (#2989)

2292af8f1cefmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: bash_view.rs split - under 1,000 lines (#3008)

15d9c1a659efmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: auth_panel.rs split - under 1,000 lines (#3009)

8c3061a5db29merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon+pa-core+pa-cli: the second windows-cross run pins the remaining cross-target lint surface - cfg-gate the unix-only reaping/signal/socket helpers their unix callers prove dead on the cross target, add the # Errors docs the windows stubs never carried, and fix the two doc/code-order nits (the #2833 pattern, zero unix behavior change)

- pa-daemon: boot_reap gates the reaping census family (is_product_binary, is_worker_argv, supervisor_argv_names_socket, normalize_socket_spelling - its doc now states the darwin truth the gate keeps, all(unix, not(linux)) on the proc-environ stub, dead-code-allowed ReapKind::Supervisor whose one constructor is linux), rpc/mod.rs gates spawn_signal_handlers' call+fn and its SIGTERM/SIGHUP exit consts, signal_drain.rs gates the unix signal imports and recv_opt, socket.rs gates unlink_stale_socket and the LOCK_* lease consts + documents the windows no-op stub, accept_loop.rs gates the four unix socket-pair stand-in tests, signals_shutdown.rs gates begin_signal_drain (its only lib caller is the unix drain loop) + the two drain-state tests, supervisor.rs splits the unix-only PrepareState import, the venv/download/installer unix-test helpers and the supervisor/roster test imports carry their platform truth, session_store/info.rs marks the windows twin's unused identity param
- pa-core: perms.rs/shell.rs give the cfg(windows)/cfg(not(unix)) stubs the # Errors sections their unix siblings have + backtick ProgramFiles/SystemRoot + hoist the windows gh-command consts above the statements, export_share.rs hoists CREATE_NO_WINDOW
- pa-types: the windows is_process_alive stubs get their # Errors sections, STILL_ACTIVE backticks, swallow_sigint and the non-linux STDIN_TTY_PATH arm take their platform cfgs
- pa-cli: the DaemonProbe probe-result enum waives large_enum_variant (the windows pipe client's transport state crosses the budget; the probe value is a rare one-shot)
- pa-models: refresh_compat's snapshot metadata binds only its unix mode reader uses

cargo clippy --locked --workspace --target x86_64-pc-windows-gnu --all-targets -- -D warnings: clean; native clippy -D warnings: clean; fmt: clean

* pa-tui: heartbeats_picker.rs split - under 1,000 lines (#3011)

13849ce9138cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the queue groups internal prompts in the summary; the edit surface is user-origin only (#3012)

b19ffd2ff84fmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* docs: docs/ ends empty per the operator's ruling; the README's install detail goes with it (#3007)

d89e319660c4merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the terminal-state differential - every armed mode restores on every exit route (#3002)

aba71e8b491dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: the worker test mass splits by family - under 1,000 lines (#3014)

f011aaac54c7merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-ai/pa-agent: /tier command + Default service tier settings row + footer badge + completions service_tier forwarding + proxy serviceTier (TS #2144 half + #2491 half) (#2735)

e8cdef33d443merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core/pa-daemon/pa-types: the Windows platform gaps close - the tilde arm, the win32 path resolution, the TS launch budgets (#3016)

438012e04c27merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the agents_view test mass splits by family - under 1,000 lines (#3018)

7c488aca640bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* fix(pa-daemon): the compacting admission gate - a racing turn defers through the compaction window, the parked work delivers after it (#3021)

b15dc777d141merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core): cut the refine pre-LLM full-entries snapshot clone (-9.5ms / -30.4% pre-LLM at 10MiB) (#3013)

f9c343f8d7a5merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge); optional lane gate evidence: gate_1790621761_1065006 GREEN.

* perf(tui): slice the kitty-probe reader-lock window to 10ms polls - early typing delivers while the probe listens (#3010)

07be8ffbcc74merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* install: the installer bootstraps its own Python via uv; the output flow; the bash-3.2 parse fix; the test suite moves lane-side (#3017)

a2c94944cc40merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core): refine pushes its appended rows instead of rebuilding the context (-25.4ms / -35% at 10MiB; TS-parity restoring) (#3020)

f3a9757dd30dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* fix(pa-core): the digest terms' window direction - TS slice(-4) keeps the NEWEST four texts, not truncate(4)'s oldest four (#3019)

f310e1c9bc42merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* test(pa-core): the compact digest-capture placement oracles - the ENTER capture is the TS-parity shield (byte-identity across placements in frozen windows; the racing class) (#3006)

ae542c6a56bcmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core/pa-agent/pa-daemon/pa-tui: settings.imageModel routes image turns to a configured image model + the [python-skills-unavailable] notice (TS #2453 + #2381) (#2741)

5098db88b8f8merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* install: the TS daemon always stops on install - busy daemons get the forced shutdown (#3028)

78b0b58de028merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: per-call-site durability for the shared atomic_write - the TS WriteFileAtomicOptions shape (#3023)

2acae69edf1fmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* docs: the last docs/ file goes - the terminal-leak audit repo copy (the ruling final straggler) (#3026)

0d72ff3d77d0merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-daemon): flush the RPC compaction_start frame before the pre-summarizer CPU span (client-visibility: +48.8ms p50 -> +0.143ms, 341x) (#3024)

ddf75643ab00merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge); optional lane gate evidence: gate_1790634676_1065157 GREEN.

* pa-tui: agents_view_forest.rs split - under 1,000 lines (#3040)

741be982e655merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* privacy: scrub personal machine paths and identity data from docs + fixtures (the security-scan lane) (#3046)

ba9ea3b7eb5amerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the subagent surfaces - one running count on the prompt bar, one dropdown in the agents view (#3031)

b1ee386c0ddemerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* ci: the windows runtime triage workflow - on-demand Windows battery runs on any ref (#3022)

425b1751cb67merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: manager.rs split - under 1,000 lines (#3039)

5220b3c2f589merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* clippy: pa-cli is pedantic-clean (#3050)

f2fdb439d3demerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* clippy: pa-daemon is pedantic-clean (#3029)

c233c84b62dcmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* skills: the parity quick-fixes (#3058)

4de8f9c2acc9merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: info_commands.rs split - under 1,000 lines (#3057)

febdcffc7cbbmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: fold 3's auto-merge doubled the gated PrepareState import (both sides added #[cfg(unix)] use crate::update_prepare::PrepareState at different spots and git kept both) - keep the commented one, drop the bare twin (E0252)

* pa-core: agent_traces.rs split - under 1,000 lines (#3061)

5518a73acaf0merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: markdown.rs split - under 1,000 lines (#3066)

f23b3d05c93dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-cli: interactive_mode.rs split - under 1,000 lines (#3055)

b559cd018f80merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the settings page pass - spacing, arrow value-cycling, the tab keys, the white selection, the fullscreen retirement, two regressions (#3051)

286006389509merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: the folded signals_shutdown imports PrepareState from super ungated while the fold's parent keeps the re-export behind #[cfg(unix)] - E0432 on both windows targets; gate the import to its one unix use (the #2833 pattern, zero behavior change)

* skills/runtime: the generic mcp skill + the discovery/tooling surface (#3063)

563c576e8123merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-core): the recurring capture-freshness memo - skip the redundant kernel re-dump while the namespace provably cannot have changed (#3037)

09043ae3b2b4merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: telemetry.rs split - under 1,000 lines (#3074)

2aeda90ba25bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: model_picker/mod.rs split - under 1,000 lines (#3070)

867dfa067633merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: session_engine/mod.rs split - under 1,000 lines (#3062)

fe1ee606180bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: the compact_session test mass splits by family - under 1,000 lines (#3073)

e27835fee7f4merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: rlm_ledger.rs split - under 1,000 lines (#3078)

758ea09ebc34merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: auth/manager.rs split - under 1,000 lines (#3071)

36a261afd673merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: queued.rs split - under 1,000 lines (#3079)

91873baa42cbmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: the promoted windows-cross finally reaches the merged tip surface - the tip's own ci.yml never ran these jobs, so its signals_shutdown kept ClientRouting in the ungated import list (its only use sits in the unix begin_signal_drain arm) and the fold carried my #[cfg(unix)] gates onto the four accept-loop tests whose tip versions are portable duplex tests - gate the ClientRouting import, un-gate the four tests to the tip's shape (the #2833 pattern, zero behavior change)

* pa-tui: ctrl+s stashes and restores the prompt draft (#3072)

443ab531022amerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: venv.rs split - under 1,000 lines (#3077)

d6ae9a7770e9merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* comments: the CI-unification surfaces drop the migration-era staging narration - the ci.yml header, the Makefile perf-wave gate, and the two perf-wave script headers describe current behavior only (one home for workflows; the perf wave is command-line-only because a hosted run would need self-hosted prime-sandbox labels no registered runner carries); the historical record stays in the docs (bugbot 65dfc19a)

* pa-tui: sequence_guard.rs split - under 1,000 lines (#3083)

430d6141a0ccmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: session_engine/request_timing.rs split - under 1,000 lines (#3084)

fdd1f5bbfbcamerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the session_ui composition root trims under 1,000 lines (#3064)

b068d7a48a13merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: chat.rs split - under 1,000 lines (#3081)

65525952ae25merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: daemon_client.rs split - under 1,000 lines (#3086)

ddef55111f26merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* make: the actionlint target lints every live workflow file - add .github/workflows/windows-runtime-triage.yml to the invocation (the #3022 on-demand windows triage workflow arrived with the fold; it pre-verifies LINT-CLEAN under actionlint 1.7.12, so 'lints every workflow' is true again) (macroscope d2cf164e)

* pa-daemon: supervisor_e2e.rs splits by test family - under 1,000 lines (#3067)

81b928e55a00merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: view.rs split - the 3,888-line god-file ends as an 841-line composition root + 5 concern children (#3088)

0ff470e08385merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: the agent_engine test mass splits by family - under 1,000 lines (#3059)

9cabd79136demerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* runtime: blocking usage beyond the auto-bg threshold degrades to a handle - bash awaits and python execution alike (#3076)

b17703d1425cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: chrome.rs split - under 1,000 lines (#3087)

7af1b5840f32merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai/ci: the TS-parity sweep-2 quick-fixes - Gemma 4 thinkingLevel on Vertex (TS #2946), Azure store:false (TS #2948), the staleness gate live (TS #2567) (#3068)

b5cf6ec2b29cmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: tree_list.rs split - under 1,000 lines (#3091)

d54b591b12a2merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: autocomplete.rs split - under 1,000 lines (#3092)

6a90ccf77948merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: keybindings.rs split - under 1,000 lines (#3090)

337d2efcc712merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: mcp_view.rs split - under 1,000 lines (#3094)

500fcd9581a9merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: the fold-5 tip restructured the venv probe surface and its windows-cross gate pair went inconsistent - the venv.rs test import list carried clear_in_process_probe_memo_for_tests and installed_package_dir at cfg(test) while their defs/callers sit at cfg(all(test, unix)) - E0432 + unused-import on the windows cross target (tip debt the promoted job surfaces: the tip's own ci.yml never runs it); split both names to the matching all(test, unix) gate (the #2833 pattern, zero behavior change). Pre-verified on-box: cargo check+clippy --locked --workspace --target x86_64-pc-windows-gnu --all-targets -D warnings BOTH GREEN

* pa-daemon: worker/turn_stream_tests.rs split - under 1,000 lines (#3095)

2b9778a0dc6emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* clippy: pa-core is pedantic-clean (#3093)

273b29234448merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: the goal timer counts from the goal creation; the goal continuation fires once per boundary (#3048)

f116a6b5a849merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the termios + process-tree exit audit - no raw-mode/flow/orphan/fd leaks (#3089)

13683dba140dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: agent_engine/turn.rs split - under 1,000 lines (#3102)

c8af2dd96ba0merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: the per-model layer trims to the minimal format reference - the empty block gone (#3106)

bd3b03f57b6bmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: scheduled_jobs.rs split - under 1,000 lines (#3105)

67ea4b6ff782merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-core: the image-heavy session-open fix - the render-path skip + the measured fast paths (#3098)

3325e22b396emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: settings_menu.rs split - under 1,000 lines (#3108)

b789ea8dc265merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* clippy: the small crates are pedantic-clean (pa-ai, pa-agent, pa-types, pa-telemetry, pa-models) (#3110)

25ab57d2829fmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui: the hover + click affordances - the dock groups, the hints, the agents-view rows, the dropdowns; every clickable thing shows it (#3109)

0f871da2e8a1merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* install/pa-daemon: the takeover completes - the rust daemon stops on update; the schema-family match; the no-auto-resume contract (#3107)

29645e1b9bb7merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: supervisor_restart_e2e.rs splits by test family - under 1,000 lines (#3114)

9434853a18e7merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-telemetry: the #2117 tracking intent lands clean - the modular catalog, the accurate firing, the edge cases pinned (#3100)

942f003642b0merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-ai: stream_failure.rs split - under 1,000 lines (#3116)

4b7300a6147dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: engine.rs split - under 1,000 lines (#3118)

8b6dda11865dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: the handshake channel stays private until the auth answer installs it - the launch-storm connect-budget wedge closes (#3075)

80e9fe60091emerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: harness_digest.rs split - under 1,000 lines (#3119)

c806bee6fe79merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-tui/pa-daemon: the bare /skill: invocation guards - the TUI hint + the empty-args notice + the engine floor (#3113)

2d72de5cef32merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: agent_messaging.rs split - under 1,000 lines (#3120)

691e0785cca3merge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-tui): the cross-view layout handoff - reuse the visible-window packs on the agents->chat re-entry (-100.1ms / -35.7% at canon) (#3103)

cd55ae21aefemerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: session_stats.rs split - under 1,000 lines (#3122)

af8138eaee3amerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-core: models/registry.rs split - under 1,000 lines (#3124)

4c4d622bcb8dmerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* pa-daemon: compaction_arms.rs split - under 1,000 lines (#3125)

16d6c239ae3amerge bar v23: mandatory CI green on the exact head + zero unresolved bot threads + head unmoved (verified by fleet_pipeline.fleet_merge).

* perf(pa-ai): append streamed Responses mirror text and reasoning-details fragments in place instead of re-copying per delta (#3035)

* perf(pa-core): scan only new bytes for newlines - linear line framing (TS #2781 twin) (#3042)

* test(pa-core): the multi-MiB protocol-line timing tests for the kernel reader and the extension LineDecoder (TS #2781 twin)

A 4 MiB decoder line fed in 1 KiB chunks and a 31 MiB blank kernel line
read through the 64 KiB pipe reader must complete under the computed
bounds: while every chunk rescans the buffered prefix, they scan >= 8.6
GB and >= 8 GB and overrun them. The blank line never reaches
parse_event, so the bound separates pure scanning from the quadratic
rescan. Failing runs report their real duration in the assertion
message.

* perf(pa-core): the kernel protocol reader and the extension LineDecoder scan each byte once - linear line framing (TS #2781 twin)

Both readers keep only the newline-free tail of earlier chunks, so the
newline scan resumes at the old buffer length instead of restarting at
zero: while one line accumulates, every chunk rescanned bytes already
known to hold no newline. The decoder also consumes lines by offset and
drains once per feed instead of one O(remaining) drain per line.

Measured (8-core sandbox, prebuilt debug test binaries, medians of 3):
a 4 MiB decoder line in 1 KiB feeds 14.27s -> 0.014s (~1000x); a 31 MiB
blank kernel line 13.85s -> 0.65s (the ~13.2s quadratic rescan
eliminated; the remainder is the one-pass scan plus the UTF-8 and trim
checks the blank line still pays). Frame handling is byte-identical:
same oversize checks and order, CR and blank-line rules, invalid-UTF-8
endings, and post-error buffers.

* perf(pa-daemon): mint session entry ids against the by_id index instead of rebuilding an id map per append (#3053)

append_entry and persist_entry_at rebuilt a HashMap of every entry id on each call just to check the new id for collisions. The store's by_id index already holds the same ids, so check against it: appends drop from O(n) to O(1). The fork and branch paths in session_tree reuse by_id the same way instead of keeping their own id copies.

* perf(pa-ai): Anthropic stream edits the output blocks directly instead of copying a second block list per delta (#3056)

* pa-ai(anthropic): mutate output.content directly instead of copying a duplicate block list per delta

* pa-ai(anthropic): trim the stream snapshot test per review (struct-update expected values, one-line terminal assert)

* pa-ai(anthropic): state why the stream snapshot test allows too_many_lines

* pa-cli/pa-daemon: daemon-attached ACP honors the CLI session flags (#3096)

The daemon-attached ACP path dropped --append-system-prompt, --system…
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants