From c1bccf552b4fda5905814ff01e7ac7cb880a3f21 Mon Sep 17 00:00:00 2001 From: "Xin.Zh" Date: Sat, 24 Oct 2026 13:17:46 +0800 Subject: [PATCH 1/2] fix(migrations): match native portable receipt boolean layout seekDB and OceanBase reflect BOOL as TINYINT(1). Freeze that actual type in s1402 so the strict post-DDL recovery check accepts its own receipt table. Apply required Ruff formatting to the new Compose regression test. Constraint: Preserve strict schema comparison, the existing DDL and all historical layouts. Scope-risk: Unreleased s1402 receipt-column expectation and formatting-only Compose test changes. Tested: Existing native initialization recovery test (seekDB/OceanBase: 2 failed before, 2 passed after); focused pytest (65 passed, 3 disabled native probes skipped); UV_NO_SYNC=1 prek run -a (all passed). --- .../migrations/server_resources/schemas/mysql-s1402.json | 6 ++++-- tests/test_bub_compose_startup.py | 9 +++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/powercontext/builtin/persistence/migrations/server_resources/schemas/mysql-s1402.json b/src/powercontext/builtin/persistence/migrations/server_resources/schemas/mysql-s1402.json index 8cd9b32951..9e124db439 100644 --- a/src/powercontext/builtin/persistence/migrations/server_resources/schemas/mysql-s1402.json +++ b/src/powercontext/builtin/persistence/migrations/server_resources/schemas/mysql-s1402.json @@ -98,8 +98,10 @@ }, "projections_ready": { "type": [ - "bool", - [] + "tinyint", + [ + "1" + ] ], "nullable": false, "default": null, diff --git a/tests/test_bub_compose_startup.py b/tests/test_bub_compose_startup.py index d2b955fb8f..58dc7cadde 100644 --- a/tests/test_bub_compose_startup.py +++ b/tests/test_bub_compose_startup.py @@ -32,7 +32,9 @@ def _run(tmp_path, monkeypatch, *, vector=False, code=False, failed_action=""): events = tmp_path / "events.jsonl" # Substitute only process boundaries: execute the real shell launcher and # its inline maintenance program without Docker or a database service. - executable = f"#!{sys.executable}\n" + r""" + executable = ( + f"#!{sys.executable}\n" + + r""" import json import os import subprocess @@ -64,6 +66,7 @@ def record(action): assert args[args.index("--plan-id") + 1] == "reviewed-plan" print(json.dumps({"plan_id": "reviewed-plan", "state": "ready", "server_ready": True})) """ + ) for name in ("docker", "powercontext"): path = commands / name path.write_text(executable, encoding="utf-8") @@ -75,7 +78,9 @@ def record(action): monkeypatch.setenv("POWERCONTEXT_E2E_DATABASE", "oceanbase") monkeypatch.setenv("POWERCONTEXT_E2E_OUTPUT", str(tmp_path / "output")) monkeypatch.setenv("POWERCONTEXT_SERVER_DATABASE_KIND", "oceanbase") - monkeypatch.setenv("POWERCONTEXT_SERVER_DATABASE_URL", "mysql+aoceanbase://test@database.invalid:2881/test?charset=utf8mb4") + monkeypatch.setenv( + "POWERCONTEXT_SERVER_DATABASE_URL", "mysql+aoceanbase://test@database.invalid:2881/test?charset=utf8mb4" + ) monkeypatch.setenv("POWERCONTEXT_SERVER_CODE", json.dumps({"enabled": code})) monkeypatch.setenv("BUB_TEST_EVENTS", str(events)) monkeypatch.setenv("BUB_TEST_FAILED_ACTION", failed_action) From f5036122e8b57812780f647411457aa4fead0f90 Mon Sep 17 00:00:00 2001 From: "Xin.Zh" Date: Sat, 24 Oct 2026 13:29:54 +0800 Subject: [PATCH 2/2] chore(migrations): record receipt layout compatibility review Record the managed persistence digest and native receipt type correction in the release compatibility review. Constraint: Preserve upgrade-required mode and the twelve-case acceptance matrix. Scope-risk: Compatibility review metadata only; no runtime changes. Tested: scripts/upgrade_release_gate.py; pytest tests/test_upgrade_release_gate.py tests/test_upgrade_publication.py (70 passed); UV_NO_SYNC=1 prek run -a (all passed). --- release/upgrade-support.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/upgrade-support.json b/release/upgrade-support.json index 9d4a365884..fee9c04f56 100644 --- a/release/upgrade-support.json +++ b/release/upgrade-support.json @@ -3,8 +3,8 @@ "target_version": "1.4.0", "mode": "upgrade-required", "schema_review": { - "persistence_sha256": "bf8900ac8131e2db663c6a1deaacff4641e8d9bc4722d7693095a1ebd072e41c", - "rationale": "The shared s1300 -> s1400 -> s1401 -> s1402 chain registers installed 1.3.0 no-vector Server storage on SQLite, seekDB and OceanBase with Code disabled or enabled. SQLite/OceanBase Code caches remain separate; embedded seekDB Code uses the three frozen released tables. A selected vector profile binds the frozen schema and domain contract to the exact historical profile ID, model, dimension, distance and normalization. SQLite maintenance registers and backfills the Atomic vec0 helper and transactional triggers; native layouts preserve vector column dimensions and explicit HNSW parameters, including ordered key columns, algorithm, distance, library and construction/search options. Unknown index options remain rejected. The vector-only configuration declaration is not a second revision or recovery journal. Full layout and domain checks precede managed use; configured or injected model drift and missing helpers cannot trigger startup repair. No embedding provider is called during migration and historical embeddings, Topic shape, authority and evidence are preserved. Full Server readiness validates Atomic Memory projections against authority and checks complete SQLite FTS identities for both vector and no-vector profiles before admission. Validation is read-only and damaged projections require explicit maintenance. SQLite startup preflight reads authority and projections in one explicit read transaction so concurrent WAL writes cannot produce a mixed-revision validation result; no schema or stored data format changes are introduced. Reviewed plans bind the draft validation resources; selected vector profiles have separately bound checksums. Target locks, original recovery points, acknowledgements and backup policies remain shared. The installed-release gate requires all twelve backend/configuration combinations, with Code enabled or disabled and vectors enabled or disabled. Vector cases seed nonempty Atomic and Topic vectors through the actual source Server, preserve exact embedding digests and retrieval shape, and verify historical/new semantic reads, configuration-drift rejection, SQLite missing-helper rejection and fresh-storage equivalence using the independently installed target. Maintenance must not call an embedding provider. SQLite vector cases also restore the automatic backup with the old Server before re-upgrading. Complete current-artifact and recovery/restore acceptance remain required. Source tests and schema captures do not establish that release acceptance passed. Policy remains upgrade-required. Revision s1402 adapts the storage already present on master: portable restore receipts and native microsecond precision for Artifact creation, policy updates, Topic publications and tag assignments. Earlier revision resources and checksums remain unchanged. Pending archive restores reject ordinary managed startup and readiness; only the explicit archive recovery entry can open a registered layout to finish projections, and it still checks the configured embedding profile. Interrupted first-revision MySQL initialization defers domain preflight until the executor has completed the registered baseline statements and seed data; missing maintenance evidence and unregistered DDL remain rejected." + "persistence_sha256": "3d04b5c8461718120eb69a2ae17909a0f6381c10519d679a2a1a6bfd52e476e4", + "rationale": "The shared s1300 -> s1400 -> s1401 -> s1402 chain registers installed 1.3.0 no-vector Server storage on SQLite, seekDB and OceanBase with Code disabled or enabled. SQLite/OceanBase Code caches remain separate; embedded seekDB Code uses the three frozen released tables. A selected vector profile binds the frozen schema and domain contract to the exact historical profile ID, model, dimension, distance and normalization. SQLite maintenance registers and backfills the Atomic vec0 helper and transactional triggers; native layouts preserve vector column dimensions and explicit HNSW parameters, including ordered key columns, algorithm, distance, library and construction/search options. Unknown index options remain rejected. The vector-only configuration declaration is not a second revision or recovery journal. Full layout and domain checks precede managed use; configured or injected model drift and missing helpers cannot trigger startup repair. No embedding provider is called during migration and historical embeddings, Topic shape, authority and evidence are preserved. Full Server readiness validates Atomic Memory projections against authority and checks complete SQLite FTS identities for both vector and no-vector profiles before admission. Validation is read-only and damaged projections require explicit maintenance. SQLite startup preflight reads authority and projections in one explicit read transaction so concurrent WAL writes cannot produce a mixed-revision validation result; no schema or stored data format changes are introduced. Reviewed plans bind the draft validation resources; selected vector profiles have separately bound checksums. Target locks, original recovery points, acknowledgements and backup policies remain shared. The installed-release gate requires all twelve backend/configuration combinations, with Code enabled or disabled and vectors enabled or disabled. Vector cases seed nonempty Atomic and Topic vectors through the actual source Server, preserve exact embedding digests and retrieval shape, and verify historical/new semantic reads, configuration-drift rejection, SQLite missing-helper rejection and fresh-storage equivalence using the independently installed target. Maintenance must not call an embedding provider. SQLite vector cases also restore the automatic backup with the old Server before re-upgrading. Complete current-artifact and recovery/restore acceptance remain required. Source tests and schema captures do not establish that release acceptance passed. Policy remains upgrade-required. Revision s1402 adapts the storage already present on master: portable restore receipts and native microsecond precision for Artifact creation, policy updates, Topic publications and tag assignments. Earlier revision resources and checksums remain unchanged. Pending archive restores reject ordinary managed startup and readiness; only the explicit archive recovery entry can open a registered layout to finish projections, and it still checks the configured embedding profile. Interrupted first-revision MySQL initialization defers domain preflight until the executor has completed the registered baseline statements and seed data; missing maintenance evidence and unregistered DDL remain rejected. The unreleased s1402 portable receipt layout records the native TINYINT(1) reflection of its BOOL projections_ready column on seekDB and OceanBase. This corrects the expected post-DDL type without changing the SQL, stored representation, historical revisions or strict schema validation. The original interrupted-initialization recovery test fails on both real backends before this correction and passes on both afterward; installed-release acceptance remains independently required." }, "cases": [], "automatic_sources": {