carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1| Round-one finding | Disposition at `89f01372` |
2|---|---|
3| A1-1 — Only one enabled NLB zone | **Closed.** Final topology enables both zones. The one-subnet wording in §6 and §12 needs updating. |
4| A1-2 — Circular boot/enrolment dependency | **Partial.** Joining mode breaks the original cycle, but the sequence omits required attempt management and restart recovery; see 1 and 4. |
5| A1-3 — Healthy termination by `AZRebalance` | **Closed.** Explicitly suspended. |
6| A1-4 — Relay/MX moved too late | **Partial.** Ordering is fixed; the running relay’s advertised address is not; see 6. |
7| A1-5 — Pre-enrolment edges publication | **Closed.** Joining explicitly publishes no edges file and admits no instances. |
8| A1-6 — Bootstrap does not install a release | **Partial.** Installation is explicit, but the proposed previous binary fails guard-arm; see 2. |
9| A1-7 — Executor-less create has no recovery contract | **Partial.** Keeping it outside the claim is sound; the database-to-claim handoff remains unsafe; see 5. |
10| A1-8 — Headroom freshness below publication interval | **Closed.** Fifteen minutes covers the stated cadence. |
11| A1-9 — Local-registry consumers omitted | **Closed at design level.** Named consumers and a prerequisite audit are included. |
12| A1-10 — One map load does not establish readiness | **Original gap addressed.** Freshness, key, TLS and heartbeat checks are added, but coupling them to termination introduces finding 3. |
13| A1-11 — Pending enrolment invisible to alarms | **Partial.** Eligible-capacity signal added, but its publisher lacks the proposed namespace permission; see 8. The never-healthy target-group exception also still contradicts §5’s unconditional replacement promise. |
14| A1-12 — Published address becomes the NLB | **Partial.** Publication barrier added, but selecting the second address is unspecified; see 7. |
15| A1-13 — Rollback cannot reclaim NLB-owned EIP | **Partial.** Release/wait/reassociate and executor retention are fixed. Address-policy and IE service rollback remain broken; see 9. |
16
171. **P1 — Enrolment omits the signed attempt and confirmation-expiry protocol.**
18 [Spec:143](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/docs/superpowers/specs/2026-10-15-region-ha-two-box-regions-design.md:143) starts with the worker writing a confirmation, but `EnrollAutomatic` requires an existing, matching `Roster.EnrollmentAttempts` entry. Only `BeginEnrollmentAttempt` establishes that entry and its IDs. It also requires confirmation evidence no older than **one minute** ([enrollment_confirmation.go:66](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/hostactors/enrollment_confirmation.go:66), [freshness check:111](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/hostactors/enrollment_confirmation.go:111)). As written, the first enrolment fails; adding the missing attempt alone still fails whenever invitation delivery and guard installation take over a minute. Specify attempt creation before confirmation and fresh attempts/confirmations after expiry, preserving the stable invitation.
19
202. **P1 — Keeping the bootstrap binary as `.prev` prevents guard-arm.**
21 [Spec:135](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/docs/superpowers/specs/2026-10-15-region-ha-two-box-regions-design.md:135) retains the bootstrap object as the previous binary. However, [guardarm.go:75](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/host/guardarm.go:75) checks **both** installed binaries against the supplied identity and executing build; [floor.go:138](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/hostfloor/floor.go:138) requires the exact artifact hash. Whenever bootstrap differs from the channel release, guard installation fails and the replacement never enrols. Initialise both protected slots with the verified channel artifact, or explicitly design a different guarded installation contract.
22
233. **P1 — A shared bucket outage becomes destructive box replacement.**
24 [Spec:170](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/docs/superpowers/specs/2026-10-15-region-ha-two-box-regions-design.md:170) makes stale map/key refreshes fail the same health check that authorises ASG replacement. A deployment-bucket outage lasting over two minutes therefore marks functioning boxes unhealthy even while their cached maps, keys and running instances remain usable. The current map deliberately retains those cached values ([homemap.go:235](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/edge/homemap.go:235)). ASG can then terminate boxes; throttling replacement does not prevent the first termination. Without spec 3, those customers remain down after bucket access recovers. Separate shared-dependency readiness from the local failure signal authorising termination. [AWS replacement behaviour](https://docs.aws.amazon.com/autoscaling/ec2/userguide/health-checks-overview.html).
25
264. **P2 — Joining mode cannot recover a restart after writing `host-actor.json`.**
27 [Spec:138](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/docs/superpowers/specs/2026-10-15-region-ha-two-box-regions-design.md:138) selects joining mode by the file’s absence, but step 5.3 writes it **before** enrolment. If the agent restarts in that interval, it selects ordinary claim startup, which refuses the missing roster row ([claimproduction.go:96](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/host/claimproduction.go:96)). It can no longer finish guard installation or readiness publication. Select hosting only after verifying the matching roster entry and guard; retain resumable joining states for the intermediate cases.
28
295. **P2 — A database lock cannot make pending-create consumption atomic with the claim.**
30 [Spec:239](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/docs/superpowers/specs/2026-10-15-region-ha-two-box-regions-design.md:239) promises that starting the claim and leaving pending state are atomic. Today’s create path generates fresh operation IDs and writes registration and claim state to the bucket ([claim_create.go:50](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/console/claim_create.go:50), [start:101](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/console/claim_create.go:101)). A crash after the claim write but before database commit leaves a pending row whose create already exists. Retry starts with a new identity; cancellation can delete the row while the accepted claim continues. Persist a stable operation identity and a recoverable `starting` state before external writes, reconcile ambiguous outcomes, and make the immediate create door and cancellation honour the same hostname reservation.
31
326. **P2 — Moving relay DNS does not change TURN’s advertised relay address.**
33 [Spec:277](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/docs/superpowers/specs/2026-10-15-region-ha-two-box-regions-design.md:277) moves DNS and waits for TTLs, but the relay reads its public IP at startup ([serve.go:175](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/relay/serve.go:175)) and advertises that stored address for allocations ([server.go:645](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/relay/server.go:645)). Clients can reach the new control address yet receive the old region EIP as their media destination. Once that EIP belongs to the web-only NLB, media fails. Configure and restart the relay on the new advertised address, account for existing allocations, and verify a TURN allocation and media exchange before cut-over.
34
357. **P2 — The publication barrier has no way to select the new secondary EIP.**
36 [Spec:285](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/docs/superpowers/specs/2026-10-15-region-ha-two-box-regions-design.md:285) requires publishing a second EIP while the original remains attached. Yet §6 specifies only rereading IMDS `public-ipv4`; [agent.go:2957](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/host/agent.go:2957) reads that single value, with no selection of the new secondary association. It can keep returning the original address, which the new ingress-list filter rejects, so republication cannot establish the required direct address. Specify the secondary private-IP/ENI configuration and an explicit address selector or override. AWS exposes multiple public addresses and their private associations separately. [AWS metadata fields](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html).
37
388. **P2 — The eligible-capacity metric lacks IAM permission.**
39 [Spec:96](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/docs/superpowers/specs/2026-10-15-region-ha-two-box-regions-design.md:96) introduces `Carlos/Region`, but the current role permits `cloudwatch:PutMetricData` only for `Carlos/Host` ([main.tf:418](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/infra/modules/region-host/main.tf:418)). The spec’s IAM additions cover ASG, SSM and KMS only. On the supplied flagship configuration, publication is denied and the alarm receives no capacity samples. Add the scoped namespace grant to the console’s platform-box role and define missing-data handling.
40
419. **P2 — Rollback removes addresses still required by forwarding and IE services.**
42 [Spec:301](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/docs/superpowers/specs/2026-10-15-region-ha-two-box-regions-design.md:301) reassociates the region EIP and removes the temporary EIP. But §6 still forbids publishing any address in the configured ingress list, including that reassociated region EIP. Other regions consequently lose the old box’s direct forwarding address. In IE, the “temporary” address is also the permanent relay/MX address from step 0; removing it breaks those services again. Rollback must restore the address-publication policy, wait for reader convergence before releasing a forwarding address, and retain IE’s service EIP.
43
44The **NLB API sequence itself is valid**: create with B, supply both mappings when adding A, then remove A and wait for release during rollback. `SetSubnets` replaces the mapping set; removing A also makes A’s targets unused. The B-only rehearsal therefore does not validate A’s targets. [AWS SetSubnets](https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_SetSubnets.html), [subnet-removal behaviour](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/availability-zones.html).
45
46Reviewed the specified platform HEAD and flagship checkout `7c99ff8f`. No files changed; no builds, tests or infrastructure commands run.
47
48**Verdict: not ready for an implementation plan.**