specs: Astra review brief for carlos run and seeded instances
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 file changed,
+141
−0
docs/superpowers/specs/CODEX-REVIEW-BRIEF-RUN-AND-SEEDED.md+141 −0
CI passed — run details
diff --git a/docs/superpowers/specs/CODEX-REVIEW-BRIEF-RUN-AND-SEEDED.md b/docs/superpowers/specs/CODEX-REVIEW-BRIEF-RUN-AND-SEEDED.md| new file mode 100644 |
| index 000000000..8045d8c0c |
| --- /dev/null |
| +++ b/docs/superpowers/specs/CODEX-REVIEW-BRIEF-RUN-AND-SEEDED.md |
| @@ -0,0 +1,141 @@ |
| +# Review brief: `carlos run` and seeded instances |
| + |
| +You are an independent second reader of two design specs for the CARLOS |
| +platform (this repository). Read them cold and adversarially. |
| + |
| +**Specs:** read both, at the commit named in the prompt: |
| + |
| +- `docs/superpowers/specs/2026-10-08-carlos-run-design.md` (#259) |
| +- `docs/superpowers/specs/2026-10-08-seeded-instances-design.md` (#260, |
| + #261) |
| + |
| +## Fixed rulings: do not re-argue them |
| + |
| +§2 of each spec lists the rulings the product owner made on 2026-10-08. |
| +Do not propose alternatives to them. That includes: |
| + |
| +- member-wide access; |
| +- service credentials with the `instance` role on the seed doors; |
| +- output as bucket chunks; |
| +- uploads streaming through the console; |
| +- the operator-account exception for the swap. |
| + |
| +Report only: |
| + |
| +- a mechanism that **fails to honour** a ruling; |
| +- a mechanism that breaks something else in the platform; |
| +- a mechanism that cannot be built as described against the code on |
| + `main`. |
| + |
| +## What to check |
| + |
| +Check against the code, not the specs' description of it. Cite |
| +`file:line` for every claim about existing code. These are the places that |
| +matter. |
| + |
| +**Instances and units:** |
| + |
| +- `internal/host/units/carlos-instance-seed@.service` and its two |
| + siblings; |
| +- `internal/instancectl/` (names.go, server.go `/seed`, client.go); |
| +- `internal/instanceexec/exec.go`. |
| + |
| +**The activator:** |
| + |
| +- `internal/activator/backend_exec.go`: `Restore`, the staging |
| + fallback, `seedUnit`, `seedVars`, `instanceEnv`, `nestedGate`; |
| +- `prepare.go` (`writeLaunch`); |
| +- `layout.go` (`Classify`); |
| +- `claimwake.go`; |
| +- hibernation and the `Quiesced` and idle logic in `activator.go`. |
| + |
| +**The box:** |
| + |
| +- `internal/host/restart.go`: the serial and ETag pattern the run pickup |
| + copies; |
| +- `logship.go`; |
| +- `agent.go`: the serial poll. |
| + |
| +**The console:** |
| + |
| +- `internal/console/apidb.go`: `dbGate`, `resolveReplica`; |
| +- `internal/dbdoor/restore.go`; |
| +- `apiinstances.go`: `handleAPIInstanceCreate`; |
| +- `authcli.go`: `cliRoute`; |
| +- `apicli.go`: `apiAccountApp`, the ship size limits; |
| +- `server.go`: audit helpers; |
| +- `apistatuslayout.go`. |
| + |
| +**Provisioning, claims and storage:** |
| + |
| +- `internal/provision/provision.go`: `Record`, `CreateRecord`; |
| +- `reconcile.go`: around lines 1140-1300, the "leave it alone" rule; |
| +- the host claim: `internal/hostclaim`, `internal/hostbox`, |
| + `internal/hostops/record.go`; |
| +- the moves protocol floor (`moves_protocol`); |
| +- `infra/modules/region-host/main.tf`: what a box and the console may |
| + read and write; |
| +- `docs/superpowers/specs/2026-10-02-move-any-app-design.md`: the claim |
| + and restore contract a new restore fallback must fit. |
| + |
| +## Questions worth your time |
| + |
| +**`carlos run`** |
| + |
| +1. Can a run reach anything beyond the instance's own reach? |
| + - Environment, files, the cmd unit's sandbox against the seed unit's. |
| + - The exe link the control service binds. |
| + - The output sockets. |
| + - `.carlos-run/` inside the instance tree. |
| +2. **Data loss.** Can the command's writes be lost, or can it write to a |
| + database nobody replicates? Look at: |
| + - hibernation during a run; |
| + - a move; |
| + - a host-claim handoff; |
| + - a restore that replaces the file under it; |
| + - the run hold as specified. |
| +3. **Pickup.** Does "the box that owns the row" pick it up exactly once? |
| + Consider: |
| + - the claim on and off; |
| + - replica placements; |
| + - two boxes during a move; |
| + - a box restart mid-run; |
| + - the index ETag pattern against restart.go's seed-don't-replay rule. |
| +4. **Output.** Ordering, the cap, cancel, timeout, ack and the sweep. Can |
| + a run be left open forever, or deleted while the CLI still follows it? |
| + |
| +**Seeded instances** |
| + |
| +5. **The new restore fallback.** Does it fit both the plain and the claim |
| + restore paths, as the move-any-app spec's generation and marker |
| + contract requires? Can a seeded instance ever come up empty, come up |
| + with the source's lineage, or replicate into the source's prefix? |
| +6. **The swap.** Is a registry transaction plus a claim CAS, in that |
| + order, actually achievable in reconcile? Can it take a route that |
| + isn't the app's own? Does abort-after-swap restore the addr row |
| + exactly, and is "refused once it has served a non-verify request" |
| + observable by the platform at all? |
| +7. **Old boxes.** Does the protocol-floor gate stop an old box minting a |
| + seeded record as an empty instance? Is there a window where it |
| + doesn't? |
| +8. **`--from` on the console.** Disk, memory and time per restore; the |
| + claim read; residency; scratch cleanup on every exit path. |
| +9. **Missing pieces.** Anything either spec relies on that doesn't exist, |
| + or exists in a different shape. |
| + |
| +## Output |
| + |
| +A numbered list of findings. Each one gives: |
| + |
| +- **severity:** P1 breaks a ruling, loses data or crosses a tenant; P2 is |
| + wrong behaviour; P3 is clarity or a gap; |
| +- the spec and section; |
| +- the code evidence, with `file:line`; |
| +- a concrete fix. |
| + |
| +Then a one-line verdict for each spec: accept, or revise. Don't rewrite |
| +the specs. No praise. |
| + |
| +On a later round you'll be given your earlier findings files. Start with a |
| +disposition table (finding: fixed, declined with an acceptable reason, or |
| +not fixed), then give only new findings. |