# ServerFS MCP v0.7.0 Development Plan 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**. ## 1. Product boundary 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. ## 2. Frozen v0.7.0 scope ### 2.1 Event envelope v1 and structured audit correlation Normalized task events use envelope schema version 1: ```text 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. ### 2.2 Task lifetime, interaction expiry and retention Defaults: - task timeout: `86400` seconds (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: 1. request provider cancellation best-effort; 2. stale any pending approval/question; 3. mark the task `interrupted`; 4. 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. ### 2.3 Provider-aware restart reconciliation and persistent active-slot guard 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/` 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: 1. acquire flock; 2. atomically publish the active-slot guard; 3. start the provider; 4. on a clean terminal path confirm the provider run has stopped/returned; 5. remove the guard; 6. 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: - `REATTACHED` - `SESSION_RESUMABLE` - `NOT_RECOVERABLE` - `UNKNOWN` 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. ### 2.4 Immutable execution manifest Every task receives exactly one immutable manifest at creation. It is persisted as: - `manifest_json` - `manifest_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_version` - `bridge_version` - `protocol_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. ### 2.5 Large final-result spool and exact retrieval 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/.txt` under the configured `state_dir`; results directory mode 0700 and result file mode 0600. SQLite records: - `result_storage = inline | spool` - `result_size_bytes` - `result_sha256` For spooled results, `get_agent_task` returns: - a bounded `final_response` preview; - `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: - `text` - `offset_bytes` - `next_offset_bytes` - `eof` `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. ## 3. Compatibility rules - 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. ## 4. Verification contract v0.7.0 is not releasable until executed evidence covers: 1. event envelope `schema_version=1` and correlation propagation; 2. correlation validation and opaque behavior; 3. immutable manifest creation and exact SHA-256 verification; 4. task timeout and stale HITL behavior; 5. 168 h retention GC including result-spool deletion; 6. active-slot guard creation, crash persistence and mutation-side `WORKDIR_RECOVERY_REQUIRED`; 7. provider-aware reconciliation with no blind rerun; 8. inline <=256 KiB, spooled >256 KiB to <=8 MiB, fail >8 MiB; 9. exact multi-chunk UTF-8 result reconstruction and SHA-256; 10. protocol/MCP schema tests for the new result reader; 11. full Agent Bridge gate; 12. full root gate; 13. deployment/config syntax gates where touched; 14. documentation/version consistency. ## 5. Integration sequence 1. Freeze this plan on the v0.7 development branch. 2. Implement persistence/models + manifest + correlation/event envelope. 3. Implement lifetime/expiry/retention. 4. Implement spool/retrieval. 5. Implement persistent guard + provider-aware startup reconciliation. 6. Wire MCP surface and mutation-side recovery blocking. 7. Add regression/unit/integration tests. 8. Update README, Agent Bridge docs, config/deployment docs, AGENTS and versions. 9. Run targeted gates, then all applicable release gates. 10. Commit and push the development branch. 11. 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.