Flow Relay Status Summary
Use this status memo when deciding whether to finish the remaining relay runtime features first or proceed with a narrower relay gate around the current control-plane surface.
Status date: 2026-05-03.
Executive Summary
Section titled “Executive Summary”The flow relay is no longer only a proposal. The canonical contract exists,
the wap-flow relay command group is implemented, relay-owned generated state
has a durable ledger, inspect relay and relay status expose aligned
read-only projections, and relay serve exposes the same ledger through a
foreground HTTP plus server-sent events boundary.
The implementation is still a control-plane relay, not a managed provider runtime. It records runtime metadata, provider profiles, session records, leases, control requests, event/result cursors, token digests, and quarantine records. It does not spawn provider subprocesses, keep a live Codex session pool, run heartbeat-driven renewal, execute tasks, or repair crashed provider sessions.
That means a relay gate can be implemented now if the gate is scoped to ledger/projection/transport readiness. A gate that claims live managed session pooling or provider execution readiness would be premature.
Canonical Contract
Section titled “Canonical Contract”The relay owner is now canonical in flow/specs/flow-relay-contract.md.
The contract defines a single-host, wap-flow-owned relay control plane with
durable truth in flow/state/relay/relay-state.json and rebuildable runtime
scratch under flow/tmp/relay/**.
The relay is explicitly non-authoritative for task, acceptance, PR, worktree, memory, and provider-health truth. It may render or route source references to those owners, but it must not mutate them or become a generic scheduler.
The CLI contract in flow/specs/flow-cli-contract.md is also aligned with the
current command surface:
relay statusandinspect relayare read-only.relay bootstrapandrelay shutdownrecord runtime metadata only.relay profile register/listrecords provider runtime profiles.relay session create/listrecords managed session ledger entries only.relay borrow,relay release, andrelay lease grant/release/renew/revokemanage explicit borrow leases.relay control recordrecords idempotent control requests.relay event append/listandrelay result append/listprovide cursor-backed stream records.relay quarantine session/clearandrelay recoverprovide quarantine and recovery classification.relay servestarts a foreground HTTP plus SSE relay over the existing ledger.
Current Workspace State
Section titled “Current Workspace State”wap-flow relay status --json currently reports a healthy relay projection:
status:passprojection:relay_generated_state_v1relay_mode:readyledger_path:flow/state/relay/relay-state.jsonstate_present:truetmp_present:trueledger_present:true- durable artifacts:
1 - tmp artifacts:
1 - warnings:
0 - profiles:
0 - sessions:
0 - active leases:
0 - active quarantines:
0 - control requests:
0 - events:
0 - results:
0
The current ledger contains only loopback runtime metadata:
- endpoint:
http://127.0.0.1:9876 - status:
ready - bootstrapped at:
2026-05-01T11:35:03Z - token id: none
There are no registered runtime profiles, managed sessions, leases, quarantines, control requests, events, or results in the current workspace ledger.
Implemented Surfaces
Section titled “Implemented Surfaces”The Rust implementation is split cleanly:
flow/wap-flow/src/relay/state.rs: typed relay state model and domain transitions.flow/wap-flow/src/relay/store.rs: ledger read/write, validation, and lock orchestration.flow/wap-flow/src/relay/inspection.rs: generated-state inspection and freshness summary.flow/wap-flow/src/relay_cli.rs: publicwap-flow relaycommand group.flow/wap-flow/src/relay_server.rs: HTTP plus SSE serving boundary.
The current model supports the important control-plane invariants:
- durable relay truth is centralized in
flow/state/relay/relay-state.json - relay mutations are serialized with
flow/tmp/relay/relay-state.lock - matching duplicate control requests return
duplicatewithout rewriting the ledger - shared-read leases may coexist
- exclusive-write leases require no active readers or writer
- waiting writers block new readers until readers release and the writer retries
- lease renewal records
last_renewed_atandexpires_at - lease revocation records a reason and removes active occupancy
- event and result streams use per-session monotonic sequence numbers
- recovery classification distinguishes mutable lease blocks, quarantine repair, resumable sessions, and replacement-session starts
- active quarantines keep sessions failed until cleared under safe conditions
- token secrets are stored only as SHA-256 digests
- trusted-LAN runtime endpoints must use private-network IPs and require bearer token authentication for serving
HTTP And Web Facade
Section titled “HTTP And Web Facade”wap-flow relay serve exists as a foreground Axum server. It records served
runtime metadata and exposes:
GET /healthGET /api/relay/statusGET /api/relay/profilesGET /api/relay/sessionsGET /api/relay/eventsGET /api/relay/resultsGET /events
The server authenticates API and stream requests when the current runtime has a token id. It compares bearer-token digests against the persisted token digest. Loopback serving may run without a token; trusted-LAN serving requires one.
flow-relay-web/ is present as a separate, non-authoritative companion facade.
The Rust gateway proxies relay status, profiles, sessions, events, and results,
and intentionally returns not_configured for task projections because tasks
are not exposed through relay serve yet. The React frontend is a polling JSON
dashboard rather than an operational session-borrowing app.
Generated State Integration
Section titled “Generated State Integration”Generated-state ownership is in place:
flow/state/relay/relay-state.jsonis the schema-backed singleton relay ledger.- other
flow/state/relay/**descendants are reserved relay-owned durable artifacts and are not parsed as the relay ledger. flow/tmp/relay/**is rebuildable relay scratch.state inventoryvalidates the singleton ledger and reports malformed relay state as owner-scoped warnings.state cleanup --owner relay --applyremoves eligible relay tmp cache material while preservingflow/tmp/relay/relay-state.lock.
This is enough foundation for a gate that checks relay-generated-state health.
Not Yet Implemented
Section titled “Not Yet Implemented”The following capabilities are still future work or only partially shaped:
- real provider subprocess ownership
- live Codex pooled subprocess reuse
- supervised one-borrow subprocess execution for Claude or Kimi
- automatic heartbeat-driven lease renewal
- automatic lease expiry handling
- provider crash detection
- provider-health integration
- automatic session quarantine after crash, heartbeat loss, or tmp corruption
- repair flows that rebuild or replace unsafe provider sessions
- token rotation and revocation commands
- companion-app mutating request paths for profile/session/borrow/release
- task projections through
relay serve - rich frontend controls for borrowing, releasing, streaming, or repairing sessions
The current relay recover command classifies what should happen; it does not
perform repair.
Gate Planning Implications
Section titled “Gate Planning Implications”A relay gate is viable now if it answers this question:
Is the relay control-plane projection healthy enough for operators and companion tooling to trust the current ledger state?
That gate could check:
relay status --jsonreturnsstatus=passinspect relay --jsonexposes the same projection fieldsflow/state/relay/relay-state.jsonparses and validates when present- tmp relay cleanup preserves the relay lock
- trusted-LAN serving is rejected without a token
- persisted token records contain SHA-256 digests, not raw tokens
- pooled profiles are Codex-only
- event/result cursor order is valid
- active quarantine/session-state invariants hold
- HTTP read endpoints and SSE replay do not mutate
flow/state
A relay gate should not yet require:
- an active provider session pool
- a running Codex subprocess
- provider task execution through relay
- heartbeat renewal
- automatic crash repair
- frontend borrowing workflows
- task projection through the relay server
The practical next step is therefore to implement a narrow relay gate as a
readiness and safety gate for relay-owned generated state and the HTTP/SSE
projection. Treat runtime pooling as a follow-up feature track with its own
acceptance criteria.
Recommended Sequencing
Section titled “Recommended Sequencing”- Implement a narrow relay gate around the stable control-plane invariants.
- Add a small operator-facing report that names the failed relay invariant and the owner-scoped repair command or next diagnostic.
- Decide separately whether token rotation/revocation belongs before or after live provider runtime work. It is security-relevant, but not required for a loopback-only readiness gate.
- Finish live runtime design before claiming pooled-session readiness: provider subprocess lifecycle, heartbeat renewal, crash quarantine, repair, and safe idle re-borrow cleanup.
- Expand
flow-relay-webonly after the relay server has modeled mutating request paths; until then the facade should remain read-oriented.
Validation Run
Section titled “Validation Run”Commands run on 2026-05-03:
cargo run -q --manifest-path flow/Cargo.toml -p wap-flow -- relay status --jsoncargo test --manifest-path flow/Cargo.toml -p wap-flow --test local_cli local_relaycargo check --manifest-path flow-relay-web/server/Cargo.tomlResults:
- relay status:
pass - relay-focused local CLI tests: 13 passed, 0 failed
flow-relay-webserver check: passed
Frontend checks were not run because flow-relay-web/frontend/node_modules is
not installed in this workspace.
Source Evidence
Section titled “Source Evidence”Primary files reviewed:
flow/specs/flow-relay-contract.mdflow/specs/flow-cli-contract.mdflow/specs/flow-inspection-contract.mdflow/specs/flow-generated-state-contract.mdflow/specs/flow-state-placement-contract.mdflow/playbooks/managed-cli-relay.mdflow/candidates/fc-2026-029--managed-cli-relay-and-session-pooling.mdflow/wap-flow/src/relay_cli.rsflow/wap-flow/src/relay/state.rsflow/wap-flow/src/relay/store.rsflow/wap-flow/src/relay/inspection.rsflow/wap-flow/src/relay_server.rsflow/wap-flow/tests/local_cli.rsflow-relay-web/README.mdflow-relay-web/AGENTS.mdflow-relay-web/server/src/main.rsflow-relay-web/frontend/src/main.tsx