carlos / platform Public
Reviewed rev 2 at bd4ed0c4 against the clean worktree, after reading AGENTS.md. R1–R4 remain settled.
| Round-1 finding | Status | Why | |---|---|---| | 1. Picker bypasses pool exclusion | Resolved | Named-pool manifests now produce no candidates or guess; a distinct shared-pool eligibility gap remains below. | | 2. Browser adoption changes the default | Resolved | Automatic inference happens after adoption detection; an untouched form no longer supplies an explicit region. | | 3. Unnamed home prevents override | Resolved | Non-home app defaults require a named home, whose explicit code bypasses the fill. | | 4. Mixed versions and rollback unspecified | Partly | Read-first rollout and a binary floor are specified; accepting that operational floor remains §17 Q3. | | 5. Existing-canary --region undefined | Resolved | Equal proceeds; different refuses before record mutation or upload. | | 6. Manifest absence versus failure unspecified | Resolved | The three policy states are distinguished, and legacy topology fields remain available. | | 7. Absent-region explanation disappears | Resolved | app_default represents absent regions independently of the topology list; C8 is no longer count-dependent. | | 8. Query hints reflected by redirects | Resolved | Hints move into POST bodies, with explicit redirect, logging, and audit privacy tests. |
The following findings are new.
- P1 — Automatic candidates can still include regions that cannot mint shared instances. Spec: §2, §6.1, §12, §16.
Hosting checks reachability and activator configuration, without pool or inbound eligibility (instancesplacement.go:189). However, an explicitly configured pool list excludes the shared "" pool unless it contains it (reconcile.go:1339), and CARLOS_INBOUND=none independently refuses new routed instances (reconcile.go:925).
For example, UK has one reachable, hosting box configured with CARLOS_POOLS=tito. A new, ordinary app has no pooled manifest, so UK remains a candidate. The guess selects UK, the create door accepts the record, and no box provisions it. This is the reverse of round-1 finding 1: the target box, rather than the app, is pool-restricted.
Fix: Require positive shared-pool and inbound eligibility for automatic candidates. Within the console-only scope, use an explicit operator-verified eligibility declaration and audit it before activation. Otherwise, publish the missing capabilities before enabling inference. Add reconciliation tests for named-pool-only and no-inbound targets.
- P1 — Losing the last placement publication disables the promised unavailable-default refusal. Spec: §7, §14, §15’s dormant-gate test.
Failed edges reads become an empty result (instancesplacement.go:87); with no placement-bearing files, published stays false (instancesplacement.go:173). The create door then skips capability checks (apiinstances.go:848).
Suppose an app stores uk, and the sole UK box is retired, leaving only the uncoded home. A no-region create fills uk, but dormancy permits it. The API writes an instance that cannot be provisioned, while app_default reports absent. §15 explicitly requires that acceptance, contradicting §7’s refusal promise.
Fix: Preserve legacy dormancy for explicit requests and legacy home defaults, but require positive eligibility for a non-home app-derived default. Distinguish unavailable topology from confirmed absence where practical. Replace the conflicting test with last-region-removal and edges-read-failure cases.
- P2 —
autocollides with a valid placement code. Spec: §5.5, §10.
Placement codes accept lowercase letters up to 16 characters, so auto is valid (provision.go:688).
On a deployment with a region named auto, the automatic option and that explicit region have identical submitted values. The browser cannot distinguish deliberate selection from inference. During adoption, an explicit choice can consequently be discarded.
Fix: Use a sentinel outside the placement grammar, such as @auto, or encode explicit choices separately. Do not retroactively reserve a currently valid region code. Test a region—and named home—called auto.
- P2 — Fleet
app_default.codegives the deploy preflight the wrong value. Spec: §9.3, §11, §12.
Fleet placement is resolved from the store or existing routes (fleets.go:479) and replaces the instance region (apiinstances.go:798). Nevertheless, §9.3 requires app_default.code to report the platform home for fleet-placed apps.
An app storing region uk, currently placed on fleet/acme, therefore reports ie. deploy --region uk is refused despite matching the stored app region; deploy --region ie passes despite matching neither that region nor its fleet placement.
Fix: Expose the stored app region separately from effective instance placement. Compare deploy --region against the stored region, and represent fleet placement explicitly rather than presenting the platform home as its destination.
- P2 — The prescribed
regionReqcannot carry the IP needed insideclaimApp. Spec: §5.5, §6.2, §8.1.
claimApp receives a context and identity arguments, but no HTTP request (server.go:3466). Its addr argument is the audit actor (apicli.go:349), whereas trusted IP extraction requires the request (authcli.go:876).
Moving inference inside claimApp fixes adoption, but the specified {explicit, tz, person} structure loses the network address. Following that interface literally makes old-CLI and JavaScript-disabled browser requests fall back to home despite configured GeoIP.
Fix: Pass an optional, request-local IP obtained through s.clientIP into regionReq, or provide a request-scoped lookup callback. Resolve it only after adoption is known, and never persist or log it.
- P2 — The rollback detector flags ordinary, correct deployments. Spec: §5.7, §14.
The proposed detector identifies non-home apps with later records whose region is empty. Normal static deployment creates exactly that record (deploy.go:858); explicit home selection also normalizes to empty (apiinstancemove.go:136).
A correctly operating non-home app with a static apex or deliberate home override is therefore reported as a rollback gap. §7 keeps region_from outside the persisted record, so those records cannot conclusively distinguish intentional overrides from old-console defaults.
Fix: Exclude shapes that never inherit the app default, and describe remaining matches as possible placement discrepancies, not detected rollback violations. Reliable attribution needs additional persisted provenance or an independently recorded rollback interval.
The remaining requested checks support the design: the fill’s insertion preserves fleet precedence and pool/static/address-backed/replica exclusions; sidecars retain their separate door. Normalized inferred values still pass the manifest predicate, so I found no allow-list bypass. Migration ordering and the fixed rebuild lists match §5.2 (store.go:402, store.go:487). Old JSON clients remain compatible through permissive decoding.
Existing migrated apps retain "", so the new unarmed-default refusal does not newly strand them. For non-home apps, an explicit override remains subject to the manifest: if every allowed region is unavailable, capacity or policy must change. POST-body hints and the proposed storage fields introduce no identified IP or coordinate retention requirement.
| §17 question | Recommendation | |---|---| | Q1 — titogo completion | (b). Include titogo adoption in operational completion if Ireland relief is the objective; unchanged callers on existing apps retain home placement. | | Q2 — latency | (a). Ship placement separately and measure the actual request path before claiming latency gains. The cited DNS seam remains unimplemented at apiinstances.go:1052. | | Q3 — rollback floor | (a), with explicit acceptance. Preserve the region-aware binary during rollback and use the switch to disable new defaults. Below-floor rollback can violate placement promises; the proposed audit is not a preventive safeguard. |
All code citations supporting these findings were checked in this worktree. No files changed, no tests ran, and production configuration was not inspected.
Verdict: not ready for planning. Resolve candidate eligibility and the dormant-gate contradiction first, then correct the four implementation contracts above.