dev_plan_v0.7.md
Rama main · réplica de lectura del repositorio original.
# 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/<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:
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/<task_id>.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.