@sekiban/create-dcb 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +90 -0
- package/README.md +18 -2
- package/bin/create-dcb.mjs +91 -0
- package/package.json +17 -4
- package/template/AGENTS.md +23 -0
- package/template/LICENSE +90 -0
- package/template/README.md +76 -0
- package/template/REPLACE.md +34 -0
- package/template/cloudflare.config.ts +13 -0
- package/template/migrations/d1/g32/0001_dcb_events.sql +119 -0
- package/template/migrations/d1/g32/0002_g44_global_completeness.sql +88 -0
- package/template/migrations/d1/g32/0003_g58_safe_lane_health.sql +12 -0
- package/template/migrations/d1/g32/0004_g58_live_poll_health.sql +18 -0
- package/template/migrations/d1/g32/0005_g58_safe_lane_history.sql +18 -0
- package/template/migrations/d1/g32/0006_g60_durable_hop_measurements.sql +31 -0
- package/template/migrations/d1/g32/0007_g60_post_admission_decomposition.sql +30 -0
- package/template/migrations/d1/g32/0008_g60_unsafe_writer_boundaries.sql +24 -0
- package/template/migrations/d1/g32/0009_g65_admission_attempts.sql +23 -0
- package/template/migrations/d1/g32/0010_g65_direct_rings.sql +26 -0
- package/template/migrations/d1/g32/0011_g67_safe_lane_passes.sql +25 -0
- package/template/migrations/d1/g32/0012_g67_safe_lane_pass_ownership.sql +20 -0
- package/template/migrations/d1/g32/0013_g67_safe_lane_catch_up_observations.sql +6 -0
- package/template/migrations/d1/g32/0014_g67_safe_lane_fence_expiry.sql +6 -0
- package/template/migrations/d1/g32/0015_g69_admission_attempts.sql +33 -0
- package/template/migrations/d1/g32/0016_g69_consultation003.sql +12 -0
- package/template/migrations/d1/g32/0017_g69_receipt_identity.sql +61 -0
- package/template/migrations/d1/g32/0018_g69_mutation_evidence.sql +5 -0
- package/template/migrations/d1/g32/0019_g69_mutation_receipt_label.sql +6 -0
- package/template/migrations/d1/g32/0020_g69_hotpath_costs.sql +6 -0
- package/template/migrations/mv/0001_materialized_views.sql +87 -0
- package/template/migrations/mv/0002_unsafe_window_materialized_views.sql +58 -0
- package/template/migrations/mv/0003_checkpoint_ahead_hardening.sql +14 -0
- package/template/migrations/mv/0004_unsafe_window_failure_findings.sql +12 -0
- package/template/migrations/mv/0005_g31_wait_receipts.sql +25 -0
- package/template/migrations/mv/0006_g31_wait_target_poison.sql +48 -0
- package/template/migrations/mv/0007_g69_ordering_quarantine.sql +21 -0
- package/template/migrations/mv/0008_g69_rebuild_verification.sql +4 -0
- package/template/migrations/mv/0009_g69_rebuild_proof.sql +11 -0
- package/template/package.json +24 -0
- package/template/public/.assetsignore +2 -0
- package/template/public/app.js +40 -0
- package/template/public/index.html +58 -0
- package/template/public/styles.css +20 -0
- package/template/scripts/deploy.sh +5 -0
- package/template/scripts/migrate.sh +5 -0
- package/template/src/booking-domain.ts +285 -0
- package/template/src/booking-mv.ts +166 -0
- package/template/src/booking-routes.ts +160 -0
- package/template/src/booking-transport.ts +169 -0
- package/template/src/worker.ts +38 -0
- package/template/tsconfig.json +13 -0
- package/template/wrangler.jsonc +55 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- SDT-G58 safe-lane operational health. This is intentionally an additive
|
|
2
|
+
-- pipeline-D1 migration: the runtime never performs DDL, and the row records
|
|
3
|
+
-- the last *scheduled* coverage decision rather than inferring it from a
|
|
4
|
+
-- request-time read.
|
|
5
|
+
CREATE TABLE serialized_dcb_safe_lane_health (
|
|
6
|
+
service_id TEXT PRIMARY KEY,
|
|
7
|
+
coverage_kind TEXT NOT NULL CHECK (coverage_kind IN ('SETTLED', 'BLOCK/UNSETTLED')),
|
|
8
|
+
coverage_reason TEXT,
|
|
9
|
+
coverage_partition_tag TEXT COLLATE BINARY,
|
|
10
|
+
settled_frontier_suid TEXT NOT NULL COLLATE BINARY DEFAULT '',
|
|
11
|
+
observed_at INTEGER NOT NULL
|
|
12
|
+
);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
-- SDT-G58 AC5 live-poll lifecycle diagnostics. This is additive and
|
|
2
|
+
-- observation-only: projection checkpoints and all SafeWindow/fence decisions
|
|
3
|
+
-- remain in their existing tables and transactions.
|
|
4
|
+
CREATE TABLE serialized_dcb_live_poll_health (
|
|
5
|
+
service_id TEXT NOT NULL,
|
|
6
|
+
projector_id TEXT NOT NULL,
|
|
7
|
+
attempted_at INTEGER NOT NULL,
|
|
8
|
+
outcome TEXT NOT NULL CHECK (outcome IN (
|
|
9
|
+
'never-invoked',
|
|
10
|
+
'invoked-and-threw',
|
|
11
|
+
'invoked-but-no-work',
|
|
12
|
+
'explicitly-gated',
|
|
13
|
+
'advanced'
|
|
14
|
+
)),
|
|
15
|
+
reason TEXT,
|
|
16
|
+
advanced_source_events INTEGER NOT NULL DEFAULT 0 CHECK (advanced_source_events >= 0),
|
|
17
|
+
PRIMARY KEY (service_id, projector_id)
|
|
18
|
+
);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
-- SDT-G58 AC1 scheduled safe-lane history. This is append-only evidence of
|
|
2
|
+
-- the coverage decision made by each cron tick. An empty frontier is an
|
|
3
|
+
-- explicit record of a tick for which no proven FULL frontier existed; the
|
|
4
|
+
-- health guard treats that value as red rather than substituting an MV head.
|
|
5
|
+
CREATE TABLE serialized_dcb_safe_lane_history (
|
|
6
|
+
service_id TEXT NOT NULL,
|
|
7
|
+
tick_id TEXT NOT NULL COLLATE BINARY,
|
|
8
|
+
coverage_kind TEXT NOT NULL CHECK (coverage_kind IN ('SETTLED', 'BLOCK/UNSETTLED')),
|
|
9
|
+
coverage_reason TEXT,
|
|
10
|
+
coverage_partition_tag TEXT COLLATE BINARY,
|
|
11
|
+
settled_frontier_suid TEXT NOT NULL COLLATE BINARY DEFAULT '',
|
|
12
|
+
observed_at INTEGER NOT NULL,
|
|
13
|
+
PRIMARY KEY (service_id, tick_id),
|
|
14
|
+
UNIQUE (service_id, observed_at)
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
CREATE INDEX serialized_dcb_safe_lane_history_service_observed
|
|
18
|
+
ON serialized_dcb_safe_lane_history (service_id, observed_at ASC, tick_id COLLATE BINARY ASC);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
-- SDT-G60 AC1 operational hop ledger.
|
|
2
|
+
--
|
|
3
|
+
-- This table is intentionally outside the logical event record and has no
|
|
4
|
+
-- foreign key to dcb_events: command receipt is captured before downstream
|
|
5
|
+
-- delivery creates the global event row. Stable EventId/SUID/attempt identity
|
|
6
|
+
-- is retained in every stage row; no protocol or public response reads it.
|
|
7
|
+
CREATE TABLE serialized_dcb_hop_measurements (
|
|
8
|
+
service_id TEXT NOT NULL,
|
|
9
|
+
event_id TEXT NOT NULL COLLATE BINARY,
|
|
10
|
+
suid TEXT NOT NULL COLLATE BINARY,
|
|
11
|
+
attempt_id TEXT NOT NULL COLLATE BINARY,
|
|
12
|
+
stage TEXT NOT NULL CHECK (stage IN (
|
|
13
|
+
'command-receipt',
|
|
14
|
+
'tag-append-committed',
|
|
15
|
+
'outbox-obligation-written',
|
|
16
|
+
'queue-send-returned',
|
|
17
|
+
'consumer-invocation-started',
|
|
18
|
+
'record-delivery-batch-committed',
|
|
19
|
+
'first-unsafe-visible-read'
|
|
20
|
+
)),
|
|
21
|
+
partition_tag TEXT NOT NULL COLLATE BINARY DEFAULT '',
|
|
22
|
+
view_id TEXT NOT NULL COLLATE BINARY DEFAULT '',
|
|
23
|
+
transport TEXT NOT NULL CHECK (transport IN ('', 'queue', 'fast', 'import', 'public-read')),
|
|
24
|
+
observed_at INTEGER NOT NULL CHECK (observed_at >= 0),
|
|
25
|
+
PRIMARY KEY (service_id, event_id, stage, partition_tag, view_id, transport)
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE INDEX serialized_dcb_hop_measurements_service_event_idx
|
|
29
|
+
ON serialized_dcb_hop_measurements (service_id, event_id COLLATE BINARY, observed_at ASC);
|
|
30
|
+
CREATE INDEX serialized_dcb_hop_measurements_service_time_idx
|
|
31
|
+
ON serialized_dcb_hop_measurements (service_id, observed_at ASC, stage COLLATE BINARY);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
-- SDT-G60 post-admission decomposition observations.
|
|
2
|
+
--
|
|
3
|
+
-- This is a separate append-only operational ledger so the original seven-hop
|
|
4
|
+
-- table and its deployed schema remain unchanged. Every row retains the exact
|
|
5
|
+
-- event/SUID/attempt identity; no protocol path reads this table.
|
|
6
|
+
CREATE TABLE serialized_dcb_hop_submeasurements (
|
|
7
|
+
service_id TEXT NOT NULL,
|
|
8
|
+
event_id TEXT NOT NULL COLLATE BINARY,
|
|
9
|
+
suid TEXT NOT NULL COLLATE BINARY,
|
|
10
|
+
attempt_id TEXT NOT NULL COLLATE BINARY,
|
|
11
|
+
stage TEXT NOT NULL CHECK (stage IN (
|
|
12
|
+
'post-record-delivery-global-receipt-readback',
|
|
13
|
+
'source-tag-acknowledgement',
|
|
14
|
+
'completeness-coverage',
|
|
15
|
+
'detector',
|
|
16
|
+
'unsafe-view-apply'
|
|
17
|
+
)),
|
|
18
|
+
boundary TEXT NOT NULL CHECK (boundary IN ('start', 'end')),
|
|
19
|
+
outcome TEXT NOT NULL CHECK (length(outcome) > 0),
|
|
20
|
+
partition_tag TEXT NOT NULL COLLATE BINARY DEFAULT '',
|
|
21
|
+
view_id TEXT NOT NULL COLLATE BINARY DEFAULT '',
|
|
22
|
+
transport TEXT NOT NULL CHECK (transport IN ('', 'queue', 'fast', 'import', 'public-read')),
|
|
23
|
+
observed_at INTEGER NOT NULL CHECK (observed_at >= 0),
|
|
24
|
+
PRIMARY KEY (service_id, event_id, stage, boundary, partition_tag, view_id, transport)
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
CREATE INDEX serialized_dcb_hop_submeasurements_service_event_idx
|
|
28
|
+
ON serialized_dcb_hop_submeasurements (service_id, event_id COLLATE BINARY, observed_at ASC);
|
|
29
|
+
CREATE INDEX serialized_dcb_hop_submeasurements_service_time_idx
|
|
30
|
+
ON serialized_dcb_hop_submeasurements (service_id, observed_at ASC, stage COLLATE BINARY, boundary COLLATE BINARY);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
-- SDT-G60 concrete unsafe-row writer boundaries.
|
|
2
|
+
--
|
|
3
|
+
-- This is observation-only. It has no foreign keys and is never read by
|
|
4
|
+
-- admission, Queue acknowledgement, projection fencing, or public reads.
|
|
5
|
+
-- Each row retains the exact event/SUID/attempt/view identity and names the
|
|
6
|
+
-- concrete path at the unsafe apply boundary.
|
|
7
|
+
CREATE TABLE serialized_dcb_unsafe_writer_boundaries (
|
|
8
|
+
service_id TEXT NOT NULL,
|
|
9
|
+
event_id TEXT NOT NULL COLLATE BINARY,
|
|
10
|
+
suid TEXT NOT NULL COLLATE BINARY,
|
|
11
|
+
attempt_id TEXT NOT NULL COLLATE BINARY,
|
|
12
|
+
writer_path TEXT NOT NULL CHECK (writer_path IN ('inline-delivery', 'scheduled-drain')),
|
|
13
|
+
boundary TEXT NOT NULL CHECK (boundary IN ('start', 'end')),
|
|
14
|
+
outcome TEXT NOT NULL CHECK (length(outcome) > 0),
|
|
15
|
+
view_id TEXT NOT NULL COLLATE BINARY,
|
|
16
|
+
transport TEXT NOT NULL CHECK (transport IN ('', 'queue', 'fast', 'import', 'scheduled')),
|
|
17
|
+
observed_at INTEGER NOT NULL CHECK (observed_at >= 0),
|
|
18
|
+
PRIMARY KEY (service_id, event_id, writer_path, view_id, boundary, transport)
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
CREATE INDEX serialized_dcb_unsafe_writer_boundaries_service_event_idx
|
|
22
|
+
ON serialized_dcb_unsafe_writer_boundaries (service_id, event_id COLLATE BINARY, observed_at ASC);
|
|
23
|
+
CREATE INDEX serialized_dcb_unsafe_writer_boundaries_service_time_idx
|
|
24
|
+
ON serialized_dcb_unsafe_writer_boundaries (service_id, observed_at ASC, writer_path COLLATE BINARY, view_id COLLATE BINARY);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
-- SDT-G65 admission timing and outcome observations.
|
|
2
|
+
--
|
|
3
|
+
-- This is an operational ledger only. No admission, Queue, projection, or
|
|
4
|
+
-- public response path reads it. The clock is the Worker wall clock captured
|
|
5
|
+
-- at the boundary (`Date.now()`, epoch milliseconds); it is intentionally not
|
|
6
|
+
-- confused with an authored event timestamp or D1's received_at value.
|
|
7
|
+
CREATE TABLE serialized_dcb_g65_admission_attempts (
|
|
8
|
+
service_id TEXT NOT NULL,
|
|
9
|
+
event_id TEXT NOT NULL COLLATE BINARY,
|
|
10
|
+
suid TEXT NOT NULL COLLATE BINARY,
|
|
11
|
+
attempt_id TEXT NOT NULL COLLATE BINARY,
|
|
12
|
+
partition_tag TEXT NOT NULL COLLATE BINARY,
|
|
13
|
+
delivery_source TEXT NOT NULL CHECK (delivery_source IN ('fast')),
|
|
14
|
+
admission_started_at INTEGER NOT NULL CHECK (admission_started_at >= 0),
|
|
15
|
+
admission_finished_at INTEGER NOT NULL CHECK (admission_finished_at >= admission_started_at),
|
|
16
|
+
outcome TEXT NOT NULL CHECK (outcome IN ('admitted', 'not-admitted', 'unknown')),
|
|
17
|
+
global_completion_observed_at INTEGER,
|
|
18
|
+
clock_origin TEXT NOT NULL CHECK (clock_origin = 'Date.now epoch ms'),
|
|
19
|
+
PRIMARY KEY (service_id, event_id, attempt_id, delivery_source, admission_started_at)
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
CREATE INDEX serialized_dcb_g65_admission_attempts_service_time_idx
|
|
23
|
+
ON serialized_dcb_g65_admission_attempts (service_id, admission_started_at ASC, event_id COLLATE BINARY);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
-- SDT-G65 AC0 receiver ring/apply ledger.
|
|
2
|
+
--
|
|
3
|
+
-- The ring is the only receiver work awaited by the Tag Durable Object. The
|
|
4
|
+
-- message bytes are retained before the RPC returns; the receiver then reads
|
|
5
|
+
-- this durable row from its own execution context and performs the existing
|
|
6
|
+
-- idempotent D1 delivery/apply. This table is diagnostic/transport state, not
|
|
7
|
+
-- an event or admission authority.
|
|
8
|
+
CREATE TABLE serialized_dcb_g65_direct_rings (
|
|
9
|
+
service_id TEXT NOT NULL,
|
|
10
|
+
event_id TEXT NOT NULL COLLATE BINARY,
|
|
11
|
+
suid TEXT NOT NULL COLLATE BINARY,
|
|
12
|
+
attempt_id TEXT NOT NULL COLLATE BINARY,
|
|
13
|
+
partition_tag TEXT NOT NULL COLLATE BINARY,
|
|
14
|
+
message_json TEXT NOT NULL,
|
|
15
|
+
ring_started_at INTEGER NOT NULL CHECK (ring_started_at >= 0),
|
|
16
|
+
ring_finished_at INTEGER NOT NULL CHECK (ring_finished_at >= ring_started_at),
|
|
17
|
+
ring_outcome TEXT NOT NULL CHECK (ring_outcome IN ('rung', 'duplicate')),
|
|
18
|
+
apply_started_at INTEGER,
|
|
19
|
+
apply_finished_at INTEGER,
|
|
20
|
+
apply_outcome TEXT,
|
|
21
|
+
apply_error TEXT,
|
|
22
|
+
PRIMARY KEY (service_id, event_id, attempt_id)
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
CREATE INDEX serialized_dcb_g65_direct_rings_service_time_idx
|
|
26
|
+
ON serialized_dcb_g65_direct_rings (service_id, ring_finished_at ASC, event_id COLLATE BINARY);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-- SDT-G67 AC1/AC6 event-driven safe-lane pass provenance.
|
|
2
|
+
-- This is observation-only: no safe frontier or Queue decision reads this
|
|
3
|
+
-- table. A row is created before a kick is started and then updated through
|
|
4
|
+
-- the pass lifecycle so a missing kick, coalesced request, or failed pass is
|
|
5
|
+
-- distinguishable from a completed pass.
|
|
6
|
+
CREATE TABLE serialized_dcb_safe_lane_passes (
|
|
7
|
+
service_id TEXT NOT NULL,
|
|
8
|
+
pass_id TEXT NOT NULL COLLATE BINARY,
|
|
9
|
+
trigger TEXT NOT NULL CHECK (trigger IN ('kick', 'cron')),
|
|
10
|
+
status TEXT NOT NULL CHECK (status IN ('scheduled', 'running', 'completed', 'failed', 'coalesced')),
|
|
11
|
+
scheduled_at INTEGER NOT NULL,
|
|
12
|
+
started_at INTEGER,
|
|
13
|
+
completed_at INTEGER,
|
|
14
|
+
coverage_kind TEXT CHECK (coverage_kind IS NULL OR coverage_kind IN ('SETTLED', 'BLOCK/UNSETTLED')),
|
|
15
|
+
coverage_reason TEXT,
|
|
16
|
+
coverage_partition_tag TEXT COLLATE BINARY,
|
|
17
|
+
settled_frontier_suid TEXT COLLATE BINARY,
|
|
18
|
+
safe_heads_before_json TEXT,
|
|
19
|
+
safe_heads_after_json TEXT,
|
|
20
|
+
error TEXT,
|
|
21
|
+
PRIMARY KEY (service_id, pass_id)
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
CREATE INDEX serialized_dcb_safe_lane_passes_service_scheduled
|
|
25
|
+
ON serialized_dcb_safe_lane_passes (service_id, scheduled_at ASC, pass_id COLLATE BINARY ASC);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- SDT-G67 AC4 durable ownership and effective catch-up attribution.
|
|
2
|
+
-- These columns are observation-only. The G44 frontier and Queue
|
|
3
|
+
-- disposition never read this table.
|
|
4
|
+
ALTER TABLE serialized_dcb_safe_lane_passes ADD COLUMN delivery_event_id TEXT COLLATE BINARY;
|
|
5
|
+
ALTER TABLE serialized_dcb_safe_lane_passes ADD COLUMN delivery_attempt_id TEXT COLLATE BINARY;
|
|
6
|
+
ALTER TABLE serialized_dcb_safe_lane_passes ADD COLUMN delivery_partition_tag TEXT COLLATE BINARY;
|
|
7
|
+
ALTER TABLE serialized_dcb_safe_lane_passes ADD COLUMN delivery_obligation_sequence INTEGER;
|
|
8
|
+
ALTER TABLE serialized_dcb_safe_lane_passes ADD COLUMN catch_up_started_at INTEGER;
|
|
9
|
+
ALTER TABLE serialized_dcb_safe_lane_passes ADD COLUMN catch_up_completed_at INTEGER;
|
|
10
|
+
ALTER TABLE serialized_dcb_safe_lane_passes ADD COLUMN catch_up_outcome TEXT;
|
|
11
|
+
ALTER TABLE serialized_dcb_safe_lane_passes ADD COLUMN catch_up_error TEXT;
|
|
12
|
+
|
|
13
|
+
CREATE INDEX serialized_dcb_safe_lane_passes_delivery_identity
|
|
14
|
+
ON serialized_dcb_safe_lane_passes (
|
|
15
|
+
service_id,
|
|
16
|
+
delivery_partition_tag COLLATE BINARY,
|
|
17
|
+
delivery_obligation_sequence,
|
|
18
|
+
scheduled_at ASC,
|
|
19
|
+
pass_id COLLATE BINARY ASC
|
|
20
|
+
);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
-- SDT-G67 AC4 observation-only catch-up result attribution.
|
|
2
|
+
-- These columns identify the exact Queue delivery SUID and the observed
|
|
3
|
+
-- SafeWindow/MV result. No safe-lane admission, frontier, or Queue decision
|
|
4
|
+
-- reads them.
|
|
5
|
+
ALTER TABLE serialized_dcb_safe_lane_passes ADD COLUMN delivery_suid TEXT COLLATE BINARY;
|
|
6
|
+
ALTER TABLE serialized_dcb_safe_lane_passes ADD COLUMN catch_up_result_json TEXT;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
-- SDT-G67 amended AC1 fence-expiry and coverage-retry provenance.
|
|
2
|
+
-- These fields are observation-only. They never participate in G44
|
|
3
|
+
-- certification, Queue disposition, MV advancement, or public reads.
|
|
4
|
+
ALTER TABLE serialized_dcb_safe_lane_passes ADD COLUMN trigger_kind TEXT CHECK (trigger_kind IS NULL OR trigger_kind IN ('delivery', 'fence-expiry', 'coverage-retry', 'cron', 'kick'));
|
|
5
|
+
ALTER TABLE serialized_dcb_safe_lane_passes ADD COLUMN stop_deadline_at INTEGER;
|
|
6
|
+
ALTER TABLE serialized_dcb_safe_lane_passes ADD COLUMN stop_reason TEXT;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
-- SDT-G69 AC3 append-only per-recordDelivery admission-attempt evidence.
|
|
2
|
+
-- This table is diagnostic only. No Queue, retry, G44, MV, or public-read
|
|
3
|
+
-- path may use it as an authority.
|
|
4
|
+
CREATE TABLE serialized_dcb_g69_admission_attempts (
|
|
5
|
+
sequence INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
6
|
+
service_id TEXT NOT NULL,
|
|
7
|
+
event_id TEXT NOT NULL COLLATE BINARY,
|
|
8
|
+
suid TEXT NOT NULL COLLATE BINARY,
|
|
9
|
+
partition_tag TEXT NOT NULL COLLATE BINARY,
|
|
10
|
+
delivery_source TEXT NOT NULL CHECK (delivery_source IN ('queue', 'fast', 'import')),
|
|
11
|
+
queue_message_id TEXT NOT NULL COLLATE BINARY,
|
|
12
|
+
attempt_id TEXT NOT NULL COLLATE BINARY,
|
|
13
|
+
allocator_lineage_id TEXT NOT NULL COLLATE BINARY,
|
|
14
|
+
obligation_sequence INTEGER NOT NULL CHECK (obligation_sequence >= 1),
|
|
15
|
+
enqueued_at INTEGER NOT NULL,
|
|
16
|
+
observed_at INTEGER NOT NULL,
|
|
17
|
+
arrived_at INTEGER NOT NULL,
|
|
18
|
+
first_arrived_at_before INTEGER,
|
|
19
|
+
last_arrived_at_before INTEGER,
|
|
20
|
+
first_arrived_at_after INTEGER,
|
|
21
|
+
last_arrived_at_after INTEGER,
|
|
22
|
+
receipt_status TEXT NOT NULL CHECK (receipt_status IN ('stored', 'duplicate', 'suid-collision', 'lineage-mismatch', 'failed')),
|
|
23
|
+
retry_reason TEXT,
|
|
24
|
+
clock_origin TEXT NOT NULL CHECK (clock_origin = 'Date.now epoch ms')
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
CREATE INDEX serialized_dcb_g69_admission_attempts_identity_idx
|
|
28
|
+
ON serialized_dcb_g69_admission_attempts
|
|
29
|
+
(service_id, event_id COLLATE BINARY, sequence ASC);
|
|
30
|
+
|
|
31
|
+
CREATE INDEX serialized_dcb_g69_admission_attempts_arrival_idx
|
|
32
|
+
ON serialized_dcb_g69_admission_attempts
|
|
33
|
+
(service_id, partition_tag COLLATE BINARY, observed_at ASC);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- SDT-G69 consultation-003: diagnostic observation is non-blocking and
|
|
2
|
+
-- ordering detection trusts only normal delivery timestamps.
|
|
3
|
+
-- Existing rows are deliberately marked unknown: imported/repaired history
|
|
4
|
+
-- cannot be promoted to a safety witness after the fact.
|
|
5
|
+
ALTER TABLE serialized_dcb_g69_admission_attempts ADD COLUMN before_observed_at INTEGER;
|
|
6
|
+
ALTER TABLE serialized_dcb_g69_admission_attempts ADD COLUMN after_observed_at INTEGER;
|
|
7
|
+
ALTER TABLE serialized_dcb_g69_admission_attempts ADD COLUMN observation_consistency TEXT NOT NULL DEFAULT 'unverified';
|
|
8
|
+
ALTER TABLE dcb_event_ops ADD COLUMN FirstArrivedSource TEXT NOT NULL DEFAULT 'unknown';
|
|
9
|
+
ALTER TABLE dcb_event_ops ADD COLUMN LastArrivedSource TEXT NOT NULL DEFAULT 'unknown';
|
|
10
|
+
|
|
11
|
+
CREATE INDEX serialized_dcb_g69_admission_attempts_retention_idx
|
|
12
|
+
ON serialized_dcb_g69_admission_attempts (service_id, sequence DESC);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
-- SDT-G69 F5: keep the diagnostic Queue wrapper identity distinct from the
|
|
2
|
+
-- envelope attempt identity. Direct delivery has no Queue wrapper, so its
|
|
3
|
+
-- queue_message_id is intentionally nullable. This table remains diagnostic;
|
|
4
|
+
-- no admission, retry, G44 or safe-lane path reads it.
|
|
5
|
+
DROP INDEX IF EXISTS serialized_dcb_g69_admission_attempts_identity_idx;
|
|
6
|
+
DROP INDEX IF EXISTS serialized_dcb_g69_admission_attempts_arrival_idx;
|
|
7
|
+
DROP INDEX IF EXISTS serialized_dcb_g69_admission_attempts_retention_idx;
|
|
8
|
+
ALTER TABLE serialized_dcb_g69_admission_attempts RENAME TO serialized_dcb_g69_admission_attempts_legacy;
|
|
9
|
+
|
|
10
|
+
CREATE TABLE serialized_dcb_g69_admission_attempts (
|
|
11
|
+
sequence INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
12
|
+
service_id TEXT NOT NULL,
|
|
13
|
+
event_id TEXT NOT NULL COLLATE BINARY,
|
|
14
|
+
suid TEXT NOT NULL COLLATE BINARY,
|
|
15
|
+
partition_tag TEXT NOT NULL COLLATE BINARY,
|
|
16
|
+
delivery_source TEXT NOT NULL CHECK (delivery_source IN ('queue', 'fast', 'import')),
|
|
17
|
+
queue_message_id TEXT COLLATE BINARY,
|
|
18
|
+
attempt_id TEXT NOT NULL COLLATE BINARY,
|
|
19
|
+
allocator_lineage_id TEXT NOT NULL COLLATE BINARY,
|
|
20
|
+
obligation_sequence INTEGER NOT NULL CHECK (obligation_sequence >= 1),
|
|
21
|
+
enqueued_at INTEGER NOT NULL,
|
|
22
|
+
observed_at INTEGER NOT NULL,
|
|
23
|
+
arrived_at INTEGER NOT NULL,
|
|
24
|
+
first_arrived_at_before INTEGER,
|
|
25
|
+
last_arrived_at_before INTEGER,
|
|
26
|
+
first_arrived_at_after INTEGER,
|
|
27
|
+
last_arrived_at_after INTEGER,
|
|
28
|
+
before_observed_at INTEGER,
|
|
29
|
+
after_observed_at INTEGER,
|
|
30
|
+
observation_consistency TEXT NOT NULL DEFAULT 'unverified',
|
|
31
|
+
receipt_status TEXT NOT NULL CHECK (receipt_status IN ('stored', 'duplicate', 'suid-collision', 'lineage-mismatch', 'failed')),
|
|
32
|
+
retry_reason TEXT,
|
|
33
|
+
clock_origin TEXT NOT NULL CHECK (clock_origin = 'Date.now epoch ms')
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
INSERT INTO serialized_dcb_g69_admission_attempts (
|
|
37
|
+
sequence, service_id, event_id, suid, partition_tag, delivery_source,
|
|
38
|
+
queue_message_id, attempt_id, allocator_lineage_id, obligation_sequence,
|
|
39
|
+
enqueued_at, observed_at, arrived_at, first_arrived_at_before,
|
|
40
|
+
last_arrived_at_before, first_arrived_at_after, last_arrived_at_after,
|
|
41
|
+
before_observed_at, after_observed_at, observation_consistency,
|
|
42
|
+
receipt_status, retry_reason, clock_origin
|
|
43
|
+
)
|
|
44
|
+
SELECT sequence, service_id, event_id, suid, partition_tag, delivery_source,
|
|
45
|
+
queue_message_id, attempt_id, allocator_lineage_id, obligation_sequence,
|
|
46
|
+
enqueued_at, observed_at, arrived_at, first_arrived_at_before,
|
|
47
|
+
last_arrived_at_before, first_arrived_at_after, last_arrived_at_after,
|
|
48
|
+
before_observed_at, after_observed_at, observation_consistency,
|
|
49
|
+
receipt_status, retry_reason, clock_origin
|
|
50
|
+
FROM serialized_dcb_g69_admission_attempts_legacy;
|
|
51
|
+
|
|
52
|
+
DROP TABLE serialized_dcb_g69_admission_attempts_legacy;
|
|
53
|
+
|
|
54
|
+
CREATE INDEX serialized_dcb_g69_admission_attempts_identity_idx
|
|
55
|
+
ON serialized_dcb_g69_admission_attempts
|
|
56
|
+
(service_id, event_id COLLATE BINARY, sequence ASC);
|
|
57
|
+
CREATE INDEX serialized_dcb_g69_admission_attempts_arrival_idx
|
|
58
|
+
ON serialized_dcb_g69_admission_attempts
|
|
59
|
+
(service_id, partition_tag COLLATE BINARY, observed_at ASC);
|
|
60
|
+
CREATE INDEX serialized_dcb_g69_admission_attempts_retention_idx
|
|
61
|
+
ON serialized_dcb_g69_admission_attempts (service_id, sequence DESC);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
-- SDT-G69 F5: retain the mutation-owned first-admission witness separately
|
|
2
|
+
-- from the diagnostic pre-read. The admission batch populates it atomically;
|
|
3
|
+
-- a diagnostic receipt may never infer duplicate status from a late read.
|
|
4
|
+
ALTER TABLE dcb_event_ops ADD COLUMN FirstAdmissionAttemptId TEXT;
|
|
5
|
+
ALTER TABLE dcb_event_ops ADD COLUMN LastAdmissionAttemptId TEXT;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
-- SDT-G69 F5: expose the mutation-owned classification on the append-only
|
|
2
|
+
-- diagnostic receipt. A late/failed diagnostic read is never allowed to infer
|
|
3
|
+
-- duplicate admission.
|
|
4
|
+
ALTER TABLE serialized_dcb_g69_admission_attempts
|
|
5
|
+
ADD COLUMN mutation_evidence TEXT NOT NULL DEFAULT 'unverified'
|
|
6
|
+
CHECK (mutation_evidence IN ('first-admission', 'duplicate-admission', 'unverified'));
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
-- SDT-G69 W167: retain diagnostic cost without making diagnostic work part of
|
|
2
|
+
-- the durable admission response. The value is the elapsed observation and
|
|
3
|
+
-- receipt-preparation time before the append is issued, measured with the
|
|
4
|
+
-- same Date.now epoch clock as the receipt. It is diagnostic only.
|
|
5
|
+
ALTER TABLE serialized_dcb_g69_admission_attempts
|
|
6
|
+
ADD COLUMN diagnostic_duration_ms INTEGER;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
-- SDT-G19 versioned MV schema. Runtime code never executes DDL.
|
|
2
|
+
-- Pipeline D1 and MV D1 are separate bindings; checkpoints live beside rows.
|
|
3
|
+
CREATE TABLE mv_instances (
|
|
4
|
+
service_id TEXT NOT NULL,
|
|
5
|
+
view_id TEXT NOT NULL COLLATE BINARY,
|
|
6
|
+
generation INTEGER NOT NULL,
|
|
7
|
+
status TEXT NOT NULL CHECK (status IN ('active', 'candidate', 'retired')),
|
|
8
|
+
last_suid TEXT NOT NULL COLLATE BINARY,
|
|
9
|
+
definition_version INTEGER NOT NULL,
|
|
10
|
+
updated_at INTEGER NOT NULL,
|
|
11
|
+
PRIMARY KEY (service_id, view_id, generation)
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
CREATE UNIQUE INDEX mv_instances_active_idx
|
|
15
|
+
ON mv_instances (service_id, view_id, status)
|
|
16
|
+
WHERE status = 'active';
|
|
17
|
+
|
|
18
|
+
CREATE TABLE mv_active_generations (
|
|
19
|
+
service_id TEXT NOT NULL,
|
|
20
|
+
view_id TEXT NOT NULL COLLATE BINARY,
|
|
21
|
+
generation INTEGER NOT NULL,
|
|
22
|
+
updated_at INTEGER NOT NULL,
|
|
23
|
+
PRIMARY KEY (service_id, view_id),
|
|
24
|
+
FOREIGN KEY (service_id, view_id, generation)
|
|
25
|
+
REFERENCES mv_instances (service_id, view_id, generation)
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE TABLE mv_rows (
|
|
29
|
+
service_id TEXT NOT NULL,
|
|
30
|
+
view_id TEXT NOT NULL COLLATE BINARY,
|
|
31
|
+
generation INTEGER NOT NULL,
|
|
32
|
+
row_key TEXT NOT NULL COLLATE BINARY,
|
|
33
|
+
value_json TEXT NOT NULL,
|
|
34
|
+
row_version INTEGER NOT NULL,
|
|
35
|
+
source_suid TEXT NOT NULL COLLATE BINARY,
|
|
36
|
+
PRIMARY KEY (service_id, view_id, generation, row_key),
|
|
37
|
+
FOREIGN KEY (service_id, view_id, generation)
|
|
38
|
+
REFERENCES mv_instances (service_id, view_id, generation)
|
|
39
|
+
ON DELETE CASCADE
|
|
40
|
+
);
|
|
41
|
+
CREATE INDEX mv_rows_generation_idx
|
|
42
|
+
ON mv_rows (service_id, view_id, generation, row_key COLLATE BINARY);
|
|
43
|
+
|
|
44
|
+
CREATE TABLE mv_index_entries (
|
|
45
|
+
service_id TEXT NOT NULL,
|
|
46
|
+
view_id TEXT NOT NULL COLLATE BINARY,
|
|
47
|
+
generation INTEGER NOT NULL,
|
|
48
|
+
index_id TEXT NOT NULL COLLATE BINARY,
|
|
49
|
+
value_type TEXT NOT NULL CHECK (value_type IN ('text', 'integer', 'real')),
|
|
50
|
+
text_value TEXT COLLATE BINARY,
|
|
51
|
+
integer_value INTEGER,
|
|
52
|
+
real_value REAL,
|
|
53
|
+
row_key TEXT NOT NULL COLLATE BINARY,
|
|
54
|
+
PRIMARY KEY (service_id, view_id, generation, index_id, value_type,
|
|
55
|
+
text_value, integer_value, real_value, row_key),
|
|
56
|
+
FOREIGN KEY (service_id, view_id, generation)
|
|
57
|
+
REFERENCES mv_instances (service_id, view_id, generation)
|
|
58
|
+
ON DELETE CASCADE,
|
|
59
|
+
CHECK (
|
|
60
|
+
(value_type = 'text' AND text_value IS NOT NULL AND integer_value IS NULL AND real_value IS NULL)
|
|
61
|
+
OR (value_type = 'integer' AND text_value IS NULL AND integer_value IS NOT NULL AND real_value IS NULL)
|
|
62
|
+
OR (value_type = 'real' AND text_value IS NULL AND integer_value IS NULL AND real_value IS NOT NULL)
|
|
63
|
+
)
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
CREATE INDEX mv_index_entries_typed_idx
|
|
67
|
+
ON mv_index_entries (
|
|
68
|
+
service_id, view_id, generation, index_id, value_type,
|
|
69
|
+
text_value COLLATE BINARY, integer_value, real_value, row_key COLLATE BINARY
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
-- SQLite permits NULLs in an ordinary composite primary key. This expression
|
|
73
|
+
-- index makes the nullable typed columns behave as one typed value for
|
|
74
|
+
-- idempotent index insertion while retaining the public typed columns above.
|
|
75
|
+
CREATE UNIQUE INDEX mv_index_entries_unique_typed_idx
|
|
76
|
+
ON mv_index_entries (
|
|
77
|
+
service_id, view_id, generation, index_id, value_type,
|
|
78
|
+
COALESCE(text_value, CAST(integer_value AS TEXT), CAST(real_value AS TEXT)),
|
|
79
|
+
row_key COLLATE BINARY
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
-- A NOT NULL guard row is inserted and deleted in each atomic batch. A stale
|
|
83
|
+
-- CAS selects NULL, causing the batch to abort before any mutation executes.
|
|
84
|
+
CREATE TABLE mv_atomic_guards (
|
|
85
|
+
operation_id TEXT PRIMARY KEY COLLATE BINARY,
|
|
86
|
+
checkpoint_match INTEGER NOT NULL CHECK (checkpoint_match = 1)
|
|
87
|
+
);
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
-- SDT-G23 unsafe-window layer. This is deliberately a new migration: 0001
|
|
2
|
+
-- is already applied to deployed G19/G20 MV databases and Wrangler keys its
|
|
3
|
+
-- migration ledger by filename.
|
|
4
|
+
CREATE TABLE mv_unsafe_rows (
|
|
5
|
+
service_id TEXT NOT NULL,
|
|
6
|
+
view_id TEXT NOT NULL COLLATE BINARY,
|
|
7
|
+
generation INTEGER NOT NULL,
|
|
8
|
+
row_key TEXT NOT NULL COLLATE BINARY,
|
|
9
|
+
value_json TEXT NOT NULL,
|
|
10
|
+
row_version INTEGER NOT NULL,
|
|
11
|
+
source_suid TEXT NOT NULL COLLATE BINARY,
|
|
12
|
+
tombstone INTEGER NOT NULL DEFAULT 0 CHECK (tombstone IN (0, 1)),
|
|
13
|
+
PRIMARY KEY (service_id, view_id, generation, row_key),
|
|
14
|
+
FOREIGN KEY (service_id, view_id, generation) REFERENCES mv_instances (service_id, view_id, generation) ON DELETE CASCADE
|
|
15
|
+
);
|
|
16
|
+
CREATE INDEX mv_unsafe_rows_generation_idx ON mv_unsafe_rows (service_id, view_id, generation, row_key COLLATE BINARY);
|
|
17
|
+
|
|
18
|
+
CREATE TABLE mv_unsafe_index_entries (
|
|
19
|
+
service_id TEXT NOT NULL,
|
|
20
|
+
view_id TEXT NOT NULL COLLATE BINARY,
|
|
21
|
+
generation INTEGER NOT NULL,
|
|
22
|
+
index_id TEXT NOT NULL COLLATE BINARY,
|
|
23
|
+
value_type TEXT NOT NULL CHECK (value_type IN ('text', 'integer', 'real')),
|
|
24
|
+
text_value TEXT COLLATE BINARY,
|
|
25
|
+
integer_value INTEGER,
|
|
26
|
+
real_value REAL,
|
|
27
|
+
row_key TEXT NOT NULL COLLATE BINARY,
|
|
28
|
+
PRIMARY KEY (service_id, view_id, generation, index_id, value_type, text_value, integer_value, real_value, row_key),
|
|
29
|
+
FOREIGN KEY (service_id, view_id, generation) REFERENCES mv_instances (service_id, view_id, generation) ON DELETE CASCADE,
|
|
30
|
+
CHECK ((value_type = 'text' AND text_value IS NOT NULL AND integer_value IS NULL AND real_value IS NULL) OR (value_type = 'integer' AND text_value IS NULL AND integer_value IS NOT NULL AND real_value IS NULL) OR (value_type = 'real' AND text_value IS NULL AND integer_value IS NULL AND real_value IS NOT NULL))
|
|
31
|
+
);
|
|
32
|
+
CREATE INDEX mv_unsafe_index_entries_typed_idx ON mv_unsafe_index_entries (service_id, view_id, generation, index_id, value_type, text_value COLLATE BINARY, integer_value, real_value, row_key COLLATE BINARY);
|
|
33
|
+
|
|
34
|
+
CREATE TABLE mv_unsafe_receipts (
|
|
35
|
+
service_id TEXT NOT NULL, view_id TEXT NOT NULL COLLATE BINARY,
|
|
36
|
+
event_id TEXT NOT NULL COLLATE BINARY, suid TEXT NOT NULL COLLATE BINARY,
|
|
37
|
+
outcome TEXT NOT NULL CHECK (outcome IN ('applied', 'older', 'patch-not-found', 'delete-without-row', 'no-change')),
|
|
38
|
+
observed_at INTEGER NOT NULL, PRIMARY KEY (service_id, view_id, event_id, suid)
|
|
39
|
+
);
|
|
40
|
+
CREATE TABLE mv_unsafe_markers (
|
|
41
|
+
service_id TEXT NOT NULL, view_id TEXT NOT NULL COLLATE BINARY, generation INTEGER NOT NULL,
|
|
42
|
+
row_key TEXT NOT NULL COLLATE BINARY, event_id TEXT NOT NULL COLLATE BINARY, suid TEXT NOT NULL COLLATE BINARY,
|
|
43
|
+
reason TEXT NOT NULL CHECK (reason IN ('patch-not-found', 'delete-without-row', 'no-change', 'older')),
|
|
44
|
+
PRIMARY KEY (service_id, view_id, generation, row_key, event_id, suid, reason)
|
|
45
|
+
);
|
|
46
|
+
CREATE TABLE mv_unsafe_arrivals (
|
|
47
|
+
service_id TEXT NOT NULL, view_id TEXT NOT NULL COLLATE BINARY, generation INTEGER NOT NULL,
|
|
48
|
+
safe_head TEXT NOT NULL COLLATE BINARY DEFAULT '', arrival_watermark TEXT NOT NULL COLLATE BINARY DEFAULT '',
|
|
49
|
+
behind_frontier_event_id TEXT COLLATE BINARY, behind_frontier_suid TEXT COLLATE BINARY,
|
|
50
|
+
rebuild_required INTEGER NOT NULL DEFAULT 0 CHECK (rebuild_required IN (0, 1)),
|
|
51
|
+
PRIMARY KEY (service_id, view_id, generation)
|
|
52
|
+
);
|
|
53
|
+
CREATE TABLE mv_unsafe_kicks (
|
|
54
|
+
service_id TEXT NOT NULL, view_id TEXT NOT NULL COLLATE BINARY,
|
|
55
|
+
target_suid TEXT NOT NULL COLLATE BINARY DEFAULT '', lease_owner TEXT COLLATE BINARY,
|
|
56
|
+
lease_until INTEGER NOT NULL DEFAULT 0, dirty INTEGER NOT NULL DEFAULT 0 CHECK (dirty IN (0, 1)),
|
|
57
|
+
PRIMARY KEY (service_id, view_id)
|
|
58
|
+
);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
-- SDT-G24 checkpoint-ahead hardening. A finding is scoped to the affected
|
|
2
|
+
-- generation, so the only recovery path is the existing rebuild/promote flow.
|
|
3
|
+
CREATE TABLE mv_checkpoint_ahead_findings (
|
|
4
|
+
service_id TEXT NOT NULL,
|
|
5
|
+
view_id TEXT NOT NULL COLLATE BINARY,
|
|
6
|
+
generation INTEGER NOT NULL,
|
|
7
|
+
checkpoint_suid TEXT NOT NULL COLLATE BINARY,
|
|
8
|
+
store_max_suid TEXT NOT NULL COLLATE BINARY,
|
|
9
|
+
observed_at INTEGER NOT NULL,
|
|
10
|
+
PRIMARY KEY (service_id, view_id, generation),
|
|
11
|
+
FOREIGN KEY (service_id, view_id, generation)
|
|
12
|
+
REFERENCES mv_instances (service_id, view_id, generation)
|
|
13
|
+
ON DELETE CASCADE
|
|
14
|
+
);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- SDT-G25: an unsafe apply failure is an idempotent operational finding.
|
|
2
|
+
-- The source event is already durable; this records that the exceptional
|
|
3
|
+
-- immediate projection write requires Queue retry or DLQ attention.
|
|
4
|
+
CREATE TABLE mv_unsafe_failure_findings (
|
|
5
|
+
service_id TEXT NOT NULL,
|
|
6
|
+
view_id TEXT NOT NULL COLLATE BINARY,
|
|
7
|
+
event_id TEXT NOT NULL COLLATE BINARY,
|
|
8
|
+
suid TEXT NOT NULL COLLATE BINARY,
|
|
9
|
+
classification TEXT NOT NULL CHECK (classification IN ('UNSAFE_APPLY_RETRY')),
|
|
10
|
+
observed_at INTEGER NOT NULL,
|
|
11
|
+
PRIMARY KEY (service_id, view_id, event_id, suid, classification)
|
|
12
|
+
);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-- SDT-G31: a wait receipt is an active-generation/definition observation.
|
|
2
|
+
-- It is intentionally separate from mv_unsafe_receipts, whose historical
|
|
3
|
+
-- identity is cross-generation and remains the G23/G26 delivery oracle.
|
|
4
|
+
CREATE TABLE mv_wait_receipts (
|
|
5
|
+
service_id TEXT NOT NULL,
|
|
6
|
+
view_id TEXT NOT NULL COLLATE BINARY,
|
|
7
|
+
generation INTEGER NOT NULL,
|
|
8
|
+
definition_version INTEGER NOT NULL,
|
|
9
|
+
event_id TEXT NOT NULL COLLATE BINARY,
|
|
10
|
+
suid TEXT NOT NULL COLLATE BINARY,
|
|
11
|
+
observed_at INTEGER NOT NULL,
|
|
12
|
+
PRIMARY KEY (service_id, view_id, generation, event_id, suid),
|
|
13
|
+
FOREIGN KEY (service_id, view_id, generation)
|
|
14
|
+
REFERENCES mv_instances (service_id, view_id, generation)
|
|
15
|
+
ON DELETE CASCADE
|
|
16
|
+
);
|
|
17
|
+
CREATE INDEX mv_wait_receipts_active_target_idx
|
|
18
|
+
ON mv_wait_receipts (
|
|
19
|
+
service_id,
|
|
20
|
+
view_id,
|
|
21
|
+
generation,
|
|
22
|
+
definition_version,
|
|
23
|
+
event_id COLLATE BINARY,
|
|
24
|
+
suid COLLATE BINARY
|
|
25
|
+
);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
-- SDT-G31: poison is a target fact for one active generation/definition, not
|
|
2
|
+
-- a global view switch. This lets the wait loop use the same bounded active
|
|
3
|
+
-- generation point-read shape for receipt, checkpoint, rebuild, and poison.
|
|
4
|
+
CREATE TABLE mv_wait_target_poison (
|
|
5
|
+
service_id TEXT NOT NULL,
|
|
6
|
+
view_id TEXT NOT NULL COLLATE BINARY,
|
|
7
|
+
generation INTEGER NOT NULL,
|
|
8
|
+
definition_version INTEGER NOT NULL,
|
|
9
|
+
event_id TEXT NOT NULL COLLATE BINARY,
|
|
10
|
+
suid TEXT NOT NULL COLLATE BINARY,
|
|
11
|
+
classification TEXT NOT NULL CHECK (classification IN ('UNSAFE_APPLY_RETRY')),
|
|
12
|
+
observed_at INTEGER NOT NULL,
|
|
13
|
+
PRIMARY KEY (service_id, view_id, generation, event_id, suid, classification),
|
|
14
|
+
FOREIGN KEY (service_id, view_id, generation)
|
|
15
|
+
REFERENCES mv_instances (service_id, view_id, generation)
|
|
16
|
+
ON DELETE CASCADE
|
|
17
|
+
);
|
|
18
|
+
CREATE INDEX mv_wait_target_poison_active_target_idx
|
|
19
|
+
ON mv_wait_target_poison (
|
|
20
|
+
service_id,
|
|
21
|
+
view_id,
|
|
22
|
+
generation,
|
|
23
|
+
definition_version,
|
|
24
|
+
event_id COLLATE BINARY,
|
|
25
|
+
suid COLLATE BINARY
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
-- Preserve historical pre-G31 poison as a finding on the generation that was
|
|
29
|
+
-- active while this migration ran. A later generation is deliberately free to
|
|
30
|
+
-- rebuild and prove its own state without inheriting an old receipt/failure.
|
|
31
|
+
INSERT OR IGNORE INTO mv_wait_target_poison
|
|
32
|
+
(service_id, view_id, generation, definition_version, event_id, suid, classification, observed_at)
|
|
33
|
+
SELECT finding.service_id,
|
|
34
|
+
finding.view_id,
|
|
35
|
+
instance.generation,
|
|
36
|
+
instance.definition_version,
|
|
37
|
+
finding.event_id,
|
|
38
|
+
finding.suid,
|
|
39
|
+
finding.classification,
|
|
40
|
+
finding.observed_at
|
|
41
|
+
FROM mv_unsafe_failure_findings finding
|
|
42
|
+
JOIN mv_active_generations active
|
|
43
|
+
ON active.service_id = finding.service_id
|
|
44
|
+
AND active.view_id = finding.view_id
|
|
45
|
+
JOIN mv_instances instance
|
|
46
|
+
ON instance.service_id = active.service_id
|
|
47
|
+
AND instance.view_id = active.view_id
|
|
48
|
+
AND instance.generation = active.generation;
|