Status: frozen implementation plan for v0.7.0
Theme: Runtime Reliability & Observability
Baseline: v0.6.0 on main at d556c3265bd225470e21d83c738d1c3ef28bda42
Release-state note: this file is the frozen historical plan for v0.7.0. v0.7.2 kept the v0.7.0 public/runtime contract frozen while adding only the bounded-FD filesystem fix, proven-inactive Agent task state reconciliation, and bounded read-only runtime-readiness verification recorded in
dev_plan_v0.7.2.md. Historical pre-release stop instructions below are retained as audit evidence, not as the current release state. Repository current stable: v0.18.0.
ServerFS remains:
- a controlled Workspace Access Plane;
- an Agent Runtime Gateway / Harness bridge;
- a minimal durable control plane for delegated execution.
A ServerFS Agent task is an execution/delegation run, not a business workflow.
The following remain out of scope and must not be added to ServerFS itself:
- Memory/RAG/Skills;
- provider sandboxing or a new isolation layer;
- scheduler/cron;
- workflow or multi-agent orchestration;
- a generic model gateway;
- a general evaluation platform.
v0.7.0 adds reliability and evidence around the existing provider-neutral Agent Bridge. Existing authorization, provider approval semantics, writer leases and the v0.6 Jev advisory-only contract remain authoritative.
Normalized task events use envelope schema version 1:
schema_version
event_id
task_id
correlation_id
event_type
created_at
payload
schema_version=1 is stable for additive event types.
correlation_id is optional and opaque:
- UTF-8 string;
- at most 256 encoded bytes;
- no ASCII control characters;
- stored on the task;
- returned by task reads;
- copied into event envelopes, immutable task manifest and metadata-only audit logs;
- never parsed, routed, authorized, made unique, used for idempotency or used as a continuation key;
- never forwarded to a provider as instructions.
Audit remains metadata-only. Prompts, final responses, credentials and host paths must never be added to audit records.
Defaults:
- task timeout:
86400seconds (24 h); - terminal retention:
168 h(7 d).
deadline_at is frozen when the task is created.
Approval/question requests carry expires_at and may never outlive the task deadline. There is no independent longer interaction lifetime.
At task deadline:
- request provider cancellation best-effort;
- stale any pending approval/question;
- mark the task
interrupted; - use
AGENT_TASK_TIMED_OUT.
At interaction expiry:
- request becomes
stale; - waiter fails with
AGENT_INTERACTION_EXPIRED; - a late human response is rejected as
REQUEST_STALE.
GC removes the complete retained task unit: task row, events, requests and spooled result. GC runs at startup, submission and terminal completion/cancellation. It never deletes nonterminal tasks.
The existing flock remains the live cross-process writer lease. v0.7.0 adds a Bridge-owned persistent recovery guard beside the shared lease files so the read-only MCP lock mount can observe stale recovery state:
runtime/locks/active/<slot>
The Bridge is the only writer of this guard. The MCP container only reads it through the existing read-only lock-directory bind mount.
For a workspace-write run:
- acquire flock;
- atomically publish the active-slot guard;
- start the provider;
- on a clean terminal path confirm the provider run has stopped/returned;
- remove the guard;
- release flock.
A Bridge crash can release flock while leaving the persistent guard. Container-side filesystem mutations must then fail closed with:
WORKDIR_RECOVERY_REQUIRED
The guard is cleared only after startup reconciliation can establish that the old provider is no longer active or that a safe takeover/reattachment succeeded. There is no blind rerun.
Reconciliation classifications are provider-neutral:
REATTACHEDSESSION_RESUMABLENOT_RECOVERABLEUNKNOWN
Codex may be classified REATTACHED only when there is live proof that the exact native turn still exists, belongs to the persisted task/session, and event consumption can continue safely. Otherwise its persistent native session/thread may only support a later explicit continuation.
Claude is conservative: a persisted session id can make a task SESSION_RESUMABLE; ServerFS does not assume the prior subprocess survived a Bridge crash.
Unresolved recovery preserves native IDs and the active-slot guard, interrupts the old ServerFS task instead of rerunning it, and blocks new writes for that slot until the provider is proven stopped or a safe takeover is implemented.
Required reconciliation events include runtime/task reconciliation start and finish evidence; exact event type additions are additive under envelope v1.
Every task receives exactly one immutable manifest at creation. It is persisted as:
manifest_jsonmanifest_sha256
The canonical JSON is UTF-8, sorted keys, compact separators, no NaN; hash is SHA-256.
Manifest schema version is 1 and captures the execution facts needed to interpret a result later:
schema_versionbridge_versionprotocol_version- runtime: name, measured version, declared
in_flight_recovery - workspace: alias, slot, relative cwd, profile
- policy: read-only, agent mode,
policy_sha256 - limits
- advisor state
- continuation
- optional
correlation_id deadline_at
There is no manifest update API. A later runtime/config change must not rewrite old task evidence.
The existing final_response > 256 KiB => AGENT_RESULT_TOO_LARGE behavior changes:
- result <= 256 KiB: inline, unchanged success path;
- result > 256 KiB and <= 8 MiB: atomically spool to private Bridge state and mark task
succeeded; - result > 8 MiB:
AGENT_RESULT_TOO_LARGE.
Private spool path:
~/.local/state/serverfs-agent-bridge/results/<task_id>.txt
under the configured state_dir; results directory mode 0700 and result file mode 0600.
SQLite records:
result_storage = inline | spoolresult_size_bytesresult_sha256
For spooled results, get_agent_task returns:
- a bounded
final_responsepreview; final_response_truncated: true;result.size_bytes;result.sha256;result.retrievable: true.
A new read-only MCP tool / Bridge RPC reads the exact spooled UTF-8 result:
read_agent_task_result(task_id, offset_bytes=0, max_bytes=65536)
Return fields:
textoffset_bytesnext_offset_byteseof
max_bytes is capped at 64 KiB. Offsets are byte offsets. Chunks must end on a valid UTF-8 boundary so concatenating the returned UTF-8 bytes reproduces the stored bytes exactly. The spool is removed with task retention GC.
A task.result_spooled event records metadata only.
- Bridge protocol remains version 1; new optional params/RPC method are additive.
- Existing eight Agent tools retain their semantics; v0.7.0 adds exactly one read-only result retrieval tool.
- Existing inline results remain readable through
get_agent_task. - Existing SQLite databases are migrated additively at Bridge startup.
- Existing tasks created before v0.7 migration receive safe legacy/default values; no historical evidence is fabricated.
- Existing Jev behavior remains optional, fail-open and advisory only.
- Base filesystem-only deployments remain Agent-unaware unless Agent mode is enabled.
v0.7.0 is not releasable until executed evidence covers:
- event envelope
schema_version=1and correlation propagation; - correlation validation and opaque behavior;
- immutable manifest creation and exact SHA-256 verification;
- task timeout and stale HITL behavior;
- 168 h retention GC including result-spool deletion;
- active-slot guard creation, crash persistence and mutation-side
WORKDIR_RECOVERY_REQUIRED; - provider-aware reconciliation with no blind rerun;
- inline <=256 KiB, spooled >256 KiB to <=8 MiB, fail >8 MiB;
- exact multi-chunk UTF-8 result reconstruction and SHA-256;
- protocol/MCP schema tests for the new result reader;
- full Agent Bridge gate;
- full root gate;
- deployment/config syntax gates where touched;
- documentation/version consistency.
- Freeze this plan on the v0.7 development branch.
- Implement persistence/models + manifest + correlation/event envelope.
- Implement lifetime/expiry/retention.
- Implement spool/retrieval.
- Implement persistent guard + provider-aware startup reconciliation.
- Wire MCP surface and mutation-side recovery blocking.
- Add regression/unit/integration tests.
- Update README, Agent Bridge docs, config/deployment docs, AGENTS and versions.
- Run targeted gates, then all applicable release gates.
- Commit and push the development branch.
- Merge to
main, remove the development branch, and verify a clean single-branch release-ready repository.
Stop before creating the v0.7.0 tag or GitHub Release. The user must confirm the final main commit first.