docs(#771): close role split rc.8 residuals
This commit is contained in:
@@ -152,11 +152,10 @@ for any `<Image>` components added in the future.
|
|||||||
## How to Apply
|
## How to Apply
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Run the DB migration (requires a live DB)
|
# PostgreSQL migration is a dedicated pre-runtime phase.
|
||||||
pnpm --filter @mosaicstack/db exec drizzle-kit migrate
|
# Deployment injects migration-only credentials/TLS material; Gateway startup only verifies readiness.
|
||||||
|
mosaic-db-migrator --run
|
||||||
# Or, in Docker/Swarm — migrations run automatically on gateway startup
|
mosaic-db-migrator --verify
|
||||||
# via runMigrations() in packages/db/src/migrate.ts
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
10
docs/PRD.md
10
docs/PRD.md
@@ -133,19 +133,19 @@ PostgreSQL Gateway/storage currently uses one `DATABASE_URL` for runtime queries
|
|||||||
|
|
||||||
### Normative requirements
|
### 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 one dedicated `mosaic-db-migrator` phase in `standalone`/`federated`; local PGlite is the explicit exception. Every current/future PostgreSQL DDL entrypoint SHALL route to that runner or be denied, and SHALL reject `DATABASE_URL`-only execution before connection/DDL. The finite source-backed inventory includes every existing direct DDL/test/init/operator/harness path and a two-gateway pair matrix; `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 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.
|
||||||
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.
|
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, login migrator, non-login runtime capability, and login runtime roles; runtime 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.
|
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.
|
||||||
4. `K101-REQ-04`: `mosaicstack/stack` KBN-101-00/05 SHALL own current Compose/Portainer/two-gateway/bootstrap-renderer artifacts; 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.
|
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.
|
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.
|
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.
|
||||||
7. `K101-REQ-07`: KBN-100 SHALL begin only after the KBN-101 foundation role/schema-boundary certificate; it SHALL rebase on that main head, restore generated Drizzle declaration/snapshot/journal consistency, and bound procedural immutable-table grant/trigger/backfill additions to its schema slice. KBN-101 real deployed-role immutable-operation certification SHALL complete after KBN-100 creates those relations and before KBN-105.
|
7. `K101-REQ-07`: KBN-100 SHALL begin only after the KBN-101 foundation role/schema-boundary certificate; it SHALL rebase on that main head, restore generated Drizzle declaration/snapshot/journal consistency, and bound procedural immutable-table grant/trigger/backfill additions to its schema slice. KBN-101 real deployed-role immutable-operation certification SHALL complete after KBN-100 creates those relations and before KBN-105.
|
||||||
|
|
||||||
### Acceptance criteria
|
### Acceptance criteria
|
||||||
|
|
||||||
1. `AC-K101-01`: DTO/command-matrix tests prove required modes, PGlite exception, every finite DDL/static-bypass inventory path and both harness pairs reject `DATABASE_URL`-only before connection/DDL, no migration-to-runtime fallback, and `db:push` refusal outside an allowlisted disposable DB.
|
1. `AC-K101-01`: DTO/command-matrix tests prove required modes, PGlite exception, `mosaic-db-migrator --help|--run|--verify`/stable exits/argv refusal, public-import negative, every finite classified DDL/static-bypass inventory path and both harness pairs reject `DATABASE_URL`-only before connection/DDL, no migration-to-runtime fallback, and `db:push` refusal outside an allowlisted disposable DB.
|
||||||
2. `AC-K101-02`: Fixed namespace lock contention/crash/readiness/non-interference and exact manifest-v1 reconciliation tests prove no replica race/runtime auto-migration and fail closed on every missing/unknown/duplicate/ambiguous/corrupt/stale ledger state.
|
2. `AC-K101-02`: Fixed namespace lock contention/crash/readiness/non-interference and exact manifest-v1 reconciliation tests prove no replica race/runtime auto-migration and fail closed on every missing/unknown/duplicate/ambiguous/corrupt/stale ledger state.
|
||||||
3. `AC-K101-03`: Catalog, Drizzle-generation, vector-query/operator, clean/current-public/partial/reverse-rollback, and real deployed-role tests prove platform/schema-owner/migrator/runtime separation, `pg_catalog,mosaic` per-session pool safety, `mosaic_extensions` qualification, identifier injection denial, ownership/membership/ledger-read/TEMP/default grants, and unsafe privilege denial.
|
3. `AC-K101-03`: Catalog, Drizzle-generation, vector-query/operator, fresh/approved-owner/legacy-shadow/partial/resume/rollback/N-1, and real deployed-role tests prove platform/schema/extension-owner/migrator/runtime separation, `pg_extension.extowner` plus extension-member/schema/version assertions, runtime/migrator/schema-owner ALTER/DROP/member-update denial, `pg_catalog,mosaic` per-session pool safety, `mosaic_extensions` qualification, identifier injection denial, ownership/membership/ledger-read/TEMP/default grants, and unsafe privilege denial.
|
||||||
4. `AC-K101-04`: Disposable standalone, federated/Swarm, and two-gateway verified-TLS positives plus for both pairs missing CA/wrong CA/wrong SAN/sslmode downgrade, server/Gateway key mode, UID/GID, secret-consumer isolation, and legacy-drain/`hostssl` negatives prove server bootstrap, ordering, and readiness; PGlite is expressly excluded from this PostgreSQL evidence.
|
4. `AC-K101-04`: Disposable standalone, federated/Swarm, and two-gateway verified-TLS positives plus for both pairs missing CA/wrong CA/wrong SAN/sslmode downgrade, server/Gateway key mode, UID/GID, secret-consumer isolation, and legacy-drain/`hostssl` negatives prove server bootstrap, ordering, and readiness; PGlite is expressly excluded from this PostgreSQL evidence.
|
||||||
5. `AC-K101-05`: Real runtime-role evidence proves INSERT/SELECT succeeds and UPDATE/DELETE fails for every frozen immutable KBN relation.
|
5. `AC-K101-05`: Real runtime-role evidence proves INSERT/SELECT succeeds and UPDATE/DELETE fails for every frozen immutable KBN relation.
|
||||||
6. `AC-K101-06`: N-1/atomic activation/rollback, Vault/CA-overlap rotation/redaction, health/operator behavior, CI/deployment handoff, independent exact-head security review, and terminal-green CI evidence the foundation before KBN-100; after KBN-100, the real deployed-role immutable-operation certificate and Ultron approval release KBN-105.
|
6. `AC-K101-06`: N-1/atomic activation/rollback, Vault/CA-overlap rotation/redaction, health/operator behavior, CI/deployment handoff, independent exact-head security review, and terminal-green CI evidence the foundation before KBN-100; after KBN-100, the real deployed-role immutable-operation certificate and Ultron approval release KBN-105.
|
||||||
|
|||||||
@@ -14,9 +14,9 @@
|
|||||||
- [Workstream index](native-kanban-sot/INDEX.md) — artifact map, lane partition, and delivery order.
|
- [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.
|
- [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.
|
- [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.7 finite DDL closure, executable `mosaic`/`mosaic_extensions` relocation, 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.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.
|
||||||
- [Frozen shared contract](native-kanban-sot/SHARED-CONTRACT.md) — schema, API, Coordinator, health, recovery, and migration contracts.
|
- [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.7 awaits independent exact-head re-review of 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.8 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.
|
- [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.
|
- [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.
|
- [Ultron final gate](reports/native-kanban-sot/ultron-final-go.md) — final requirements, authority, schema, migration, recovery, and evidence review.
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ PGlite is real Postgres semantics in-process — including the row locks the ato
|
|||||||
claim relies on — so the **same code** runs on a laptop (embedded, single-host
|
claim relies on — so the **same code** runs on a laptop (embedded, single-host
|
||||||
default) and on a full Postgres deployment. Switching tiers is config-only.
|
default) and on a full Postgres deployment. Switching tiers is config-only.
|
||||||
|
|
||||||
The schema (`backlog` table) is created automatically on first CLI use:
|
For embedded PGlite only, the local backlog routine may prepare its local schema on first use. PostgreSQL never migrates on CLI first use: it requires the dedicated `mosaic-db-migrator --run` phase and its read-only runtime readiness check before `mosaic fleet backlog` connects.
|
||||||
`runMigrations()` for Postgres, `runPgliteMigrations()` for embedded PGlite.
|
|
||||||
|
|
||||||
### Update safety
|
### Update safety
|
||||||
|
|
||||||
|
|||||||
@@ -6,23 +6,23 @@
|
|||||||
|
|
||||||
## Artifacts
|
## Artifacts
|
||||||
|
|
||||||
| Artifact | Purpose |
|
| 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 |
|
| [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 |
|
| [`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 |
|
| [`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.7 frozen complete DDL inventory, executable `mosaic`/`mosaic_extensions` relocation, two-gateway TLS/bootstrap, role/search-path, activation, and one-card/one-PR contract; foundation prerequisite of KBN-100 and real-role gate before KBN-105 |
|
| [`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 |
|
| [`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/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/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/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 |
|
| [`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 |
|
| [`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 |
|
| [`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.7 awaits independent exact-head re-review for the later residual report |
|
| [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 |
|
| [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 |
|
| [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 |
|
| [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
|
## Recommended USC lane partition
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# KBN-101 — Database Runtime/Migration Role Split
|
# KBN-101 — Database Runtime/Migration Role Split
|
||||||
|
|
||||||
**Status:** frozen implementation contract; rc.7 residual remediation pending independent exact-head re-review for [#771](https://git.mosaicstack.dev/mosaicstack/stack/issues/771)
|
**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)
|
||||||
|
|
||||||
**Version:** 1.0.0-rc.7
|
**Version:** 1.0.0-rc.8
|
||||||
|
|
||||||
**Dependency:** KBN-010 → **KBN-101 foundation** → KBN-100 → **KBN-101 deployed-role certification** → KBN-105
|
**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.
|
**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.
|
||||||
@@ -27,13 +27,18 @@ Current `main` has one `DATABASE_URL` path in `packages/db/src/client.ts`, `migr
|
|||||||
|
|
||||||
## 2. The sole PostgreSQL DDL control plane
|
## 2. The sole PostgreSQL DDL control plane
|
||||||
|
|
||||||
`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 an external privileged platform/IaC bootstrap actor (§6), which is not an application command, never receives either application URL, and has its separately audited fixed bootstrap artifact.
|
`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.
|
||||||
|
|
||||||
|
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:
|
The implementation must inventory and close every present and future entrypoint as follows:
|
||||||
|
|
||||||
| Current entrypoint | Required rc.7 disposition |
|
| 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/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. |
|
| `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. |
|
| `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. |
|
| `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. |
|
||||||
@@ -46,10 +51,16 @@ The implementation must inventory and close every present and future entrypoint
|
|||||||
| `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. |
|
| `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`. |
|
| `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. |
|
| `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. |
|
| `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. |
|
| 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 static inventory containing every row above by exact path plus the existing `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`; it fails on an unclassified current DDL token, URL-consuming setup hook, init mount, or raw operator DDL guidance. The same card owns a `DATABASE_URL`-only denial matrix for **each inventory path** and both `gateway-a`/`gateway-b`: every negative must fail before connection/DDL, including missing migration URL, runtime-only fixture/test, direct Drizzle, `db:push`, init artifact, tier migration guidance, and each harness migration job/Gateway. The `db:push` negatives also cover production-like tier and production-like URL rejection.
|
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**.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
## 3. Exact migration manifest, ledger, and lock
|
## 3. Exact migration manifest, ledger, and lock
|
||||||
|
|
||||||
@@ -97,14 +108,15 @@ 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 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 |
|
| 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. |
|
| `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. |
|
| 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`; final ownership is only `mosaic`, `drizzle`, and `mosaic_extensions` schemas/objects. | Never an application login; no database/extension authority except reviewed bootstrap scope. |
|
| `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_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_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_runtime_capability` | `NOLOGIN` and no ownership/administrative attributes. | Holds only named runtime grants. |
|
| `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` | `LOGIN INHERIT` with no ownership/administrative attributes. | Only `mosaic_runtime_capability WITH INHERIT TRUE, SET FALSE, ADMIN FALSE`; never owner/migrator member. |
|
| `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 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.
|
||||||
|
|
||||||
@@ -112,11 +124,19 @@ The sole runner has one narrowly bounded **legacy-history bootstrap subphase** f
|
|||||||
|
|
||||||
`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`.
|
`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`.
|
||||||
|
|
||||||
The selected extension policy is fixed: external bootstrap creates `vector` fresh as `CREATE EXTENSION vector WITH SCHEMA mosaic_extensions`; `mosaic_extensions` is owned by `mosaic_schema_owner`, non-writable by runtime, and grants runtime only `USAGE`/read-only function access proven by catalog. Existing databases may execute `ALTER EXTENSION vector SET SCHEMA mosaic_extensions` only after a catalog eligibility check proves the exact supported `extversion`, `extrelocatable = true`, a complete expected extension-member set, and no dependent object that would change the selected qualification policy; any other version, false relocatability, extra/missing member, or partial prior move fails eligibility closed. `schema.ts` must emit `mosaic_extensions.vector(...)`, and all vector casts/operators/functions in runner, application queries, fixtures, and generated SQL must explicitly qualify `mosaic_extensions` (for example `OPERATOR(mosaic_extensions.<->)`); `mosaic_extensions` is deliberately **not** added to runtime `search_path`.
|
### 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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
A `vector` extension owned by a legacy runtime/single login is **not activated in place**. It fails closed before activation and requires this controlled shadow-database migration: (1) approved backup and read-only inventory; (2) create new database/roles; (3) privileged actor creates vector under `mosaic_extension_owner`; (4) sole runner applies migrations and relocation; (5) copy data with vector dimensions, row counts, checksums, FK, and sequence evidence; (6) quiesce/drain writers; (7) apply and verify final delta; (8) prove role/TLS/readiness; (9) atomically switch connections; and (10) retain the old database read-only for the approved rollback window. Partial/cancel/resume and rollback preserve the old read-only source until the switch; no target unable to shadow-migrate is eligible until separately reviewed. Required tests cover fresh, approved-owner clean existing relocation, legacy-owner shadow path, partial/resume/rollback, N-1, exact `extowner`/member/schema/version assertions, and ALTER/DROP/member-update denials for runtime, migrator, and schema owner.
|
||||||
|
|
||||||
|
`schema.ts` must emit `mosaic_extensions.vector(...)`, and all vector casts/operators/functions in runner, application queries, fixtures, and generated SQL must explicitly qualify `mosaic_extensions` (for example `OPERATOR(mosaic_extensions.<->)`); `mosaic_extensions` is deliberately **not** added to runtime `search_path`.
|
||||||
|
|
||||||
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.
|
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, current-public relocation, interrupted/partial relocation 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 and generated-artifact verification → 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`, and all extension eligibility negatives.
|
`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.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
@@ -126,7 +146,7 @@ Immutable KBN relations, after KBN-100 creates them, grant runtime only `SELECT,
|
|||||||
|
|
||||||
## 5. Deployable verified-TLS bootstrap
|
## 5. Deployable verified-TLS bootstrap
|
||||||
|
|
||||||
`mosaicstack/stack` is the named repository/control plane for KBN-101-00 and KBN-101-05. Those cards exclusively own the current `docker-compose.yml`, `docker-compose.federated.yml`, `deploy/portainer/federated-test.stack.yml`, and `tools/federation-harness/docker-compose.two-gateways.yml`, plus the new `apps/gateway/Dockerfile`, bootstrap renderer/templates, and rendered-config validation tests. The named **Mosaic deployment control plane / Jason** is activation authority; the environment-specific IaC/Vault owner supplies only the approved input secret versions and may not substitute an unreviewed current-repository artifact. The renderer is the only handoff: it reads secret-provider references, validates owners/modes/digests/SANs, writes each output atomically (`mkstemp` on the target tmpfs, `fsync`, `chmod`/`chown`, atomic rename), and records only secret-version identifiers and hashes.
|
`mosaicstack/stack` is the named repository/control plane. Ownership is intentionally non-overlapping: **KBN-101-00 exclusively owns** the versioned external bootstrap interface `infra/pg-bootstrap/roles.sql`, `infra/pg-bootstrap/extensions.sql`, and `infra/pg-bootstrap/README.md`, plus its bootstrap tests—roles, extension-owner transition, and no renderer/deployment manifests. **KBN-101-05 exclusively owns** `tools/db/render-postgres-secrets.ts`, its tests, the current `docker-compose.yml`, `docker-compose.federated.yml`, `deploy/portainer/federated-test.stack.yml`, `tools/federation-harness/docker-compose.two-gateways.yml`, and `apps/gateway/Dockerfile`; it consumes the versioned KBN-101-00 bootstrap interface and owns no bootstrap SQL. The named **Mosaic deployment control plane / Jason** is activation authority; the environment-specific IaC/Vault owner supplies only approved input secret versions and may not substitute an unreviewed current-repository artifact. The KBN-101-05 renderer is the only deployment handoff: it reads secret-provider references, validates owners/modes/digests/SANs, writes each output atomically (`mkstemp` on the target tmpfs, `fsync`, `chmod`/`chown`, atomic rename), and records only secret-version identifiers and hashes.
|
||||||
|
|
||||||
`KBN-101-05` changes the Gateway image to fixed non-root `USER 10001:10001`. Gateway CA and Gateway leaf-certificate mounts, and its own Gateway private key only when it terminates its HTTPS listener, must be readable by `10001:10001`; PostgreSQL private keys and migration-only material are never mounted there, and no secret is world-readable. PostgreSQL is not assigned a guessed UID/GID: its image must first be pinned by digest, and an image-inspection plus rendered Compose/Swarm test freezes the image's effective PostgreSQL UID:GID before the renderer selects mount owner/group. A digest, service UID/GID, rendered secret `uid`/`gid`/`mode`, or container `USER` mismatch is a KBN-101-05 failure. Mosaic applications never generate, self-sign, copy, or persist production certificates; the external bootstrap actor receives them only through the deployment secret mechanism and no plaintext development exception exists for production-like modes.
|
`KBN-101-05` changes the Gateway image to fixed non-root `USER 10001:10001`. Gateway CA and Gateway leaf-certificate mounts, and its own Gateway private key only when it terminates its HTTPS listener, must be readable by `10001:10001`; PostgreSQL private keys and migration-only material are never mounted there, and no secret is world-readable. PostgreSQL is not assigned a guessed UID/GID: its image must first be pinned by digest, and an image-inspection plus rendered Compose/Swarm test freezes the image's effective PostgreSQL UID:GID before the renderer selects mount owner/group. A digest, service UID/GID, rendered secret `uid`/`gid`/`mode`, or container `USER` mismatch is a KBN-101-05 failure. Mosaic applications never generate, self-sign, copy, or persist production certificates; the external bootstrap actor receives them only through the deployment secret mechanism and no plaintext development exception exists for production-like modes.
|
||||||
|
|
||||||
@@ -171,18 +191,18 @@ 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.
|
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 |
|
| Card | Depends on | Exact ownership and required result |
|
||||||
| ----------------------------------------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ----------------------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `KBN-101-00` platform bootstrap / IaC | contract | `mosaicstack/stack` owns the fixed external bootstrap artifact, its renderer/templates, and rendered validation; environment IaC/Vault is named deployment-owner input only. It creates/transitions roles, `mosaic`/`drizzle`/`mosaic_extensions` ownership, eligible vector bootstrap, Vault-to-secret bindings, service UID/GID declarations, server TLS config, fresh/existing inventory, and reversible evidence. It is not an app migration or runtime command. |
|
| `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-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 paths in §2 except runner/journal: storage, CLI, adapters, Gateway startup, tier probes, fleet backlog, and direct-DDL test closure. |
|
| `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/src/schema.ts`, generated snapshots/journal/migration, exact DB tests, `mosaic-db-migrator`, canonical Git-blob/LF manifest v1, fixed lock, journal logical-order repair, runner-only legacy-public bootstrap, `mosaic`/`mosaic_extensions` relocation/eligibility/rollback, ledger/manifest grants, and PostgreSQL runner tests. Shipped `0009` bytes remain unchanged. |
|
| `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-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 | `mosaicstack/stack` exclusively owns current local/federated Compose, Portainer test stack, the two-gateway harness, bootstrap renderer/templates, gateway `10001:10001`, verified PostgreSQL image UID/GID, secret references/targets, TLS server/client mounts, server configuration, one Job per database, readiness, standalone/federated/Swarm/two-gateway TLS tests, and no plaintext exception. |
|
| `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 static DDL inventory, every-path `DATABASE_URL`-only denial matrix, runner-prepared persistent pgvector fixture, and repository checks rejecting DDL bypasses/insecure URLs. |
|
| `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-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-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. |
|
| `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. |
|
||||||
|
|
||||||
**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.
|
**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.
|
||||||
|
|
||||||
@@ -190,16 +210,16 @@ Every KBN-101 card remains one PR with exclusive ownership. Cards `00`–`07` ma
|
|||||||
|
|
||||||
## 8. Acceptance traceability
|
## 8. Acceptance traceability
|
||||||
|
|
||||||
| Requirement / acceptance criterion | Required implementation evidence |
|
| Requirement / acceptance criterion | Required implementation evidence |
|
||||||
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| K101-REQ-01 / AC-K101-01 | DTO and command matrix covers local/PGlite, standalone, federated, and both harness pairs; every §2 inventory entry rejects `DATABASE_URL`-only before connection/DDL; no runtime fallback/default. |
|
| 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, contention/crash/readiness/unrelated-key tests; manifest-v1 canonical bytes/digest and all reconciliation states; Gateway/replica DDL impossibility. |
|
| 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; KBN-101-01/03 role, `pg_catalog,mosaic`, `mosaic_extensions` qualification, identifier, ownership, membership, TEMP, ledger/default-grant, and pool-reset tests. |
|
| 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/05 fresh/existing verified-TLS bootstrap and 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-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-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-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. |
|
| 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. |
|
| 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
|
## 9. Non-goals and residual authority
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
# Native Kanban/SOT — Remediated Shared Contract v1
|
# Native Kanban/SOT — Remediated Shared Contract v1
|
||||||
|
|
||||||
**Status:** CONTROL-PLANE rc.7 DB role/connection residual remediation pending 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
|
**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.7
|
**Version:** 1.0.0-rc.8
|
||||||
**Date:** 2026-07-15
|
**Date:** 2026-07-15
|
||||||
**Change authority:** Mosaic control plane/Jason only
|
**Change authority:** Mosaic control plane/Jason only
|
||||||
**SI-001 amendment authority:** `web1:mosaic-100` control-plane decision under issue #753
|
**SI-001 amendment authority:** `web1:mosaic-100` control-plane decision under issue #753
|
||||||
|
|
||||||
## Amendment record
|
## Amendment record
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
- **Executable exclusive cards:** KBN-101-03 alone publishes `mosaic-db-migrator` from `packages/db/package.json`/`src/cli.ts`, owns `docker/db-migrator.Dockerfile`, and keeps `{runner,config.dto,manifest,identity,tls}` private, with exact `--run|--verify|--help`, env-only input, stable exits, and command tests. KBN-101-00 alone owns `infra/pg-bootstrap/roles.sql`, `infra/pg-bootstrap/extensions.sql`, `infra/pg-bootstrap/README.md`, plus bootstrap tests. KBN-101-05 alone owns `tools/db/render-postgres-secrets.ts`, renderer tests, and Compose/Portainer/Swarm/two-gateway declarations, consuming the versioned bootstrap interface. No card overlaps renderer/bootstrap/deployment ownership.
|
||||||
|
- **Extension-owner transition:** `mosaic_extension_owner` is a dedicated NOLOGIN role whose membership/credentials never reach services; the external bootstrap actor alone may `SET ROLE` during bootstrap. Fresh vector and member objects retain that owner. PostgreSQL has no supported extension-owner alteration: approved-owner existing extension relocation validates `pg_extension.extowner`, members/schema/version and uses tested `ALTER EXTENSION ... SET SCHEMA`; legacy runtime-owned extension fails closed to a controlled shadow database migration with backup, evidence, quiesce/final delta, atomic switch, and read-only rollback window. No catalog mutation, ownership adoption, or `DROP CASCADE` is permitted. Runtime/migrator/schema-owner extension ALTER/DROP/member-update denial is mandatory.
|
||||||
|
- **Non-effect:** manifest v1, lock namespace, role/search-path, relocation/TLS/activation, KBN-100/KBN-105 serial gates, and all retained canon decisions are strengthened, not weakened. The normative detail remains [`KBN-101-DB-ROLE-SPLIT.md`](./KBN-101-DB-ROLE-SPLIT.md).
|
||||||
|
|
||||||
### 1.0.0-rc.7 — KBN-101 complete current-path, relocation, and two-gateway remediation
|
### 1.0.0-rc.7 — KBN-101 complete current-path, relocation, and two-gateway remediation
|
||||||
|
|
||||||
- **Finite current-path closure:** static inventory and the `DATABASE_URL`-only-before-connect/DDL denial matrix now explicitly include Gateway's former temporary-table pgvector test (runner-prepared persistent read/query-only fixture), `docker/init-db.sql` retirement, `migrate-tier.ts` runner/bootstrap-only guidance, and the active two-gateway harness. The harness is migrated, not retired: `postgres-a/b → mosaic-db-migrator-a/b → gateway-a/b`, each with isolated URL/CA material, verified readiness, SANs, and positive/negative TLS evidence.
|
- **Finite current-path closure:** static inventory and the `DATABASE_URL`-only-before-connect/DDL denial matrix now explicitly include Gateway's former temporary-table pgvector test (runner-prepared persistent read/query-only fixture), `docker/init-db.sql` retirement, `migrate-tier.ts` runner/bootstrap-only guidance, and the active two-gateway harness. The harness is migrated, not retired: `postgres-a/b → mosaic-db-migrator-a/b → gateway-a/b`, each with isolated URL/CA material, verified readiness, SANs, and positive/negative TLS evidence.
|
||||||
@@ -42,7 +49,7 @@
|
|||||||
|
|
||||||
## 1. Authority
|
## 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.7 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.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.
|
||||||
|
|
||||||
## 2. Health proof and exact failures
|
## 2. Health proof and exact failures
|
||||||
|
|
||||||
|
|||||||
@@ -95,14 +95,14 @@ No consumer implementation begins before KBN-105. No schema work begins before K
|
|||||||
|
|
||||||
### KBN-101 — PostgreSQL runtime/migration role split and deployed-role certification
|
### 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.7 closes the rc.6 exact-head residuals for complete current DDL paths, executable relocation, and active two-gateway TLS/bootstrap. It awaits independent exact-head re-review; implementation remains held.
|
- **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.
|
||||||
- **Owner:** Mos integration control plane; independently reviewed by security/Ultron.
|
- **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.
|
- **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 `mosaic-db-migrator` PostgreSQL DDL path and all legacy/future entrypoint closure; `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-owner/migrator/runtime roles; 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.
|
- **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.
|
- **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.
|
- **Depends on:** KBN-010 completed.
|
||||||
- **Contract surfaces:** [`KBN-101-DB-ROLE-SPLIT.md`](./KBN-101-DB-ROLE-SPLIT.md); `SHARED-CONTRACT.md` rc.7 amendment.
|
- **Contract surfaces:** [`KBN-101-DB-ROLE-SPLIT.md`](./KBN-101-DB-ROLE-SPLIT.md); `SHARED-CONTRACT.md` rc.8 amendment.
|
||||||
- **Evidence:** foundation: exact command/DTO entrypoint negatives for every finite current DDL/static-bypass path (including `DATABASE_URL`-only, runner fixture, retired init, sanitized 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; 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; 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.
|
- **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
|
### KBN-100 — Unified Drizzle schema and concrete N-1 migration
|
||||||
|
|
||||||
|
|||||||
@@ -96,3 +96,12 @@ Independent Codex review found two blockers and security review found two medium
|
|||||||
- **Plan:** (1) make the finite DDL/static-bypass inventory and `DATABASE_URL`-only denial matrix exact, including the runner-prepared persistent pgvector fixture and migrated two-gateway harness; (2) freeze executable `public`-to-`mosaic` and `mosaic_extensions` transition, Drizzle ownership, object-catalog classes/order, eligibility and rollback tests; (3) bind repository/control-plane ownership, UID/GID validation, exact artifact/mount rules, and both gateway TLS topology; (4) correct PRD acceptance mapping and cross-document rc.7 status; then run formatting, link/contract, source-path, diff, review, commit, queue guard, and push.
|
- **Plan:** (1) make the finite DDL/static-bypass inventory and `DATABASE_URL`-only denial matrix exact, including the runner-prepared persistent pgvector fixture and migrated two-gateway harness; (2) freeze executable `public`-to-`mosaic` and `mosaic_extensions` transition, Drizzle ownership, object-catalog classes/order, eligibility and rollback tests; (3) bind repository/control-plane ownership, UID/GID validation, exact artifact/mount rules, and both gateway TLS topology; (4) correct PRD acceptance mapping and cross-document rc.7 status; then run formatting, link/contract, source-path, diff, review, commit, queue guard, and push.
|
||||||
- **Independent review closure:** initial Codex review found Gateway-key consumer wording, `CLAUDE.md` omission, final schema-owner set, and placeholder SANs; all are now explicit. Re-review found the legacy `0001` vector-type resolution problem and `docs/federation/SETUP.md` raw-DDL instruction; the legacy runner now uses only its fixed non-writable `pg_catalog,public,mosaic_extensions` history path, while runtime remains `pg_catalog,mosaic`, and the federation setup path is assigned to KBN-101-07/static inventory. Security review final verdict: no confident vulnerability. The review also repeated the pre-existing tracked `.mosaic` session-state concern; it remains deliberately unstaged/excluded by this task.
|
- **Independent review closure:** initial Codex review found Gateway-key consumer wording, `CLAUDE.md` omission, final schema-owner set, and placeholder SANs; all are now explicit. Re-review found the legacy `0001` vector-type resolution problem and `docs/federation/SETUP.md` raw-DDL instruction; the legacy runner now uses only its fixed non-writable `pg_catalog,public,mosaic_extensions` history path, while runtime remains `pg_catalog,mosaic`, and the federation setup path is assigned to KBN-101-07/static inventory. Security review final verdict: no confident vulnerability. The review also repeated the pre-existing tracked `.mosaic` session-state concern; it remains deliberately unstaged/excluded by this task.
|
||||||
- **Completion evidence:** changed Markdown is Prettier-formatted; local links and strict native-kanban TypeScript passed; source-path inventory confirmed all current referenced paths (the new `apps/gateway/Dockerfile` is explicitly a planned KBN-101-05 artifact); diff check and authorized-doc allowlist passed. No source-code TDD applies to this documentation-only remediation.
|
- **Completion evidence:** changed Markdown is Prettier-formatted; local links and strict native-kanban TypeScript passed; source-path inventory confirmed all current referenced paths (the new `apps/gateway/Dockerfile` is explicitly a planned KBN-101-05 artifact); diff check and authorized-doc allowlist passed. No source-code TDD applies to this documentation-only remediation.
|
||||||
|
|
||||||
|
## 2026-07-15 — rc.8 exact residual remediation session
|
||||||
|
|
||||||
|
- **Objective / correction:** Close all three HIGH findings in the independent rc.7 exact-head re-review at `/home/hermes/agent-work/reviews/771-kbn101-contract-rereview2-0778eba.md` for `0778eba2db3c2dfbaca3af352b12ba0389d3552b`. Scope remains documentation-only: no source, config, Compose, CI, deployment, secret, or migration artifact changed; pre-existing `.mosaic/orchestrator` state remains excluded.
|
||||||
|
- **Finite authority closure:** KBN-101-06 now classifies exact current source/scripts/package bins, operator docs, and deploy manifests. `packages/db/src/index.ts` has explicit removal/compile-import negative ownership; `docs/fleet/backlog-conventions.md` and `docs/PERFORMANCE.md` now remove first-use/direct-Drizzle/Gateway-startup migration instructions and point to sole runner/readiness. Byte-immutable historical SQL, PGlite-only routines, negative-test literals, vendored/generated artifacts, and labeled historical reports are exact-path/category reviewed allowlists; unknown hits fail. The contract explicitly rejects relying on a naive token scan alone.
|
||||||
|
- **Executable and exclusive handoff closure:** KBN-101-03 exclusively owns the published `mosaic-db-migrator` bin, `packages/db/src/cli.ts`, private migrator modules, `docker/db-migrator.Dockerfile`, exact `--run|--verify|--help`, environment/argv limits, sanitized exits, and command/order tests. KBN-101-00 exclusively owns `infra/pg-bootstrap/roles.sql`, `infra/pg-bootstrap/extensions.sql`, `infra/pg-bootstrap/README.md`, and bootstrap tests. KBN-101-05 exclusively owns `tools/db/render-postgres-secrets.ts`, its tests, and deployment declarations, consuming the versioned bootstrap interface without overlap.
|
||||||
|
- **pgvector owner closure:** `mosaic_extension_owner` is dedicated NOLOGIN, available only to the external bootstrap actor during bootstrap; fresh vector/member ownership remains there. The contract records PostgreSQL's unsupported extension-owner transfer and forbids catalog mutation, ownership adoption, and `DROP CASCADE`. Approved-owner existing extensions use verified `ALTER EXTENSION ... SET SCHEMA`; legacy runtime-owned extensions fail closed to a controlled backup/shadow/runner/copy-evidence/quiesce/final-delta/atomic-switch/read-only-rollback migration. It requires `pg_extension.extowner`, member/schema/version, and runtime/migrator/schema-owner ALTER/DROP/member-update denial tests across clean, approved-owner, legacy shadow, partial/resume/rollback, and N-1.
|
||||||
|
- **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. Next: stage authorized docs only, commit, queue guard, push, and verify remote exact SHA; then await a fresh independent exact-head re-review.
|
||||||
|
|||||||
Reference in New Issue
Block a user