| 1 | # Seeded Instances Implementation Plans: Index |
| 2 | |
| 3 | > **For agentic workers:** this file is the map. Each plan it names is a |
| 4 | > self-contained implementation plan with the superpowers header; execute |
| 5 | > them in the order below with superpowers:subagent-driven-development or |
| 6 | > superpowers:executing-plans. Do not start a plan whose dependencies are |
| 7 | > not merged on `main`. |
| 8 | |
| 9 | **Goal:** Build `carlos instances create --from` (#260) and the import door |
| 10 | (#261) from the seeded-instances design, as an ordered series of plans that |
| 11 | each produce working, tested, mergeable software. |
| 12 | |
| 13 | **Spec:** `docs/superpowers/specs/2026-10-08-seeded-instances-design.md` rev |
| 14 | 7 (Astra accepted round 7, `CODEX-FINDINGS-RUN-AND-SEEDED-R7.md`; Paul |
| 15 | approved). Every disposition in its §11 to §16 is a requirement here. The |
| 16 | companion `2026-10-08-carlos-run-design.md` (#259) is built by its own |
| 17 | series (`2026-10-08-carlos-run-*.md`). |
| 18 | |
| 19 | **Build target:** `main` at 4a51a6da or later. Every name these plans cite |
| 20 | was read at that commit on 2026-10-08. |
| 21 | |
| 22 | **Copy deck:** `2026-10-08-seeded-instances-copy.md`. Plan 1 puts it through |
| 23 | Paul's copy review. No later plan wires a string before that review lands. |
| 24 | |
| 25 | ## The switch: the seeds floor |
| 26 | |
| 27 | There is no feature flag. The seeds floor (spec §3.3) is the switch: |
| 28 | |
| 29 | - every console door that writes seed state first checks that every box in |
| 30 | the home region reports the floor armed, `carlos.prev` excluded or |
| 31 | seed-capable, the nested layout and no claim control (Plan 3 Task 5); the |
| 32 | import door also requires a one-box region (a deviation, Plan 3 Task 5); |
| 33 | - a box reports `seeds_protocol` from `seeds.ProtocolVersion`, which Plan 3 |
| 34 | introduces at **0** and Plan 8's Task 6 raises to **1**, once the box |
| 35 | can place, swap and roll back, refuses moves of an unplaced or |
| 36 | uncommitted seed, and the console sweeps and assigns; |
| 37 | - the console requires `seeds_protocol >= 1` from every box. |
| 38 | |
| 39 | So Plans 2 to 7 merge dark: no box running their builds can claim to be |
| 40 | seed-capable, and no operator can publish a floor that a box would arm in a |
| 41 | way that lets a door through. Plan 8 completes the console side. Rollout |
| 42 | (spec §10) needs Paul. |
| 43 | |
| 44 | ## The series |
| 45 | |
| 46 | | # | plan | produces | depends on | |
| 47 | |---|---|---|---| |
| 48 | | 1 | [`2026-10-08-seeded-instances-1-copy-deck.md`](2026-10-08-seeded-instances-1-copy-deck.md) | the copy gate `approved_seeded_copy_test.go`, Paul's review of the deck, every row approved | nothing | |
| 49 | | 2 | [`2026-10-08-seeded-instances-2-record.md`](2026-10-08-seeded-instances-2-record.md) | `internal/seeds` (ids, keys, states, the verify token), `provision.SeedSource` on the record, the guarded seed transitions, the field protected from ordinary writers, the move and run predicates | 1 | |
| 50 | | 3 | [`2026-10-08-seeded-instances-3-floor.md`](2026-10-08-seeded-instances-3-floor.md) | `control/seeds-protocol.json`, the box's local seeds floor and `carlos.prev` verdict, both system units, the activation rule, the edges-file fields, the console's region readiness check, `carlos system seeds-floor publish` | 1, 2 | |
| 51 | | 4 | [`2026-10-08-seeded-instances-4-placement.md`](2026-10-08-seeded-instances-4-placement.md) | the registry's `seed_source` column, reconcile's seed-state dispatch for `--from` records, the plain-path restore fallback with the `<db>.seed` marker and the purge, the first-upload `placed` CAS and the seed-ID-scoped snapshot delete, refusal on flat and claim-armed boxes | 2 | |
| 52 | | 5 | [`2026-10-08-seeded-instances-5-from.md`](2026-10-08-seeded-instances-5-from.md) | `resolveDBSource`, the instance-role gate, `RestoreTo` with a TXID target, the last-LTX-header size, the scratch reservation pool and shared limits, reserve then upload then publish, private-storage rules with the seed ID on the store, `--from` and `--at` in the CLI, the list cell | 2, 3 | |
| 53 | | 6 | [`2026-10-08-seeded-instances-6-import-door.md`](2026-10-08-seeded-instances-6-import-door.md) | begin, upload, stopped, commit and abort, the delete refusal, the console's finish of an abandoned seed (`finishSeed`: seed-ID-guarded store teardown, record deleted last), `carlos instances import` with `--verify`, `import commit` and `import abort` | 2, 3, 5; Task 5 also needs the run series' `Record.ActiveRun` | |
| 54 | | 7 | [`2026-10-08-seeded-instances-7-swap-rollback.md`](2026-10-08-seeded-instances-7-swap-rollback.md) | `import_gate` and the `import_journal` table, the operator assignment reader, the journal-first dispatch, the swap transaction with every predicate, crash resume, the gate at the edge and door and in the schedule runner, commit's clear, the fenced rollback, and `cleanup-pending` (the protocol stays 0) | 2, 4 | |
| 55 | | 8 | [`2026-10-08-seeded-instances-8-finish-sweeps.md`](2026-10-08-seeded-instances-8-finish-sweeps.md) | the seeds sweep (stale reservations and imports abandoned by CAS, rolled-back seeds finished, unreferenced snapshots deleted), the move door and worker refusals, `carlos system legacy-routes assign`, `seeds.ProtocolVersion = 1`, the series' last copy-gate check | 5, 6, 7 | |
| 56 | |
| 57 | ``` |
| 58 | main ─► Plan 1 ─► Plan 2 ─┬─► Plan 3 ─┬─► Plan 5 ─► Plan 6 ─┐ |
| 59 | │ │ ├─► Plan 8 |
| 60 | └─► Plan 4 ─┴──────► Plan 7 ───────┘ |
| 61 | ``` |
| 62 | |
| 63 | Plans 3 and 4 are independent of each other once Plan 2 lands. Plan 7 needs |
| 64 | Plan 4's registry column and dispatch. Plan 8 needs everything. |
| 65 | |
| 66 | ## Interfaces shared across plans |
| 67 | |
| 68 | Defined once, in the plan named, and used with exactly these names after. |
| 69 | |
| 70 | **Plan 2, package `internal/seeds`:** |
| 71 | |
| 72 | - `seeds.KindReplica = "replica"`, `seeds.KindImport = "import"`. |
| 73 | - States: `StateReserving`, `StateAwaitingUpload`, `StateUploaded`, |
| 74 | `StateReady`, `StateSwapped`, `StatePlaced`, `StateCommitted`, |
| 75 | `StateRefused`, `StateAborted`, `StateRolledBack` with the spec's strings. |
| 76 | - `seeds.MaxBytes int64 = 4 << 30`. |
| 77 | - `seeds.NewID() (string, error)` (`sd_` and 26 lowercase base32 characters), |
| 78 | `seeds.ValidID(string) bool`. |
| 79 | - `seeds.HostPrefix(host) string` (`seeds/<host>/`), |
| 80 | `seeds.SnapshotPrefix(host, id) string` (`seeds/<host>/<id>/`), |
| 81 | `seeds.SnapshotKey(host, id) string` (`seeds/<host>/<id>/snapshot.db`), |
| 82 | `seeds.ParseSnapshotKey(key) (host, id string, ok bool)`. |
| 83 | - `seeds.NewVerifyToken() (token, hash string, err error)`, |
| 84 | `seeds.TokenMatches(hash, token string) bool`, `seeds.ClosedGate`. |
| 85 | - `seeds.RowSeed{ID, Kind, SHA256 string; Bytes int64; State string}`, |
| 86 | `(RowSeed).Encode() string`, `seeds.ParseRowSeed(string) (*RowSeed, error)`, |
| 87 | `(RowSeed).Placeable() bool` (ready, swapped or placed). |
| 88 | |
| 89 | **Plan 2, package `internal/provision`:** |
| 90 | |
| 91 | - `Record.Seed *SeedSource` (`json:"seed,omitempty"`) and `SeedSource` with |
| 92 | every spec §3.2 field. |
| 93 | - `(*SeedSource).Import() bool`, `(*SeedSource).Abandoned() bool`, |
| 94 | `(*SeedSource).BlocksRun() bool` (an import not yet `committed`; for the run |
| 95 | series' admission, run spec §5.1 step 9), `(*SeedSource).MoveBlock() string` |
| 96 | returning `""`, `SeedMoveUnplaced` or `SeedMoveUncommitted` (Plan 8 gives |
| 97 | each its sentence). |
| 98 | - `ErrSeedConflict`, `ErrSeedProtected`. |
| 99 | - `SetRecordSeed(ctx, s, acct, app, host, mut) (*Record, error)`: one CAS |
| 100 | on the record's etag, retried once; a retried transition re-checks the |
| 101 | state, so a commit and an abort racing end with exactly one winner. |
| 102 | - Transitions: `SeedPublishReplica(id, txid, sha string, bytes int64)`, |
| 103 | `SeedUploaded(id)`, `SeedStopped(id)`, `SeedSwapped(id)`, `SeedPlace(id)`, |
| 104 | `SeedCommit(id)`, `SeedRefuse(id, reason)`, `SeedAbort(id)`, |
| 105 | `SeedRolledBack(id)`, `SeedRolledBackBeforeSwap(id)`. |
| 106 | - `SeedColumn(rec Record) string` (Plan 4 uses it for the registry column). |
| 107 | |
| 108 | **Plan 3:** `seeds.ProtocolVersion`, `seeds.FloorKey`, `seeds.ReadFloor`, |
| 109 | `seeds.PublishFloor`, the box files `.moves/seeds-floor.json`, |
| 110 | `.moves/seeds-floor.min-release` and `/opt/carlos/carlos.prev.seeds-allowed`, |
| 111 | the edges-file fields `seeds_protocol`, `seeds_floor_min_release`, |
| 112 | `prev_seeds_allowed_for`, and `(s *Server) seedRegionReady(ctx, region string, oneBox bool) *doorRefusal`. |
| 113 | |
| 114 | **Plan 4:** `registry.Route.SeedSource` (column `seed_source`), |
| 115 | `(*Registry).SetSeedSource`, `lease.HasReplica`, `release.NewS3StoreIn`, |
| 116 | `activator.SeedObjects`, `ExecBackend.Seeds`, `ExecBackend.ClaimArmed`, |
| 117 | `ExecBackend.OnSeedPlaced`, `activator.SeedPlacementError`, |
| 118 | `activator.SeedMarkerSuffix`, `provision.SeedHooks{Data}` on |
| 119 | `ReconcileConfig.Seeds`. |
| 120 | |
| 121 | **Plan 5:** `(s *Server) resolveDBSource`, `dbdoor.RestoreToTarget`, |
| 122 | `dbdoor.PlanRestore`, `dbdoor.ErrHistoryGone`, `seedScratch`, `replicaDoer`, |
| 123 | `Config.SeedData`, `Config.SeedScratchDir`, `objstore.Declared.Seed`, |
| 124 | `seedCreate`, `seedStoreRefusal`, `abortSeedQuietly`. |
| 125 | |
| 126 | **Plan 6:** `(s *Server) finishSeed(ctx, sqid, app, host, seedID string) error`. |
| 127 | |
| 128 | **Plan 7:** `registry.Route.ImportGate` (column `import_gate`), the |
| 129 | `import_journal` table with `registry.ImportJournal` and its five |
| 130 | transactions, `registry.OpsAccountSqid`, `registry.ImportGateClosed`, |
| 131 | `seeds.LegacyOwnersKey`, `seeds.ReadLegacyOwners`, the `SeedHooks` swap and |
| 132 | rollback hooks. |
| 133 | |
| 134 | **From the run series (#259):** `provision.Record.ActiveRun *RunState` with |
| 135 | `RunState.State` in `queued | picked | cancel | done | cancelled | expired` |
| 136 | (run spec §5.1). Plan 6 Task 5 reads it; if the run series' record task has |
| 137 | not merged, Plan 6 Task 5 waits for it. The run series uses |
| 138 | `(*SeedSource).BlocksRun()` from Plan 2. If the run series lands a minimal |
| 139 | `SeedSource` first, Plan 2 Task 2 extends that type instead of declaring it. |
| 140 | |
| 141 | ## What these plans do not build |
| 142 | |
| 143 | - The claim algorithm of spec §3.4 (#250). Every claim-armed box and console |
| 144 | refuses. |
| 145 | - `--at <time>` (spec §4 step 4, codex R2-18). |
| 146 | - Titogo's half of the conversion (spec §10 step 5). |
| 147 | - Rollout steps (spec §10), which need Paul's go at each step. |
| 148 | |