Collapse expensive CLI smoke coverage into scenario tests, replace the
slow doctor no-color integration check with a unit-level render test,
and remove duplicate attach coverage. Also fix local Unix-socket
autostart so missing daemons don't spend the full 5s readiness wait
before startup.
The commit includes the measured slow-test report updates for the work
landed here.
Route subprocess worker stderr directly into server tracing and remove
the scratch-file sink. Update the run-directory docs to reflect that
runtime now only documents blob materialization here.
Drop scratch-only compatibility paths and legacy test scaffolding now that
SlateDB-backed state is authoritative. This removes scratch file fallbacks,
updates docs and UI labels, and moves tests onto durable store-backed helpers.
Guard server worker cleanup against superseded subprocesses so rewind and
resume flows do not append a synthetic failure from an older worker. Update
CLI snapshots for the current interview events and give the shared test
session lock more time to cover daemon startup and shutdown.
Collapse the live answer rendezvous into ControlInterviewer, move pending
question storage onto a shared typed record, and route HTTP and Slack answer
submission through one server-side flow.
Persist pending interviews in run state, deliver accepted answers to workers
through the server-owned control path, and remove the old scratch-file and
WebInterviewer transports.
This also moves Slack onto the canonical server answer flow, adds richer
question metadata to the API and run events, and covers the subprocess
question lifecycle with end-to-end tests.
Share one store-dump export pipeline across the server-backed CLI path
and the local test helper, and add mixed blob-ref plus artifact coverage
for the exported output.
Route `fabro store dump` through the server client for run state, events,
blob hydration, and artifact downloads instead of reopening storage directly
from the CLI process. This fixes blob-backed checkpoint exports and restores
store-dump coverage under the in-memory test server.
Reapply the lint-safe changes that were partially displaced while merging
origin/main, including the billing serialization assertion and the attach
replay/server annotation cleanups. This keeps the merged main branch back to a
clean full-workspace clippy pass before the store-dump debugging continues.
Tighten the worker upload path so object-backed runs only fail when an
artifact upload is actually attempted without a token, and update CLI
snapshots for the new artifact storage metadata.
Fold in the workspace test and clippy fixes needed to verify the final
artifact upload implementation cleanly across Rust and web targets.
Store large context payloads in the global CAS and keep durable
checkpoint state as blob://sha256 refs instead of execution-local file
paths. Resolve and materialize blob refs at execution, output, and export
time so resumed and remote runs can read legacy and new artifacts
consistently.
Add scoped worker upload tokens and HTTP artifact upload clients.
Support manifest-first multipart stage artifact uploads with validation and checksums.
Gate artifact reads by run capability while preserving legacy scratch fallback.
Active runs deleted through rm --force were removed from server state
without signalling the worker process, which could leave detached
workers orphaned after test cleanup. Terminate the tracked worker
process group before deleting run state and cover it with an
integration regression.
The workflow routes were importing types that do not exist in the generated
OpenAPI client. Define the workflow endpoint response shapes locally so the
web app typechecks against the actual server responses.
Replace the overlapping usage and cost model with canonical billing
primitives centered on ModelRef, ModelHandle, TokenCounts, and
BilledModelUsage. This also renames the public API and web surface from
usage to billing, removes compatibility aliases, and normalizes provider
usage adapters onto the shared billing vocabulary.
Move detached workers onto an HTTP-backed runtime store so the server
remains the only SlateDB owner. This replaces the worker's seeded local
RunDatabase with a canonical server-backed handle for state, events, and
blobs, and updates workflow runtime plumbing to use that abstraction.
Replay persisted run events for attach requests, keep the SSE stream live
only while the run is active, and close on terminal run events instead of
returning 410 for completed runs.
The CLI now treats premature attach EOF as an error, and the affected
integration tests were stabilized around store-backed event ordering and
recovered rewind timelines.
Persist server, client, and subject provenance on run creation so
run state and inspect output can show which Fabro version created a
run, which first-party client submitted it, and how the request was
authenticated.
Replace the attach polling loop with the existing run attach SSE endpoint.
Seed from stored history once, fetch interview questions only when needed,
and keep completed-run replay behavior intact.
Default test daemons now opt into an in-memory object store and test
helpers carry explicit run ids instead of rediscovering runs from
shared state.
This also disables the disk-backed store dump integration tests until
store dump is routed through the server's live store handles.
Make fabro-store::RunProjection the single projection type used by the
server, CLI, and CLI test helpers. This removes the duplicated CLI-side
mirrors and adds serde coverage for the store-owned projection.
Pass a real cancel signal from __run-worker through the workflow engine
into sandbox command execution so cancelled runs reap gated shell loops
instead of leaking slow.gate waiters.
Give the harness longer to stop the shared test server than the server
itself uses to shut down active run workers. This prevents session cleanup
from SIGKILLing the server before it can terminate worker process groups,
which was leaving orphaned `fabro <run> running` subprocesses behind.
Eagerly start one shared test server per nextest session and point default
TestContext commands at that session socket instead of leaking per-test
daemons keyed by FABRO_STORAGE_DIR. Add isolated_server() for tests that
need an explicit separate daemon, and tighten the ps filtering test so it
still proves the contract without timing out under full-suite load.
Remove GET /workflows, GET /workflows/{name}, GET /workflows/{name}/runs,
and POST /runs/{id}/steer from the OpenAPI spec, server routes, demo
fixtures, pagination tests, docs navigation, and generated TS client.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>