Repository navigation
feat(s03): additive migration for task requirements, rehearsed on a restored store - #60
Merged
Merged
Conversation
…estored store Migration 008-ship-task-requirements follows the 006/007 new-table convention exactly: ledger-recorded on every store, guarded by the write-shaped shape probe (hasColumns) and the DDL-parity test, and a rename-aside rebuild limb that is unreachable today because no other shape of ship_task_requirements was ever released (nothing copied, nothing dropped, the aside keeps what it held). The store itself stays deliberately unwired: taskRecord() remains a read-only projection, no route/worker/UI writes the table, and a write path is future work gated on the programme's S03 rollout list. Rehearsed on a restored copy of the production store (verified pre-80c9187-shadow-deploy-2026-10-04 backup; isolated throwaway engine on a private docker network; live ship-* containers never touched): - additive-only: 45 tables / 4223 rows identical before and after, the only change being ship_migrations 7 -> 8 (the 008 ledger row) - replay: a second migrate() applies nothing - real-engine store proof (not the unit-test fake): DDL creates the table, idempotent add, conflict refusal via the primary key, exactly-once waiver via the conditional UPDATE, waived rows stay listed; own proof rows deleted afterwards Driver scripts/check-task-requirements-migration.mjs (the check-intake-concurrency isolation contract: SHIP_ISOLATED_CHECK=1 + NUCLEUS_URL); receipt evals/receipts/2026-10-04-s03-requirements-migration.json. Unit tests: 008 write-shaped probe, no-op on fresh install, rename-aside on a stale shape, ledger-only on a current shape, replay no-op, plus the DDL-parity owner entry for task-requirements.ts. Full suite green (2163 + 222 pass, 1 documented local skip). No upstream defect found; no Neutron or Nucleus change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
S03 storage, finished to the boundary the programme draws: migration
008-ship-task-requirementsforsrc/task-requirements.ts(the draftedaccepted/waived requirements store), rehearsed on a restored copy of the
real store. No write path is enabled —
taskRecord()stays aread-only projection; wiring the store into enqueue/run page remains
future work.
Migration shape
Follows the 006/007 new-table convention exactly (the most recent table
additions, PRs #41/#51, add no migration at all; 006/007 exist to give a
new table the two guards that only a migration entry provides):
needed(): write-shaped probe (hasColumns, never a SELECT — Nucleusresolves unknown SELECT columns to NULL); false when the table is
absent, because the store's own
CREATE TABLE IF NOT EXISTScreates itrun(): rename-aside +CREATE TABLEmatching the store DDL(enforced by the DDL-parity test); nothing copied (no other shape was
ever released), nothing dropped — same as 006/007
ship_migrationsunder the KV lock; replay is a no-opRehearsal (receipt:
evals/receipts/2026-10-04-s03-requirements-migration.json)Driver
scripts/check-task-requirements-migration.mjs(thecheck-intake-concurrencyisolation contract:SHIP_ISOLATED_CHECK=1+NUCLEUS_URL), run against a throwawayengine on a private docker network holding the verified
pre-80c9187-shadow-deploy-2026-10-04backup. Liveship-*containers and
/deployments/shipwere never touched (verified Upbefore and after, no restart); only the proof container/network/dir were
created and removed.
migrate()exceptship_migrations7 → 8 (the 008 ledger row). Theapplied-ids list is empty because the table does not exist on the real
store (the store is unwired): ledger-only is the designed path; the
rename-aside limb is covered by the unit tests against a stale shape.
migrate()applied nothing (12 ms).DDL creates the table; idempotent add; different content under the
same id refused via the primary key; waiver exactly-once via the
conditional UPDATE; waived requirements stay listed. Proof rows
deleted afterwards (final count 0, everything else unchanged).
Tests
008 probes ship_task_requirements write-shaped, and is a no-op on a fresh install008 is ledger-only on a current-shape table, and replay is a no-optask-requirements.tsgreen
(grader-sensitivity port 8901; the one failure seen first was the
documented environmental
web/node_modulesabsence in a freshworktree, fixed by installing web deps)
Not done (deliberate)
Wiring into enqueue + run page, accept/waive authorisation on approval
grants, feeding waived/active requirements into
taskRecord()acceptance, versioned plans, lost-response / two-tab / steer scenarios
on a real run — all still listed on the programme's S03 rollout row.
Do not merge from this session.