carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

| Round-1 finding | Disposition at 999fc5c2 | |---|---| | 1. Run hold misses stop paths | Not fixed. Run §5.3 addresses stop ordering, but §5.1 still does not serialize run and move admission. Both requests can read “idle,” then successfully update different objects. Moves update the instance record (provision.go:1129); Put conditions only the object being written (store.go:767). Both admissions must acquire the same conditional reservation. | | 2. Claim-enabled execution prerequisite | Fixed by scope. Both specs explicitly refuse claim-armed boxes and defer guarded launch integration to #250. | | 3. Dropped or replayed runs | Not fixed. Startup scans and create-only pickup address those cases, but requests still identify only the hostname, without the requested instance incarnation. Delete/recreate before pickup can execute the old request against the replacement. Existing incarnation identity includes CreatedAt (record.go:91). Bind request, pickup and launch to that identity. | | 4. Oneshot completion | Fixed. Run §5.4 defines invocation-specific completion, result capture, stop and settlement. | | 5. Ack deletes unread output | Fixed. Run §§5.5–5.6 require durable chunks, last_seq, complete consumption and a matching ack. | | 6. Long-host upload paths | Fixed. Run §5.2 uses provision.InstanceDir. | | 7. Command region environment | Fixed. Run §4 specifies authoritative set/remove behavior in cmdVars. | | 8. Warm-file shortcut versus claim restore | Fixed by scope. Seeded §3.4 excludes claim restore from this implementation. | | 9. Operator row’s destination account | Fixed. Seeded §6.4 requires an operator-authored destination-account/app assignment. | | 10. Invalid addr-route predicate | Not fixed completely. The kind/backing vocabulary is corrected, but §5.4 still admits Backing, Caps, Platform and Canary rows. Existing adoption explicitly protects these ownership fields (reconcile.go:598). Preserve those refusals unless an explicit transfer contract covers them. | | 11. Claim acquisition during swap | Fixed by scope. Claim-armed imports are refused; the proposed swap no longer acquires a claim. | | 12. Flat paths derived from legacy row | Fixed. Seeded §5.4 explicitly derives nested replacement paths. | | 13. Aborted state skipped | Fixed. Seeded §3.2 dispatches rollback before the admission filter. | | 14. Original row cannot be reconstructed | Fixed. Seeded §5.4 journals the complete row in the replacement transaction. | | 15. Unobservable ordinary-traffic condition | Fixed for HTTP admission. Seeded §5.4 supplies authenticated verification and a durable commit boundary. A separate command-path interaction appears below. | | 16. Downgrade consumes seed records | Fixed. Seeded §3.3 requires an armed seed floor and rollback-binary verdict before any seed record. | | 17. Service credentials rejected | Fixed. Seeded §4 separates seed authorization from source resolution. | | 18. Historical restore | Not fixed for timestamps. Passing Timestamp through is insufficient: dbdoor.Client.LTXFiles discards useMetadata (client.go:78), and the console listing requests false (apidb.go:273). That selects S3 modification time rather than transaction metadata (replica_client.go:1574). Preserve transaction timestamps throughout historical planning. | | 19. Scratch bounds | Not fixed. LTX pages are compressed (encoder.go:255); restored output expands to database pages (decoder.go:235). Twice the listed object sizes does not bound scratch or establish the claimed 4-GiB database limit. Concurrent free-space checks also reserve nothing, and imports have no stated concurrency bound. Reserve aggregate scratch, bound decoded output, and include uploads in admission. | | 20. Multipart support and permissions | Fixed. Seeded §5.2 replaces multipart with a bounded, seekable spool and single PutFrom. |

  1. P1 — Seeded §§3.4, 5.6: abort followed by re-import restores the aborted database. Import snapshot A, verify it, abort, let the original process advance, then import snapshot B at the same hostname. Abort deletes the remote replica and snapshot but leaves the local database. Stopping deliberately preserves that database (activator.go:2104), and restore accepts an existing local file without restoring anything (backend_exec.go:611). Section 3.4 therefore treats A as an interrupted installation of B, ignores B and republishes stale data.

Fix: bind local seed installation to a unique import identity. After proven shutdown, abort must remove that import’s database, WAL/SHM and replication metadata before allowing another import. A warm file without matching installation evidence must not suppress the new snapshot.

  1. P1 — Run §5.1; seeded §§5.4–5.6: carlos run bypasses the import’s abort-safety gate. After verification places the snapshot, the imported row satisfies run’s platform-exec, nested and replication conditions. Neither run admission nor pickup checks whether the import is committed. A member can successfully run a database mutation, then another member can abort and delete its replica. The command operates through the activator/control path, rather than an edge request: existing wake starts the process directly (activator.go:1282), and instance control starts its unit directly (server.go:344). An HTTP verification header cannot protect this path.

Fix: refuse runs against uncommitted imports at console admission and again at launch. Serialize this check with import state transitions so a queued run cannot cross an abort or replacement.

  1. P2 — Seeded §5.4: the registry transaction does not make the complete swap crash-safe. Crash after committing replaced_routes and the exec row but before setting the bucket record to swapped. On restart the record remains ready; the prescribed swap predicate encounters a provisioned, socket-backed row and marks it refused. The record-state table then skips it indefinitely. Existing reconcile independently reads bucket records and registry rows (reconcile.go:824, reconcile.go:1062); a registry transaction cannot include the later bucket write.

Fix: consult a journal bound to the import identity before applying legacy-row predicates. Resume the bucket transition when that import’s replacement already exists. Define recovery when abort wins during this interval, retaining the abort record until local rollback is acknowledged.

  1. P2 — Seeded §5.6: stopping does not exclude another verification wake during rollback. The sequence stops the instance while its verification-enabled exec row remains installed, then restores the original row and deletes the replica. A second request carrying the valid token can wake the instance between stop completion and replacement. Ordinary stop forgets the entry (activator.go:2373); the separate maintenance API exists specifically to close admission before collecting stop evidence (maintenance.go:45). Without that exclusion, rollback can delete replication state while a new invocation is using it.

Fix: install an import-bound maintenance fence before stopping, reject further verification admission, and require complete stop evidence before replacement or deletion. Keep the fence through cleanup and recover it after restart.

  1. P1 — Seeded §§3.1, 3.4: seven-day expiration deletes seeds that are still required. The lifecycle rule covers every seeds/<host>/snapshot.db, including a successful --from instance that nobody wakes for seven days. Creation only mints a route (reconcile.go:1173); restore happens on wake (activator.go:1180). Such an instance has neither local data nor its own replica when expiration removes its only accepted snapshot. Its first wake must fail permanently.

Fix: retain snapshots while a live record still needs initial placement. Sweep abandoned imports through an explicit terminal transition; expire only objects proved unreferenced or superseded by a durable replica.

  1. P2 — Run §§5.2, 5.6–5.8: a “not picked up” failure leaves an executable request behind. At 60 seconds the CLI exits with code 3, but no state transition closes the request. A box returning at 61 seconds scans open runs and can execute it after the caller received failure. The create-only pickup precondition tests object absence, not request age or cancellation (store.go:774). Cancellation before pickup similarly needs a launch refusal, not merely “stop the unit” when no unit exists.

Fix: define a durable queued/picked/cancelled/expired state machine. Pickup and terminal cancellation must compete on the same conditional state, with the deadline and cancellation checked before launch. A terminal pickup-timeout response must prevent later execution.

  1. P2 — Seeded §§3.2, 5.6: ordinary instance deletion bypasses import rollback. An uncommitted import remains reachable through the ordinary instance-delete endpoint (authcli.go:683). In the claims-off implementation, deleting a record is an object deletion (provision.go:1844); reconcile then removes its provisioned route (reconcile.go:1386). No aborted record remains to dispatch restoration of replaced_routes, leaving the original route unrestored.

Fix: route deletion of an uncommitted import through the durable abort protocol, or refuse it with the abort operation identified. Recover outstanding replacement journals independently of the continued existence of their instance records.

carlos run: revise.

Seeded instances: revise.