PRD: reprovision on gateway startup - bottle ca (chunk 1/5) #519

Open
didericis-claude wants to merge 9 commits from prd-0081-reconcile-1-ca into prd-gateway-reprovision-on-bringup
Collaborator

Stacked on #517. First of the bring-up reconcile PRs tracked by #516.

Implements the reconcile contract + its first step (CA):

  • attach_bottled_agents_to_gateway() as an @abc.abstractmethod on BottleBackend (backend/base.py). 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 every backend must implement it. Cross-backend by construction, no per-backend follow-up.
  • CA reconcile in all three backends: on a gateway cold boot, replace each already-running agent's trusted CA with the freshly-minted gateway CA and rebuild its trust store (unconditional — there is one gateway, so no fingerprint match). The gateway rootfs is ephemeral, so a rebuild mints a new CA that running bottles distrust (SSL certificate verification failed#510); this is what distributes the fresh CA, so a routine gateway rebuild now doubles as a free CA rotation.
  • 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.
  • Per-bottle steps are best-effort: one unreachable/malformed bottle is logged and skipped, never blocking the others or the gateway coming up.

Still to come on this branch (see #516)

  • git-gate re-provision folded into the same reconcile (fixes #512).
  • egress-token restore folded in + short-lived host-credential (Codex) refresh; retire the launch-time _reprovision_running_bottles.
  • drop docker/macOS host_gateway_ca_dir bind-mount so they rotate the CA like firecracker (maintainer confirmed "consistent across backends" on #517).

Tests: ABC + CA push per backend (test_backend_secret_reprovision), the cold-boot bool on each connect_to_orchestrator (test_orchestrator_gateway / test_firecracker_gateway / test_macos_gateway), and the cold-boot-gated wiring in each infra (test_*_infra). Full unit suite green (the sole failure is test_wheel_install, an environment-only missing-build-module issue, unrelated).

Refs #516. Addresses #510.

🤖 Generated with Claude Code

Stacked on #517. First of the bring-up reconcile PRs tracked by #516. Implements the reconcile **contract** + its first step (**CA**): - **`attach_bottled_agents_to_gateway()` as an `@abc.abstractmethod` on `BottleBackend`** (`backend/base.py`). 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 every backend must implement it. Cross-backend by construction, no per-backend follow-up. - **CA reconcile** in all three backends: on a gateway cold boot, replace each already-running agent's trusted CA with the freshly-minted gateway CA and rebuild its trust store (unconditional — there is one gateway, so no fingerprint match). The gateway rootfs is ephemeral, so a rebuild mints a new CA that running bottles distrust (`SSL certificate verification failed` — #510); this is what distributes the fresh CA, so a routine gateway rebuild now **doubles as a free CA rotation**. - **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**. - Per-bottle steps are best-effort: one unreachable/malformed bottle is logged and skipped, never blocking the others or the gateway coming up. **Still to come on this branch (see #516)** - git-gate re-provision folded into the same reconcile (fixes #512). - egress-token restore folded in + short-lived host-credential (Codex) refresh; retire the launch-time `_reprovision_running_bottles`. - drop docker/macOS `host_gateway_ca_dir` bind-mount so they rotate the CA like firecracker (maintainer confirmed "consistent across backends" on #517). **Tests:** ABC + CA push per backend (`test_backend_secret_reprovision`), the cold-boot bool on each `connect_to_orchestrator` (`test_orchestrator_gateway` / `test_firecracker_gateway` / `test_macos_gateway`), and the cold-boot-gated wiring in each infra (`test_*_infra`). Full unit suite green (the sole failure is `test_wheel_install`, an environment-only missing-`build`-module issue, unrelated). Refs #516. Addresses #510. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
didericis-codex requested changes 2026-07-26 20:15:51 -04:00
Dismissed
didericis-codex left a comment
Collaborator

P1 — CA lookup failures abort gateway startup on Docker and macOS. In bot_bottle/backend/docker/consolidated_launch.py:123-124 and bot_bottle/backend/macos_container/consolidated_launch.py:144-145, ca_cert_pem() is called outside the best-effort exception handling. It can raise GatewayError after its polling timeout. Because these methods run synchronously from ensure_running(), a temporarily unavailable CA makes the whole bring-up command fail after the gateway has already started. This contradicts the stated contract that reconciliation never blocks the gateway coming up. Firecracker already handles this correctly. Please catch GatewayError around CA retrieval, log the skipped reconciliation, and return.

I could not run the focused tests because pytest is not installed in the review environment. Static inspection otherwise found no additional correctness issues.

P1 — CA lookup failures abort gateway startup on Docker and macOS. In `bot_bottle/backend/docker/consolidated_launch.py:123-124` and `bot_bottle/backend/macos_container/consolidated_launch.py:144-145`, `ca_cert_pem()` is called outside the best-effort exception handling. It can raise `GatewayError` after its polling timeout. Because these methods run synchronously from `ensure_running()`, a temporarily unavailable CA makes the whole bring-up command fail after the gateway has already started. This contradicts the stated contract that reconciliation never blocks the gateway coming up. Firecracker already handles this correctly. Please catch `GatewayError` around CA retrieval, log the skipped reconciliation, and return. I could not run the focused tests because `pytest` is not installed in the review environment. Static inspection otherwise found no additional correctness issues.
didericis reviewed 2026-07-26 20:17:48 -04:00
didericis requested changes 2026-07-26 20:29:02 -04:00
Dismissed
didericis left a comment
Owner

Same inconsistency @didericis-codex mentioned, but solve should be in the opposite direction (purposefully fail gateway startup). We don't want hidden broken behavior. If PRD needs updating for that do it. Also noticed some other issues.

Same inconsistency @didericis-codex mentioned, but solve should be in the opposite direction (purposefully fail gateway startup). We don't want hidden broken behavior. If PRD needs updating for that do it. Also noticed some other issues.
@@ -507,0 +524,4 @@
fingerprint match is needed), which rotates the CA for free on every
bring-up. Git-gate re-provision and egress-token restore fold into this
same reconcile on the same trigger (see #516)."""
Owner

We should enforce the flow more in here/only overwrite specific methods so things are more consistent. This is a larger theme we should have as an ADR somewhere... as much as possible, try to encode shared behavior in the base backend logic. We want to lean towards LESS freedom in the specific backend implementations, and MORE consistency.

Basic structure is I think uniform. Rough shape

  1. Find resources (CA, secrets, etc) needed to connect a bottle to the gateway
  2. List active running bottles
  3. For each running bottle, pass the stuff from step 1 to the bottle/gateway
We should enforce the flow more in here/only overwrite specific methods so things are more consistent. This is a larger theme we should have as an ADR somewhere... as much as possible, try to encode shared behavior in the base backend logic. We want to lean towards LESS freedom in the specific backend implementations, and MORE consistency. Basic structure is I think uniform. Rough shape 1. Find resources (CA, secrets, etc) needed to connect a bottle to the gateway 2. List active running bottles 3. For each running bottle, pass the stuff from step 1 to the bottle/gateway
@@ -77,0 +139,4 @@
_push_ca_to_container(name, ca_pem)
reconciled += 1
except (OSError, ConsolidatedLaunchError) as exc:
log.info(f"CA reconcile skipped for {name}: {exc}")
Owner

Same comment as below, never skip

Same comment as below, never skip
@@ -92,0 +106,4 @@
input=ca_pem, capture_output=True, text=True, check=False,
)
if proc.returncode != 0:
raise ConsolidatedLaunchError(
Owner

Nit, but should rename this "InfraLaunchError" and have a consistent infra_launch file across backends. "consolidated launch" is unclear. In glossary explain "infra" refers to the gateway and orchestrator services.

Nit, but should rename this "InfraLaunchError" and have a consistent `infra_launch` file across backends. "consolidated launch" is unclear. In glossary explain "infra" refers to the gateway and orchestrator services.
@@ -92,0 +124,4 @@
try:
ca_pem = gateway.ca_cert_pem()
except GatewayError as exc:
info(f"bring-up reconcile skipped: gateway CA unavailable: {exc}")
Owner

Don't skip, do a hard fail here

Don't skip, do a hard fail here
@@ -92,0 +136,4 @@
_push_gateway_ca_to_agent(private_key, guest_ip, ca_pem)
reconciled += 1
except (OSError, ConsolidatedLaunchError) as exc:
info(f"CA reconcile skipped for {guest_ip}: {exc}")
Owner

Same, do a hard fail/never skip. If the attachment doesn't work we want to vocalize it

Same, do a hard fail/never skip. If the attachment doesn't work we want to vocalize it
@@ -101,0 +146,4 @@
try:
agents = list(enumerate_active())
except (EnumerationError, OSError) as exc:
info(f"CA reconcile skipped: {exc}")
Owner

same issue as before/should fail hard

same issue as before/should fail hard
Author
Collaborator

Thanks both. Going with @didericis's fail-hard direction over the skip in the codex review: a bottle that silently can't reach the fresh gateway (TLS just starts failing) is exactly the hidden-broken-behavior we don't want, so a loud bring-up failure beats limping on. Concrete plan:

Fail hard, never skip (6139 / 6140 / 6142 / 6144, + codex's P1). Every attach step raises instead of log-and-continue — CA lookup and each per-bottle push, on all three backends. If a running bottle can't be reconciled against the fresh gateway, bring-up fails and names the bottle. This reverses the current PRD 0081 goal "per-bottle failures are tolerated / one unreachable bottle does not block the others" — I'll flip that goal in the PRD to say the opposite (fail loud on any attach failure).

  • One sub-decision I'll take unless you'd rather not: attempt all bottles and then raise an aggregate naming every one that failed, rather than fail-fast on the first — so a single bring-up surfaces the whole blast radius instead of one bottle per run. Say the word if you'd prefer fail-fast.

Encode the flow in the base backend (6143). Make attach_bottled_agents_to_gateway() a concrete method on BottleBackend that owns the shared shape + the fail-hard policy, with backends overriding only the primitives:

  1. _gateway_attach_resources() → what's needed to attach a bottle (CA now; egress secrets / git-gate state as the later stacked PRs land)
  2. _running_bottles() → enumerate the live bottles
  3. _attach_bottle_to_gateway(bottle, resources) → push the resources into one bottle (SSH for firecracker, exec+cp for docker/macOS)

The base runs steps 2–3 and raises on any failure, so a backend can't drift onto a bespoke loop or a silent skip. I'll capture the theme — shared behavior lives in the base backend; subclasses override primitives, not control flow — as an ADR under docs/decisions/.

Rename (6141). ConsolidatedLaunchErrorInfraLaunchError and consolidated_launch.pyinfra_launch.py across the three backends, plus a glossary entry defining infra = the gateway + orchestrator services. Heads-up that consolidated_launch is referenced fairly widely (including other in-flight branches), so I'll keep the rename mechanical and in its own commit to keep the diff readable.

Since 6143 is architectural and you called for an ADR, I'll start on the base-class refactor + fail-hard now unless you'd rather shape the primitive split first.

Thanks both. Going with @didericis's fail-hard direction over the skip in the codex review: a bottle that silently can't reach the fresh gateway (TLS just starts failing) is exactly the hidden-broken-behavior we don't want, so a loud bring-up failure beats limping on. Concrete plan: **Fail hard, never skip** (6139 / 6140 / 6142 / 6144, + codex's P1). Every attach step raises instead of log-and-continue — CA lookup *and* each per-bottle push, on all three backends. If a running bottle can't be reconciled against the fresh gateway, bring-up fails and names the bottle. This reverses the current PRD 0081 goal *"per-bottle failures are tolerated / one unreachable bottle does not block the others"* — I'll flip that goal in the PRD to say the opposite (fail loud on any attach failure). - One sub-decision I'll take unless you'd rather not: attempt **all** bottles and then raise an aggregate naming every one that failed, rather than fail-fast on the first — so a single bring-up surfaces the whole blast radius instead of one bottle per run. Say the word if you'd prefer fail-fast. **Encode the flow in the base backend** (6143). Make `attach_bottled_agents_to_gateway()` a *concrete* method on `BottleBackend` that owns the shared shape + the fail-hard policy, with backends overriding only the primitives: 1. `_gateway_attach_resources()` → what's needed to attach a bottle (CA now; egress secrets / git-gate state as the later stacked PRs land) 2. `_running_bottles()` → enumerate the live bottles 3. `_attach_bottle_to_gateway(bottle, resources)` → push the resources into one bottle (SSH for firecracker, exec+cp for docker/macOS) The base runs steps 2–3 and raises on any failure, so a backend can't drift onto a bespoke loop or a silent skip. I'll capture the theme — *shared behavior lives in the base backend; subclasses override primitives, not control flow* — as an ADR under `docs/decisions/`. **Rename** (6141). `ConsolidatedLaunchError` → `InfraLaunchError` and `consolidated_launch.py` → `infra_launch.py` across the three backends, plus a glossary entry defining **infra** = the gateway + orchestrator services. Heads-up that `consolidated_launch` is referenced fairly widely (including other in-flight branches), so I'll keep the rename mechanical and in its own commit to keep the diff readable. Since 6143 is architectural and you called for an ADR, I'll start on the base-class refactor + fail-hard now unless you'd rather shape the primitive split first.
Author
Collaborator

Pushed de80aaf..3c0d2fb addressing the review — two commits on top of the original:

4f2ccae rename (6141). consolidated_launch.pyinfra_launch.py and ConsolidatedLaunchErrorInfraLaunchError across all three backends + callers/tests. Unified the three identical per-backend error classes into one shared InfraLaunchError in backend/base.py. Added a glossary entry defining infra = the per-host gateway + orchestrator pair. No behaviour change.

3c0d2fb base owns the flow + fail hard (6143 + the fail-hard direction).

  • attach_bottled_agents_to_gateway() is now concrete on BottleBackend, delegating to gateway_attach.reconcile_running_bottles. Backends override only three primitives: _gateway_attach_resources()_running_bottles()_attach_bottle_to_gateway() — exactly the shape you sketched (find resources → list running bottles → attach each). The flow + GatewayAttachResources live in a new backend/gateway_attach.py so base.py stays the contract.
  • Fail hard, never skip (your direction over the codex skip): any attach failure now aborts bring-up. I went with attempt-all-then-aggregate as floated above — every bottle is attempted and the failures raise together (one InfraLaunchError naming them all) so a bring-up surfaces the full blast radius. Resource gathering (the CA fetch) fails hard too.
  • Captured the theme as ADR 0006 (shared behaviour in the base backend; subclasses override primitives, not control flow) and updated PRD 0081's goal/design (reversed the "tolerate per-bottle failures" line).
  • Bumped the base.py size guardrail 580→600 for the new contract surface (delegator + 3 abstract primitives); the flow itself is in gateway_attach.py, not base.py.

Verification: full unit suite green except test_wheel_install (environment missing the build module, unrelated); pyright clean; pylint 9.76. Ready for another look.

Pushed `de80aaf..3c0d2fb` addressing the review — two commits on top of the original: **`4f2ccae` rename (6141).** `consolidated_launch.py` → `infra_launch.py` and `ConsolidatedLaunchError` → `InfraLaunchError` across all three backends + callers/tests. Unified the three identical per-backend error classes into one shared `InfraLaunchError` in `backend/base.py`. Added a glossary entry defining **infra** = the per-host gateway + orchestrator pair. No behaviour change. **`3c0d2fb` base owns the flow + fail hard (6143 + the fail-hard direction).** - `attach_bottled_agents_to_gateway()` is now concrete on `BottleBackend`, delegating to `gateway_attach.reconcile_running_bottles`. Backends override only three primitives: `_gateway_attach_resources()` → `_running_bottles()` → `_attach_bottle_to_gateway()` — exactly the shape you sketched (find resources → list running bottles → attach each). The flow + `GatewayAttachResources` live in a new `backend/gateway_attach.py` so `base.py` stays the contract. - **Fail hard, never skip** (your direction over the codex skip): any attach failure now aborts bring-up. I went with attempt-all-then-aggregate as floated above — every bottle is attempted and the failures raise together (one `InfraLaunchError` naming them all) so a bring-up surfaces the full blast radius. Resource gathering (the CA fetch) fails hard too. - Captured the theme as **ADR 0006** (*shared behaviour in the base backend; subclasses override primitives, not control flow*) and updated PRD 0081's goal/design (reversed the "tolerate per-bottle failures" line). - Bumped the `base.py` size guardrail 580→600 for the new contract surface (delegator + 3 abstract primitives); the flow itself is in `gateway_attach.py`, not `base.py`. Verification: full unit suite green except `test_wheel_install` (environment missing the `build` module, unrelated); pyright clean; pylint 9.76. Ready for another look.
didericis-claude changed title from PRD 0081: reconcile running bottles' CA on gateway bring-up to PRD: reprovision on gateway startup - bottle ca (chunk 1/5) 2026-07-26 22:10:38 -04:00
didericis force-pushed prd-0081-reconcile-1-ca from b315a127b8 to 75957b75b8 2026-07-27 01:00:41 -04:00 Compare
didericis force-pushed prd-0081-reconcile-1-ca from 75957b75b8 to ec45dd2764 2026-07-27 10:59:59 -04:00 Compare
didericis force-pushed prd-0081-reconcile-1-ca from ec45dd2764 to 606a57b7ed 2026-07-27 11:16:18 -04:00 Compare
didericis added 7 commits 2026-07-27 11:35:14 -04:00
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>
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>
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>
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>
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>
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>
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
a401310865
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).
didericis force-pushed prd-0081-reconcile-1-ca from 606a57b7ed to a401310865 2026-07-27 11:35:14 -04:00 Compare
didericis added 1 commit 2026-07-27 12:41:26 -04:00
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
e49f9a4e53
didericis-codex reviewed 2026-07-27 12:41:51 -04:00
didericis-codex left a comment
Collaborator

Implemented the requested fail-closed fix.

Implemented the requested fail-closed fix.
@@ -0,0 +89,4 @@
"docker", "network", "inspect", "--format",
"{{range .Containers}}{{.Name}}\n{{end}}", network,
])
if proc.returncode != 0:
Collaborator

Fixed in e49f9a4: nonzero docker network inspect now raises InfraLaunchError with stderr (or the exit code), and the regression test covers a completed process returning failure.

Fixed in `e49f9a4`: nonzero `docker network inspect` now raises `InfraLaunchError` with stderr (or the exit code), and the regression test covers a completed process returning failure.
didericis approved these changes 2026-07-27 12:43:24 -04:00
didericis added 1 commit 2026-07-27 12:44:09 -04:00
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
3dc901c057
didericis-codex approved these changes 2026-07-27 12:46:16 -04:00
didericis-codex left a comment
Collaborator

The blocking Docker enumeration issue is fixed, the custom-infra regression is covered, and all CI checks pass.

The blocking Docker enumeration issue is fixed, the custom-infra regression is covered, and all CI checks pass.
Some checks are pending
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
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin prd-0081-reconcile-1-ca:prd-0081-reconcile-1-ca
git checkout prd-0081-reconcile-1-ca
Sign in to join this conversation.