TODOS.md
Rama main · réplica de lectura del repositorio original.
# TODOS
Deferred items from the Gantry deployment-modes plan
([docs/architecture/deployment-profiles.md](docs/architecture/deployment-profiles.md)).
Each item records why it is deferred and the trigger to revisit it. These are out
of scope for the current plan by explicit decision; do not implement them as part
of Phases 0–3.
| Item | Why deferred | Trigger to revisit |
| --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Fleet management UI | The desired-state control API ships first and is the UI's backend; the UI is its own plan. See [ADR Settings Authority](docs/decisions/0025-settings-authority.md). | Control-API desired-state endpoints are shipped and stable (end of Phase 3). |
| GCP / Azure Terraform module sets | AWS-first per user; module interfaces stay cloud-neutral so these are cheap to add later. See [ADR Delivery Vehicle](docs/decisions/0022-delivery-vehicle.md). | A deployment target requires GCP or Azure. |
| Helm chart / Kubernetes operator | Terraform-first per user (gate U1 pending); cloud-neutral interfaces keep K8s open. | A deployment target requires Kubernetes, or gate U1 resolves to ship Helm. |
| Support **product** layer (CRM, human handoff, retention, customer-visible audit) | This plan ships the security envelope (locked preset, isolation); the product layer is a separate plan (Codex finding). | Locked support stack is in production and a customer-facing support product is prioritized. |
| Browser profile snapshot GC / TTL | The cross-worker browser profile store (snapshot on turn end → restore on launch) shipped, but has **no garbage collection or TTL**: every changed snapshot writes a new content-addressed object under `browser-profiles/<name>/<hash>/`, and old objects + superseded rows are never reaped. Storage grows unbounded with browser activity. A reaper (expire snapshot objects/rows past a TTL or beyond the current content hash, like the toolchain noncurrent-version lifecycle) is the fix. | Fleet S3 storage pressure, or a high-churn browser agent accumulating snapshots. |
| Customer-side image-bake CI pipeline | The sandboxed bake-job toolchain artifacts cover fleet correctness without customer-side CI. See [ADR Capability Artifacts](docs/decisions/0021-capability-artifacts.md). | A customer needs to build/publish their own worker images in their own CI. |
| Support-agent rate limiting | The existing conversation sender policy covers v1. | Observed abuse exceeds what the sender policy bounds, or a per-support-agent quota is required. |
| pip bake lane (live Python package installs in fleet) | The bake subsystem is npm-only by binding decision; the worker image now ships python3 so Python skill _scripts_ run, but Python _packages_ would need a pip lane (lockfile-pinned venv baked as an artifact, same shape as npm). Language enforcement lives in one place (the bake manifest validator), so this is a contained addition. | Skill authors need per-skill Python dependencies in fleet (not satisfiable by adding common libs to the image). |
| Pinned-binary bake lane (Go-built and other static CLI tools) | Go-built tools ship as static binaries, not toolchains; today each is one Dockerfile line (image roll). A bake lane distributing admin-approved URL + sha256-pinned binaries as verified artifacts would avoid image rolls per tool. The Go toolchain itself stays out of the image (runtime compilation = worker self-mutation). | Image rolls for individual CLI tools become frequent enough to hurt. |
| CLI dry-run probe with missing-OS-dependency report | When an agent requests a CLI tool absent from the fleet image, run the existing local_cli preflight as a dry run and return a structured "missing from worker image: <packages>" message the agent relays to the admin (who adds it to ops/docker/Dockerfile and rolls). Builds on the capability-paused one-clear-action surface; never triggers live installs on workers. | First fleet deployment where agents regularly request CLI tools not in the image. |
| Locked-agent unmet-need telemetry | Instruction stripping means a locked agent never attempts capability tools, so `denied_by_profile` audit rows capture forged attempts only — genuine customer demand ("N users asked for X this week") leaves zero signal. Needs a locked-safe demand record (audit event when the agent reports inability, or transcript mining) designed together with the human-handoff piece of the support product layer. | Locked support stack reaches production traffic, or the support product layer plan starts. |
| Fleet container sandbox hardening (tailored seccomp profile + doctor check) | PARTIALLY LANDED 2026-06-12: fleet rehearsal compose and the Terraform worker `docker run` now pass `--security-opt seccomp=unconfined` so bubblewrap namespaces work, and fleet desired state seeds `runtime.sandbox.provider: sandbox_runtime` (the production security gate rejects `direct`, so this is also a boot-coherence fix). Remaining: replace `seccomp=unconfined` with a reviewed userns-capable seccomp profile (unconfined removes container-level syscall filtering for the runtime process; bubblewrap still confines runner children), add the boot-time `doctor-runner-sandbox` check surfaced through readyz/logs, and prove the rehearsal stack boots a sandboxed turn end-to-end. | Before the first production fleet that runs untrusted/public-facing agent workloads. |
| Subagent-aware run slots | Native SDK subagents execute inside their parent turn's runner process: a turn that fans out N subagents consumes one run slot but multiplies memory and model load invisibly to `runtime.queue` and `run_slots` accounting. Fine at v1 scale; needs slot weighting or a per-runner subagent cap when dense fan-out becomes common. | Memory pressure or noisy-neighbor incidents on workers traced to subagent-heavy turns. |
| Live-conversation auto-resume after bake | Scheduled jobs self-heal when a capability lands (readiness unpauses → runs → notifies); a live conversation blocked on a dependency does not resume — the bake success notice tells the user to re-ask, which covers v1. Auto-resume would need a durable "blocked turn" record reattached on capability activation. | Users in fleet regularly hit the approve→wait→re-ask loop and the re-ask friction matters. |
| Simple-YAML codec escaping fidelity | `yaml.ts` `unquote` strips outer quotes without unescaping `\"`/`\\`, while the renderer quotes via `JSON.stringify` — string settings values containing `"` or `\` gain backslashes on round-trip (pre-existing file-surface defect; since the typed settings document is produced through the same codec, it is also visible in the desired-state API GET payload). Relatedly, the codec's scalar parser only number-parses integers, so the one float field (`memory.llm.extractor_min_confidence`) appears as a string in the document (re-hydration coerces correctly). | A settings value legitimately needs `"` or `\` (e.g. Windows paths), or SDK consumers start reading numeric fields off the desired-state document. |