carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1Reviewed `ddd0617f` against its code base, `origin/main` at `70e57449`, and the supplied flagship checkout. No files changed; no builds, tests or infrastructure commands run.
2
31. **P1 — The NLB cannot use both boxes with only one enabled zone.**
4 [Spec:83](/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:83) specifies one subnet mapping but instance targets spread across two zones. Cross-zone balancing reaches targets in **enabled** zones; the second zone’s target remains `unused`. If the first box hangs while its zone remains available, the healthy second box cannot receive ingress. Enable both target zones; customers can retain their existing A record. [AWS target-health documentation](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/target-group-health-checks.html).
5
62. **P1 — Boot and enrolment have a circular dependency.**
7 [Spec:128–134](/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:128) starts the claim-enabled agent before enrolment, then enrols before arming the guard. Today, agent construction requires `/etc/carlos/host-actor.json` and a matching roster entry ([claimproduction.go:87](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/host/claimproduction.go:87)); failure exits before the identity-publication loop starts. Separately, adding a box after floor publication requires its guard-ready report ([membership.go:40](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/hostactors/membership.go:40)). A clean replacement therefore cannot complete either ordering. Specify a non-hosting enrolment mode, signed invitation, guard installation and readiness report **before** final enrolment.
8
93. **P1 — Fixed group size does not prevent healthy-box termination.**
10 [Spec:81](/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:81) omits scale-in protection because scaling is deferred. However, `AZRebalance` can launch and terminate instances without changing desired capacity. If an unavailable zone forces both boxes into the surviving zone, recovery can trigger termination of a healthy box hosting customer instances. Spec 2 then leaves those instances down until spec 3. Explicitly suspend zone rebalancing or provide a relocation-aware protection mechanism. [AWS process behaviour](https://docs.aws.amazon.com/autoscaling/ec2/userguide/understand-how-suspending-processes-affects-other-processes.html).
11
124. **P1 — IE’s relay and MX move too late.**
13 [Spec:246](/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:246) assigns the platform EIP and changes relay/MX DNS only after all customer instances migrate. From step 2 onward, their old address belongs to an NLB accepting only 80/443. Relay traffic and inbound mail therefore fail for the entire migration, plus DNS cache expiry—not merely the announced web cut-over. The current relay record directly uses the IE EIP ([dns53.tf:103](/home/paulca/github.com/carlosframework/carloku-infrastructure/dns53.tf:103)). Move these services and account for DNS TTLs before transferring that address.
14
155. **P2 — Pre-enrolment publication can permanently disqualify automatic enrolment.**
16 [Spec:130](/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:130) needs an explicit publication boundary. Once pre-enrolment startup is enabled, the normal agent also starts `edgesFileLoop`. An edges file naming the new box makes `Directory.Referenced` true, and automatic enrolment explicitly rejects referenced boxes ([enroll.go:37](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/hostactors/enroll.go:37), [references.go:63](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/hostactors/references.go:63)). A delayed confirmation can consequently turn an otherwise valid replacement into an operator-only case. Suppress ordinary edges publication until enrolment, or define a safely distinguishable provisional record.
17
186. **P2 — `carlos bootstrap` does not install the signed channel release.**
19 [Spec:119](/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:119) attributes release installation to a command that installs users, directories and units. It finishes by instructing the operator to copy the binary and configure the host ([bootstrap.go:619](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/host/bootstrap.go:619)). A replacement would run the bootstrap object’s version, potentially below the published floor. Specify the signed-release installation step, including identity and previous-binary material required by guard-arm; obtain its verification configuration beforehand.
20
217. **P2 — `unplaced` needs a claim transition and recovery contract.**
22 [Spec:207](/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:207) cannot use today’s create path unchanged. `BeginCreateOn` rejects an empty executor, and production recovery requires both `selected_executor` and `executor_enrollment` ([create.go:109](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/hostclaim/create.go:109), [production_create.go:257](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/hostops/production_create.go:257)). A persisted executor-less create would remain unrecoverable after capacity returns. Define reservation, cancellation, concurrent placer CAS, one-time executor selection, and old-reader behaviour. Also define how edges recognise an unplaced hostname and return the promised 503 without a published home.
23
248. **P2 — Healthy boxes will repeatedly fail the freshness threshold.**
25 [Spec:195](/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:195) rejects edges files older than five minutes, but publication is **five minutes plus up to one minute of jitter**, not every 30 seconds ([edgesfile.go:794–798](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/host/edgesfile.go:794)). Quiet, healthy boxes periodically become ineligible; overlapping windows produce false capacity alerts and unplaced instances. Change the publication cadence explicitly or set the cutoff above its maximum interval plus delivery margin.
26
279. **P2 — §8 omits customer operations and accounting that depend on the console’s local registry.**
28 [Spec:217](/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:217) does not close these concrete regressions when IE customers leave the console box:
29
30 - Scoped restart refuses hosts known only to another box ([apirestartscope.go:45](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/console/apirestartscope.go:45)).
31 - Domain attachment finds no existing primary route and takes the first-route path ([domainattach.go:150](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/console/domainattach.go:150)).
32 - Remote customer processes fall into platform-overhead attribution ([economicspass.go:308](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/console/economicspass.go:308)).
33 - Fleet app/service listings use the elected publisher’s local routes ([fleet.go:154](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/status/fleet.go:154)); retention enumerates apps from the housekeeper’s local registry ([retention.go:49](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/host/retention.go:49)).
34
35 Add these consumers to the prerequisite audit and give them complete, ownership-checked inputs.
36
3710. **P2 — Loading the forwarding map once does not prove forwarding readiness.**
38 [Spec:149](/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:149) permits a permanent 200 after one map load. Map and mesh-key refreshes fail independently ([homemap.go:259](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/edge/homemap.go:259)); forwarding refuses without a key. A new forwarding-only box can therefore pass health checks while every forwarded request fails. The same answer does not establish TLS readiness or detect a stalled hosting worker. Define cached readiness and local liveness conditions for the services this health check is meant to protect.
39
4011. **P2 — Pending enrolment is invisible to the proposed alarms.**
41 [Spec:141](/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:141) promises an alert after 15 minutes, but an unenrolled forwarding box can be both ASG `InService` and NLB healthy. Both proposed alarm predicates remain false indefinitely. Add an enrolment-age or eligible-capacity signal. Initial boot failure also needs qualification: AWS does not replace ELB-unhealthy instances while an attached target group has never reached its first healthy target. [ASG metrics](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-metrics.html), [attachment-state behaviour](https://docs.aws.amazon.com/autoscaling/ec2/userguide/load-balancer-status.html).
42
4312. **P2 — EIP cut-over needs a direct-address publication barrier.**
44 [Spec:240–242](/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:240) moves the old box’s published dial address onto the NLB. The publisher re-probes it only on timed passes and retains the previous address across blank IMDS reads ([edgesfile.go:589](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/host/edgesfile.go:589)). During that interval, another region forwards a signed hop to the NLB; a group box receiving it cannot forward again and returns 503 ([edge.go:1505](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-region-ha-two-box/internal/edge/edge.go:1505)). Require a direct public address, forced publication and reader convergence for the old box during cut-over, as well as private forwarding within its region.
45
4613. **P2 — Rollback omits releasing the NLB-owned address and retaining the old executor.**
47 [Spec:250](/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:250) cannot be executed as a direct EIP reassociation: AWS forbids disassociating addresses from requester-managed interfaces. The owning NLB/subnet mapping must release it first. After step 4 terminates the old box, the stated rollback is no longer available at all. Define the rollback boundary, preserve the allocation, retain the old box until acceptance, and specify the release/wait/reassociate sequence. [AWS interface restrictions](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/requester-managed-eni.html).
48
49For §13:
50
51- **Fresh headroom:** resolve finding 8 first. Five minutes is workable only with an explicitly faster publisher.
52- **Temporary NLB:** the creation-only assertion is too broad. `SetSubnets` accepts an EIP when adding a mapping. A temporary mapping in the other zone, followed by adding the existing-EIP mapping, could retain the rehearsal NLB and address finding 1. Rehearse that exact sequence on dev. [AWS API](https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_SetSubnets.html).
53- **SSM/KMS:** a separate secrets key only adds isolation if its authorised readers differ. A dedicated deployment configuration key can suffice, with exact parameter-path restrictions and decrypt conditions binding SSM and `PARAMETER_ARN`. Keep the existing explicit Deny covering all four read operations outside the permitted paths; adding a narrow Allow alone does not constrain the managed-policy grants. [AWS encryption-context documentation](https://docs.aws.amazon.com/systems-manager/latest/userguide/secure-string-parameter-kms-encryption.html).
54
55I found no new two-writer path in the existing cold-admission mechanism. Preserve H13: exclusive executorship alone does **not** make an old local database safe after relocation. Certificate challenge read-through supports the proposed ingress, and preserving client IPs avoids an inherent NLB-induced GeoIP change.
56
57**Verdict: not ready for a plan.**