From 8cbad2bcd9bc7507052f74f35670ef7c8e39e44e Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Wed, 15 Jul 2026 02:18:34 -0500 Subject: [PATCH] docs(#771): close role split rc.9 residuals --- docs/PRD.md | 4 +- docs/SITEMAP.md | 4 +- docs/native-kanban-sot/INDEX.md | 34 ++--- .../KBN-101-DB-ROLE-SPLIT.md | 120 +++++++++--------- docs/native-kanban-sot/SHARED-CONTRACT.md | 13 +- docs/native-kanban-sot/TASKS.md | 4 +- .../2026-03-15-agent-platform-architecture.md | 4 +- docs/scratchpads/771-kbn101-db-role-split.md | 10 ++ 8 files changed, 107 insertions(+), 86 deletions(-) diff --git a/docs/PRD.md b/docs/PRD.md index bba48d6..75509b2 100644 --- a/docs/PRD.md +++ b/docs/PRD.md @@ -133,9 +133,9 @@ PostgreSQL Gateway/storage currently uses one `DATABASE_URL` for runtime queries ### Normative requirements -1. `K101-REQ-01`: `DATABASE_URL` SHALL be the non-owner PostgreSQL runtime connection and `DATABASE_MIGRATION_URL` SHALL be the migration-only owner/migrator connection. They are required respectively for runtime and the dedicated `mosaic-db-migrator --run|--verify` phase in `standalone`/`federated`; local PGlite is the explicit exception. The published `@mosaicstack/db` bin has fixed CLI/package/module ownership, accepts no URL/SQL/schema/role argv, and returns stable sanitized exits. Every current/future PostgreSQL DDL entrypoint SHALL route to that runner or be denied, and SHALL reject `DATABASE_URL`-only execution before connection/DDL. A reviewed finite classifier inventories executable current source/scripts/package bins, operator docs, and deploy manifests by exact path; only byte-immutable historical SQL, PGlite-only routines, negative test literals, vendored/generated artifacts, and labeled historical reports are exact-path/category allowlists. Unknown hits fail; a naive token scan alone proves no authority. `db:push` is forbidden outside an explicitly disposable local developer database and cannot accept a production-like URL. +1. `K101-REQ-01`: `DATABASE_URL` SHALL be the non-owner PostgreSQL runtime connection and `DATABASE_MIGRATION_URL` SHALL be the migration-only owner/migrator connection. They are required respectively for runtime and the dedicated `mosaic-db-migrator --run|--verify` phase in `standalone`/`federated`; local PGlite is the explicit exception. The published `@mosaicstack/db` bin maps exactly `mosaic-db-migrator` to `./dist/cli.js`, its image entrypoint is exactly `mosaic-db-migrator`, accepts no URL/SQL/schema/role argv, and returns stable sanitized exits. Every current/future PostgreSQL DDL entrypoint SHALL route to that runner or be denied, and SHALL reject `DATABASE_URL`-only execution before connection/DDL. A reviewed finite classifier inventories executable current source/scripts/package bins, operator docs, and deploy manifests by exact path; every record pins `path`, `class`, `ownerCard`, `disposition`, `allowedTokens`, `rationale`, `expiry`, and `reviewRevision`. Only byte-immutable historical SQL, PGlite-only routines, negative test literals, vendored/generated artifacts, and labeled historical review reports are exact-path/category allowlists; unknown, duplicate-owner, ownerless, missing-path, and historical-category masking hits fail. A naive token scan alone proves no authority. `db:push` is forbidden outside an explicitly disposable local developer database and cannot accept a production-like URL. 2. `K101-REQ-02`: Gateway runtime/replicas SHALL not execute migrations or DDL. The runner SHALL hold one `max:1` session and fixed two-int advisory namespace `1297044289` (`MOSA`), `1262636593` (`KBN1`) across preflight, reconciliation, migration, verification, and release. It SHALL compare the versioned canonical manifest v1 tuple (journal logical index/tag plus exact SQL-byte SHA-256) to the complete observed ledger mapping; count/set-only, timestamps, and physical insertion order are non-normative and insufficient. -3. `K101-REQ-03`: PostgreSQL SHALL separate non-login platform database owner, non-login schema owner, dedicated non-login `mosaic_extension_owner`, login migrator, non-login runtime capability, and login runtime roles. Only the external bootstrap actor may temporarily `SET ROLE mosaic_extension_owner`; no runtime service receives membership or credentials. Fresh `vector` creation retains that owner; existing approved-owner extension relocation validates `pg_extension.extowner`, member ownership/schema/version, while legacy runtime-owned extension fails closed to a controlled shadow-database migration—never unsupported ownership alteration, catalog mutation, ownership adoption, or `DROP CASCADE`. Runtime ownership, superuser/role-creation/schema-creation/TEMPORARY, unsafe membership, untrusted search path, missing grants, unauthenticated TLS, immutable privilege drift, and extension ALTER/DROP/member-update authority SHALL fail startup/readiness closed. Application schema is fixed `mosaic` with exact `pg_catalog,mosaic` session path; historical public migrations remain byte-immutable legacy bootstrap only, every future Drizzle application declaration targets `mosaic`, and `vector` is explicitly qualified from non-writable `mosaic_extensions`. No config-derived SQL identifier is permitted. +3. `K101-REQ-03`: PostgreSQL SHALL separate non-login platform database owner, non-login schema owner, dedicated non-login `mosaic_extension_owner`, login migrator, non-login runtime capability, and login runtime roles. Only the external bootstrap actor may temporarily `SET ROLE mosaic_extension_owner`; it creates and owns `mosaic_extensions`, fresh `vector`, and its members, while `mosaic_schema_owner` receives only `USAGE` for type resolution and never ownership/`CREATE`/`ALTER`/`DROP`/member-change/default-privilege authority there. No runtime service receives membership or credentials. Existing approved-owner extension relocation validates `pg_namespace.nspowner`, `pg_extension.extowner`, member ownership/schema/version, while legacy runtime-owned extension fails closed to a controlled shadow-database migration—never unsupported ownership alteration, catalog mutation, ownership adoption, or `DROP CASCADE`. Runtime, migrator, and schema owner catalog/direct-DDL denials, role ownership, superuser/role-creation/schema-creation/TEMPORARY, unsafe membership, untrusted search path, missing grants, unauthenticated TLS, and immutable privilege drift SHALL fail startup/readiness closed. Application schema is fixed `mosaic` with exact `pg_catalog,mosaic` session path; historical public migrations remain byte-immutable legacy bootstrap only, every future Drizzle application declaration targets `mosaic`, and `vector` is explicitly qualified from non-writable `mosaic_extensions`. No config-derived SQL identifier is permitted. 4. `K101-REQ-04`: `mosaicstack/stack` KBN-101-00 SHALL exclusively own `infra/pg-bootstrap/roles.sql`, `infra/pg-bootstrap/extensions.sql`, `infra/pg-bootstrap/README.md`, and bootstrap tests; KBN-101-05 SHALL exclusively own `tools/db/render-postgres-secrets.ts`, its tests, and current Compose/Portainer/two-gateway deployment declarations, consuming the versioned bootstrap interface without overlap. Environment IaC/Vault is named input and Mosaic deployment control plane/Jason is activation authority. Distinct runtime/migrator URL, CA, Gateway leaf, and PostgreSQL server key/certificate secrets are provisioned before a production-like database starts; runtime and migrator require mounted CA plus `sslmode=verify-full`. Exact UID/GID/mode/rendering, service-DNS SANs, Vault/compose/Swarm consumer isolation, two-gateway pair ordering, server activation, pre-enforcement legacy-client drain and `hostssl` zero-plaintext-session proof, fresh/existing transition, CA-overlap rotation, TLS-only rollback, and standalone/federated/Swarm/two-gateway positive/negative TLS evidence are required. No application-generated production certificate or plaintext bootstrap exception is permitted. 5. `K101-REQ-05`: KBN immutable relations SHALL permit the real runtime role INSERT/SELECT only and deny UPDATE/DELETE; parent retention remains RESTRICT/no-cascade. Role/password/Vault creation is external platform control, never application migration/source. 6. `K101-REQ-06`: N-1 single-URL compatibility, rollout/rollback, Vault ownership/rotation/redaction, CI, installer, compose/Portainer, observability, and deployment handoffs SHALL be separately bounded one-card/one-PR work. Prepared slices remain inactive while current owner-runtime deployments stay N-1; Mosaic control plane/Jason alone authorizes one final atomic activation or rollback, with no force-on-red/bypass. KBN-101 planning itself SHALL not mutate production. diff --git a/docs/SITEMAP.md b/docs/SITEMAP.md index 9d120bc..c0bff25 100644 --- a/docs/SITEMAP.md +++ b/docs/SITEMAP.md @@ -14,9 +14,9 @@ - [Workstream index](native-kanban-sot/INDEX.md) — artifact map, lane partition, and delivery order. - [Mission manifest](native-kanban-sot/MISSION-MANIFEST.md) — scope, authority, invariants, and gate model. - [Task decomposition](native-kanban-sot/TASKS.md) — dependency-ordered implementation slices and ownership boundaries. -- [KBN-101 database role split](native-kanban-sot/KBN-101-DB-ROLE-SPLIT.md) — rc.8 finite authority classifier, executable `mosaic-db-migrator`, exclusive bootstrap/renderer cards, pgvector extension-owner/shadow transition, two-gateway verified-TLS bootstrap, role/search-path, atomic activation, and certification prerequisite. +- [KBN-101 database role split](native-kanban-sot/KBN-101-DB-ROLE-SPLIT.md) — rc.9 extension-schema-owner boundary, complete disjoint card manifests, mechanical DDL classifier, executable `mosaic-db-migrator`, two-gateway verified-TLS bootstrap, role/search-path, atomic activation, and certification prerequisite. - [Frozen shared contract](native-kanban-sot/SHARED-CONTRACT.md) — schema, API, Coordinator, health, recovery, and migration contracts. -- [KBN-101 exact-head security review](reports/native-kanban-sot/kbn-101-contract-security-review-82ce325.md) — retained prior REQUEST CHANGES evidence for `da742ca`; rc.8 awaits independent exact-head re-review after later residual remediation. +- [KBN-101 exact-head security review](reports/native-kanban-sot/kbn-101-contract-security-review-82ce325.md) — retained prior REQUEST CHANGES evidence for `da742ca`; rc.9 awaits independent exact-head re-review after later residual remediation. - [Initial independent review](reports/native-kanban-sot/canon-initial-review-no-go.md) — KCR-001–016 findings that blocked the first draft. - [Final independent re-review](reports/native-kanban-sot/canon-final-rereview-go.md) — closure evidence and GO verdict. - [Ultron final gate](reports/native-kanban-sot/ultron-final-go.md) — final requirements, authority, schema, migration, recovery, and evidence review. diff --git a/docs/native-kanban-sot/INDEX.md b/docs/native-kanban-sot/INDEX.md index 81dda42..57e312a 100644 --- a/docs/native-kanban-sot/INDEX.md +++ b/docs/native-kanban-sot/INDEX.md @@ -6,23 +6,23 @@ ## Artifacts -| Artifact | Purpose | -| -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Canonical requirements](../requirements/native-kanban-sot.md) | Canonical P0–P3 requirements, all seven ratified decisions, fixed invariants, thin MVP, recovery tiers, non-goals, and per-requirement acceptance criteria | -| [`MISSION-MANIFEST.md`](./MISSION-MANIFEST.md) | Mission/authority boundaries, exact role chain, gate model, mandatory SecReview triggers, Certifier final/no-merge rule, and collision-free slice ownership | -| [`TASKS.md`](./TASKS.md) | Dependency-ordered, bounded P0–P3 slices with IN/OUT scope, dependencies, shared contracts, file ownership, evidence, and USC coder2/3/4/5 parallelization | -| [`KBN-101-DB-ROLE-SPLIT.md`](./KBN-101-DB-ROLE-SPLIT.md) | rc.8 frozen finite authority classifier, executable `mosaic-db-migrator`, exclusive bootstrap/renderer cards, extension-owner/shadow transition, two-gateway TLS/bootstrap, role/search-path, activation, and certification contract; foundation prerequisite of KBN-100 and real-role gate before KBN-105 | -| [`SHARED-CONTRACT.md`](./SHARED-CONTRACT.md) | Remediated v1 integration contract: proof authority, exact failures/routes/DTOs/MCP ownership, concrete current-main field migration map, relational invariants, Coordinator split, recovery delivery | -| [`contracts/kanban-schema.v1.ts`](./contracts/kanban-schema.v1.ts) | Drizzle target declarations including exact owner/principal membership, project congruence, tags/archive, proposals, persisted assignments, monotonic fences, durable retry, immutable evidence/audit | -| [`contracts/mechanical-coordinator.v1.ts`](./contracts/mechanical-coordinator.v1.ts) | Pure snapshot decision engine separated from persistence/service adapter; ID-bound approvals, bigint-safe fences, durable retry/quarantine, artifact-backed checkpoints, exact failures | -| [`contracts/health-state.v1.ts`](./contracts/health-state.v1.ts) | Discriminated public health, separate branded transaction-local write proof, and non-overlapping denial/transport/version-conflict mappings | -| [`contracts/recovery-posture.v1.ts`](./contracts/recovery-posture.v1.ts) | Provider-neutral shape schema plus normative runtime refinement, cross-field constraints, and Lite/Standard/High-assurance defaults | -| [`tsconfig.json`](./tsconfig.json) | Strict no-emit project scope for linting and compiling the four frozen TypeScript contracts against the current Stack Drizzle declarations | -| [`DOCUMENTATION-CHECKLIST.md`](./DOCUMENTATION-CHECKLIST.md) | Publication documentation gate and implementation-slice deferrals | -| [KBN-101 exact-head security review](../reports/native-kanban-sot/kbn-101-contract-security-review-82ce325.md) | Historical `da742ca` REQUEST CHANGES report retained as prior closure evidence; rc.8 awaits independent exact-head re-review after closing the later residual reports | -| [Initial independent review](../reports/native-kanban-sot/canon-initial-review-no-go.md) | KCR-001–016 findings that blocked the first draft | -| [Final independent re-review](../reports/native-kanban-sot/canon-final-rereview-go.md) | Closure matrix, reproducible validation evidence, and GO verdict | -| [Ultron final gate](../reports/native-kanban-sot/ultron-final-go.md) | Final requirements, authority, schema, migration, recovery, decomposition, and evidence review GO | +| Artifact | Purpose | +| -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [Canonical requirements](../requirements/native-kanban-sot.md) | Canonical P0–P3 requirements, all seven ratified decisions, fixed invariants, thin MVP, recovery tiers, non-goals, and per-requirement acceptance criteria | +| [`MISSION-MANIFEST.md`](./MISSION-MANIFEST.md) | Mission/authority boundaries, exact role chain, gate model, mandatory SecReview triggers, Certifier final/no-merge rule, and collision-free slice ownership | +| [`TASKS.md`](./TASKS.md) | Dependency-ordered, bounded P0–P3 slices with IN/OUT scope, dependencies, shared contracts, file ownership, evidence, and USC coder2/3/4/5 parallelization | +| [`KBN-101-DB-ROLE-SPLIT.md`](./KBN-101-DB-ROLE-SPLIT.md) | rc.9 frozen extension-schema-owner boundary, exact disjoint card manifests, mechanical DDL classifier, executable `mosaic-db-migrator`, two-gateway TLS/bootstrap, role/search-path, atomic activation, and certification contract; foundation prerequisite of KBN-100 and real-role gate before KBN-105 | +| [`SHARED-CONTRACT.md`](./SHARED-CONTRACT.md) | Remediated v1 integration contract: proof authority, exact failures/routes/DTOs/MCP ownership, concrete current-main field migration map, relational invariants, Coordinator split, recovery delivery | +| [`contracts/kanban-schema.v1.ts`](./contracts/kanban-schema.v1.ts) | Drizzle target declarations including exact owner/principal membership, project congruence, tags/archive, proposals, persisted assignments, monotonic fences, durable retry, immutable evidence/audit | +| [`contracts/mechanical-coordinator.v1.ts`](./contracts/mechanical-coordinator.v1.ts) | Pure snapshot decision engine separated from persistence/service adapter; ID-bound approvals, bigint-safe fences, durable retry/quarantine, artifact-backed checkpoints, exact failures | +| [`contracts/health-state.v1.ts`](./contracts/health-state.v1.ts) | Discriminated public health, separate branded transaction-local write proof, and non-overlapping denial/transport/version-conflict mappings | +| [`contracts/recovery-posture.v1.ts`](./contracts/recovery-posture.v1.ts) | Provider-neutral shape schema plus normative runtime refinement, cross-field constraints, and Lite/Standard/High-assurance defaults | +| [`tsconfig.json`](./tsconfig.json) | Strict no-emit project scope for linting and compiling the four frozen TypeScript contracts against the current Stack Drizzle declarations | +| [`DOCUMENTATION-CHECKLIST.md`](./DOCUMENTATION-CHECKLIST.md) | Publication documentation gate and implementation-slice deferrals | +| [KBN-101 exact-head security review](../reports/native-kanban-sot/kbn-101-contract-security-review-82ce325.md) | Historical `da742ca` REQUEST CHANGES report retained as prior closure evidence; rc.9 awaits independent exact-head re-review after closing the later residual reports | +| [Initial independent review](../reports/native-kanban-sot/canon-initial-review-no-go.md) | KCR-001–016 findings that blocked the first draft | +| [Final independent re-review](../reports/native-kanban-sot/canon-final-rereview-go.md) | Closure matrix, reproducible validation evidence, and GO verdict | +| [Ultron final gate](../reports/native-kanban-sot/ultron-final-go.md) | Final requirements, authority, schema, migration, recovery, decomposition, and evidence review GO | ## Recommended USC lane partition diff --git a/docs/native-kanban-sot/KBN-101-DB-ROLE-SPLIT.md b/docs/native-kanban-sot/KBN-101-DB-ROLE-SPLIT.md index 8750e5f..3b1d965 100644 --- a/docs/native-kanban-sot/KBN-101-DB-ROLE-SPLIT.md +++ b/docs/native-kanban-sot/KBN-101-DB-ROLE-SPLIT.md @@ -1,8 +1,8 @@ # KBN-101 — Database Runtime/Migration Role Split -**Status:** frozen implementation contract; rc.8 exact residual remediation complete, awaiting independent exact-head re-review for [#771](https://git.mosaicstack.dev/mosaicstack/stack/issues/771) +**Status:** frozen implementation contract; rc.9 final residual remediation complete, awaiting independent exact-head re-review for [#771](https://git.mosaicstack.dev/mosaicstack/stack/issues/771) -**Version:** 1.0.0-rc.8 +**Version:** 1.0.0-rc.9 **Dependency:** KBN-010 → **KBN-101 foundation** → KBN-100 → **KBN-101 deployed-role certification** → KBN-105 **Scope:** PostgreSQL standalone/federated runtime identity, the sole application DDL runner, TLS bootstrap, readiness, deployment handoff, and evidence. This documentation card changes no database, secret, deployment, CI, runtime, migration, or compose artifact. @@ -29,38 +29,38 @@ Current `main` has one `DATABASE_URL` path in `packages/db/src/client.ts`, `migr `mosaic-db-migrator` is the **only application/CI/test command that may connect with DDL authority to PostgreSQL**. It owns, in one `max: 1` PostgreSQL session: migration-DTO parse, TLS/identity/search-path preflight, advisory-lock acquisition, manifest/ledger reconciliation, migration execution, postflight/readiness verification, lock release, and session close. It rejects `DATABASE_URL`-only invocation **before opening a connection or emitting DDL**. The only exception is the external privileged platform/IaC bootstrap actor (§4/§7), which is not an application command, never receives either application URL, and executes only the fixed bootstrap artifact. -**Executable contract (KBN-101-03 exclusive):** `packages/db/package.json` publishes `bin.mosaic-db-migrator`; its executable target is `packages/db/src/cli.ts`. KBN-101-03 also exclusively owns the immutable runner image recipe `docker/db-migrator.Dockerfile`. The CLI imports only private implementation modules `packages/db/src/migrator/runner.ts`, `packages/db/src/migrator/config.dto.ts`, `packages/db/src/migrator/manifest.ts`, `packages/db/src/migrator/identity.ts`, and `packages/db/src/migrator/tls.ts`, plus their tests. Package root exports do **not** expose `runMigrations`; no other programmatic migration API is public. The sole typed programmatic runner is private to the package/CLI boundary and accepts the typed migration DTO, never a URL/string/SQL/schema/role argument. +**Executable contract (KBN-101-03 exclusive):** `packages/db/package.json` publishes the exact mapping `"mosaic-db-migrator": "./dist/cli.js"`; `packages/db/src/cli.ts` compiles to that target. `docker/db-migrator.Dockerfile` builds that package and has the exact image entrypoint `ENTRYPOINT ["mosaic-db-migrator"]`. KBN-101-03 alone owns package/bin/build/pack/discovery tests that execute this compiled bin and image as `mosaic-db-migrator --help|--run|--verify`. The CLI imports only private implementation modules in `packages/db/src/migrator/`; package root exports do **not** expose `runMigrations`, and no other programmatic migration API is public. The sole typed programmatic runner is private to the package/CLI boundary and accepts the typed migration DTO, never a URL/string/SQL/schema/role argument. The exact user-facing interface is `mosaic-db-migrator --run` and `mosaic-db-migrator --verify`. `--help` is required and is the only discovery mode. Both commands use the fixed packaged migration folder and accept only `DATABASE_MIGRATION_URL`, `DATABASE_TLS_CA_CERT_PATH`, and non-secret `MOSAIC_DATABASE_TIER`/correlation input from the environment. They reject `DATABASE_URL` as fallback and reject URL, SQL, schema, role, database, migration-folder, and identifier arguments in argv. Stable sanitized process exits are: `0` success; `64` configuration; `65` TLS; `66` unsafe identity; `67` ledger/schema; `68` lock contention; `69` migration failure. CI, Compose, Swarm, and each two-gateway migration Job invoke the immutable db-migrator image with exactly `mosaic-db-migrator --run`; their readiness verification invokes exactly `mosaic-db-migrator --verify`. Required tests cover `--help`, argv rejection, runtime-only refusal before connect, migration-only success, each sanitized error/lock exit, and ordered `postgres-a → mosaic-db-migrator-a → gateway-a` plus `postgres-b → mosaic-db-migrator-b → gateway-b` execution. The implementation must inventory and close every present and future entrypoint as follows: -| Current entrypoint | Required rc.8 disposition | -| ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `packages/db/src/migrate.ts:runMigrations()` | Remove its optional URL, `DATABASE_URL`, and default fallback API from public/runtime exports. Its PostgreSQL behavior moves behind `mosaic-db-migrator`; callers cannot invoke it with an arbitrary URL. | -| `packages/db/src/index.ts` | `KBN-101-03` removes the public `runMigrations` re-export; only the explicit PGlite-local API remains as separately typed local behavior. A compile/import-negative proves `@mosaicstack/db` cannot directly import `runMigrations`; a `DATABASE_URL`-only direct-library attempt fails before connect. | -| `packages/db/drizzle.config.ts` and direct `drizzle-kit migrate` | A database-connecting Drizzle configuration reads only `DATABASE_MIGRATION_URL` through the migration DTO and rejects its absence before connection. Replace direct `drizzle-kit migrate` exposure with `mosaic-db-migrator`. `db:generate` is an offline schema artifact command and must neither resolve nor connect to a URL. | -| `pnpm --filter @mosaicstack/db db:migrate` and CI invocation | Make it a thin `mosaic-db-migrator` wrapper; no direct Drizzle migrator invocation remains. CI supplies an isolated disposable migration URL only to that job. | -| `db:push` / direct `drizzle-kit push` | Forbidden for standalone, federated, CI production-like, Portainer, and any URL outside a disposable developer database. If retained for local experimentation, a wrapper requires `MOSAIC_DISPOSABLE_DEVELOPER_DB=1`, a locally allowlisted disposable target, `DATABASE_MIGRATION_URL`, verified TLS when PostgreSQL is used, and rejects `DATABASE_URL`, any production-like tier, and every non-allowlisted host/database before connection. It is never a release, repair, or migration procedure. | -| `mosaic storage migrate --run` | Delegates only to `mosaic-db-migrator`; it rejects `DATABASE_URL`-only execution before spawning or connecting. Its PGlite form remains explicitly local-only. | -| `PostgresAdapter.migrate()`, Gateway `DatabaseModule`/startup, and PostgreSQL adapter factories | Runtime PostgreSQL migration is removed: no `runMigrations`, DDL, `CREATE EXTENSION`, or migration-compatible handle is reachable from startup. Gateway performs read-only identity, TLS, `search_path`, and manifest-ledger readiness checks only. | -| `packages/mosaic/src/commands/fleet-backlog.ts` | PostgreSQL fleet backlog never migrates or creates tables. It consumes a ready runtime connection; PGlite may use only its explicit local migration routine. | -| `packages/storage/src/{adapters/postgres,tier-detection}.ts` extension work and `infra/pg-init/01-extensions.sql` | Runtime probes become read-only catalog/extension-presence checks. Extension provisioning is a fixed external bootstrap prerequisite or a reviewed runner migration where the migrator has the required scoped authority; it is never a probe side effect or a reason to grant runtime database CREATE. | -| `packages/db/src/federation.integration.test.ts` direct type/table/index DDL | Replace with a pre-migrated disposable database created by `mosaic-db-migrator`, or make the test invoke that runner. The test itself has runtime credentials and no direct DDL. | -| `apps/gateway/src/__tests__/integration/federated-pgvector.integration.test.ts` `CREATE TEMP TABLE` | `KBN-101-06` replaces the temporary runtime DDL with a runner-prepared disposable **persistent** `mosaic.federated_pgvector_fixture` database/table. The test receives only its runtime URL/CA and performs read/query-only qualified-vector assertions (including the selected vector operator); it has no setup hook, temporary privilege, or DDL. Runtime `TEMPORARY` remains denied. | -| `docker/init-db.sql` | `KBN-101-00` deletes this duplicate tracked init artifact. `infra/pg-init/01-extensions.sql` is also retired from image-init ownership; neither may remain as a hidden extension authority. The sole extension action is the fixed external bootstrap artifact described in §5/§7, or the runner only when its reviewed implementation card explicitly grants that authority. | -| `packages/storage/src/migrate-tier.ts` operator remediation | `KBN-101-07` replaces the raw SQL recommendation with the sanitized instruction `mosaic-db-migrator --run` (secret injection and target selection are deployment-owned; no URL, SQL, or credential is accepted on the command line), or directs the operator to the approved external-bootstrap runbook when extension eligibility has not been met. It never recommends `CREATE EXTENSION`. | -| `tools/federation-harness/docker-compose.two-gateways.yml` | Active topology; `KBN-101-05` migrates it rather than retires it. It must contain `postgres-a`, `postgres-b`, `mosaic-db-migrator-a`, `mosaic-db-migrator-b`, `gateway-a`, and `gateway-b`; each database has separate runtime/migrator URL and CA consumers, TLS server material, verified-TLS readiness, and runner-before-Gateway ordering. Its existing plaintext URLs/init mount are forbidden. | -| `docs/fleet/backlog-conventions.md` | `KBN-101-07` removes the current automatic first-use PostgreSQL `runMigrations()` claim. It points PostgreSQL operators to the sole runner/readiness sequence and labels only the PGlite routine as local-only. A documentation-route `DATABASE_URL`-only test asserts no first-use/migration instruction is executable before connect. | -| `docs/PERFORMANCE.md` | `KBN-101-07` removes direct `drizzle-kit migrate` and Gateway-startup `runMigrations()` instructions. It points to the sole runner/readiness sequence. A documentation-route `DATABASE_URL`-only test asserts neither direct command nor Gateway fallback remains. | -| `README.md`, `CLAUDE.md`, `docs/guides/{dev-guide,deployment}.md`, and `docs/federation/SETUP.md` operator instructions | `KBN-101-07` replaces direct `db:migrate`, `db:push`, and `CREATE EXTENSION` production-like instructions with the runner/bootstrap procedure, and labels any remaining disposable-local command as non-production with the §2 guard. Documentation is a DDL entrypoint and cannot advertise a bypass. | -| New package scripts, test helpers, setup hooks, CLI commands, installers, CI steps, adapters, or operator docs | A repository check rejects any new PostgreSQL DDL-capable entrypoint or instruction unless it is the dedicated runner or the named external bootstrap artifact. No future script may accept a URL parameter or `DATABASE_URL` as a DDL escape hatch. | +| Current entrypoint | Required rc.9 disposition | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `packages/db/src/migrate.ts:runMigrations()` | Remove its optional URL, `DATABASE_URL`, and default fallback API from public/runtime exports. Its PostgreSQL behavior moves behind `mosaic-db-migrator`; callers cannot invoke it with an arbitrary URL. | +| `packages/db/src/index.ts` | `KBN-101-03` removes the public `runMigrations` re-export; only the explicit PGlite-local API remains as separately typed local behavior. A compile/import-negative proves `@mosaicstack/db` cannot directly import `runMigrations`; a `DATABASE_URL`-only direct-library attempt fails before connect. | +| `packages/db/drizzle.config.ts` and direct `drizzle-kit migrate` | A database-connecting Drizzle configuration reads only `DATABASE_MIGRATION_URL` through the migration DTO and rejects its absence before connection. Replace direct `drizzle-kit migrate` exposure with `mosaic-db-migrator`. `db:generate` is an offline schema artifact command and must neither resolve nor connect to a URL. | +| `pnpm --filter @mosaicstack/db db:migrate` and CI invocation | Make it a thin `mosaic-db-migrator` wrapper; no direct Drizzle migrator invocation remains. CI supplies an isolated disposable migration URL only to that job. | +| `db:push` / direct `drizzle-kit push` | Forbidden for standalone, federated, CI production-like, Portainer, and any URL outside a disposable developer database. If retained for local experimentation, a wrapper requires `MOSAIC_DISPOSABLE_DEVELOPER_DB=1`, a locally allowlisted disposable target, `DATABASE_MIGRATION_URL`, verified TLS when PostgreSQL is used, and rejects `DATABASE_URL`, any production-like tier, and every non-allowlisted host/database before connection. It is never a release, repair, or migration procedure. | +| `mosaic storage migrate --run` | Delegates only to `mosaic-db-migrator`; it rejects `DATABASE_URL`-only execution before spawning or connecting. Its PGlite form remains explicitly local-only. | +| `PostgresAdapter.migrate()`, Gateway `DatabaseModule`/startup, and PostgreSQL adapter factories | Runtime PostgreSQL migration is removed: no `runMigrations`, DDL, `CREATE EXTENSION`, or migration-compatible handle is reachable from startup. Gateway performs read-only identity, TLS, `search_path`, and manifest-ledger readiness checks only. | +| `packages/mosaic/src/commands/fleet-backlog.ts` | PostgreSQL fleet backlog never migrates or creates tables. It consumes a ready runtime connection; PGlite may use only its explicit local migration routine. | +| `packages/storage/src/{adapters/postgres,tier-detection}.ts` extension work and `infra/pg-init/01-extensions.sql` | Runtime probes become read-only catalog/extension-presence checks. Extension provisioning is a fixed external bootstrap prerequisite or a reviewed runner migration where the migrator has the required scoped authority; it is never a probe side effect or a reason to grant runtime database CREATE. | +| `packages/db/src/federation.integration.test.ts` direct type/table/index DDL | `KBN-101-02` replaces it with a pre-migrated disposable database created by `mosaic-db-migrator`, or makes the test invoke that runner. The test itself has runtime credentials and no direct DDL. | +| `apps/gateway/src/__tests__/integration/federated-pgvector.integration.test.ts` `CREATE TEMP TABLE` | `KBN-101-02` replaces the temporary runtime DDL with a runner-prepared disposable **persistent** `mosaic.federated_pgvector_fixture` database/table. The test receives only its runtime URL/CA and performs read/query-only qualified-vector assertions (including the selected vector operator); it has no setup hook, temporary privilege, or DDL. Runtime `TEMPORARY` remains denied. | +| `docker/init-db.sql` and `infra/pg-init/01-extensions.sql` | `KBN-101-02` retires these duplicate tracked init artifacts; neither may remain as a hidden extension authority. The sole extension action is the fixed external bootstrap artifact described in §4/§5, or the runner only when its reviewed implementation card explicitly grants that authority. | +| `packages/storage/src/{cli,migrate-tier}.ts` operator/runtime command closure | `KBN-101-02` alone replaces raw SQL/DDL behavior with delegation to `mosaic-db-migrator --run` (or the explicit PGlite-local path), rejects `DATABASE_URL`-only execution before spawning/connecting, and exposes no URL, SQL, or credential argv. KBN-101-07 documents that produced interface but owns neither source file. | +| `tools/federation-harness/docker-compose.two-gateways.yml` | Active topology; `KBN-101-05` migrates it rather than retires it. It must contain `postgres-a`, `postgres-b`, `mosaic-db-migrator-a`, `mosaic-db-migrator-b`, `gateway-a`, and `gateway-b`; each database has separate runtime/migrator URL and CA consumers, TLS server material, verified-TLS readiness, and runner-before-Gateway ordering. Its existing plaintext URLs/init mount are forbidden. | +| `docs/fleet/backlog-conventions.md` | `KBN-101-07` removes the current automatic first-use PostgreSQL `runMigrations()` claim. It points PostgreSQL operators to the sole runner/readiness sequence and labels only the PGlite routine as local-only. A documentation-route `DATABASE_URL`-only test asserts no first-use/migration instruction is executable before connect. | +| `docs/PERFORMANCE.md` | `KBN-101-07` removes direct `drizzle-kit migrate` and Gateway-startup `runMigrations()` instructions. It points to the sole runner/readiness sequence. A documentation-route `DATABASE_URL`-only test asserts neither direct command nor Gateway fallback remains. | +| `README.md`, `CLAUDE.md`, `docs/guides/{dev-guide,deployment}.md`, `docs/federation/SETUP.md`, `docs/fleet/backlog-conventions.md`, `docs/PERFORMANCE.md`, and `docs/plans/2026-03-15-agent-platform-architecture.md` operator instructions | `KBN-101-07` replaces direct `db:migrate`, `db:push`, `CREATE EXTENSION`, first-use migration, and Gateway-startup migration instructions with the runner/bootstrap procedure, and labels any remaining disposable-local command as non-production with the §2 guard. The architecture plan explicitly marks direct `db:migrate` superseded. Documentation is a DDL entrypoint and cannot advertise a bypass. | +| New package scripts, test helpers, setup hooks, CLI commands, installers, CI steps, adapters, or operator docs | A repository check rejects any new PostgreSQL DDL-capable entrypoint or instruction unless it is the dedicated runner or the named external bootstrap artifact. No future script may accept a URL parameter or `DATABASE_URL` as a DDL escape hatch. | The runner must run the original migration bytes, including shipped `0009`; no migration command may repair a ledger by manual insertion, adoption, `db:push`, or schema diff. Tests requiring PostgreSQL schema consume a pre-migrated disposable database or invoke this exact runner. -`KBN-101-06` owns a finite scanner and `DATABASE_URL`-only-before-connect matrix. It inventories by exact path every executable current source/script/package bin, operator document, and deploy manifest—including every §2 row, `packages/db/src/index.ts`, `docs/fleet/backlog-conventions.md`, `docs/PERFORMANCE.md`, `infra/pg-init/01-extensions.sql`, `.woodpecker/ci.yml`, `packages/db/{src/migrate.ts,drizzle.config.ts,package.json}`, `packages/db/src/migrate.test.ts`, `packages/storage/src/cli.ts`, `CLAUDE.md`, and `docs/federation/SETUP.md`. The matrix assigns each row an owner, disposition, and test; `packages/db/src/index.ts` is KBN-101-03/import-compile-negative, the two current documents are KBN-101-07/operator-route negatives, and both gateway pairs are KBN-101-05/06 ordered-Job negatives. It rejects every unclassified hit in scanner classes **executable current source/scripts/package bins**, **operator docs**, and **deploy manifests**. +`KBN-101-06` alone owns `.woodpecker/ci.yml`, `tools/ci/kbn101-ddl-inventory.ts`, `tools/ci/kbn101-ddl-inventory.spec.ts`, `tools/ci/fixtures/kbn101-ddl-inventory.json`, `tools/ci/kbn101-entrypoint-matrix.ts`, and `tools/ci/kbn101-entrypoint-matrix.spec.ts`. The scanner inventory is canonical JSON whose every record has exactly `path`, `class`, `ownerCard`, `disposition`, `allowedTokens`, `rationale`, `expiry`, and `reviewRevision`. `class` is one of `executable-source`, `script-or-package-bin`, `operator-document`, or `deploy-manifest`; `ownerCard` is one KBN-101 card; `disposition` is one of `runner`, `delegate`, `deny`, `retire`, `superseded-document`, or `allowlisted`; and `allowedTokens` is a nonempty subset of the fixed rules below only for `allowlisted` or `superseded-document`. The latter is allowed only for the exact architecture-plan path when adjacent text says the direct command is superseded/MUST NOT run and names `mosaic-db-migrator --run`. The scanner rejects duplicate path owners, ownerless non-allowlisted rows, missing paths, malformed fields, and an inventory path outside its declared class. The classifier's exact case-insensitive token/rule set is: `runMigrations\\s*\\(`; `drizzle-kit\\s+(?:migrate|push)`; `\\bdb:(?:migrate|push)\\b`; `mosaic\\s+storage\\s+migrate`; `CREATE\\s+(?:TEMP(?:ORARY)?\\s+)?(?:EXTENSION|TABLE|TYPE|INDEX|SCHEMA)`; `ALTER\\s+(?:EXTENSION|TABLE|TYPE|SCHEMA)`; `DROP\\s+(?:EXTENSION|TABLE|TYPE|INDEX|SCHEMA)`; and `DATABASE_URL` when it occurs in the same file as any preceding rule. It scans exact-path current executable source/scripts/package bins, operator documents, and deploy manifests; any hit not represented by a permitted inventory record fails. The matrix harness invokes the compiled runner/package/image and produced deployment artifacts; it edits no producer file. -The only reviewed allowlists are exact path/category pairs: byte-immutable historical SQL under `packages/db/drizzle/**` (reviewed solely as runner input); PGlite-only routines; negative-test literals; vendored/generated artifacts; and clearly labeled historical review reports. Each allowlist entry records path, category, rationale, reviewer, and expiry/review revision; it cannot mask a current executable or current instruction. An unknown token hit fails. The scanner is a classifier plus path inventory and review—not a naive token scan alone—and therefore never by itself proves DDL authority. For every non-allowlisted inventory row and `gateway-a`/`gateway-b`, the matrix proves `DATABASE_URL`-only, missing migration URL, direct library import, direct Drizzle, `db:push`, init artifact, operator route, runtime-only fixture/test, and each harness migration Job/Gateway fail before connection/DDL as applicable. The `db:push` negatives also cover production-like tier and production-like URL rejection. +The only allowlist categories are `historical-sql` (`packages/db/drizzle/**`, byte-immutable runner input only), `pglite-local` (an explicitly PGlite-only source/test path), `negative-test-literal` (a focused negative test), `vendored-generated` (a generated or vendored artifact), and `historical-review-report` (`docs/reports/**` only). Every allowed record names its exact path, token(s), rationale, expiry, and review revision. No allowlist category is valid for an executable current source/script/package bin, operator document, deploy manifest, `README.md`, `CLAUDE.md`, `docs/plans/**`, or `docs/guides/**`; `historical-review-report` cannot contain an operative command. Scanner self-tests place each token in an unowned current path, prove duplicate-owner/ownerless/path-existence failure, and prove an operative `db:migrate` instruction in a path labeled historical fails rather than being masked. The scanner is a classifier plus path inventory and review—not a naive token scan alone—and never by itself proves DDL authority. For every non-allowlisted inventory row and `gateway-a`/`gateway-b`, the matrix proves `DATABASE_URL`-only, missing migration URL, direct library import, direct Drizzle, `db:push`, init artifact, operator route, runtime-only fixture/test, and each harness migration Job/Gateway fail before connection/DDL as applicable. The `db:push` negatives also cover production-like tier and production-like URL rejection. ## 3. Exact migration manifest, ledger, and lock @@ -108,25 +108,25 @@ Before any preflight that can decide migration state, `mosaic-db-migrator` acqui Role creation, passwords, membership, database ownership, certificates, and Vault values are platform/IaC/operator work—not Drizzle/application migrations. Application SQL must not issue credential/role management statements or embed credentials. -| Role | Attributes and ownership | Membership / session use | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `mosaic_platform_database_owner` | `NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOBYPASSRLS`; platform-only database owner after bootstrap. | Never granted to application roles. | -| external platform bootstrap actor | Provider/operator/IaC-controlled privileged identity outside the Mosaic role graph and Vault/application configuration. | Creates/transitions the database and roles, then retires from application use. | -| `mosaic_schema_owner` | `NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOBYPASSRLS`; owns only `mosaic`/`drizzle` schemas and application/ledger objects. It owns the `mosaic_extensions` **schema** but not its extension/member objects. | Never an application login; no database/extension authority. A bootstrap-only schema `CREATE` grant is revoked after extension creation. | -| `mosaic_extension_owner` | Dedicated `NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOBYPASSRLS` extension owner, distinct from platform/schema/migrator/runtime. It owns `vector` and all extension-member objects in `mosaic_extensions`: the explicit exception to the schema-owner object rule. | No application login has membership, `SET ROLE`, credential, or inheritable grant to it. Only the external bootstrap actor may `SET ROLE mosaic_extension_owner`, only during bootstrap. | -| `mosaic_migrator` | `LOGIN NOINHERIT NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOBYPASSRLS`. | Only `mosaic_schema_owner`; runner verifies `session_user=mosaic_migrator`, `SET ROLE mosaic_schema_owner`, then `current_user=mosaic_schema_owner`. | -| `mosaic_runtime_capability` | `NOLOGIN` and no ownership/administrative attributes. | Holds only named runtime grants. | -| `mosaic_runtime` | `LOGIN INHERIT` with no ownership/administrative attributes. | Only `mosaic_runtime_capability WITH INHERIT TRUE, SET FALSE, ADMIN FALSE`; never owner/migrator member. | +| Role | Attributes and ownership | Membership / session use | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `mosaic_platform_database_owner` | `NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOBYPASSRLS`; platform-only database owner after bootstrap. | Never granted to application roles. | +| external platform bootstrap actor | Provider/operator/IaC-controlled privileged identity outside the Mosaic role graph and Vault/application configuration. | Creates/transitions the database and roles, then retires from application use. | +| `mosaic_schema_owner` | `NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOBYPASSRLS`; owns only `mosaic`/`drizzle` schemas and application/ledger objects. It has only `USAGE` on `mosaic_extensions` for fixed legacy type resolution. | Never an application login; no ownership, `CREATE`, `ALTER`, `DROP`, extension/member-change, or default-privilege authority in `mosaic_extensions`; its migrator subphase never receives temporary `CREATE` there. | +| `mosaic_extension_owner` | Dedicated `NOLOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOBYPASSRLS` extension owner, distinct from platform/schema/migrator/runtime. It creates and owns the `mosaic_extensions` schema, `vector`, and every extension-member object there. | No application login has membership, `SET ROLE`, credential, or inheritable grant to it. Only the external bootstrap actor may temporarily `SET ROLE mosaic_extension_owner` for fresh creation or approved-owner relocation, then revokes that membership. | +| `mosaic_migrator` | `LOGIN NOINHERIT NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOBYPASSRLS`. | Only `mosaic_schema_owner`; runner verifies `session_user=mosaic_migrator`, `SET ROLE mosaic_schema_owner`, then `current_user=mosaic_schema_owner`. | +| `mosaic_runtime_capability` | `NOLOGIN` and no ownership/administrative attributes. | Holds only named runtime grants. | +| `mosaic_runtime` | `LOGIN INHERIT` with no ownership/administrative attributes. | Only `mosaic_runtime_capability WITH INHERIT TRUE, SET FALSE, ADMIN FALSE`; never owner/migrator member. | The fixed application/runtime schema is **`mosaic`**. Every application/runtime pooled connection executes and verifies exactly `SET search_path TO pg_catalog, mosaic` before its first application query; connection checkout repeats this after reset/reconnect. Transactional application operations use `SET LOCAL search_path TO pg_catalog, mosaic` and verify it before query execution. `public` and `$user` are forbidden in all runtime paths. -The sole runner has one narrowly bounded **legacy-history bootstrap subphase** for the immutable current journal: before it runs, external bootstrap revokes `CREATE` on `public` from `PUBLIC`, temporarily assigns its ownership to `mosaic_schema_owner`, and denies all runtime connections. In its locked `max:1` migration session only, after `SET ROLE mosaic_schema_owner`, it uses the fixed legacy-only `SET LOCAL search_path TO pg_catalog, public, mosaic_extensions` solely to execute byte-immutable historical migrations `0000` through the current head. `mosaic_extensions` is non-writable in that session and is included only so immutable `0001` resolves its unqualified existing `vector` type; it is never in a runtime session path. After relocation/catalog verification and before manifest certification or any runtime readiness, the runner transfers `public` ownership to `mosaic_platform_database_owner`, revokes application `USAGE`/`CREATE`, and restores `pg_catalog,mosaic`. This compatibility subphase is not a runtime/operator option, accepts no configuration identifier, has no fallback, and is removed/disabled before KBN-101-08. +The sole runner has one narrowly bounded **legacy-history bootstrap subphase** for the immutable current journal: before it runs, external bootstrap revokes `CREATE` on `public` from `PUBLIC`, temporarily assigns its ownership to `mosaic_schema_owner`, and denies all runtime connections. The external bootstrap actor first temporarily `SET ROLE mosaic_extension_owner` to create/own `mosaic_extensions` and fresh `vector`, or to perform the approved-owner relocation; it then removes its temporary membership. In its locked `max:1` migration session only, after `SET ROLE mosaic_schema_owner`, the runner has only `USAGE` (not ownership or `CREATE`) on `mosaic_extensions` and uses the fixed legacy-only `SET LOCAL search_path TO pg_catalog, public, mosaic_extensions` solely so immutable `0001` resolves its unqualified existing `vector` type. It cannot create, alter, drop, reassign, or change a member there. The preflight catalogs `pg_namespace.nspowner`, schema ACL/default ACLs, `pg_extension.extowner`, and member owners, then directly proves `CREATE`/`ALTER`/`DROP`/member-change denial for runtime, migrator, and schema owner. After relocation/catalog verification and before manifest certification or any runtime readiness, the runner transfers `public` ownership to `mosaic_platform_database_owner`, revokes application `USAGE`/`CREATE`, and restores `pg_catalog,mosaic`. This compatibility subphase is not a runtime/operator option, accepts no configuration identifier, has no fallback, and is removed/disabled before KBN-101-08. `KBN-101-03` exclusively owns `packages/db/src/schema.ts`, `packages/db/drizzle/meta/*`, `packages/db/drizzle/meta/_journal.json`, the generated relocation migration, and exact database/Drizzle tests. It freezes one exported `export const mosaic = pgSchema('mosaic')`; every application `pgTable` and every application `pgEnum` must be declared through that export. The generated snapshot/journal and future `db:generate` output must target `mosaic` only; a static declaration/SQL test rejects a default-schema application `pgTable`/`pgEnum`, `public` application declaration, or future generated application DDL outside `mosaic`. Historical `0000` through current SQL and the shipped journal provenance are byte-immutable and execute only in the trusted legacy-`public` subphase; they are never rewritten to claim they originally targeted `mosaic`. ### 4.1 pgvector ownership and supported transition -The selected extension policy is fixed. Fresh databases: the external bootstrap actor temporarily `SET ROLE mosaic_extension_owner`, creates `vector` as `CREATE EXTENSION vector WITH SCHEMA mosaic_extensions`, validates `pg_extension.extowner`, extension-member ownership/schema/version, then revokes the temporary bootstrap-only schema grant. `mosaic_extensions` remains non-writable by runtime and grants runtime only catalog-proven `USAGE`/read-only function access. Runtime, migrator, and schema owner have no membership in `mosaic_extension_owner` and must be denied `ALTER EXTENSION`, `DROP EXTENSION`, and extension-member `UPDATE`/DDL. +The selected extension policy is fixed. Fresh databases: the external bootstrap actor temporarily `SET ROLE mosaic_extension_owner`, creates and owns `mosaic_extensions`, then creates `vector` as `CREATE EXTENSION vector WITH SCHEMA mosaic_extensions`; under that owner it revokes default `TABLES`, `SEQUENCES`, `FUNCTIONS`, `TYPES`, and `SCHEMAS` privileges from `PUBLIC`, `mosaic_schema_owner`, `mosaic_migrator`, and `mosaic_runtime`, then grants only the explicitly required read/type/function privileges. It validates `pg_namespace.nspowner`, `pg_extension.extowner`, extension-member ownership/schema/version, schema/default privileges, then revokes its temporary membership. Approved-owner relocation is likewise performed only while that external actor is set to `mosaic_extension_owner`. `mosaic_extensions` remains non-writable by runtime, migrator, and schema owner; the schema owner receives only `USAGE` for type resolution, and runtime only catalog-proven `USAGE`/read-only function access. Runtime, migrator, and schema owner have no membership in `mosaic_extension_owner` and must fail both catalog assertions and direct `CREATE`/`ALTER`/`DROP EXTENSION` and extension-member `UPDATE`/DDL denial tests. Shadow migration and rollback repeat these owner/default-privilege/preflight assertions before copying, before atomic switch, after resume, and before read-only rollback. PostgreSQL has **no supported** `ALTER EXTENSION ... OWNER TO`. No card may invent it, mutate system catalogs, use `DROP ... CASCADE`, or adopt legacy extension ownership. An existing `vector` is eligible for the clean in-place path only when `pg_extension.extowner` already resolves to the approved `mosaic_extension_owner`; after exact supported-version, `extrelocatable=true`, dependency, and complete expected member-set checks, the bootstrap actor may perform the tested `ALTER EXTENSION vector SET SCHEMA mosaic_extensions`. The same postflight verifies `extowner`, each member owner/schema, version, dependency inventory, and denial for runtime/migrator/schema owner. @@ -136,7 +136,7 @@ A `vector` extension owned by a legacy runtime/single login is **not activated i Before relocation, the runner records a parameterized catalog inventory and dependency graph. It must classify, in dependency order, application enum/domain/base types; owned and identity sequences; application tables; table columns/defaults; functions/procedures; views/materialized views; extension-owned objects; then triggers, constraints/FKs, indexes, and dependent rules/policies. It moves base types, sequences, tables, and functions as required; OID-bound constraints/indexes follow their owning objects and are catalog-verified rather than recreated blindly. Every object must be expected exactly once and be in either the immutable legacy/bootstrap allowlist, the `mosaic` application allowlist, or the selected `mosaic_extensions` extension membership; unknown, extra, duplicate, cross-schema, dependency-cycle, or partial-resume state fails closed. No raw client-side identifier interpolation is allowed. -`KBN-101-03` tests clean bootstrap, approved-owner existing relocation, legacy-owner shadow migration, interrupted/partial relocation resume, partial/cancel shadow resume, and pre-activation reverse rollback-before-activation; reverse rollback is allowed only before KBN-101-08 and restores the approved backup or the reviewed inverse relocation, never a runtime `search_path` bypass. Its N-1 order is: current legacy release → inactive bootstrap/runner and `mosaic` declarations → catalog relocation/generated-artifact verification or approved shadow migration → verified non-owner runtime activation. Tests include byte-immutable historical execution, no public application objects/declarations/future SQL, vector type/cast/operator query success under fixed `pg_catalog,mosaic`, exact extension-owner/member/schema/version assertions, ALTER/DROP denial for runtime/migrator/schema owner, and all extension eligibility negatives. +`KBN-101-00` owns bootstrap-role/schema/extension/default-privilege and direct-denial tests. `KBN-101-03` owns the runner integration tests that consume those bootstrap fixtures: approved-owner existing relocation, legacy-owner shadow migration, interrupted/partial relocation resume, partial/cancel shadow resume, and pre-activation reverse rollback-before-activation. Reverse rollback is allowed only before KBN-101-08 and restores the approved backup or the reviewed inverse relocation, never a runtime `search_path` bypass. Its N-1 order is: current legacy release → inactive bootstrap/runner and `mosaic` declarations → catalog relocation/generated-artifact verification or approved shadow migration → verified non-owner runtime activation. The combined evidence includes byte-immutable historical execution, no public application objects/declarations/future SQL, vector type/cast/operator query success under fixed `pg_catalog,mosaic`, exact extension-owner/member/schema/version assertions, catalog and direct ALTER/DROP/member-change denials for runtime/migrator/schema owner, and all extension eligibility negatives. No SQL identifier may come from URL/config/environment/operator input. Catalog comparisons use parameter values. The fixed identifiers above are constants; the external bootstrap artifact alone may use server-side `format('%I', fixed_allowlisted_identifier)` after allowlist validation. Raw client-side interpolation for identifiers, `SET search_path`, database, schema, role, table, or extension names is forbidden. Tests include injection-shaped values, a poisoned pooled-session reset, and transaction `SET LOCAL` restoration negatives. @@ -191,18 +191,20 @@ Stable sanitized codes are `DATABASE_RUNTIME_URL_REQUIRED`, `DATABASE_MIGRATION_ Every KBN-101 card remains one PR with exclusive ownership. Cards `00`–`07` may merge only as **prepared, inactive capability**: no current owner-runtime deployment consumes their image/config, and no compatibility switch is exposed to a runtime operator. They must not retain `ALLOW_LEGACY_*`, runtime DDL, `DATABASE_URL` migration fallback, plaintext TLS, direct Drizzle, or test-only bypass flags. Current owner-runtime deployments remain on their known N-1 release until final activation. -| Card | Depends on | Exact ownership and required result | -| ----------------------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `KBN-101-00` platform bootstrap / IaC | contract | Exclusively owns `infra/pg-bootstrap/roles.sql`, `infra/pg-bootstrap/extensions.sql`, `infra/pg-bootstrap/README.md`, and bootstrap tests: role graph, `mosaic_extension_owner`, fresh/approved-existing/legacy-owner eligibility, shadow migration interface, and bootstrap evidence. It owns no renderer, Compose, Portainer, Swarm, or deployment manifest. | -| `KBN-101-01` runtime config/DB boundary | 00 | Typed split DTOs, verified TLS config, fixed schema/session verifier, no PostgreSQL Gateway startup migration. | -| `KBN-101-02` entrypoint closure | 01 | Owns all §2 runtime paths except runner/journal: storage, CLI, adapters, Gateway startup, tier probes, fleet backlog, and direct-DDL test closure. | -| `KBN-101-03` runner/manifest/schema foundation | 00,01 | Exclusively owns `packages/db/package.json`, `packages/db/src/cli.ts`, `packages/db/src/migrator/runner.ts`, `packages/db/src/migrator/config.dto.ts`, `packages/db/src/migrator/manifest.ts`, `packages/db/src/migrator/identity.ts`, `packages/db/src/migrator/tls.ts`, `docker/db-migrator.Dockerfile`, their tests, `packages/db/src/schema.ts`, generated snapshots/journal/migration, and exact DB/command tests. It owns the published `mosaic-db-migrator` bin, canonical Git-blob/LF manifest v1, fixed lock, journal logical-order repair, runner-only legacy-public bootstrap, relocation/approved-owner/shadow-path tests, ledger/manifest grants, and no renderer/bootstrap artifact. Shipped `0009` bytes remain unchanged. | -| `KBN-101-04` installer/wizard/config | 01 | Production-like config persists no DSN and has no fallback; only non-secret references/injected variables. | -| `KBN-101-05` compose/Portainer deployment | 00,01,03 | Exclusively owns `tools/db/render-postgres-secrets.ts` and tests; current local/federated Compose, Portainer test stack, two-gateway harness, and `apps/gateway/Dockerfile`; gateway `10001:10001`, verified PostgreSQL image UID/GID, secret references/targets, TLS server/client mounts, server configuration, one immutable-image `mosaic-db-migrator --run` Job per database before readiness, and standalone/federated/Swarm/two-gateway TLS/order tests. It consumes—not edits—the versioned `infra/pg-bootstrap` interface. | -| `KBN-101-06` CI/test topology | 02,03,05 | Disposable identities and pre-migrated/runner test topology; owns the finite scanner classifier/allowlist review, every-path `DATABASE_URL`-only-before-connect denial matrix (including public-import and live-doc routes), runner-prepared persistent pgvector fixture, and repository checks rejecting DDL bypasses/insecure URLs. | -| `KBN-101-07` Vault/runbook/observability | 00,04,05,06 | Named control-plane/Vault-bootstrap handoff, activation/rotation/incident/backup/rollback runbook, sanitized observability evidence, and replacement of direct-DDL operator documentation (`README.md`, `CLAUDE.md`, `docs/guides/dev-guide.md`, `docs/guides/deployment.md`, `docs/federation/SETUP.md`, `packages/storage/src/{cli,migrate-tier}.ts`). | -| `KBN-101-08` foundation certification and **atomic activation release** | 00…07 | Independent review verifies all prepared cards and terminal-green CI; Mosaic control plane/Jason authorizes one ordered activation: backup → drain/scale zero all N-1 runtime clients → TLS server start → terminate non-TLS sessions and enforce `hostssl`/no `host` rule → verify no plaintext session → roles → runner → verified readiness → rolling non-owner runtime. Any red test/readiness/CI result aborts; no force-on-red or bypass. Remove/disable all temporary compatibility support before this gate. | -| `KBN-101-09` post-KBN-100 certification | KBN-100,08 | Real deployed-role immutable INSERT/SELECT and UPDATE/DELETE-denial evidence plus independent security/Ultron approval. | +| Card | Depends on | Complete, disjoint file/glob manifest and required test/evidence paths | +| ----------------------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `KBN-101-00` platform bootstrap / IaC | contract | **Only:** `infra/pg-bootstrap/roles.sql`, `infra/pg-bootstrap/extensions.sql`, `infra/pg-bootstrap/README.md`, `infra/pg-bootstrap/tests/**`. It creates the extension-owner role/schema/extension interface and proves fresh, approved-owner, legacy-shadow, catalog/default-privilege, and direct-denial bootstrap cases. No renderer, runner, Compose, CI, or deployment path. | +| `KBN-101-01` typed runtime config and verifier | 00 | **Only:** `packages/config/src/index.ts`, `packages/config/src/mosaic-config.ts`, `packages/config/src/mosaic-config.spec.ts`; `packages/db/src/client.ts`, `packages/db/src/defaults.ts`, `packages/db/src/connection-identity.ts`, `packages/db/src/client.spec.ts`, `packages/db/src/defaults.spec.ts`, `packages/db/src/connection-identity.spec.ts`; `apps/gateway/src/database/database.module.ts`, `apps/gateway/src/database/database.module.spec.ts`. It supplies runtime/migration/TLS DTO parsing plus runtime identity/search-path/readiness verification. No migrator, storage, installer, deploy, or CI path. | +| `KBN-101-03` sole runner, manifest, and schema foundation | 00,01 | **Only:** `.gitattributes`; `packages/db/package.json`; `packages/db/drizzle.config.ts`; `packages/db/src/cli.ts`, `packages/db/src/cli.spec.ts`, `packages/db/src/index.ts`, `packages/db/src/index.import-negative.spec.ts`, `packages/db/src/migrate.ts`, `packages/db/src/migrate.test.ts`, `packages/db/src/schema.ts`, `packages/db/src/schema.spec.ts`; `packages/db/src/migrator/**`; `packages/db/drizzle/*.sql`, `packages/db/drizzle/meta/*.json`; `docker/db-migrator.Dockerfile`, `docker/db-migrator.Dockerfile.spec.ts`; `packages/db/package-bin.spec.ts`. It alone publishes `"mosaic-db-migrator": "./dist/cli.js"`, verifies source/build/pack/discovery, and sets `ENTRYPOINT ["mosaic-db-migrator"]`; it owns journal/manifest/ledger/lock/relocation/shadow tests. Shipped `0009` bytes stay unchanged. | +| `KBN-101-02` runtime DDL closure | 01,03 | **Only:** `docker/init-db.sql`, `infra/pg-init/01-extensions.sql`; `packages/storage/src/adapters/postgres.ts`, `packages/storage/src/adapters/postgres.spec.ts`, `packages/storage/src/factory.ts`, `packages/storage/src/factory.spec.ts`, `packages/storage/src/types.ts`, `packages/storage/src/tier-detection.ts`, `packages/storage/src/tier-detection.spec.ts`, `packages/storage/src/cli.ts`, `packages/storage/src/cli.spec.ts`, `packages/storage/src/migrate-tier.ts`, `packages/storage/src/migrate-tier.spec.ts`, `packages/storage/src/migrate-tier.integration.test.ts`; `apps/gateway/src/main.ts`, `apps/gateway/src/__tests__/integration/federated-boot.pg-unreachable.integration.test.ts`, `apps/gateway/src/__tests__/integration/federated-boot.success.integration.test.ts`, `apps/gateway/src/__tests__/integration/federated-pgvector.integration.test.ts`; `packages/db/src/federation.integration.test.ts`; `packages/mosaic/src/commands/fleet-backlog.ts`, `packages/mosaic/src/commands/fleet-backlog.spec.ts`. It consumes the -03 runner and closes runtime/retired-init DDL only. It excludes every -03 runner, index, migrate, and Drizzle-config asset, and every deployment/CI/doc path. | +| `KBN-101-04` installer/wizard | 01 | **Only:** `packages/mosaic/src/stages/gateway-config.ts`, `packages/mosaic/src/stages/gateway-config.spec.ts`, `packages/mosaic/src/stages/gateway-config-cors.spec.ts`, `packages/mosaic/src/stages/wizard-menu.spec.ts`, `packages/mosaic/src/wizard.ts`. It persists only non-secret references/injected-variable contracts; source inspection excludes `tools/install.sh`, which does not read/write the database DSN. | +| `KBN-101-05` renderer and deployment | 00,03 | **Only:** `tools/db/render-postgres-secrets.ts`, `tools/db/render-postgres-secrets.spec.ts`; `apps/gateway/Dockerfile`, `apps/gateway/Dockerfile.spec.ts`; `docker-compose.yml`, `docker-compose.spec.ts`; `docker-compose.federated.yml`, `docker-compose.federated.spec.ts`; `deploy/portainer/federated-test.stack.yml`, `deploy/portainer/federated-test.stack.spec.ts`; `tools/federation-harness/docker-compose.two-gateways.yml`, `tools/federation-harness/docker-compose.two-gateways.spec.ts`. It consumes the -00 bootstrap interface and -03 immutable runner image, and owns no bootstrap, runner, config, storage, or CI file. | +| `KBN-101-07` operator/runbook/docs | 02,03,04,05 | **Only:** `README.md`, `CLAUDE.md`, `docs/guides/dev-guide.md`, `docs/guides/deployment.md`, `docs/federation/SETUP.md`, `docs/fleet/backlog-conventions.md`, `docs/PERFORMANCE.md`, `docs/plans/2026-03-15-agent-platform-architecture.md`, `docs/runbooks/kbn-101-database-role-split.md`, `docs/reports/native-kanban-sot/kbn-101-operator-readiness-report.md`, `docs/native-kanban-sot/tests/kbn-101-operator-docs.spec.ts`. It documents the interfaces produced by -02/-03/-04/-05 and owns no source, storage, CLI, runner, or CI file. | +| `KBN-101-06` CI classifier and command matrix | 02,03,05,07 | **Only:** `.woodpecker/ci.yml`, `tools/ci/kbn101-ddl-inventory.ts`, `tools/ci/kbn101-ddl-inventory.spec.ts`, `tools/ci/fixtures/kbn101-ddl-inventory.json`, `tools/ci/kbn101-entrypoint-matrix.ts`, `tools/ci/kbn101-entrypoint-matrix.spec.ts`. It invokes the already-produced bin/image/deployment/doc artifacts and edits no producer file. Its inventory test enforces manifest overlap, ownerless, duplicate-owner, path-existence, allowlist, and historical-category masking failures. | +| `KBN-101-08` foundation certification and **atomic activation release** | 00…07 | **Only evidence:** `docs/reports/native-kanban-sot/kbn-101-foundation-activation-certificate.md`, `docs/reports/native-kanban-sot/kbn-101-foundation-activation-evidence.json`. It changes no implementation path. Independent review and terminal-green CI must verify prepared artifacts before Mosaic control plane/Jason authorizes backup → drain/scale-zero N-1 → TLS → roles → runner → verified readiness → rolling runtime; any red result aborts. | +| `KBN-101-09` post-KBN-100 certification | KBN-100,08 | **Only evidence:** `docs/reports/native-kanban-sot/kbn-101-immutable-role-certificate.md`, `docs/reports/native-kanban-sot/kbn-101-immutable-role-evidence.json`. It changes no implementation path and records real deployed runtime INSERT/SELECT plus UPDATE/DELETE-denial evidence and independent security/Ultron approval. | + +The manifests above are the complete ownership universe for KBN-101 implementation paths; the KBN-101-06 inventory test fails on overlap, an ownerless in-scope path, or a nonexistent declared path. Cards `00`–`07` are prepared artifacts, not independently deployed releases: the immutable N-1 owner-runtime image stays live until KBN-101-08 control-plane atomic activation. No activation card edits a source-changing path, and no runtime bypass or broken deployed intermediate exists. **Authority:** Mosaic control plane/Jason is the sole activation and rollback authority. CI, Gateway, migrator, Coordinator, and Certifier cannot activate, waive a red result, or force release. Before an incompatible KBN-100 switch, the authority stops/scales runtime, uses the approved backup/restore or separately reviewed runner artifact, restores only a known TLS-compatible runtime with its runtime secret after `hostssl` enforcement, and verifies no plaintext sessions plus TLS/readiness. Migration URL is never injected into Gateway to enable rollback. KBN-100 starts only after KBN-101-08; KBN-105 starts only after KBN-101-09. @@ -210,16 +212,16 @@ Every KBN-101 card remains one PR with exclusive ownership. Cards `00`–`07` ma ## 8. Acceptance traceability -| Requirement / acceptance criterion | Required implementation evidence | -| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| K101-REQ-01 / AC-K101-01 | DTO/command matrix covers local/PGlite, standalone, federated, and both harness pairs; every finite classified §2 path rejects `DATABASE_URL`-only before connection/DDL; no runtime fallback/default; `--help`, argv, import-compile, and live-operator-route negatives pass. | -| K101-REQ-02 / AC-K101-02 | KBN-101-03 one-session fixed two-int lock, `--run`/`--verify` exit-code, contention/crash/readiness/unrelated-key tests; manifest-v1 canonical bytes/digest and all reconciliation states; Gateway/replica DDL impossibility. | -| K101-REQ-03 / AC-K101-03 | KBN-101-03 catalog relocation and future-Drizzle-only-`mosaic` proof; fresh/approved-owner/shadow extension paths; `pg_extension.extowner`, member/schema/version, and runtime/migrator/schema-owner ALTER/DROP/member-update denials; KBN-101-01/03 role, path, TEMP, ledger/default-grant, and pool-reset tests. | -| K101-REQ-04 / AC-K101-04 | KBN-101-00 bootstrap-interface and KBN-101-05 renderer/deployment tests; immutable-image exact Job commands and runner-before-readiness order; fresh/existing verified-TLS Compose/Swarm/two-gateway positives; both-pair CA/SAN/downgrade/key-permission negatives; exact UID/GID/mode and runtime/migrator secret-consumer rendering/CI negatives. | -| K101-REQ-05 / AC-K101-05 | KBN-101-09 after KBN-100: real deployed runtime INSERT/SELECT success and UPDATE/DELETE denial for each frozen relation, with RESTRICT retention evidence. | -| K101-REQ-06 / AC-K101-06 | KBN-101-00…08 prepared-card/no-intermediate-deploy evidence; one final activation authority record; N-1 drain/zero-plaintext-session/`hostssl`, backup/restore, CA overlap rotation, TLS-only rollback, Vault/redaction, and no-force-on-red evidence. | -| K101-REQ-07 / KBN sequence | KBN-101-08 foundation certificate before KBN-100, KBN-101-09 real immutable-role certificate plus Ultron approval before KBN-105; KBN-100 rebases/restores Drizzle consistency and never bypasses the serial gates. | -| Delivery integrity | One-card/one-PR DAG, exact file ownership, docs/link/contract checks, independent author≠reviewer re-review on the pushed exact head, and terminal-green CI for implementation cards. | +| Requirement / acceptance criterion | Required implementation evidence | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| K101-REQ-01 / AC-K101-01 | DTO/command matrix covers local/PGlite, standalone, federated, and both harness pairs; every finite classified §2 path rejects `DATABASE_URL`-only before connection/DDL; no runtime fallback/default; `--help`, argv, import-compile, and live-operator-route negatives pass. | +| K101-REQ-02 / AC-K101-02 | KBN-101-03 one-session fixed two-int lock, `--run`/`--verify` exit-code, contention/crash/readiness/unrelated-key tests; manifest-v1 canonical bytes/digest and all reconciliation states; Gateway/replica DDL impossibility. | +| K101-REQ-03 / AC-K101-03 | KBN-101-00 bootstrap schema/extension-owner/default-privilege and direct-denial proof; KBN-101-03 catalog relocation and future-Drizzle-only-`mosaic` proof plus approved-owner/shadow runner integration; `pg_namespace.nspowner`, `pg_extension.extowner`, member/schema/version, and runtime/migrator/schema-owner catalog plus ALTER/DROP/member-update denials; KBN-101-01/03 role, path, TEMP, ledger/default-grant, and pool-reset tests. | +| K101-REQ-04 / AC-K101-04 | KBN-101-00 bootstrap-interface and KBN-101-05 renderer/deployment tests; immutable-image exact Job commands and runner-before-readiness order; fresh/existing verified-TLS Compose/Swarm/two-gateway positives; both-pair CA/SAN/downgrade/key-permission negatives; exact UID/GID/mode and runtime/migrator secret-consumer rendering/CI negatives. | +| K101-REQ-05 / AC-K101-05 | KBN-101-09 after KBN-100: real deployed runtime INSERT/SELECT success and UPDATE/DELETE denial for each frozen relation, with RESTRICT retention evidence. | +| K101-REQ-06 / AC-K101-06 | KBN-101-00…08 prepared-card/no-intermediate-deploy evidence; one final activation authority record; N-1 drain/zero-plaintext-session/`hostssl`, backup/restore, CA overlap rotation, TLS-only rollback, Vault/redaction, and no-force-on-red evidence. | +| K101-REQ-07 / KBN sequence | KBN-101-08 foundation certificate before KBN-100, KBN-101-09 real immutable-role certificate plus Ultron approval before KBN-105; KBN-100 rebases/restores Drizzle consistency and never bypasses the serial gates. | +| Delivery integrity | One-card/one-PR DAG, exact file ownership, docs/link/contract checks, independent author≠reviewer re-review on the pushed exact head, and terminal-green CI for implementation cards. | ## 9. Non-goals and residual authority diff --git a/docs/native-kanban-sot/SHARED-CONTRACT.md b/docs/native-kanban-sot/SHARED-CONTRACT.md index 53cd3c6..63c6e91 100644 --- a/docs/native-kanban-sot/SHARED-CONTRACT.md +++ b/docs/native-kanban-sot/SHARED-CONTRACT.md @@ -1,13 +1,20 @@ # Native Kanban/SOT — Remediated Shared Contract v1 -**Status:** CONTROL-PLANE rc.8 KBN-101 exact residual remediation complete; awaiting independent exact-head re-review. Prior KCR-001–016 and rc.4 SI-001 decisions retained; KBN-101 foundation certification precedes KBN-100 and real immutable-operation certification precedes KBN-105 -**Version:** 1.0.0-rc.8 +**Status:** CONTROL-PLANE rc.9 KBN-101 final residual remediation complete; awaiting independent exact-head re-review. Prior KCR-001–016 and rc.4 SI-001 decisions retained; KBN-101 foundation certification precedes KBN-100 and real immutable-operation certification precedes KBN-105 +**Version:** 1.0.0-rc.9 **Date:** 2026-07-15 **Change authority:** Mosaic control plane/Jason only **SI-001 amendment authority:** `web1:mosaic-100` control-plane decision under issue #753 ## Amendment record +### 1.0.0-rc.9 — KBN-101 extension-schema boundary, disjoint manifests, and scanner mechanics + +- **Extension schema owner:** `mosaic_extension_owner`, not `mosaic_schema_owner`, creates and owns `mosaic_extensions`, `vector`, and extension-member objects. The external bootstrap actor temporarily `SET ROLE`s for fresh creation or approved-owner relocation, then loses that membership. Schema owner has only `USAGE` for legacy type resolution—never ownership, `CREATE`, `ALTER`, `DROP`, member change, or default-privilege authority. Runtime, migrator, and schema owner must fail catalog and direct DDL denials; shadow/resume/rollback repeat the owner/default-privilege proof. +- **Exclusive delivery DAG:** KBN-101-00…09 now has a complete, nonoverlapping exact file/glob manifest with named tests/evidence. The runner mapping is exactly `"mosaic-db-migrator": "./dist/cli.js"` and image `ENTRYPOINT ["mosaic-db-migrator"]`; `packages/storage/src/{cli,migrate-tier}.ts` belongs only to -02, and -07 is documentation only. -08/-09 own evidence paths only. -00…07 are prepared artifacts; the immutable N-1 image remains live until -08 atomic activation, so no independently deployed intermediate can bypass runtime controls. +- **Mechanical classifier:** -06 owns the exact scanner, inventory fixture, command-matrix harness, and CI wiring. Inventory records pin path/class/owner/disposition/allowed tokens/rationale/expiry/review revision; unknown, duplicate-owner, ownerless, missing-path, invalid allowlist, and historical-category masking fail. The architecture plan's operative direct `db:migrate` is replaced by sole-runner guidance rather than hidden under a historical category. +- **Non-effect:** manifest v1, lock, `mosaic` application-schema ownership, TLS, activation, KBN-100/KBN-105 serial gates, and all earlier canon decisions remain unchanged. The normative detail remains [`KBN-101-DB-ROLE-SPLIT.md`](./KBN-101-DB-ROLE-SPLIT.md). + ### 1.0.0-rc.8 — KBN-101 finite authority, executable runner, and pgvector-owner remediation - **Finite authority closure:** KBN-101-06 classifies every current executable source/script/package bin, operator document, and deploy manifest by exact path; unclassified current hits fail. Byte-immutable historical SQL, PGlite-only routines, negative-test literals, vendored/generated artifacts, and clearly labeled historical reports are exact-path/category reviewed allowlists only. `packages/db/src/index.ts` loses its public `runMigrations` export with a direct-import/compile negative; `docs/fleet/backlog-conventions.md` and `docs/PERFORMANCE.md` lose first-use/direct-Drizzle/Gateway-startup migration instructions and carry runner/readiness route negatives. A token scan is only input to the classifier, never proof of authority. @@ -49,7 +56,7 @@ ## 1. Authority -Concrete contracts are the four `contracts/*.v1.ts` files. PostgreSQL/current-main Drizzle is the sole writable SOT. In PostgreSQL standalone/federated deployments, KBN-101 rc.8 DDL/ledger/TLS/role separation is a precondition to schema implementation and certification. Public health, Valkey, files, exports, providers, browser state, and outage notes cannot authorize/reconstruct writes. Mechanical Coordinator is non-LLM with no scope/gate/certification/merge authority. Certifier is final independent gate with no merge authority. No feature lane starts until this canon merges and the KBN-010/KBN-105 prerequisites are satisfied. +Concrete contracts are the four `contracts/*.v1.ts` files. PostgreSQL/current-main Drizzle is the sole writable SOT. In PostgreSQL standalone/federated deployments, KBN-101 rc.9 DDL/ledger/TLS/role separation is a precondition to schema implementation and certification. Public health, Valkey, files, exports, providers, browser state, and outage notes cannot authorize/reconstruct writes. Mechanical Coordinator is non-LLM with no scope/gate/certification/merge authority. Certifier is final independent gate with no merge authority. No feature lane starts until this canon merges and the KBN-010/KBN-105 prerequisites are satisfied. ## 2. Health proof and exact failures diff --git a/docs/native-kanban-sot/TASKS.md b/docs/native-kanban-sot/TASKS.md index 3eff165..504e590 100644 --- a/docs/native-kanban-sot/TASKS.md +++ b/docs/native-kanban-sot/TASKS.md @@ -95,13 +95,13 @@ No consumer implementation begins before KBN-105. No schema work begins before K ### KBN-101 — PostgreSQL runtime/migration role split and deployed-role certification -- **Status:** IN PROGRESS — issue [#771](https://git.mosaicstack.dev/mosaicstack/stack/issues/771); rc.8 closes the rc.7 exact-head finite-inventory, executable-runner/card-boundary, and pgvector-extension-owner residuals. It awaits independent exact-head re-review; implementation remains held. +- **Status:** IN PROGRESS — issue [#771](https://git.mosaicstack.dev/mosaicstack/stack/issues/771); rc.9 closes the exact-head extension-schema-owner, complete disjoint-manifest, and scanner-mechanics residuals. It awaits independent exact-head re-review; implementation remains held. - **Owner:** Mos integration control plane; independently reviewed by security/Ultron. - **Mode:** SERIAL foundation certificate blocks KBN-100; its post-KBN-100 real immutable-operation certificate blocks KBN-105. - **IN:** Exact `DATABASE_URL` non-owner runtime versus `DATABASE_MIGRATION_URL` owner/migrator connection contract; sole published `mosaic-db-migrator --run|--verify` PostgreSQL DDL path and all legacy/future entrypoint closure; finite exact-path scanner/allowlist review and every-path before-connect denial matrix; `DATABASE_TLS_CA_CERT_PATH` plus operator/IaC CA/server-key/cert lifecycle, exact service-DNS SANs, Vault/compose/Swarm mount modes, TLS server/bootstrap/rotation/rollback; PGlite exception; fixed two-int advisory lock; manifest-v1 logical-index/tag/exact-byte-SHA-256 ledger reconciliation including safe `0009`; fixed `mosaic` schema and exact `pg_catalog,mosaic` pooled session path; platform/schema/extension-owner/migrator/runtime roles; approved-owner versus legacy-owner shadow pgvector transition; ownership, membership, TEMP/ledger-read/default privilege and immutable grant proof; N-1 inactive prepared cards then atomic activation/rollback authority; Vault/redaction/observability/operator runbooks; one-card/one-PR implementation DAG. - **OUT:** Production mutation in this planning card; KBN-100 tables/data backfill; application API behavior; KBN-105 route/DTO freeze. - **Depends on:** KBN-010 completed. -- **Contract surfaces:** [`KBN-101-DB-ROLE-SPLIT.md`](./KBN-101-DB-ROLE-SPLIT.md); `SHARED-CONTRACT.md` rc.8 amendment. +- **Contract surfaces:** [`KBN-101-DB-ROLE-SPLIT.md`](./KBN-101-DB-ROLE-SPLIT.md); `SHARED-CONTRACT.md` rc.9 amendment. - **Evidence:** foundation: exact `--help|--run|--verify`/exit/argv/import-negative plus DTO entrypoint negatives for every finite classified current DDL/static-bypass path (including `DATABASE_URL`-only, runner fixture, retired init, sanitized current operator guidance, both harness pairs, and `db:push` refusal); clean/pre-0009/skipped/applied-late/duplicate/unknown/missing/corrupt/stale/backup plus public-to-`mosaic`/partial/reverse runner proof; fixed-lock contention/crash/readiness/unrelated-key tests; runtime cannot invoke migrations/DDL/TEMP; fresh/approved-owner existing/legacy-owner shadow/partial-resume-rollback/N-1 pgvector evidence with `pg_extension.extowner`, member/schema/version and runtime/migrator/schema-owner ALTER/DROP denial; disposable standalone, federated/Swarm, and two-gateway verified-TLS positives plus both-pair CA/SAN/downgrade/key mode/UID-GID/URL-secret consumer-isolation and legacy-drain/`hostssl` zero-plaintext negatives; exclusive bootstrap/renderer/manifest ownership test; catalog relocation/vector-query/operator/Drizzle-only-`mosaic`, role/grant/search-path/pool-reset/identifier checks; N-1/atomic TLS-only rollback/no-force-on-red rehearsal; named Vault/bootstrap-control-plane/CA-overlap/redaction/operator evidence; independent author≠reviewer security GO. Post-KBN-100: real deployed non-owner INSERT/SELECT and UPDATE/DELETE denial for immutable event/artifact/evidence relations plus Ultron GO. ### KBN-100 — Unified Drizzle schema and concrete N-1 migration diff --git a/docs/plans/2026-03-15-agent-platform-architecture.md b/docs/plans/2026-03-15-agent-platform-architecture.md index 889ce53..d09efab 100644 --- a/docs/plans/2026-03-15-agent-platform-architecture.md +++ b/docs/plans/2026-03-15-agent-platform-architecture.md @@ -1464,9 +1464,11 @@ Generate and apply: ```bash pnpm --filter @mosaicstack/db db:generate # generates migration SQL -pnpm --filter @mosaicstack/db db:migrate # applies to PG +mosaic-db-migrator --run # sole PostgreSQL migration runner ``` +> **KBN-101 supersession:** `pnpm --filter @mosaicstack/db db:migrate` is superseded and MUST NOT be used. The runner receives only deployment-injected migration credentials; it accepts no URL, SQL, schema, or role argv. + Platform enforcement keys (seeded with `mutable = false` by gateway `PreferencesService.onModuleInit()`): | Key | Category | Reason | diff --git a/docs/scratchpads/771-kbn101-db-role-split.md b/docs/scratchpads/771-kbn101-db-role-split.md index d9a7e3d..d031da7 100644 --- a/docs/scratchpads/771-kbn101-db-role-split.md +++ b/docs/scratchpads/771-kbn101-db-role-split.md @@ -106,3 +106,13 @@ Independent Codex review found two blockers and security review found two medium - **Cross-document state:** PRD, KBN contract, shared contract, task decomposition, index, sitemap, current operator docs, and this scratchpad are rc.8-consistent. The only intended next action is a fresh independent exact-head re-review after validation/push. - **Validation / review:** Prettier passed for all nine changed Markdown documents; local links passed (9 documents); `pnpm exec tsc --noEmit -p docs/native-kanban-sot/tsconfig.json` passed; source-path inventory passed (20 paths: 8 current, 12 explicitly planned); finite-authority requirement checklist and `git diff --check` passed. Manual documentation/security review checked the three requested paths, private-only runner boundary/exit contract, non-overlapping 00/03/05 ownership, extension-owner denial and shadow path, and `.mosaic` exclusion. No source-code TDD applies because this is contract-only remediation. - **Delivery evidence:** committed `1423c2ad02b5471eab006fb4c878808e5b29c387` as `docs(#771): close role split rc.8 residuals`. Push queue guard returned `state=unknown` without error; push hook ran repository `pnpm typecheck`, `pnpm lint`, and `pnpm format:check`, all PASS; branch push succeeded. This final evidence append is committed next, then the exact remote head is verified. The only intended next action is a fresh independent exact-head re-review. + +## 2026-07-15 — rc.9 final residual remediation session + +- **Objective / correction:** Close the three findings in `/home/hermes/agent-work/reviews/771-kbn101-contract-rereview3-9cf5d2f.md` against exact head `9cf5d2f6641b14082dc3294e2a84d1fb4ccc019d`: move `mosaic_extensions` schema ownership to `mosaic_extension_owner`; replace all broad/conflicting KBN-101 card ownership with a complete disjoint exact-path/test manifest; and classify the current architecture-plan `db:migrate` instruction with pinned scanner mechanics. Scope remains documentation-only; no source/config/Compose/CI/deployment/secret/migration artifact and no `.mosaic` path may be modified. +- **Plan:** inspect current tracked source topology to name only existing paths; update the normative contract first and synchronize PRD/shared/task/index/sitemap/version language; run Prettier, changed-doc links, strict contract TypeScript, source/path and manifest-overlap checks, diff allowlist, independent documentation/security review; then stage docs only, commit, queue-guard, push, and verify exact remote SHA. No source-code TDD applies because this is contract-only remediation. +- **Closure implemented:** rc.9 makes `mosaic_extension_owner` create and own `mosaic_extensions`, `vector`, and members; the external bootstrap actor alone temporarily `SET ROLE`s for fresh/approved-owner work, while schema owner has only `USAGE` for legacy type resolution and never temporary `CREATE`. Catalog/default-ACL plus direct DDL/member denials now cover runtime, migrator, and schema owner through fresh, relocation, shadow/resume, and rollback evidence. +- **Delivery decomposition:** Replaced broad ownership with complete disjoint 00–09 manifests, exact tests/evidence, producer-before-consumer edges, and an explicit no-intermediate-deploy N-1 activation statement. `packages/storage/src/{cli,migrate-tier}.ts` belongs only to -02; the current tracked init artifacts are retired by -02 as direct-DLL closure; -03 owns all runner/index/migrate/config/schema assets and exact compiled-bin/image mapping; -07 owns docs only; -08/-09 own evidence only. +- **Classifier closure:** -06 has exact scanner/inventory/matrix paths, canonical inventory fields, classes/dispositions, fixed token/rule set, exact allowlist categories/restrictions, and self-test requirements for unknown, duplicate-owner, ownerless, missing-path, and historical masking cases. The architecture plan now marks direct `db:migrate` superseded and uses `mosaic-db-migrator --run`. +- **Validation:** Prettier check, strict native-kanban contract TypeScript, changed-document local-link resolution, `git diff --check`, and an automated manifest-overlap/owner/current-source-path check passed. Targeted documentation/security review verified role ownership/default privileges/search path/preflight/legacy/shadow/rollback consistency, disjoint manifests/DAG/activation, scanner mechanics, exact bin/entrypoint, and no `.mosaic` staging intent. No source-code TDD applies because this is documentation-only remediation. +- **Next:** stage documentation only, commit, queue-guard, push, verify exact remote SHA, then wait for fresh exact-head review.