feat(daemon): P21 I3 sub-1 — migration 067 era-stamp on the queue-spine stores

The I3 foundation: extend the claimed-era vs derived-era boundary (mig-065 pattern) to the
queue-spine identity stores — a NULLABLE identity_provenance column on queue_transitions,
inbox_entries, outbox_entries, stream_items. The I3 routes' transport chokepoint will write
transport:v1; absence = claimed-era (no backfill, per-row honest). Additive + nullable,
identical contract to dev50's 065 mission_control_actions column.

Registered in the prod ALL_MIGRATIONS. RED-first; the test seeds from the SHIPPED ALL_MIGRATIONS
(not the curated createFullTestDb subset, which omits the inbox/outbox base tables) — migration
fixture parity. daemon tsc/build 0.

Base: dev50's P21 lane p21/body-identity-sweep @ 24a71bc58 (I import their requireSenderIdentity;
migration 067 is mine). I3 verbs (requireSenderIdentity wiring + era-stamp writes + validateTargetRepo)
follow on this branch.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
v-openrig-buildandClaude Opus 4.8 committed 2026-08-07 21:51:13 +00:00
1 parent b178d06234
commit a43ca1b2d9
3 files changed
+46 -1

No files matched your search

+3 -1
View File
@@ -69,9 +69,10 @@ import { occupantGenerationStampsSchema } from "./migrations/063_occupant_genera
import { projectionManifestSchema } from "./migrations/064_projection_manifest.js";
import { identityProvenanceSchema } from "./migrations/065_identity_provenance.js";
import { watchdogTargetGenerationSchema } from "./migrations/066_watchdog_target_generation.js";
import { i3IdentityProvenanceSchema } from "./migrations/067_i3_identity_provenance.js";
import type { Migration } from "./migrate.js";
/** Ordered 001→066 (064/066 from main, 065 the P21 identity_provenance boundary — all additive/independent). */
/** Ordered 001→067 (064/066 from main, 065 + 067 the P21 identity_provenance era-stamps — all additive/independent). */
export const ALL_MIGRATIONS: Migration[] = [
coreSchema,
bindingsSessionsSchema,
@@ -139,4 +140,5 @@ export const ALL_MIGRATIONS: Migration[] = [
projectionManifestSchema,
identityProvenanceSchema,
watchdogTargetGenerationSchema,
i3IdentityProvenanceSchema,
];
@@ -0,0 +1,20 @@
import type { Migration } from "../migrate.js";
/**
* P21 I3 — extend the CLAIMED-era vs DERIVED-era audit boundary (plan §4, migration 065) to the
* QUEUE-SPINE identity-carrying stores. Adds the same NULLABLE `identity_provenance` column to
* `queue_transitions`, `inbox_entries`, `outbox_entries`, and `stream_items`. The I3 routes' transport
* chokepoint writes `transport:v1`; **absence IS the claimed-era marker** — no backfill, no re-labeling
* (the house absent-never-fabricated doctrine). The boundary is per-ROW truth, not a timestamp: each
* store's rows stay individually honest as I3's surfaces flip at their folds. Additive + nullable —
* identical contract to 065's `mission_control_actions` column.
*/
export const i3IdentityProvenanceSchema: Migration = {
name: "067_i3_identity_provenance.sql",
sql: `
ALTER TABLE queue_transitions ADD COLUMN identity_provenance TEXT;
ALTER TABLE inbox_entries ADD COLUMN identity_provenance TEXT;
ALTER TABLE outbox_entries ADD COLUMN identity_provenance TEXT;
ALTER TABLE stream_items ADD COLUMN identity_provenance TEXT;
`,
};
@@ -0,0 +1,23 @@
import { describe, it, expect } from "vitest";
import { createDb } from "../src/db/connection.js";
import { migrate } from "../src/db/migrate.js";
import { ALL_MIGRATIONS } from "../src/db/all-migrations.js";
// P21 I3 — migration 067 extends the era-stamp audit boundary (mig-065 pattern) to the QUEUE-SPINE
// identity-carrying stores. Same contract as 065's mission_control_actions column: a NULLABLE
// identity_provenance the I3 chokepoint writes `transport:v1` into; absence = claimed-era (no backfill).
describe("migration 067 — I3 era-stamp: identity_provenance on the queue-spine stores", () => {
it("adds a NULLABLE identity_provenance column to queue_transitions, inbox_entries, outbox_entries, stream_items", () => {
// Seed with the SHIPPED migration set (not the curated createFullTestDb subset, which omits the
// inbox/outbox base tables) — migration-fixture parity: prove the real ALL_MIGRATIONS path.
const db = createDb();
migrate(db, ALL_MIGRATIONS);
for (const table of ["queue_transitions", "inbox_entries", "outbox_entries", "stream_items"]) {
const cols = db.prepare(`PRAGMA table_info(${table})`).all() as Array<{ name: string; notnull: number }>;
const col = cols.find((c) => c.name === "identity_provenance");
expect(col, `${table} must carry the identity_provenance era-stamp`).toBeTruthy();
// NULLABLE is load-bearing: absence IS the claimed-era marker (never backfilled/re-labeled).
expect(col!.notnull, `${table}.identity_provenance must be NULLABLE`).toBe(0);
}
});
});