Ctrl K
ComunidadGuías…

dev_plan_v0.14.md

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

Archivo original ↗Preguntar a KiBot
# ServerFS v0.14.0 Development Plan

Status: implementation and Windows release acceptance complete; release closeout approved.

## Goal

Make the Windows native deployment persistent without ever requiring administrator privileges for installation, runtime, upgrade, inspection, recovery, or uninstall.

The current Windows deployment is manually launched by `deployment/windows/start-native.ps1`. Its internal lifecycle is already strong (sanitizer supervisor, per-user Agent lifecycle lease, Named Pipe identity, Job Object containment), but the outer `serverfs tunnel` process has no OS-owned persistent lifecycle. When that top-level tree exits, recovery currently requires a human to run the PowerShell launcher again.

v0.14.0 closes that outer lifecycle gap.

## Non-negotiable platform invariant

Windows remains entirely **current-user scoped and non-elevated**:

- no SCM/Windows Service registration;
- no `HKLM` service template or machine-wide installer;
- no UAC elevation, `runas`, administrator token, system account, stored account password, or `LogonType=Password`;
- no root/system-wide maintenance step;
- all lifecycle state stays under the current user's profile/application-data boundary;
- provider CLIs continue to run in the interactive user's security context and keep their existing user-owned configuration/authentication.

This is a project-wide deployment invariant, not an implementation convenience.

## Architecture decision

Use **Windows Task Scheduler 2.0** as the OS persistence backend for Windows native ServerFS.

The registered task is deliberately constrained to:

- current user SID;
- `InteractiveToken` logon type;
- `LeastPrivilege` run level;
- current-user `LogonTrigger` for sign-in startup;
- an indefinite one-minute `TimeTrigger` heartbeat for deterministic outer ownership recovery;
- `MultipleInstancesPolicy=IgnoreNew` so healthy ownership remains single-instance;
- no idle/network/battery gating;
- unlimited execution time;
- Task Scheduler `RestartOnFailure` retained as an additional safety net rather than the only recovery path.

The final implementation uses three explicit recovery layers. Task Scheduler owns a windowless ServerFS watchdog; the watchdog owns one managed runner in a kill-on-close Job Object and restarts it with a short bounded backoff; the runner owns one Tunnel generation at a time and restarts Tunnel generations with its own bounded backoff.

Normal topology:

```text
Windows Task Scheduler 2.0
  current user · InteractiveToken · LeastPrivilege
  LogonTrigger + 1-minute repeating TimeTrigger
  MultipleInstancesPolicy = IgnoreNew
  -> windowless ServerFS watchdog
       -> managed runner
            -> official tunnel-client
                 -> sanitizer supervisor
                      -> serverfs serve
                      -> Agent Bridge
                           -> Codex / Claude / Qoder
```

`serverfs-windows-native` remains the narrow Rust/NTFS kernel wheel. Service/persistence logic belongs to the Python product/deployment layer and must not be added to the filesystem kernel crate.

## Public CLI

Keep one cross-platform operator surface:

```text
serverfs service install --config <serverfs.toml> [--env-file <.env>]
serverfs service status
serverfs service start
serverfs service stop
serverfs service restart
serverfs service uninstall
```

`serverfs service ...` dispatches to:

- macOS: existing `SMAppService` implementation;
- Windows: Task Scheduler implementation;
- other platforms: fail closed with a clear unsupported-platform error.

Windows `install` registers/updates the persistent current-user task and private manifest. It does not require elevation. `start` enables and starts it; `stop` disables then ends the running task, so an intentional stop cannot be mistaken for a failure and restarted. `restart` performs stop/start. `uninstall` stops and removes only v0.14.0-owned current-user artifacts.

A hidden internal runner command may be used by the scheduled task, but it is not a public operational interface.

## Runtime configuration boundary

The task stores only absolute non-secret paths and identifiers. Secrets must never appear in Task Scheduler XML, argv, task names, logs, or status output.

The runner reads the existing untracked sibling `.env` and preserves the already-supported Windows launcher environment contract, including the dedicated Agent proxy/Bridge interpreter values needed before the sanitizer supervisor starts. Control-plane credentials continue to use the existing external per-user key file boundary.

## Reliability behavior

Recovery is layered and independently bounded:

1. the runner starts and contains one Tunnel generation, records its redacted exit/runtime evidence and restarts it with a 5s→60s bounded backoff;
2. the windowless watchdog contains the runner in a kill-on-close Job Object and restarts it with a 2s→30s bounded backoff;
3. Task Scheduler uses the current-user logon trigger plus an indefinite one-minute TimeTrigger heartbeat to recreate a missing outer Task action; `RestartOnFailure` remains an additional native safety net;
4. `MultipleInstancesPolicy=IgnoreNew` prevents the heartbeat from duplicating a healthy watchdog;
5. `service stop` disables the task before ending the action, so neither heartbeat nor failure recovery can resurrect an intentional stop;
6. a native current-user ownership mutex prevents managed and direct/manual Tunnel trees from coexisting.

A configuration/startup failure therefore retries slowly rather than crash-looping, while operator stop remains authoritative.

## Status / observability

`serverfs service status` on Windows must report a structured JSON snapshot including at least:

- platform/backend (`windows-task-scheduler`);
- registered/enabled state;
- whether the registered task still matches the v0.14.0 current-user/least-privilege contract;
- watchdog PID/liveness and runner PID/liveness when available;
- last runner restart evidence and last Tunnel generation start/exit evidence;
- watchdog→runner, runner→Tunnel and Task Scheduler restart/heartbeat policy evidence;
- log directory and lifecycle state paths;
- no credentials or proxy endpoints.

Runtime logs live under the current user's ServerFS application-data directory.

## Implementation slices

### A. Windows lifecycle product layer

Add `src/serverfs_mcp/windows_service.py`:

- Task Scheduler XML generation and validation;
- current-user SID binding;
- safe `schtasks.exe` invocation through the Windows system directory;
- install/start/stop/restart/status/uninstall;
- private manifest/runtime-state/log paths;
- lifecycle runner with bounded restart backoff;
- process/job cleanup on runner termination.

### B. Tunnel child containment

Extend the internal native Tunnel launcher narrowly so a caller may receive/contain the spawned `tunnel-client` process and redirect its stdout/stderr. Existing direct `serverfs tunnel` behavior must remain unchanged when these optional hooks are absent.

### C. CLI dispatch

Generalize `serverfs service ...` from darwin-only to explicit platform dispatch while preserving the existing macOS behavior.

### D. Tests

Add regression coverage for:

- Task XML binds exactly the current user SID;
- `InteractiveToken` + `LeastPrivilege` are mandatory;
- no password/elevation/SCM/HKLM contract appears;
- logon trigger and restart-on-failure settings are present;
- secrets are absent from task XML/argv;
- install uses only the current-user Task Scheduler path;
- stop disables before ending, preventing automatic relaunch;
- start enables then runs;
- restart ordering;
- uninstall removes only owned task/artifacts;
- status validation rejects/makes visible a drifted task definition;
- runner backoff and healthy-run reset;
- Tunnel child containment/cleanup on error;
- macOS `serverfs service` behavior remains unchanged.

### E. Windows live acceptance

On the WorkPC Windows 11 native environment, verify without elevation:

1. install/update the task;
2. inspect the registered XML and current-user principal;
3. start and reach live ChatGPT connectivity;
4. kill `tunnel-client` and observe runner-level recovery without manual launcher use;
5. kill the managed runner and observe watchdog-level recovery;
6. kill the Task Scheduler Action launcher and observe native heartbeat recovery;
7. `service stop` remains stopped and `service start` restores connectivity;
8. Agent delegation still works after managed restart;
9. the managed tree exposes no visible top-level terminal windows;
10. task remains configured to start at the next logon.

Earlier development evidence recorded Tunnel recovery ≈5.20s, runner recovery ≈3.09s, outer Task Action recovery ≈52.39s, and explicit start recovery ≈1.04s. The WorkPC service state was later disturbed during development, so those historical timings are not treated as fresh release evidence.

Final WorkPC release acceptance on 2026-10-14 ran from an observer outside the managed ServerFS tree under the non-elevated current user and revalidated every layered recovery boundary. Tunnel-generation recovery completed in about 6.4s while watchdog/runner identities remained stable; runner recovery completed in about 2.73s while the watchdog stayed stable; terminating the outer watchdog was recovered by the Task Scheduler heartbeat in about 18.5s; intentional `service stop` remained stopped after a 70s observation window; explicit `service start` restored the managed tree in about 1.1s; Agent Bridge/MCP recovered with Claude/Codex/Qoder available; a fresh workspace-write probe completed and released its writer lease/guard; the final tree was windowless, exactly-one, current-user and least-privilege. No repository/config/package/runtime-environment mutation or administrator path was used during acceptance. A physical reboot/logout-login cycle was not executed, so only the presence of the configured LogonTrigger is claimed, not measured reboot/re-login recovery. Full release evidence is recorded in `docs/v0.14.0-windows-live-acceptance-2026-10-14.md`.

## Release closeout

Before tagging v0.14.0:

- bump all release version surfaces to 0.14.0;
- update README, Windows deployment docs, maintainer invariants/workflow, release-facing English/Chinese site content;
- describe v0.14.0 as already released in current-state copy only at the final release-facing cleanup stage;
- keep historical plans/evidence historically accurate;
- run root lint/format/test gates plus Windows-native tests and live acceptance;
- run site build and stale current-state wording scan;
- commit/push final main;
- tag immutable `v0.14.0` on the verified commit;
- publish the GitHub Release from that tag;
- verify tag/release/CI state and the live WorkPC managed service.