PRD: reprovision on gateway startup - bottle ca (chunk 1/5) #519
Open
didericis-claude
wants to merge 14 commits from
prd-0081-reconcile-1-ca into main
pull from: prd-0081-reconcile-1-ca
merge into: didericis:main
didericis:main
didericis:fix-demo-harness
didericis:prd-0081-reconcile-2-git-gate
didericis:production
didericis:staging
didericis:prd-forge-subroles
didericis:fix/shared-storage-permissions
didericis:fix/authoritative-cleanup-identities
didericis:fix/bounded-heavy-operations
didericis:fix/cleanup-execution-integrity
didericis:fix/gateway-output-pump-shutdown
didericis:fix/gateway-request-boundaries
didericis:fix/authoritative-cleanup-revalidation
didericis:refactor/egress-policy-pipeline
didericis:refactor/orchestrator-fastapi
didericis:refactor/supervisor-mcp-dispatch
didericis:chore/misc-quality-cleanup
didericis:host-control-server-2-secret
didericis:host-control-server-3-list-live
didericis:host-control-server-1-transport
didericis:prd-new-host-control-server
didericis:fix/gitgate-persist-512
didericis:fix/firecracker-gateway-ca-persist-510
didericis:didericis/disable-agit-refs
didericis:didericis/prd-audit-event-schema
didericis:fix/pr-495-audit-contract
didericis:prd-egress-control-plane
didericis:prd-macos-container-ci-runner
didericis:refactor/control-plane-auth-provisioning-476
didericis:fix/db-off-data-plane-469
didericis:feat/encrypted-egress-secrets
didericis:spike/rootless-docker-macos
didericis:fix/ci-coverage-artifact-paths
didericis:claude-forward-host-credentials-rebased
didericis:fix-gateway-gitleaks-arch
didericis:fix/websocket-response-dlp-multitenant
didericis:orchestrator-agent-compose
didericis:orchestrator-gateway-ca
didericis:orchestrator-consolidated-launch
didericis:orchestrator-gateway-provision
didericis:orchestrator-gateway-network
didericis:orchestrator-client
didericis:orchestrator-gateway-net
didericis:orchestrator-gitgate-provision
didericis:orchestrator-registration
didericis:orchestrator-lifecycle
didericis:orchestrator-supervise-writers
didericis:orchestrator-supervise-multitenant
didericis:orchestrator-gitgate-multitenant
didericis:orchestrator-rename-gateway
didericis:orchestrator-slice8
didericis:orchestrator-slice7
didericis:orchestrator-slice6
didericis:prd-orchestrator
didericis:orchestrator-slice5
didericis:orchestrator-slice4
didericis:orchestrator-slice3
didericis:orchestrator-slice2
didericis:firecracker-backend
didericis:forge-native-integration
didericis:prd-smolmachines-linux
didericis:manifest-break-import-cycle
didericis:dlp-supervise-quality-fixes
didericis:table-drive-dlp-tests
didericis:fix-integration-test-failures
didericis:fix/macos-container-relative-dockerfile
didericis:prd-0054-install-script
didericis:commit-bottle-state
didericis:pr-211
didericis:move-codex-auth-to-contrib
didericis:feat/pipelock-skip-scan-extensions
didericis:prd-0049-named-labelled-agents
didericis:harden-git-gate-shell-rendering
14 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3dc901c057 |
fix(docker): enumerate the active infra network
tracker-policy-pr / check-pr (pull_request) Successful in 21s
test / image-input-builds (pull_request) Successful in 59s
test / unit (pull_request) Successful in 1m2s
test / integration-docker (pull_request) Successful in 1m2s
test / coverage (pull_request) Successful in 15s
lint / lint (push) Successful in 58s
|
||
|
|
e49f9a4e53 |
fix(docker): fail closed on bottle enumeration
lint / lint (push) Successful in 1m2s
test / integration-docker (pull_request) Failing after 56s
test / image-input-builds (pull_request) Successful in 57s
test / unit (pull_request) Successful in 1m3s
test / coverage (pull_request) Has been skipped
tracker-policy-pr / check-pr (pull_request) Successful in 11s
|
||
|
|
a401310865 |
docs: renumber PRD 0083 -> 0081 across the reconcile chunk
test / image-input-builds (pull_request) Successful in 59s
test / integration-docker (pull_request) Successful in 1m3s
lint / lint (push) Successful in 3m32s
test / unit (pull_request) Successful in 2m47s
test / coverage (pull_request) Successful in 49s
tracker-policy-pr / check-pr (pull_request) Successful in 13s
Follows the base branch back to 0081. 0083 was already claimed by feat/pinned-infra-artifacts (docs/prds/0083-packaged-infra-artifacts.md), so the two PRDs would have collided on whichever merged second; 0081 is free. 29 references across 21 files — the "PRD 0083" prose in the backends, the shared gateway_attach flow, the tests, and the ADR — plus the PRD filename in the ADR's reference link, which now resolves again. requirements.gateway.lock matches "0083" inside a sha256 hash and is deliberately untouched. Unit suite unchanged: same 13 pre-existing failures as main (test_cli_start_selector, test_firecracker_cleanup). |
||
|
|
31b6724a52 |
docs: renumber PRD 0081 -> 0083 across the reconcile chunk
Follows the base PR's renumber (0081 was already taken; main is on 0082). Update every `PRD 0081` reference in the gateway-attach code, tests, and ADR 0006, plus ADR 0006's link to the PRD file. No behaviour change. Refs #516, #519. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
6f3b221823 |
fix(backend): finish infra_launch rename + base cap after rebase onto main
Reconciles the chunk-1 rebase onto the current main: - `_network_container_ips` (added on main) raised the pre-rename `ConsolidatedLaunchError`; renamed to `InfraLaunchError` to match the rest of the rename. - main grew `backend/base.py` to 563 lines; with the gateway-attach contract (39 lines) it is 602, so the guardrail cap moves 600 -> 615. The reconcile flow still lives in `backend/gateway_attach.py`, not base.py. Refs #516, #519. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
c73d6508bc |
fix(backend): reconcile reads the booted gateway's CA, not a default (0081)
The gateway-attach reconcile (PRD 0081) gathered its resources via a fresh default DockerInfraService(), so on a cold-boot bring-up of a NON-default gateway instance — e.g. an isolated integration test's `-itest-` gateway — it read the default `bot-bottle-orch-gateway`, which doesn't exist for that instance, and setUpClass died with "No such container: bot-bottle-orch-gateway" (the 0081 PR's integration-docker job). Thread the infra service whose gateway just cold-booted from DockerInfraService.ensure_running() into DockerBottleBackend so _gateway_attach_resources() reads THAT gateway's CA. Ordinary construction (no infra) still falls back to the per-host default singleton — production is unchanged — and the resources-first / fail-hard reconcile ordering is kept. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
ffffe66c95 |
refactor(backend): base owns the gateway-attach flow, fail hard (0081 review)
Addresses review on #519 (@didericis 6143 + the fail-hard direction over the codex skip). Base owns the flow (6143 / ADR 0006). `attach_bottled_agents_to_gateway()` is now a concrete method on `BottleBackend` that delegates to `gateway_attach.reconcile_running_bottles`; backends override only three primitives — `_gateway_attach_resources()`, `_running_bottles()`, `_attach_bottle_to_gateway()`. The shared control flow + error policy live in one place so a backend can't drift onto a bespoke loop or a silent skip. Keeps the reconcile flow + `GatewayAttachResources` out of `backend/base.py` (the size guardrail) in a dedicated `backend/gateway_attach.py`. New ADR 0006 records the "shared behaviour in the base backend, subclasses override primitives" theme. Fail hard, never skip (the maintainer's direction over the codex review's skip). Any attach failure now aborts bring-up instead of being logged and skipped: a bottle that silently can't reach the fresh gateway (its egress just starts failing TLS) is worse than a loud failure. Every bottle is attempted and the failures are raised together (aggregate `InfraLaunchError`) so one bring-up surfaces the full blast radius. Resource gathering (the CA fetch) also fails hard. PRD 0081 goal + design updated to match (reversed from the earlier "tolerate per-bottle failures" draft). Bumps the base.py guardrail cap 580->600 for the new contract surface (the delegator + 3 abstract primitives); the flow itself lives in gateway_attach.py. Refs #516, #519. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
56cbd4a257 |
refactor(backend): rename consolidated_launch -> infra_launch (0081 review)
Mechanical rename addressing review 6141 on #519: "consolidated launch" was unclear about what it composes. Rename the per-backend module `consolidated_launch.py` -> `infra_launch.py` and the error `ConsolidatedLaunchError` -> `InfraLaunchError` across all three backends and their callers/tests. Unify the three identical per-backend error classes into one `InfraLaunchError` defined in `backend/base.py` (re-exported by each `infra_launch`) so the base backend can raise and catch a single shared type — groundwork for the base owning the gateway-attach flow. Add a glossary entry defining **infra** = the per-host gateway + orchestrator service pair every bottle attaches to. No behavior change. Refs #516, #519. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
36f594b770 |
feat(backend): reconcile running bottles' CA on gateway bring-up (0081)
Add `attach_bottled_agents_to_gateway()` as an `@abc.abstractmethod` on `BottleBackend` and implement the first reconcile step across all three backends: on a gateway cold boot, replace every already-running agent's trusted CA with the freshly-minted gateway CA. Reconciling running bottles is a backend responsibility (only the backend can enumerate its agents and reach them — firecracker over SSH, docker/macOS over exec/cp), so making it an abstract method keeps the fix cross-backend by construction. The gateway rootfs is ephemeral, so a rebuild mints a new CA that every running bottle distrusts (SSL verification fails — #510). This reconcile is what distributes the fresh CA, so a routine gateway rebuild now doubles as a free CA rotation. Per-bottle steps are best-effort: one unreachable or malformed bottle is logged and skipped, never blocking the others. Trigger — `Gateway.connect_to_orchestrator` now returns a cold-boot bool (True when it actually (re)brought the gateway up, False when a healthy current gateway was left untouched); each infra `ensure_running` gates the reconcile on it, so it fires exactly on cold boot and never on an adopt. Git-gate re-provision and egress-token restore fold into this same reconcile on the same trigger in follow-up PRs (#516). Refs #516. Addresses #510. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
314b30c013 |
docs(prd): renumber 0083 -> 0081, and point at the umbrella issue
prd-number-check / require-numbered-prds (pull_request) Successful in 14s
test / image-input-builds (pull_request) Successful in 46s
test / unit (pull_request) Successful in 1m0s
test / integration-docker (pull_request) Successful in 1m8s
test / coverage (pull_request) Successful in 18s
tracker-policy-pr / check-pr (pull_request) Successful in 14s
|
||
|
|
cf6bbc43da |
docs(prd): renumber 0081 -> 0083 (0081 already taken)
test / integration-docker (pull_request) Has been cancelled
prd-number-check / require-numbered-prds (pull_request) Successful in 14s
lint / lint (push) Successful in 1m4s
test / image-input-builds (pull_request) Successful in 59s
tracker-policy-pr / check-pr (pull_request) Successful in 11s
test / unit (pull_request) Failing after 13m55s
test / coverage (pull_request) Has been skipped
PRD number 0081 was claimed by another PRD before this one merged (main is on 0082); renumber this design to the next free slot, 0083. File + title only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
4e26e075c8 |
docs(prd): reconcile via a backend-ABC method across all backends (0081 review)
Address review: target all backends, not firecracker-only. Make the reconcile an @abc.abstractmethod `attach_bottled_agents_to_gateway()` on BottleBackend so every backend implements it (cross-backend by construction) and the host calls it on gateway bring-up. Drop the docker/macOS non-goal; add the open question of retiring docker's now-redundant CA bind-mount. Refs #516 |
||
|
|
cca724244e |
feat(orchestrator): update a single egress secret in place (0081)
Add a single-secret counterpart to reprovision_from_secret's restore-all: update ONE egress token for a running bottle without a relaunch, for refreshing a short-lived host credential (e.g. the Codex access token) whose launch-time snapshot has expired. - registry_store.store_agent_secret: per-key upsert (delete+insert of the one row), the counterpart of store_agent_secrets' replace-all. - OrchestratorCore.update_agent_secret: set the in-memory token AND upsert the re-encrypted row under the bottle's env_var_secret, leaving other tokens untouched. - POST /bottles/<id>/secret (cli-only) + client.update_agent_secret. Refs #510, #512 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
cecc1b4d60 |
docs(prd): reprovision gateway-dependent state on gateway bring-up (0081)
Reconcile every running bottle against a freshly-booted gateway (replace each agent's CA, re-provision git-gate, restore egress tokens) instead of persisting gateway state on volumes. Supersedes the abandoned CA-volume (#511) and git-gate-volume (#513) PRs. Refs #510, #512 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |