Compare commits

..

11 Commits

Author SHA1 Message Date
didericis-codex bb1776a858 refactor(supervisor): separate MCP dispatch from transport
test / image-input-builds (pull_request) Failing after 13m22s
test / unit (pull_request) Failing after 13m27s
test / coverage (pull_request) Has been skipped
test / integration-docker (pull_request) Has been cancelled
tracker-policy-pr / check-pr (pull_request) Successful in 14s
2026-07-27 04:45:59 +00:00
didericis-codex a24fe0264d refactor(egress): extract outbound DLP request stage
test / integration-docker (pull_request) Has been cancelled
test / image-input-builds (pull_request) Failing after 13m35s
test / unit (pull_request) Failing after 13m41s
test / coverage (pull_request) Has been skipped
tracker-policy-pr / check-pr (pull_request) Failing after 12m43s
2026-07-27 04:45:59 +00:00
didericis-codex 105538d3a6 refactor(egress): extract request policy stages 2026-07-27 04:45:59 +00:00
didericis-codex ffda40abae fix(orchestrator): bound streamed request bodies
test / integration-docker (pull_request) Has been cancelled
test / image-input-builds (pull_request) Successful in 42s
test / unit (pull_request) Failing after 14m6s
test / coverage (pull_request) Has been skipped
tracker-policy-pr / check-pr (pull_request) Failing after 13s
2026-07-27 04:45:59 +00:00
didericis-codex 7dcce2ff12 fix(orchestrator): keep host client dependency-free 2026-07-27 04:45:59 +00:00
didericis-codex 31a7efc0ed refactor(orchestrator): replace manual HTTP dispatch with FastAPI 2026-07-27 04:45:59 +00:00
didericis-codex a25ea7c188 build(orchestrator): pin FastAPI runtime dependencies 2026-07-27 04:45:59 +00:00
didericis-codex 3dbf1780b4 docs(prd): require shared storage permissions
prd-number-check / require-numbered-prds (pull_request) Successful in 11s
test / image-input-builds (pull_request) Successful in 45s
test / integration-docker (pull_request) Successful in 1m8s
test / unit (pull_request) Successful in 2m30s
test / coverage (pull_request) Successful in 25s
tracker-policy-pr / check-pr (pull_request) Failing after 12m49s
2026-07-27 04:45:45 +00:00
didericis-codex ff4da6f41e docs(prd): bound heavy gateway operations
prd-number-check / require-numbered-prds (pull_request) Successful in 10s
test / unit (pull_request) Successful in 54s
test / coverage (pull_request) Has been skipped
test / integration-docker (pull_request) Has been cancelled
test / image-input-builds (pull_request) Successful in 53s
tracker-policy-pr / check-pr (pull_request) Failing after 14m19s
2026-07-27 04:16:56 +00:00
didericis-codex 3bb90da11c docs(prd): require cleanup execution integrity
test / image-input-builds (pull_request) Failing after 14m11s
test / unit (pull_request) Failing after 14m19s
prd-number-check / require-numbered-prds (pull_request) Failing after 14m25s
test / integration-docker (pull_request) Has been cancelled
test / coverage (pull_request) Has been skipped
tracker-policy-pr / check-pr (pull_request) Failing after 12m36s
2026-07-27 03:55:18 +00:00
didericis-codex 0146450951 docs(prd): extend authoritative cleanup boundaries
prd-number-check / require-numbered-prds (pull_request) Successful in 13s
test / image-input-builds (pull_request) Successful in 3m18s
test / unit (pull_request) Successful in 57s
test / integration-docker (pull_request) Successful in 1m9s
test / coverage (pull_request) Successful in 19s
tracker-policy-pr / check-pr (pull_request) Failing after 10m30s
2026-07-27 03:31:46 +00:00
@@ -13,7 +13,9 @@ resource-consuming boundary revalidate the assumptions it acts on. This
finishes the focused quality work begun under #444 without broad rewrites:
cleanup cannot act on stale identities, policy introspection cannot publish a
fabricated empty policy, gateway servers bound untrusted work, and daemon
shutdown does not emit uncaught background-thread failures.
shutdown does not emit uncaught background-thread failures. Shared
control-plane storage and gateway credential provisioning also enforce their
filesystem security contract before sensitive data is written.
## Problem
@@ -36,6 +38,27 @@ misleading behavior:
destructive plan.
5. Gateway log-pump threads race stream closure during shutdown and emit
uncaught exceptions even when shutdown otherwise succeeds.
6. Firecracker discovers VMs through whitespace-split `pgrep -a` output.
A configured cache path containing spaces can hide a live VM from the
snapshot and make its run directory appear orphaned.
7. Docker cleanup asks compose for its project snapshot in best-effort mode.
A transient query failure can therefore become an empty stopped-project
set and authorize deletion of associated state directories.
8. Firecracker artifact downloads and registry publication have no network
deadline, so an unresponsive registry can hold setup or release work
indefinitely.
9. Authenticated secret blobs select the unauthenticated legacy decoder when
their in-band version prefix is changed, allowing storage tampering to
bypass tag verification.
10. Cleanup executes the entire post-confirmation snapshot rather than the
intersection with what the operator saw, and mutation failures are not
reflected in the command result.
11. Git smart-HTTP can retain sixteen 100 MiB request bodies concurrently,
cleanup mutations have no subprocess deadline, and Firecracker signalling
failures bypass shared mutation accounting.
12. SQLite creates the shared control-plane database before its mode is
restricted, then suppresses permission-repair failures. Gateway transports
also differ in whether copied deploy-key modes are preserved.
These are one design problem: state used to authorize deletion, replacement,
or resource allocation must be authoritative at the point of use.
@@ -46,6 +69,8 @@ or resource allocation must be authoritative at the point of use.
appeared in a pre-confirmation snapshot.
- Firecracker cleanup proves immediately before action that a PID is still the
same Firecracker process and that a run directory is still orphaned.
- Firecracker process discovery reads NUL-delimited argv from `/proc`; paths
are never reconstructed from whitespace-delimited process listings.
- All backend cleanup discovery primitives raise a typed enumeration error on
operational failure. No backend may independently continue from a partial
snapshot.
@@ -60,6 +85,22 @@ or resource allocation must be authoritative at the point of use.
callers because bottles themselves are untrusted.
- Gateway child-output pumping treats expected stream closure during shutdown
as completion while preserving diagnostics for unexpected failures.
- Artifact pull, existence-check, and publication requests use explicit
network deadlines.
- Persisted secrets accept only the authenticated format. The schema migration
intentionally clears legacy rows; local agents are reprovisioned rather
than retaining a ciphertext-controlled downgrade path.
- Cleanup executes only resources present in both the displayed and current
authoritative plans, attempts every approved mutation, and returns failure
when any mutation does not complete.
- Git request bodies spool to disk behind a separate heavy-work semaphore;
cleanup commands have configurable deadlines; Firecracker signalling
failures aggregate while identity-verification uncertainty still aborts.
- The shared database directory and file are private before SQLite writes any
control-plane state; an inability to enforce those modes aborts startup.
- Gateway credential directories and files receive explicit private modes
inside the gateway, independent of Docker, Apple Container, or SSH copy
semantics.
- Unit tests cover PID/path reuse, partial backend enumeration, transient
policy resolution failure, slow bodies, concurrency saturation, and stream
closure races.
@@ -94,6 +135,13 @@ Backend-specific primitives define how to identify a resource. Firecracker
uses process start identity plus canonical config/run paths; container
backends use authoritative CLI queries and stable resource names/labels.
Container engines expose destructive name-based commands without a portable
compare-and-delete operation. Cleanup therefore refreshes after confirmation
and requires every discovery query to succeed, minimizing but not claiming to
eliminate the final name-reuse race. A future engine-specific stable-ID
primitive may close that residual window without moving control flow back
into each backend.
### Enforcement state versus introspection state
Egress enforcement retains its deny-all fallback because uncertainty must not
@@ -115,6 +163,17 @@ The gateway output pump catches only stream-closure exceptions expected after
the supervisor closes child pipes. Other I/O failures remain visible and are
reported through the supervisor's normal diagnostic channel.
### Shared filesystem security
The common SQLite store owns database creation for every backend. It creates
the parent directory and an empty database with private modes before opening
SQLite, repairs existing modes, verifies the resulting state, and propagates
every enforcement failure. Backend launchers do not duplicate this policy.
The backend-neutral gateway provisioner likewise applies directory and file
modes after transport copies complete. This avoids relying on copy behavior
that differs among Docker, Apple Container, and Firecracker's SSH transport.
## Implementation chunks
1. Existing fail-closed security and backend enumeration fixes.
@@ -124,6 +183,14 @@ reported through the supervisor's normal diagnostic channel.
5. Shared cleanup refresh/revalidation plus authoritative macOS discovery.
6. Strict supervisor introspection and bounded supervisor/Git HTTP work.
7. Gateway shutdown log-pump closure handling.
8. Lossless Firecracker process identities, authoritative Docker cleanup
queries, and bounded Firecracker artifact transfers.
9. Mandatory authenticated secret storage, shared cleanup-plan intersection
and mutation accounting, and contained Git backend process failures.
10. Disk-spooled and separately bounded Git bodies, cleanup command deadlines,
and classified Firecracker signalling failures.
11. Fail-closed shared database creation and backend-neutral gateway credential
permissions.
## Open questions