Ctrl K
ComunidadGuías…

dev_plan_v0.7.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# 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.