carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

Seeded Instances Implementation Plans: Index

> For agentic workers: this file is the map. Each plan it names is a > self-contained implementation plan with the superpowers header; execute > them in the order below with superpowers:subagent-driven-development or > superpowers:executing-plans. Do not start a plan whose dependencies are > not merged on main.

Goal: Build carlos instances create --from (#260) and the import door (#261) from the seeded-instances design, as an ordered series of plans that each produce working, tested, mergeable software.

Spec: docs/superpowers/specs/2026-10-08-seeded-instances-design.md rev 7 (Astra accepted round 7, CODEX-FINDINGS-RUN-AND-SEEDED-R7.md; Paul approved). Every disposition in its §11 to §16 is a requirement here. The companion 2026-10-08-carlos-run-design.md (#259) is built by its own series (2026-10-08-carlos-run-*.md).

Build target: main at 4a51a6da or later. Every name these plans cite was read at that commit on 2026-10-08.

Copy deck: 2026-10-08-seeded-instances-copy.md. Plan 1 puts it through Paul's copy review. No later plan wires a string before that review lands.

The switch: the seeds floor

There is no feature flag. The seeds floor (spec §3.3) is the switch:

  • every console door that writes seed state first checks that every box in the home region reports the floor armed, carlos.prev excluded or seed-capable, the nested layout and no claim control (Plan 3 Task 5); the import door also requires a one-box region (a deviation, Plan 3 Task 5);
  • a box reports seeds_protocol from seeds.ProtocolVersion, which Plan 3 introduces at 0 and Plan 8's Task 6 raises to 1, once the box can place, swap and roll back, refuses moves of an unplaced or uncommitted seed, and the console sweeps and assigns;
  • the console requires seeds_protocol >= 1 from every box.

So Plans 2 to 7 merge dark: no box running their builds can claim to be seed-capable, and no operator can publish a floor that a box would arm in a way that lets a door through. Plan 8 completes the console side. Rollout (spec §10) needs Paul.

The series

| # | plan | produces | depends on | |---|---|---|---| | 1 | 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 | | 2 | 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 | | 3 | 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 | | 4 | 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 | | 5 | 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 | | 6 | 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 | | 7 | 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 | | 8 | 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 |

main ─► Plan 1 ─► Plan 2 ─┬─► Plan 3 ─┬─► Plan 5 ─► Plan 6 ─┐
                          │           │                      ├─► Plan 8
                          └─► Plan 4 ─┴──────► Plan 7 ───────┘

Plans 3 and 4 are independent of each other once Plan 2 lands. Plan 7 needs Plan 4's registry column and dispatch. Plan 8 needs everything.

Interfaces shared across plans

Defined once, in the plan named, and used with exactly these names after.

Plan 2, package internal/seeds:

  • seeds.KindReplica = "replica", seeds.KindImport = "import".
  • States: StateReserving, StateAwaitingUpload, StateUploaded, StateReady, StateSwapped, StatePlaced, StateCommitted, StateRefused, StateAborted, StateRolledBack with the spec's strings.
  • seeds.MaxBytes int64 = 4 << 30.
  • seeds.NewID() (string, error) (sd_ and 26 lowercase base32 characters), seeds.ValidID(string) bool.
  • seeds.HostPrefix(host) string (seeds/<host>/), seeds.SnapshotPrefix(host, id) string (seeds/<host>/<id>/), seeds.SnapshotKey(host, id) string (seeds/<host>/<id>/snapshot.db), seeds.ParseSnapshotKey(key) (host, id string, ok bool).
  • seeds.NewVerifyToken() (token, hash string, err error), seeds.TokenMatches(hash, token string) bool, seeds.ClosedGate.
  • seeds.RowSeed{ID, Kind, SHA256 string; Bytes int64; State string}, (RowSeed).Encode() string, seeds.ParseRowSeed(string) (*RowSeed, error), (RowSeed).Placeable() bool (ready, swapped or placed).

Plan 2, package internal/provision:

  • Record.Seed *SeedSource (json:"seed,omitempty") and SeedSource with every spec §3.2 field.
  • (*SeedSource).Import() bool, (*SeedSource).Abandoned() bool, (*SeedSource).BlocksRun() bool (an import not yet committed; for the run series' admission, run spec §5.1 step 9), (*SeedSource).MoveBlock() string returning "", SeedMoveUnplaced or SeedMoveUncommitted (Plan 8 gives each its sentence).
  • ErrSeedConflict, ErrSeedProtected.
  • SetRecordSeed(ctx, s, acct, app, host, mut) (*Record, error): one CAS on the record's etag, retried once; a retried transition re-checks the state, so a commit and an abort racing end with exactly one winner.
  • Transitions: SeedPublishReplica(id, txid, sha string, bytes int64), SeedUploaded(id), SeedStopped(id), SeedSwapped(id), SeedPlace(id), SeedCommit(id), SeedRefuse(id, reason), SeedAbort(id), SeedRolledBack(id), SeedRolledBackBeforeSwap(id).
  • SeedColumn(rec Record) string (Plan 4 uses it for the registry column).

Plan 3: seeds.ProtocolVersion, seeds.FloorKey, seeds.ReadFloor, seeds.PublishFloor, the box files .moves/seeds-floor.json, .moves/seeds-floor.min-release and /opt/carlos/carlos.prev.seeds-allowed, the edges-file fields seeds_protocol, seeds_floor_min_release, prev_seeds_allowed_for, and (s *Server) seedRegionReady(ctx, region string, oneBox bool) *doorRefusal.

Plan 4: registry.Route.SeedSource (column seed_source), (*Registry).SetSeedSource, lease.HasReplica, release.NewS3StoreIn, activator.SeedObjects, ExecBackend.Seeds, ExecBackend.ClaimArmed, ExecBackend.OnSeedPlaced, activator.SeedPlacementError, activator.SeedMarkerSuffix, provision.SeedHooks{Data} on ReconcileConfig.Seeds.

Plan 5: (s *Server) resolveDBSource, dbdoor.RestoreToTarget, dbdoor.PlanRestore, dbdoor.ErrHistoryGone, seedScratch, replicaDoer, Config.SeedData, Config.SeedScratchDir, objstore.Declared.Seed, seedCreate, seedStoreRefusal, abortSeedQuietly.

Plan 6: (s *Server) finishSeed(ctx, sqid, app, host, seedID string) error.

Plan 7: registry.Route.ImportGate (column import_gate), the import_journal table with registry.ImportJournal and its five transactions, registry.OpsAccountSqid, registry.ImportGateClosed, seeds.LegacyOwnersKey, seeds.ReadLegacyOwners, the SeedHooks swap and rollback hooks.

From the run series (#259): provision.Record.ActiveRun *RunState with RunState.State in queued | picked | cancel | done | cancelled | expired (run spec §5.1). Plan 6 Task 5 reads it; if the run series' record task has not merged, Plan 6 Task 5 waits for it. The run series uses (*SeedSource).BlocksRun() from Plan 2. If the run series lands a minimal SeedSource first, Plan 2 Task 2 extends that type instead of declaring it.

What these plans do not build

  • The claim algorithm of spec §3.4 (#250). Every claim-armed box and console refuses.
  • --at <time> (spec §4 step 4, codex R2-18).
  • Titogo's half of the conversion (spec §10 step 5).
  • Rollout steps (spec §10), which need Paul's go at each step.