From 878d0ce5eda11fda886c6eab34945b7c91692527 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Tue, 8 Sep 2026 18:09:34 +0900 Subject: [PATCH 1/2] test: bind restored URL and independence contract The merged restore harness already asserts service URL survival and a collecting-without-retention revision. The TypeScript contract now requires those exact markers so a later edit cannot drop them unnoticed. --- docs/product-technical-gap-baseline.md | 2 +- src/postgres-restore-contract.test.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 6ad587b..7983d93 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -48,7 +48,7 @@ Action-runtime cleanup used hosted CI `34088150412` as a real control-plane RED: Queue RCA then observed distinct stale heads `cbfbdae4a4bb72433d7bdcc51afdbd8a29c102a1`, `3d576aa9e4079af0749cb03f6cc20e4cb30e6639`, and `7dd5c24eed855ef7acdfc0dcb217c86dd00d2df3` retaining separate queued CI runs because the repository workflow had no concurrency contract. Test-only head `bdaf5e8560289b7c4774d46fff2afa7489ad51c9` specifies PR-or-ref grouping and stale-head cancellation. Repository CI now groups by workflow plus pull-request number (or branch ref for push events) and sets `cancel-in-progress: true`; this prevents future superseded heads from consuming runner capacity while keeping unrelated PRs and refs independent. -The restart/restore slice remains bounded CI evidence and does not enable a hosted adapter. After the initial atomic-seed repair, review found that paired collection/applies and no-collection/none fixtures could not prove collection and retention are independent, the restored database re-exercised only the no-collection trigger, and a nullable restored `service_name` could evade `<>` through SQL three-valued logic. Test-only head `5e54834873e125b3e3ce4f599e4037e017330638` added the missing cross-state and NULL-safe assertions; exact-head CI `34204279846` was RED only in the restore step with `restart did not preserve independent collection and retention facts`. The next commit seeds a valid collecting revision with `retention_status = none`, keeps authored service and collection-item assertions NULL-safe, and executes status-side missing-rule plus rule-side unexpected-rule transactions against the restored database. Pre-documentation head `202e69d95c94e4432365d6599016a371c0f2cbc3` CI `34204464388` then passed the complete suite. A later exact-head review found that the nullable authored service URL was not selected or asserted even though the evidence claim covered complete service values. Mutation-probe head `aaef3b5489493669cdb53c08a72b6a109fc0b687` deliberately nulled that URL after restart; CI `34205653966` passed every preceding step and failed only the new NULL-safe restore assertion. Commit `57732c6dbec872ad29e97a7f22096dbba9613e9a` removes the probe while retaining literal name/URL checks. These immutable runs establish the TDD transitions but are not substitutes for the final current-head verdict. This is CI durability evidence, not operational backup, tenant authorization, or a released datastore. +The restart/restore slice remains bounded CI evidence and does not enable a hosted adapter. After the initial atomic-seed repair, review found that paired collection/applies and no-collection/none fixtures could not prove collection and retention are independent, the restored database re-exercised only the no-collection trigger, and a nullable restored `service_name` could evade `<>` through SQL three-valued logic. Test-only head `5e54834873e125b3e3ce4f599e4037e017330638` added the missing cross-state and NULL-safe assertions; exact-head CI `34204279846` was RED only in the restore step with `restart did not preserve independent collection and retention facts`. The next commit seeds a valid collecting revision with `retention_status = none`, keeps authored service and collection-item assertions NULL-safe, and executes status-side missing-rule plus rule-side unexpected-rule transactions against the restored database. Pre-documentation head `202e69d95c94e4432365d6599016a371c0f2cbc3` CI `34204464388` then passed the complete suite. A later exact-head review found that the nullable authored service URL was not selected or asserted even though the evidence claim covered complete service values. Mutation-probe head `aaef3b5489493669cdb53c08a72b6a109fc0b687` deliberately nulled that URL after restart; CI `34205653966` passed every preceding step and failed only the new NULL-safe restore assertion. Commit `57732c6dbec872ad29e97a7f22096dbba9613e9a` removes the probe while retaining literal name/URL checks. These immutable runs establish the TDD transitions but are not substitutes for the final current-head verdict. PR #9 merged into the concurrent-writer stack at `5309a6141d8f3f0c89e9cfdaae04f4644a8dfcd4`. The TypeScript restore contract now binds restored service URL survival and the collecting-without-retention cross-state fixture. This is CI durability evidence, not operational backup, tenant authorization, or a released datastore. ## Current baseline diff --git a/src/postgres-restore-contract.test.ts b/src/postgres-restore-contract.test.ts index 792c019..99c8d2e 100644 --- a/src/postgres-restore-contract.test.ts +++ b/src/postgres-restore-contract.test.ts @@ -27,6 +27,8 @@ describe('PostgreSQL restart and restore evidence contract', () => { expect(restoreTest).toMatch( /stored_item_mode[\s\S]*stored_item_path[\s\S]*stored_item_mode is distinct from 'required'[\s\S]*stored_item_path is distinct from 'Account registration form'/i, ) + expect(restoreTest).toContain("stored_service_url is distinct from 'https://restore.example.test'") + expect(restoreTest).toContain('collection_without_retention_count <> 1') expect(restoreTest).toContain('no-collection confirmation conflicts with collection items') expect(workflowSource).toContain('run: sh db/tests/policy_revision_restore.sh') }) From d0da193c48932311d970e55738ff1a12983ff3e3 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 9 Sep 2026 10:18:04 +0900 Subject: [PATCH 2/2] test: bind cross-state seed and query predicates Addresses PR #14 P2 review: the restored-URL and collection_without_retention_count markers alone could not detect a coupled seed+query change of revision ...0003 from retention none to applies. The contract now requires the ...0003 none seed tuple, its support_email item seed, and the revision-specific query predicates together. Negative control: old markers pass the coupled mutation, new predicates fail it; all 63 tests pass on the correct script. --- src/postgres-restore-contract.test.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/postgres-restore-contract.test.ts b/src/postgres-restore-contract.test.ts index 99c8d2e..e043d70 100644 --- a/src/postgres-restore-contract.test.ts +++ b/src/postgres-restore-contract.test.ts @@ -29,6 +29,15 @@ describe('PostgreSQL restart and restore evidence contract', () => { ) expect(restoreTest).toContain("stored_service_url is distinct from 'https://restore.example.test'") expect(restoreTest).toContain('collection_without_retention_count <> 1') + expect(restoreTest).toContain( + "60000000-0000-4000-8000-000000000003', '50000000-0000-4000-8000-000000000001', 3, 'none'", + ) + expect(restoreTest).toMatch( + /upsert_collection_item\(\s*'60000000-0000-4000-8000-000000000003',\s*'support_email'/, + ) + expect(restoreTest).toMatch( + /revision\.policy_revision_id = '60000000-0000-4000-8000-000000000003'[\s\S]*?revision\.no_collection_confirmed = false[\s\S]*?revision\.retention_status = 'none'[\s\S]*?item\.collection_item_key = 'support_email'/, + ) expect(restoreTest).toContain('no-collection confirmation conflicts with collection items') expect(workflowSource).toContain('run: sh db/tests/policy_revision_restore.sh') })