docs(#771): harden importer deployment contract
This commit is contained in:
@@ -1,28 +1,28 @@
|
||||
# Native Kanban/SOT Canon
|
||||
|
||||
**Status:** KCR-001–016 independently cleared; KBN-101 rc.11 target-attestation/operator-inventory remediation awaits independent exact-head re-review under issue [#771](https://git.mosaicstack.dev/mosaicstack/stack/issues/771)
|
||||
**Status:** KCR-001–016 independently cleared; KBN-101 rc.12 deployable importer-generation/SETUP-semantic remediation awaits independent exact-head re-review under issue [#771](https://git.mosaicstack.dev/mosaicstack/stack/issues/771)
|
||||
**Date:** 2026-07-14
|
||||
**Implementation hold:** no feature implementation starts until this canon is squash-merged to `main` with terminal-green CI; after merge, every slice remains held until its KBN prerequisite graph is satisfied.
|
||||
|
||||
## Artifacts
|
||||
|
||||
| Artifact | Purpose |
|
||||
| -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [Canonical requirements](../requirements/native-kanban-sot.md) | Canonical P0–P3 requirements, all seven ratified decisions, fixed invariants, thin MVP, recovery tiers, non-goals, and per-requirement acceptance criteria |
|
||||
| [`MISSION-MANIFEST.md`](./MISSION-MANIFEST.md) | Mission/authority boundaries, exact role chain, gate model, mandatory SecReview triggers, Certifier final/no-merge rule, and collision-free slice ownership |
|
||||
| [`TASKS.md`](./TASKS.md) | Dependency-ordered, bounded P0–P3 slices with IN/OUT scope, dependencies, shared contracts, file ownership, evidence, and USC coder2/3/4/5 parallelization |
|
||||
| [`KBN-101-DB-ROLE-SPLIT.md`](./KBN-101-DB-ROLE-SPLIT.md) | rc.11 PostgreSQL-valid pgvector owner exception; runner-signed target-bound importer attestation with file/digest/TLS/server/role/manifest binding; exhaustive operator-route inventory; exact disjoint card manifests, mechanical DDL classifier, executable `mosaic-db-migrator`, two-gateway TLS/bootstrap, role/search-path, atomic activation, and certification contract; foundation prerequisite of KBN-100 and real-role gate before KBN-105 |
|
||||
| [`SHARED-CONTRACT.md`](./SHARED-CONTRACT.md) | Remediated v1 integration contract: proof authority, exact failures/routes/DTOs/MCP ownership, concrete current-main field migration map, relational invariants, Coordinator split, recovery delivery |
|
||||
| [`contracts/kanban-schema.v1.ts`](./contracts/kanban-schema.v1.ts) | Drizzle target declarations including exact owner/principal membership, project congruence, tags/archive, proposals, persisted assignments, monotonic fences, durable retry, immutable evidence/audit |
|
||||
| [`contracts/mechanical-coordinator.v1.ts`](./contracts/mechanical-coordinator.v1.ts) | Pure snapshot decision engine separated from persistence/service adapter; ID-bound approvals, bigint-safe fences, durable retry/quarantine, artifact-backed checkpoints, exact failures |
|
||||
| [`contracts/health-state.v1.ts`](./contracts/health-state.v1.ts) | Discriminated public health, separate branded transaction-local write proof, and non-overlapping denial/transport/version-conflict mappings |
|
||||
| [`contracts/recovery-posture.v1.ts`](./contracts/recovery-posture.v1.ts) | Provider-neutral shape schema plus normative runtime refinement, cross-field constraints, and Lite/Standard/High-assurance defaults |
|
||||
| [`tsconfig.json`](./tsconfig.json) | Strict no-emit project scope for linting and compiling the four frozen TypeScript contracts against the current Stack Drizzle declarations |
|
||||
| [`DOCUMENTATION-CHECKLIST.md`](./DOCUMENTATION-CHECKLIST.md) | Publication documentation gate and implementation-slice deferrals |
|
||||
| [KBN-101 exact-head security review](../reports/native-kanban-sot/kbn-101-contract-security-review-82ce325.md) | Historical `da742ca` REQUEST CHANGES report retained as prior closure evidence; rc.11 awaits independent exact-head re-review after closing the target-attestation and operator-inventory HIGH findings |
|
||||
| [Initial independent review](../reports/native-kanban-sot/canon-initial-review-no-go.md) | KCR-001–016 findings that blocked the first draft |
|
||||
| [Final independent re-review](../reports/native-kanban-sot/canon-final-rereview-go.md) | Closure matrix, reproducible validation evidence, and GO verdict |
|
||||
| [Ultron final gate](../reports/native-kanban-sot/ultron-final-go.md) | Final requirements, authority, schema, migration, recovery, decomposition, and evidence review GO |
|
||||
| Artifact | Purpose |
|
||||
| -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [Canonical requirements](../requirements/native-kanban-sot.md) | Canonical P0–P3 requirements, all seven ratified decisions, fixed invariants, thin MVP, recovery tiers, non-goals, and per-requirement acceptance criteria |
|
||||
| [`MISSION-MANIFEST.md`](./MISSION-MANIFEST.md) | Mission/authority boundaries, exact role chain, gate model, mandatory SecReview triggers, Certifier final/no-merge rule, and collision-free slice ownership |
|
||||
| [`TASKS.md`](./TASKS.md) | Dependency-ordered, bounded P0–P3 slices with IN/OUT scope, dependencies, shared contracts, file ownership, evidence, and USC coder2/3/4/5 parallelization |
|
||||
| [`KBN-101-DB-ROLE-SPLIT.md`](./KBN-101-DB-ROLE-SPLIT.md) | rc.12 PostgreSQL-valid pgvector owner exception; Vault-authenticated importer URL/version generation with fixed isolated consumers/CA and sealed producer-to-importer attestation handoff, runner-signed target-bound attestation, and non-operative SETUP semantic closure; exhaustive operator-route inventory; exact disjoint card manifests, mechanical DDL classifier, executable `mosaic-db-migrator`, two-gateway TLS/bootstrap, role/search-path, atomic activation, and certification contract; foundation prerequisite of KBN-100 and real-role gate before KBN-105 |
|
||||
| [`SHARED-CONTRACT.md`](./SHARED-CONTRACT.md) | Remediated v1 integration contract: proof authority, exact failures/routes/DTOs/MCP ownership, concrete current-main field migration map, relational invariants, Coordinator split, recovery delivery |
|
||||
| [`contracts/kanban-schema.v1.ts`](./contracts/kanban-schema.v1.ts) | Drizzle target declarations including exact owner/principal membership, project congruence, tags/archive, proposals, persisted assignments, monotonic fences, durable retry, immutable evidence/audit |
|
||||
| [`contracts/mechanical-coordinator.v1.ts`](./contracts/mechanical-coordinator.v1.ts) | Pure snapshot decision engine separated from persistence/service adapter; ID-bound approvals, bigint-safe fences, durable retry/quarantine, artifact-backed checkpoints, exact failures |
|
||||
| [`contracts/health-state.v1.ts`](./contracts/health-state.v1.ts) | Discriminated public health, separate branded transaction-local write proof, and non-overlapping denial/transport/version-conflict mappings |
|
||||
| [`contracts/recovery-posture.v1.ts`](./contracts/recovery-posture.v1.ts) | Provider-neutral shape schema plus normative runtime refinement, cross-field constraints, and Lite/Standard/High-assurance defaults |
|
||||
| [`tsconfig.json`](./tsconfig.json) | Strict no-emit project scope for linting and compiling the four frozen TypeScript contracts against the current Stack Drizzle declarations |
|
||||
| [`DOCUMENTATION-CHECKLIST.md`](./DOCUMENTATION-CHECKLIST.md) | Publication documentation gate and implementation-slice deferrals |
|
||||
| [KBN-101 exact-head security review](../reports/native-kanban-sot/kbn-101-contract-security-review-82ce325.md) | Historical `da742ca` REQUEST CHANGES report retained as prior closure evidence; rc.12 awaits independent exact-head re-review after closing the deployable importer-material and federation-SETUP HIGH findings |
|
||||
| [Initial independent review](../reports/native-kanban-sot/canon-initial-review-no-go.md) | KCR-001–016 findings that blocked the first draft |
|
||||
| [Final independent re-review](../reports/native-kanban-sot/canon-final-rereview-go.md) | Closure matrix, reproducible validation evidence, and GO verdict |
|
||||
| [Ultron final gate](../reports/native-kanban-sot/ultron-final-go.md) | Final requirements, authority, schema, migration, recovery, decomposition, and evidence review GO |
|
||||
|
||||
## Recommended USC lane partition
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# KBN-101 — Database Runtime/Migration Role Split
|
||||
|
||||
**Status:** frozen implementation contract; rc.11 closes the target-bound importer-attestation and complete operator-document-inventory HIGH findings, awaiting independent exact-head re-review for [#771](https://git.mosaicstack.dev/mosaicstack/stack/issues/771)
|
||||
**Status:** frozen implementation contract; rc.12 closes the deployable importer-material and federation-SETUP indirect-DDL HIGH findings, awaiting independent exact-head re-review for [#771](https://git.mosaicstack.dev/mosaicstack/stack/issues/771)
|
||||
|
||||
**Version:** 1.0.0-rc.11
|
||||
**Version:** 1.0.0-rc.12
|
||||
|
||||
**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.
|
||||
@@ -35,44 +35,44 @@ The exact user-facing interface is `mosaic-db-migrator --run` and `mosaic-db-mig
|
||||
|
||||
The implementation must inventory and close every present and future entrypoint as follows:
|
||||
|
||||
| Current entrypoint | Required rc.11 disposition |
|
||||
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `packages/db/src/migrate.ts:runMigrations()` | Remove its optional URL, `DATABASE_URL`, and default fallback API from public/runtime exports. Its PostgreSQL behavior moves behind `mosaic-db-migrator`; callers cannot invoke it with an arbitrary URL. |
|
||||
| `packages/db/src/index.ts` | `KBN-101-03` removes the public `runMigrations` re-export; only the explicit PGlite-local API remains as separately typed local behavior. A compile/import-negative proves `@mosaicstack/db` cannot directly import `runMigrations`; a `DATABASE_URL`-only direct-library attempt fails before connect. |
|
||||
| `packages/db/drizzle.config.ts` and direct `drizzle-kit migrate` | A database-connecting Drizzle configuration reads only `DATABASE_MIGRATION_URL` through the migration DTO and rejects its absence before connection. Replace direct `drizzle-kit migrate` exposure with `mosaic-db-migrator`. `db:generate` is an offline schema artifact command and must neither resolve nor connect to a URL. |
|
||||
| `pnpm --filter @mosaicstack/db db:migrate` and CI invocation | Make it a thin `mosaic-db-migrator` wrapper; no direct Drizzle migrator invocation remains. CI supplies an isolated disposable migration URL only to that job. |
|
||||
| `db:push` / direct `drizzle-kit push` | Forbidden for standalone, federated, CI production-like, Portainer, and any URL outside a disposable developer database. If retained for local experimentation, a wrapper requires `MOSAIC_DISPOSABLE_DEVELOPER_DB=1`, a locally allowlisted disposable target, `DATABASE_MIGRATION_URL`, verified TLS when PostgreSQL is used, and rejects `DATABASE_URL`, any production-like tier, and every non-allowlisted host/database before connection. It is never a release, repair, or migration procedure. |
|
||||
| `mosaic storage migrate --run` | Delegates only to `mosaic-db-migrator`; it rejects `DATABASE_URL`-only execution before spawning or connecting. Its PGlite form remains explicitly local-only. |
|
||||
| `PostgresAdapter.migrate()`, Gateway `DatabaseModule`/startup, and PostgreSQL adapter factories | Runtime PostgreSQL migration is removed: no `runMigrations`, DDL, `CREATE EXTENSION`, or migration-compatible handle is reachable from startup. Gateway performs read-only identity, TLS, `search_path`, and manifest-ledger readiness checks only. |
|
||||
| `packages/mosaic/src/commands/fleet-backlog.ts` | PostgreSQL fleet backlog never migrates or creates tables. It consumes a ready runtime connection; PGlite may use only its explicit local migration routine. |
|
||||
| `packages/storage/src/{adapters/postgres,tier-detection}.ts` extension work and `infra/pg-init/01-extensions.sql` | Runtime probes become read-only catalog/extension-presence checks. Extension provisioning is a fixed external bootstrap prerequisite or a reviewed runner migration where the migrator has the required scoped authority; it is never a probe side effect or a reason to grant runtime database CREATE. |
|
||||
| `packages/db/src/federation.integration.test.ts` direct type/table/index DDL | `KBN-101-02` replaces it with a pre-migrated disposable database created by `mosaic-db-migrator`, or makes the test invoke that runner. The test itself has runtime credentials and no direct DDL. |
|
||||
| `apps/gateway/src/__tests__/integration/federated-pgvector.integration.test.ts` `CREATE TEMP TABLE` | `KBN-101-02` replaces the temporary runtime DDL with a runner-prepared disposable **persistent** `mosaic.federated_pgvector_fixture` database/table. The test receives only its runtime URL/CA and performs read/query-only qualified-vector assertions (including the selected vector operator); it has no setup hook, temporary privilege, or DDL. Runtime `TEMPORARY` remains denied. |
|
||||
| `docker/init-db.sql` and `infra/pg-init/01-extensions.sql` | `KBN-101-02` retires these duplicate tracked init artifacts; neither may remain as a hidden extension authority. The sole extension action is the fixed external bootstrap artifact described in §4/§5, or the runner only when its reviewed implementation card explicitly grants that authority. |
|
||||
| `packages/storage/src/{cli,migrate-tier}.ts` operator/runtime command closure | `KBN-101-02` alone replaces raw SQL/DDL behavior with delegation to `mosaic-db-migrator --run` (or the explicit PGlite-local path). Data copy requires the exact paired non-secret argv references `--target-url-file /run/secrets/mosaic_migrate_target_url` and `--target-attestation-file /run/mosaic-attestations/migrate-target.v1.json`. The trusted `mosaic-db-migrator --verify` producer reads the exact importer target-secret file only to bind and attest it; it never uses importer credentials for DDL/DML. Before target connection the importer verifies strict files, signed target attestation, credential-file digest/version, canonical TLS/database binding, role, manifest, expiry, and replay; after verified TLS but before transaction/DML it verifies server/database identity and schema. It opens only a dedicated non-DDL `mosaic_data_importer` target connection. Its DML registry is limited to declared mutable application tables and excludes schemas, roles, memberships, extensions, extension/catalog objects, Drizzle ledger, and immutable KBN relations. Raw `--target-url`, `DATABASE_URL` fallback, runtime-owner/importer role confusion, missing/unsafe/substituted files, stale/replayed/tampered/wrong-key attestation, wrong binding, and any DDL attempt fail before target connection/DDL or copy. KBN-101-07 documents that produced interface but owns neither source file. |
|
||||
| `tools/federation-harness/docker-compose.two-gateways.yml` | Active topology; `KBN-101-05` migrates it rather than retires it. It must contain `postgres-a`, `postgres-b`, `mosaic-db-migrator-a`, `mosaic-db-migrator-b`, `gateway-a`, and `gateway-b`; each database has separate runtime/migrator URL and CA consumers, TLS server material, verified-TLS readiness, and runner-before-Gateway ordering. Its existing plaintext URLs/init mount are forbidden. |
|
||||
| `docs/fleet/backlog-conventions.md` | `KBN-101-07` removes the current automatic first-use PostgreSQL `runMigrations()` claim. It points PostgreSQL operators to the sole runner/readiness sequence and labels only the PGlite routine as local-only. A documentation-route `DATABASE_URL`-only test asserts no first-use/migration instruction is executable before connect. |
|
||||
| `docs/PERFORMANCE.md` | `KBN-101-07` removes direct `drizzle-kit migrate` and Gateway-startup `runMigrations()` instructions. It points to the sole runner/readiness sequence. A documentation-route `DATABASE_URL`-only test asserts neither direct command nor Gateway fallback remains. |
|
||||
| `README.md`, `CLAUDE.md`, `docs/guides/{admin-guide,dev-guide,deployment,migrate-tier,user-guide}.md`, `docs/federation/{SETUP,TASKS}.md`, `docs/fleet/backlog-conventions.md`, `docs/PERFORMANCE.md`, `docs/design/storage-abstraction-middleware.md`, and `docs/plans/2026-03-15-agent-platform-architecture.md` documentation hits | `KBN-101-07` owns the non-normative disposition inventory in §2.2. It replaces, retires, or labels status-only every direct `db:migrate`, `db:push`, `CREATE EXTENSION`, first-use migration, Gateway-startup migration, and generic `mosaic storage migrate` instruction with the runner/bootstrap or secure `migrate-tier` route. The architecture plan explicitly marks direct `db:migrate` superseded. Historical shipped-status language is adjacent to an exact non-authorizing KBN-101 note. Documentation is a DDL entrypoint and cannot advertise a bypass. |
|
||||
| New package scripts, test helpers, setup hooks, CLI commands, installers, CI steps, adapters, or operator docs | A repository check rejects any new PostgreSQL DDL-capable entrypoint or instruction unless it is the dedicated runner or the named external bootstrap artifact. No future script may accept a URL parameter or `DATABASE_URL` as a DDL escape hatch. |
|
||||
| Current entrypoint | Required rc.12 disposition |
|
||||
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `packages/db/src/migrate.ts:runMigrations()` | Remove its optional URL, `DATABASE_URL`, and default fallback API from public/runtime exports. Its PostgreSQL behavior moves behind `mosaic-db-migrator`; callers cannot invoke it with an arbitrary URL. |
|
||||
| `packages/db/src/index.ts` | `KBN-101-03` removes the public `runMigrations` re-export; only the explicit PGlite-local API remains as separately typed local behavior. A compile/import-negative proves `@mosaicstack/db` cannot directly import `runMigrations`; a `DATABASE_URL`-only direct-library attempt fails before connect. |
|
||||
| `packages/db/drizzle.config.ts` and direct `drizzle-kit migrate` | A database-connecting Drizzle configuration reads only `DATABASE_MIGRATION_URL` through the migration DTO and rejects its absence before connection. Replace direct `drizzle-kit migrate` exposure with `mosaic-db-migrator`. `db:generate` is an offline schema artifact command and must neither resolve nor connect to a URL. |
|
||||
| `pnpm --filter @mosaicstack/db db:migrate` and CI invocation | Make it a thin `mosaic-db-migrator` wrapper; no direct Drizzle migrator invocation remains. CI supplies an isolated disposable migration URL only to that job. |
|
||||
| `db:push` / direct `drizzle-kit push` | Forbidden for standalone, federated, CI production-like, Portainer, and any URL outside a disposable developer database. If retained for local experimentation, a wrapper requires `MOSAIC_DISPOSABLE_DEVELOPER_DB=1`, a locally allowlisted disposable target, `DATABASE_MIGRATION_URL`, verified TLS when PostgreSQL is used, and rejects `DATABASE_URL`, any production-like tier, and every non-allowlisted host/database before connection. It is never a release, repair, or migration procedure. |
|
||||
| `mosaic storage migrate --run` | Delegates only to `mosaic-db-migrator`; it rejects `DATABASE_URL`-only execution before spawning or connecting. Its PGlite form remains explicitly local-only. |
|
||||
| `PostgresAdapter.migrate()`, Gateway `DatabaseModule`/startup, and PostgreSQL adapter factories | Runtime PostgreSQL migration is removed: no `runMigrations`, DDL, `CREATE EXTENSION`, or migration-compatible handle is reachable from startup. Gateway performs read-only identity, TLS, `search_path`, and manifest-ledger readiness checks only. |
|
||||
| `packages/mosaic/src/commands/fleet-backlog.ts` | PostgreSQL fleet backlog never migrates or creates tables. It consumes a ready runtime connection; PGlite may use only its explicit local migration routine. |
|
||||
| `packages/storage/src/{adapters/postgres,tier-detection}.ts` extension work and `infra/pg-init/01-extensions.sql` | Runtime probes become read-only catalog/extension-presence checks. Extension provisioning is a fixed external bootstrap prerequisite or a reviewed runner migration where the migrator has the required scoped authority; it is never a probe side effect or a reason to grant runtime database CREATE. |
|
||||
| `packages/db/src/federation.integration.test.ts` direct type/table/index DDL | `KBN-101-02` replaces it with a pre-migrated disposable database created by `mosaic-db-migrator`, or makes the test invoke that runner. The test itself has runtime credentials and no direct DDL. |
|
||||
| `apps/gateway/src/__tests__/integration/federated-pgvector.integration.test.ts` `CREATE TEMP TABLE` | `KBN-101-02` replaces the temporary runtime DDL with a runner-prepared disposable **persistent** `mosaic.federated_pgvector_fixture` database/table. The test receives only its runtime URL/CA and performs read/query-only qualified-vector assertions (including the selected vector operator); it has no setup hook, temporary privilege, or DDL. Runtime `TEMPORARY` remains denied. |
|
||||
| `docker/init-db.sql` and `infra/pg-init/01-extensions.sql` | `KBN-101-02` retires these duplicate tracked init artifacts; neither may remain as a hidden extension authority. The sole extension action is the fixed external bootstrap artifact described in §4/§5, or the runner only when its reviewed implementation card explicitly grants that authority. |
|
||||
| `packages/storage/src/{cli,migrate-tier}.ts` operator/runtime command closure | `KBN-101-02` alone replaces raw SQL/DDL behavior with delegation to `mosaic-db-migrator --run` (or the explicit PGlite-local path). Data copy requires the exact paired non-secret argv references `--target-url-file /run/secrets/mosaic-migrate-target-url` and `--target-attestation-file /run/mosaic-attestations/migrate-target.v1.json`, with the paired non-argv authenticated provider-version file `/run/secrets/mosaic-migrate-target-version`. The trusted `mosaic-db-migrator --verify` producer reads those exact importer materials only to bind and attest them; it never uses importer credentials for DDL/DML. Before target connection the importer verifies strict files, signed target attestation, credential-file digest/version, canonical TLS/database binding, role, manifest, expiry, and replay; after verified TLS but before transaction/DML it verifies server/database identity and schema. It opens only a dedicated non-DDL `mosaic_data_importer` target connection. Its DML registry is limited to declared mutable application tables and excludes schemas, roles, memberships, extensions, extension/catalog objects, Drizzle ledger, and immutable KBN relations. Raw `--target-url`, `DATABASE_URL` fallback, runtime-owner/importer role confusion, missing/unsafe/substituted files, stale/replayed/tampered/wrong-key attestation, wrong binding, and any DDL attempt fail before target connection/DDL or copy. KBN-101-07 documents that produced interface but owns neither source file. |
|
||||
| `tools/federation-harness/docker-compose.two-gateways.yml` | Active topology; `KBN-101-05` migrates it rather than retires it. It must contain `postgres-a`, `postgres-b`, `mosaic-db-migrator-a`, `mosaic-db-migrator-b`, `gateway-a`, and `gateway-b`; each database has separate runtime/migrator URL and CA consumers, TLS server material, verified-TLS readiness, and runner-before-Gateway ordering. Its existing plaintext URLs/init mount are forbidden. |
|
||||
| `docs/fleet/backlog-conventions.md` | `KBN-101-07` removes the current automatic first-use PostgreSQL `runMigrations()` claim. It points PostgreSQL operators to the sole runner/readiness sequence and labels only the PGlite routine as local-only. A documentation-route `DATABASE_URL`-only test asserts no first-use/migration instruction is executable before connect. |
|
||||
| `docs/PERFORMANCE.md` | `KBN-101-07` removes direct `drizzle-kit migrate` and Gateway-startup `runMigrations()` instructions. It points to the sole runner/readiness sequence. A documentation-route `DATABASE_URL`-only test asserts neither direct command nor Gateway fallback remains. |
|
||||
| `README.md`, `CLAUDE.md`, `docs/guides/{admin-guide,dev-guide,deployment,migrate-tier,user-guide}.md`, `docs/federation/{SETUP,TASKS}.md`, `docs/fleet/backlog-conventions.md`, `docs/PERFORMANCE.md`, `docs/design/storage-abstraction-middleware.md`, and `docs/plans/2026-03-15-agent-platform-architecture.md` documentation hits | `KBN-101-07` owns the non-normative disposition inventory in §2.2. It replaces, retires, or labels status-only every direct `db:migrate`, `db:push`, `CREATE EXTENSION`, first-use migration, Gateway-startup migration, and generic `mosaic storage migrate` instruction with the runner/bootstrap or secure `migrate-tier` route. The architecture plan explicitly marks direct `db:migrate` superseded. Historical shipped-status language is adjacent to an exact non-authorizing KBN-101 note. Documentation is a DDL entrypoint and cannot advertise a bypass. |
|
||||
| New package scripts, test helpers, setup hooks, CLI commands, installers, CI steps, adapters, or operator docs | A repository check rejects any new PostgreSQL DDL-capable entrypoint or instruction unless it is the dedicated runner or the named external bootstrap artifact. No future script may accept a URL parameter or `DATABASE_URL` as a DDL escape hatch. |
|
||||
|
||||
The runner must run the original migration bytes, including shipped `0009`; no migration command may repair a ledger by manual insertion, adoption, `db:push`, or schema diff. Tests requiring PostgreSQL schema consume a pre-migrated disposable database or invoke this exact runner.
|
||||
|
||||
`KBN-101-06` alone owns `.woodpecker/ci.yml`, `tools/ci/kbn101-ddl-inventory.ts`, `tools/ci/kbn101-ddl-inventory.spec.ts`, `tools/ci/fixtures/kbn101-ddl-inventory.json`, `tools/ci/kbn101-entrypoint-matrix.ts`, and `tools/ci/kbn101-entrypoint-matrix.spec.ts`. The scanner inventory is canonical JSON whose every record has exactly `path`, `class`, `ownerCard`, `disposition`, `allowedTokens`, `rationale`, `expiry`, and `reviewRevision`. `class` is one of `executable-source`, `script-or-package-bin`, `operator-document`, `deploy-manifest`, or `normative-contract`; `ownerCard` is one KBN-101 card; `disposition` is one of `runner`, `delegate`, `deny`, `retire`, `superseded-document`, `active-secure-data-migration`, `status-only`, or `allowlisted`; and `allowedTokens` is a nonempty subset of the fixed rules below only for `allowlisted` or `superseded-document`. `normative-contract` is excluded from **operator execution**, never from scanning: it is valid only for the exact KBN PRD/contract/shared/task canonical paths, must carry declarative requirements rather than an executable shell instruction, and a fenced executable instruction or an imperative bypass in that class fails rather than being masked. An `active-secure-data-migration` record has empty `allowedTokens` and additionally pins `route`, `targetCredentialOption`, `targetCredentialFile`, `targetAttestationOption`, `targetAttestationFile`, `attestationProducer`, `attestationKeyIds`, `attestationBindings`, `targetSchemaPrerequisite`, `targetConnectionRole`, `forbiddenInputs`, and `routeTest`; its parser rejects a missing field, a route that accepts a credential value on argv, an attestation missing any canonical binding, or a target that is not runner-prepared/verified. The latter `superseded-document` disposition is allowed only for the exact architecture-plan path when adjacent text says the direct command is superseded/MUST NOT run and names `mosaic-db-migrator --run`. The scanner rejects duplicate path owners, ownerless non-allowlisted rows, missing paths, malformed fields, an inventory path outside its declared class, and every unrecognized active command. The classifier's exact case-insensitive token/rule set is: `runMigrations\\s*\\(`; `drizzle-kit\\s+(?:migrate|push)`; `\\bdb:(?:migrate|push)\\b`; `mosaic\\s+storage\\s+migrate`; `CREATE\\s+(?:TEMP(?:ORARY)?\\s+)?(?:EXTENSION|TABLE|TYPE|INDEX|SCHEMA)`; `ALTER\\s+(?:EXTENSION|TABLE|TYPE|SCHEMA)`; `DROP\\s+(?:EXTENSION|TABLE|TYPE|INDEX|SCHEMA)`; and `DATABASE_URL` when it occurs in the same file as any preceding rule. It scans exact-path current executable source/scripts/package bins, operator documents, deploy manifests, and named normative contracts; any hit not represented by a permitted inventory record fails. The matrix harness invokes the compiled runner/package/image and produced deployment artifacts; it edits no producer file.
|
||||
`KBN-101-06` alone owns `.woodpecker/ci.yml`, `tools/ci/kbn101-ddl-inventory.ts`, `tools/ci/kbn101-ddl-inventory.spec.ts`, `tools/ci/fixtures/kbn101-ddl-inventory.json`, `tools/ci/kbn101-entrypoint-matrix.ts`, and `tools/ci/kbn101-entrypoint-matrix.spec.ts`. The scanner inventory has exactly the common fields `path`, `class`, `ownerCard`, `disposition`, `allowedTokens`, `rationale`, `expiry`, and `reviewRevision`; each disposition then has its separately required fields. `class` is one of `executable-source`, `script-or-package-bin`, `operator-document`, `deploy-manifest`, or `normative-contract`; `ownerCard` is one KBN-101 card; `disposition` is one of `runner`, `delegate`, `deny`, `retire`, `superseded-document`, `active-secure-data-migration`, `status-only`, or `allowlisted`; and `allowedTokens` is a nonempty subset of the fixed rules below only for `allowlisted` or `superseded-document`. `normative-contract` is excluded from **operator execution**, never from scanning: it is valid only for the exact KBN PRD/contract/shared/task canonical paths, must carry declarative requirements rather than an executable shell instruction, and a fenced executable instruction or an imperative bypass in that class fails rather than being masked. An `active-secure-data-migration` record has empty `allowedTokens` and additionally requires `route`, `targetCredentialOption`, `targetCredentialFile`, `targetCredentialVersionFile`, `targetAttestationOption`, `targetAttestationFile`, `attestationProducer`, `attestationKeyIds`, `attestationBindings`, `targetSchemaPrerequisite`, `targetConnectionRole`, `forbiddenInputs`, and `routeTest`; its parser rejects a missing common or disposition-specific field, a route that accepts a credential value on argv, an attestation missing any canonical binding, or a target that is not runner-prepared/verified. The latter `superseded-document` disposition is allowed only for the exact architecture-plan path when adjacent text says the direct command is superseded/MUST NOT run and names `mosaic-db-migrator --run`. The scanner rejects duplicate path owners, ownerless non-allowlisted rows, missing paths, malformed fields, an inventory path outside its declared class, and every unrecognized active command. The classifier's exact case-insensitive token/rule set is: `runMigrations\\s*\\(`; `drizzle-kit\\s+(?:migrate|push)`; `\\bdb:(?:migrate|push)\\b`; `mosaic\\s+storage\\s+migrate`; `CREATE\\s+(?:TEMP(?:ORARY)?\\s+)?(?:EXTENSION|TABLE|TYPE|INDEX|SCHEMA)`; `ALTER\\s+(?:EXTENSION|TABLE|TYPE|SCHEMA)`; `DROP\\s+(?:EXTENSION|TABLE|TYPE|INDEX|SCHEMA)`; and `DATABASE_URL` when it occurs in the same file as any preceding rule. Independently of those lexical rules, every operator document and deploy manifest receives a path-level semantic assertion that rejects an operative `extension`, `schema`, or `migration` described as `created`, `installed`, or `applied automatically` on `first boot` or `startup`; a `docker compose ... up`/Compose-up/start-first sequence before `mosaic-db-migrator --run` and `--verify`; and any init-script/init-SQL authority. The semantic assertion runs before inventory disposition: a named path, `status-only`, `normative-contract`, or any other record can never suppress it. The fixture includes the former `docs/federation/SETUP.md` wording as a failing regression and the rc.12 non-operative sequence as a passing fixture. It scans exact-path current executable source/scripts/package bins, operator documents, deploy manifests, and named normative contracts; any lexical or semantic hit not represented by a permitted record fails. The matrix harness invokes the compiled runner/package/image and produced deployment artifacts; it edits no producer file.
|
||||
|
||||
The canonical inventory includes this active—not historical—operator route record: `path=docs/guides/migrate-tier.md`, `class=operator-document`, `ownerCard=KBN-101-07`, `disposition=active-secure-data-migration`, `allowedTokens=[]`, `route=mosaic storage migrate-tier`, `targetCredentialOption=--target-url-file`, `targetCredentialFile=/run/secrets/mosaic_migrate_target_url`, `targetAttestationOption=--target-attestation-file`, `targetAttestationFile=/run/mosaic-attestations/migrate-target.v1.json`, `attestationProducer=mosaic-db-migrator --verify`, `attestationKeyIds=[migrate-target-v1-active,migrate-target-v1-overlap]`, `attestationBindings=[credentialSecretVersion,credentialFileSha256,tlsHostPortDatabase,caSpkiFingerprint,postgresSystemIdentifier,databaseOid,expectedImporterRole,manifestFingerprint,schemaFingerprint]`, `targetSchemaPrerequisite=mosaic-db-migrator --verify`, `targetConnectionRole=mosaic_data_importer`, `forbiddenInputs=[--target-url,DATABASE_URL,runtime-owner,signing-key]`, and `routeTest=packages/storage/src/migrate-tier.spec.ts::secureTargetRouteAndAttestation`. The -06 scanner/matrix must reject a changed/missing field, any `--target-url` or credential-bearing argv, a `DATABASE_URL` target fallback, a missing/unsafe/substituted credential file, missing/stale/replayed/tampered/wrong-key attestation, wrong binding, wrong mode, runtime-owner/importer confusion, target connection before attestation verification, or any DDL attempt before target connection/DDL.
|
||||
The canonical inventory includes this active—not historical—operator route record: `path=docs/guides/migrate-tier.md`, `class=operator-document`, `ownerCard=KBN-101-07`, `disposition=active-secure-data-migration`, `allowedTokens=[]`, `route=mosaic storage migrate-tier`, `targetCredentialOption=--target-url-file`, `targetCredentialFile=/run/secrets/mosaic-migrate-target-url`, `targetCredentialVersionFile=/run/secrets/mosaic-migrate-target-version`, `targetAttestationOption=--target-attestation-file`, `targetAttestationFile=/run/mosaic-attestations/migrate-target.v1.json`, `attestationProducer=mosaic-db-migrator --verify`, `attestationKeyIds=[migrate-target-v1-active,migrate-target-v1-overlap]`, `attestationBindings=[credentialSecretVersion,credentialFileSha256,tlsHostPortDatabase,caSpkiFingerprint,postgresSystemIdentifier,databaseOid,expectedImporterRole,manifestFingerprint,schemaFingerprint]`, `targetSchemaPrerequisite=mosaic-db-migrator --verify`, `targetConnectionRole=mosaic_data_importer`, `forbiddenInputs=[--target-url,DATABASE_URL,runtime-owner,signing-key]`, and `routeTest=packages/storage/src/migrate-tier.spec.ts::secureTargetRouteAndAttestation`. The -06 scanner/matrix must reject a changed/missing field, any `--target-url` or credential-bearing argv, a `DATABASE_URL` target fallback, a missing/unsafe/substituted credential or authenticated-version file, mixed URL/version generation, missing/wrong importer CA mount, missing/stale/replayed/tampered/wrong-key attestation, wrong binding, wrong mode/owner/link count, runtime-owner/importer confusion, target connection before attestation verification, or any DDL attempt before target connection/DDL.
|
||||
|
||||
### 2.1 Target-bound importer attestation v1
|
||||
|
||||
`mosaic-db-migrator --verify` is the trusted producer only after its verified-TLS identity, manifest/ledger, and schema checks pass. Its root-owned launch wrapper is the sole reader of the fixed `MOSAIC_DB_ATTESTATION_SIGNING_KEY_FILE=/run/secrets/mosaic-db-migrate-target-ed25519` reference: that regular, non-symlink `root:root` `0400` Ed25519 private-key file is mounted only to the one-shot runner. It opens the key once, passes signing capability only in memory to `mosaic-db-migrator`, and never mounts, forwards, logs, prints, or otherwise exposes the private key to the importer, runtime, or an application container. KBN-101-05 renders both that runner-only secret and the importer-only pinned public-key/key-ring mount; an alternative env path, unsafe key file, or key material in importer/runtime is a hard failure.
|
||||
|
||||
After verification the runner atomically emits the credential-free, non-secret `0444` controlled artifact `/run/mosaic-attestations/migrate-target.v1.json`: write a same-directory `0600` temporary file, write canonical bytes, `fsync` file and directory, set final owner/mode, and rename atomically. The single JSON envelope carries an RFC 8785 JCS canonical UTF-8 `attestation` payload plus a detached Ed25519 `signature` envelope (`algorithm`, `keyId`, base64 signature); the signature covers only the canonical payload bytes, never a reformatted document. The v1 payload fields are exactly `format`, `version`, `keyId`, `issuedAt`, `expiresAt`, `nonce`, `targetCredentialSecretVersion`, `targetCredentialFileSha256`, `tlsHost`, `tlsPort`, `database`, `caSpkiFingerprint`, `postgresSystemIdentifier`, `databaseOid`, `expectedImporterRole`, `manifestFingerprint`, `schemaFingerprint`, `producerInvocation`, `producerBuildDigest`, `producerImageDigest`, and `correlationId`. It contains no URL/DSN, username, password, private key, or credential bytes. The target credential must be a high-entropy DSN secret because its SHA-256 is non-secret binding evidence, never a substitute secret.
|
||||
After verification the `10003:10003` migrator atomically emits the credential-free, non-secret producer artifact to its **producer-only** handoff mount `/run/mosaic-attestations-producer/migrate-target.v1.json`: write a same-directory `0600` temporary file, write canonical bytes, `fsync` file and directory, set final `10003:10003` `0400` owner/mode, and rename atomically. A privileged deployment handoff controller runs only after runner success and before importer creation. It receives neither importer URL bytes nor private key: only a root-owned non-secret `0400` renderer generation descriptor (expected provider version, URL SHA-256, generation ID) and pinned public verifier key. It safe-opens/verifies that descriptor and the signed artifact against expected bindings, copies exact bytes into a new importer-only mount, fsyncs file/directory, sets `10002:10002` `0400`, and atomically renames `/run/mosaic-attestations/migrate-target.v1.json`. The controller then seals that importer mount read-only and starts the importer. It never alters payload bytes, forwards URL/version/key material, or exposes either mount to Gateway/runtime/unrelated containers; a controller failure leaves no importer process. The producer and importer never share a writable file or mount. The single JSON envelope carries an RFC 8785 JCS canonical UTF-8 `attestation` payload plus a detached Ed25519 `signature` envelope (`algorithm`, `keyId`, base64 signature); the signature covers only the canonical payload bytes, never a reformatted document. The v1 payload fields are exactly `format`, `version`, `keyId`, `issuedAt`, `expiresAt`, `nonce`, `targetCredentialSecretVersion`, `targetCredentialFileSha256`, `tlsHost`, `tlsPort`, `database`, `caSpkiFingerprint`, `postgresSystemIdentifier`, `databaseOid`, `expectedImporterRole`, `manifestFingerprint`, `schemaFingerprint`, `producerInvocation`, `producerBuildDigest`, `producerImageDigest`, and `correlationId`. It contains no URL/DSN, username, password, private key, or credential bytes. The target credential must be a high-entropy DSN secret because its SHA-256 is non-secret binding evidence, never a substitute secret.
|
||||
|
||||
For binding, the runner receives and reads the exact importer target-secret file only after `lstat` regular-file/no-symlink/owner/mode checks. It derives the secret version and SHA-256 from those exact bytes, parses only canonical TLS host/port/database without retaining username/password, verifies that tuple plus CA/SPKI, PostgreSQL system identifier, database OID, manifest/schema fingerprints, and expected `mosaic_data_importer` role against its verified target, then signs. The runner uses `DATABASE_MIGRATION_URL` for its verification connection; it does not use importer credentials for DDL or DML.
|
||||
For binding, the renderer obtains the importer URL `url` and its authenticated provider version from the **same successful Vault KV-v2 response** at canonical path `secret-{env}/mosaic-stack/database/importer`: `data.data.url` and `data.metadata.version`. The version is never inferred from DSN bytes, a hash, a filename, or an unverified side channel. The renderer treats exact URL bytes plus this metadata version as one generation and produces separately mounted immutable copies for the migrator-attestation producer and importer consumer. The migrator opens each copy only with `O_RDONLY|O_CLOEXEC|O_NOFOLLOW`, validates from the opened fd with `fstat` that it is a regular file with its exact fixed owner, `0400` mode, and link count `1`, then digests the URL from that fd and reads the authenticated version from its paired fd. It reads these importer-only materials solely to bind/sign; it never connects, performs DDL/DML, forwards, exports, logs, or passes either URL/version to a child environment. It zeroizes protected URL memory and closes both fds after signing. The runner uses `DATABASE_MIGRATION_URL` for its verification connection; it does not use importer credentials for DDL or DML.
|
||||
|
||||
`mosaic storage migrate-tier` accepts exactly `--target-url-file /run/secrets/mosaic_migrate_target_url` and `--target-attestation-file /run/mosaic-attestations/migrate-target.v1.json`. Before **any** target connection it `lstat`s both files; validates the pinned public key/key ID, signature, JCS canonicality, expiry, nonce replay cache, secret version, target-file digest, canonical host/port/database, CA binding, expected importer role, and manifest/schema fields; then opens the validated URL fd once, digests and parses those in-memory bytes, and connects from those same bytes with no reread. Missing, substituted, changed-after-check, stale, replayed, tampered, wrong-key, or wrong-binding inputs return stable sanitized attestation errors with **zero target connection and zero DDL**. The nonce replay cache is durable through the artifact expiry window and atomically claims `(keyId, nonce, credentialFileSha256)` before connecting; a replay is terminal. New active and overlap public keys are pinned by key ID; rotation accepts only the bounded overlap, revocation removes a key immediately, and any credential secret-version rotation invalidates prior artifacts and requires a fresh runner verification/signature.
|
||||
`mosaic storage migrate-tier` accepts exactly `--target-url-file /run/secrets/mosaic-migrate-target-url` and `--target-attestation-file /run/mosaic-attestations/migrate-target.v1.json`; the paired authenticated provider-version file is fixed, non-argv `/run/secrets/mosaic-migrate-target-version`. Before **any** target connection it safe-opens the URL, version, attestation, and pinned public-key files with `O_RDONLY|O_CLOEXEC|O_NOFOLLOW`, verifies post-open `fstat` regular-file/exact-owner/`0400`/link-count-one invariants, and validates public key/key ID, JCS signature/canonicality, expiry, nonce replay cache, authenticated provider version, URL-fd digest, canonical host/port/database, the CA file at exact `DATABASE_TLS_CA_CERT_PATH`, expected importer role, and manifest/schema fields. It reads URL bytes once into protected memory, digests/parses/connects from those exact bytes with no reread, then zeroizes memory and closes fds. Missing, substituted, symlinked, hard-linked, wrong-owner, wrong-mode, changed-after-open, mixed-generation, stale, replayed, tampered, wrong-key, revoked, missing-CA, wrong-mount, or wrong-binding inputs return stable sanitized errors with **zero target connection and zero DDL**. The nonce replay cache is durable through the artifact expiry window and atomically claims `(keyId, nonce, credentialFileSha256)` before connecting; a replay is terminal. A connecting dry-run consumes this nonce and MUST obtain fresh `mosaic-db-migrator --verify`, a new artifact handoff, and a new nonce before any `--yes` copy; tests prove the old artifact is rejected. New active and overlap public keys are pinned by key ID; rotation accepts only the bounded overlap, revocation removes a key immediately, and a provider version rotation invalidates the old attestation and requires a freshly rendered generation and runner verification/signature.
|
||||
|
||||
Only after verified TLS connection and before transaction/DML, the importer compares server system identifier, database OID, `current_user`, CA/SPKI, and manifest/schema fingerprint with the attestation. A mismatch closes the connection with **zero DML/DDL**. Its grants and statement classifier make DDL impossible. KBN-101-02 tests missing/wrong/stale/replayed/tampered attestation, wrong/revoked key, substituted URL file, file changed after check, wrong host/database/CA/role/manifest/system ID, digest/version mismatch, and both `zero target connection` versus `connection then zero DML` outcomes. KBN-101-03 tests JCS/signing/atomic producer semantics; KBN-101-05 tests private/public key and artifact mounts/rendering; KBN-101-06 invokes the complete matrix; KBN-101-07 owns the operator guide only.
|
||||
Only after verified TLS connection and before transaction/DML, the importer compares server system identifier, database OID, `current_user`, CA/SPKI, and manifest/schema fingerprint with the attestation. A mismatch closes the connection with **zero DML/DDL**. Its grants and statement classifier make DDL impossible. KBN-101-02 tests consumer isolation, absent/wrong CA mount, missing/wrong/stale/replayed/tampered attestation, wrong/revoked key, substituted URL/version file, symlink/hardlink/mode/owner/TOCTOU rejection, mixed URL/version generation, provider rotation/revocation, wrong host/database/CA/role/manifest/system ID, digest/version mismatch, no URL/version/attestation/key logging or error oracle, and both `zero target connection` versus `connection then zero DML` outcomes. KBN-101-03 tests JCS/signing/atomic producer and fd-zeroization/close semantics; KBN-101-05 tests generation-pinned private/public key, URL/version, CA, and artifact mounts/rendering; KBN-101-06 invokes the complete matrix; KBN-101-07 owns the operator guide only.
|
||||
|
||||
### 2.2 Complete current documentation disposition inventory
|
||||
|
||||
@@ -169,22 +169,24 @@ Immutable KBN relations, after KBN-100 creates them, grant runtime only `SELECT,
|
||||
|
||||
`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`, the importer image to fixed non-root `USER 10002:10002`, and the migrator process to fixed non-root `USER 10003:10003`; image and renderer tests freeze every UID:GID. A root-only migrator launch wrapper may open the private signing key before dropping to `10003:10003`, but the migrator process never regains root. 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.
|
||||
|
||||
| Material | Vault target / deployment secret | Mount, injection, and authorized consumer |
|
||||
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Runtime URL | `secret-{env}/mosaic-stack/database/runtime` (`url`) → `mosaic-db-runtime-url-v1` | Gateway only: `/run/secrets/mosaic-db-runtime-url`, `0600`, `10001:10001`; entrypoint maps it to `DATABASE_URL` only at process exec. It is denied to every migrator, storage runtime, fleet, ordinary CLI, and test except an explicit runtime-negative fixture. |
|
||||
| Migration URL | `secret-{env}/mosaic-stack/database/migrator` (`url`) → `mosaic-db-migrator-url-v1` | Each one-shot migrator only: `/run/secrets/mosaic-db-migrator-url`, `0600`, fixed migrator UID:GID asserted by the image/render test; entrypoint maps it only to `DATABASE_MIGRATION_URL`. It is denied to Gateway, storage runtime, fleet, and ordinary CLI. |
|
||||
| Attestation signing key | `secret-{env}/mosaic-stack/database/migrate-target-attestation` (`private_key`) → `mosaic-db-migrate-target-ed25519-v1` | Runner root-wrapper only: fixed `/run/secrets/mosaic-db-migrate-target-ed25519`, `root:root` `0400`, referenced only by `MOSAIC_DB_ATTESTATION_SIGNING_KEY_FILE`; no importer/runtime/Gateway mount or log/export is permitted. |
|
||||
| Attestation public key ring | versioned deployment public-key bundle → `mosaic-db-migrate-target-ed25519-public-v1` | Importer only: pinned `/run/mosaic-attestations/migrate-target.ed25519.pub`, `0444`; active/overlap key IDs are explicit and revoked IDs fail closed. It contains no private key. |
|
||||
| Target attestation artifact | runner-produced non-secret file | Controlled shared mount `/run/mosaic-attestations/migrate-target.v1.json`, `0444`, atomic write/rename only; importer may read it but cannot write it. |
|
||||
| CA bundle | `secret-{env}/mosaic-stack/database/tls-ca` (`certificate`) → `mosaic-db-ca-v1` | Gateway/migrator: `/run/secrets/mosaic-db-ca.crt`, `0444`, owned by the consuming UID:GID; CA is public trust material. PostgreSQL receives a distinct read-only CA copy only when client-cert validation is enabled. |
|
||||
| Gateway leaf certificate | `secret-{env}/mosaic-stack/federation/gateway-server-tls` (`certificate`) → `mosaic-gateway-server-cert-v1` | Gateway only: `/run/secrets/mosaic-gateway-server.crt`, `0444`, `10001:10001`; renderer emits this exact Compose and Swarm target and validates it before start. |
|
||||
| Gateway private key | same Vault record (`private_key`) → `mosaic-gateway-server-key-v1` | Gateway only: `/run/secrets/mosaic-gateway-server.key`, `0400`, `10001:10001`; not mounted to migrator or PostgreSQL and never world-readable. |
|
||||
| PostgreSQL leaf certificate | `secret-{env}/mosaic-stack/database/postgres-server-tls` (`certificate`) → `mosaic-postgres-server-cert-v1` | PostgreSQL only: `/run/secrets/mosaic-postgres-server.crt`, `0444`, frozen verified postgres UID:GID. |
|
||||
| PostgreSQL private key | same Vault record (`private_key`) → `mosaic-postgres-server-key-v1` | PostgreSQL only: `/run/secrets/mosaic-postgres-server.key`, `0400`, frozen verified postgres UID:GID; never mounted to Gateway or migrator. |
|
||||
| Material | Vault target / deployment secret | Mount, injection, and authorized consumer |
|
||||
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- |
|
||||
| Runtime URL | `secret-{env}/mosaic-stack/database/runtime` (`url`) → `mosaic-db-runtime-url-v1` | Gateway only: `/run/secrets/mosaic-db-runtime-url`, `0600`, `10001:10001`; entrypoint maps it to `DATABASE_URL` only at process exec. It is denied to every migrator, storage runtime, fleet, ordinary CLI, and test except an explicit runtime-negative fixture. |
|
||||
| Migration URL | `secret-{env}/mosaic-stack/database/migrator` (`url`) → `mosaic-db-migrator-url-v1` | Each one-shot migrator only: `/run/secrets/mosaic-db-migrator-url`, `0600`, fixed migrator UID:GID asserted by the image/render test; entrypoint maps it only to `DATABASE_MIGRATION_URL`. It is denied to Gateway, storage runtime, fleet, and ordinary CLI. |
|
||||
| Importer target URL + provider version | **Vault KV-v2** `secret-{env}/mosaic-stack/database/importer` (`url`) with the same successful response `data.metadata.version` → generation-pinned `mosaic-db-importer-url-v<version>` / `mosaic-db-importer-version-v<version>` | The renderer consumes value and authenticated provider version as one generation, never derives version from DSN bytes. It renders separate immutable copies: migrator-attestation producer only gets `/run/secrets/mosaic-migrate-target-url` and `/run/secrets/mosaic-migrate-target-version`, each `10003:10003` `0400`; importer only gets the same two fixed paths, each `10002:10002` `0400`. Each consumer receives its own read-only mount, never a shared writable file. Runtime, Gateway, ordinary CLI, fleet, and unrelated containers receive neither file nor version. |
|
||||
| Attestation signing key | `secret-{env}/mosaic-stack/database/migrate-target-attestation` (`private_key`) → `mosaic-db-migrate-target-ed25519-v1` | Runner root-wrapper only: fixed `/run/secrets/mosaic-db-migrate-target-ed25519`, `root:root` `0400`, referenced only by `MOSAIC_DB_ATTESTATION_SIGNING_KEY_FILE`; it opens once then drops to migrator `10003:10003`. No importer/runtime/Gateway mount or log/export is permitted. |
|
||||
| Attestation public key ring | versioned deployment public-key bundle → `mosaic-db-migrate-target-ed25519-public-v1` | Importer only: pinned `/run/mosaic-attestations/migrate-target.ed25519.pub`, `10002:10002` `0400`; active/overlap key IDs are explicit and revoked IDs fail closed. It contains no private key. |
|
||||
| Handoff verifier inputs | root-owned non-secret generation descriptor (expected provider version, URL SHA-256, generation ID) plus pinned public verifier key | Privileged controller only: `0400`; no importer URL bytes or private key. It verifies artifact bindings before copy/start. |
|
||||
| Target attestation artifact | runner-produced non-secret file | Migrator writes only `/run/mosaic-attestations-producer/migrate-target.v1.json`, `10003:10003` `0400`, on a producer-only mount. After runner success, privileged deployment handoff controller verifies and atomically copies the exact signed bytes to a distinct importer-only `/run/mosaic-attestations/migrate-target.v1.json` mount, `10002:10002` `0400`, seals it read-only, then creates importer. No importer write access, shared writable mount, Gateway/runtime access, or unrelated-container mount exists. | |
|
||||
| CA bundle | `secret-{env}/mosaic-stack/database/tls-ca` (`certificate`) → generation-pinned `mosaic-db-ca-v<version>` | Explicit DB-client consumers only: Gateway `/run/secrets/mosaic-db-ca.crt` `10001:10001` `0444`; migrator same path `10003:10003` `0444`; importer at the exact `DATABASE_TLS_CA_CERT_PATH=/run/secrets/mosaic-db-ca.crt`, `10002:10002` `0444`. PostgreSQL receives a distinct read-only CA copy only when client-cert validation is enabled; no unrelated container receives it. |
|
||||
| Gateway leaf certificate | `secret-{env}/mosaic-stack/federation/gateway-server-tls` (`certificate`) → `mosaic-gateway-server-cert-v1` | Gateway only: `/run/secrets/mosaic-gateway-server.crt`, `0444`, `10001:10001`; renderer emits this exact Compose and Swarm target and validates it before start. |
|
||||
| Gateway private key | same Vault record (`private_key`) → `mosaic-gateway-server-key-v1` | Gateway only: `/run/secrets/mosaic-gateway-server.key`, `0400`, `10001:10001`; not mounted to migrator or PostgreSQL and never world-readable. |
|
||||
| PostgreSQL leaf certificate | `secret-{env}/mosaic-stack/database/postgres-server-tls` (`certificate`) → `mosaic-postgres-server-cert-v1` | PostgreSQL only: `/run/secrets/mosaic-postgres-server.crt`, `0444`, frozen verified postgres UID:GID. |
|
||||
| PostgreSQL private key | same Vault record (`private_key`) → `mosaic-postgres-server-key-v1` | PostgreSQL only: `/run/secrets/mosaic-postgres-server.key`, `0400`, frozen verified postgres UID:GID; never mounted to Gateway or migrator. |
|
||||
|
||||
Compose uses identically named local **secret references** rendered by the named renderer into non-repository tmpfs paths; Swarm declares the same secrets and target paths with the tested `uid`, `gid`, and mode. KBN-101-05 rejects bind-mounted committed cert/key files, environment-encoded PEM, missing secrets, non-atomic renderer output, private-key access outside its named consumer (Gateway for Gateway key; PostgreSQL for PostgreSQL key), and any world-readable URL/key. The existing target Vault names are planned canonical paths and must be verified/provisioned by the deployment-owner input; the planning card does not claim they exist.
|
||||
Compose renders each value-plus-provider-version generation into a non-repository temporary generation directory, `fsync`s every file and directory, atomically renames the complete generation, and mounts immutable per-consumer copies only after the pair is complete. Swarm declares distinct versioned secret/config references for each migrator/importer consumer and generation. A deployment may not start, reload, or combine any URL/version/CA/attestation/public-key material across generations. The privileged handoff controller is the only bridge from migrator producer mount to importer mount: it verifies the signed producer artifact plus generation, copies atomically, seals importer read-only, and only then starts importer; it is tested for failed/partial copy, wrong generation, wrong owner/mode, and no importer start. KBN-101-05 rejects bind-mounted committed cert/key files, environment-encoded PEM, missing secrets, non-atomic renderer output, mixed generations, shared writable files, private-key access outside its named consumer (Gateway for Gateway key; PostgreSQL for PostgreSQL key), importer URL/version/attestation/key access outside their named consumer, CA outside explicit DB clients, and any world-readable URL/key. The existing target Vault names are planned canonical paths and must be verified/provisioned by the deployment-owner input; the planning card does not claim they exist.
|
||||
|
||||
The server leaf SANs are frozen to actual connection DNS names, not a configurable alias:
|
||||
|
||||
@@ -209,24 +211,24 @@ Before accepting traffic, runtime queries only parameterized/sanitized identity
|
||||
|
||||
The runner performs reciprocal preflight under the same session/lock: dedicated migration DTO only, verified TLS, exact allowlisted target, migrator `session_user`, schema-owner `current_user`, exact trusted search path, and no unsafe attributes. It fails before DDL otherwise.
|
||||
|
||||
Stable sanitized codes are `DATABASE_RUNTIME_URL_REQUIRED`, `DATABASE_MIGRATION_URL_REQUIRED`, `DATABASE_TLS_REQUIRED`, `DATABASE_TLS_VERIFICATION_FAILED`, `DATABASE_ROLE_UNSAFE`, `DATABASE_ROLE_GRANT_MISMATCH`, `DATABASE_SEARCH_PATH_UNSAFE`, `DATABASE_SCHEMA_MISMATCH`, `DATABASE_MIGRATION_RECONCILIATION_AMBIGUOUS`, `DATABASE_MIGRATION_LOCKED`, `DATABASE_MIGRATION_IDENTITY_UNSAFE`, `MIGRATE_TARGET_ATTESTATION_REQUIRED`, `MIGRATE_TARGET_ATTESTATION_INVALID`, `MIGRATE_TARGET_ATTESTATION_EXPIRED`, `MIGRATE_TARGET_ATTESTATION_REPLAYED`, and `MIGRATE_TARGET_BINDING_MISMATCH`. Logs/metrics may contain code, tier, manifest fingerprint, role class, and correlation ID only; never DSN, username, host, database name, SQL parameter, secret, or raw catalog result. External health exposes only unavailable/not-ready.
|
||||
Stable sanitized codes are `DATABASE_RUNTIME_URL_REQUIRED`, `DATABASE_MIGRATION_URL_REQUIRED`, `DATABASE_TLS_REQUIRED`, `DATABASE_TLS_VERIFICATION_FAILED`, `DATABASE_ROLE_UNSAFE`, `DATABASE_ROLE_GRANT_MISMATCH`, `DATABASE_SEARCH_PATH_UNSAFE`, `DATABASE_SCHEMA_MISMATCH`, `DATABASE_MIGRATION_RECONCILIATION_AMBIGUOUS`, `DATABASE_MIGRATION_LOCKED`, `DATABASE_MIGRATION_IDENTITY_UNSAFE`, `MIGRATE_TARGET_ATTESTATION_REQUIRED`, `MIGRATE_TARGET_ATTESTATION_INVALID`, `MIGRATE_TARGET_ATTESTATION_EXPIRED`, `MIGRATE_TARGET_ATTESTATION_REPLAYED`, `MIGRATE_TARGET_BINDING_MISMATCH`, `MIGRATE_TARGET_FILE_UNSAFE`, `MIGRATE_TARGET_GENERATION_MISMATCH`, `MIGRATE_TARGET_CA_REQUIRED`, and `MIGRATE_TARGET_CONSUMER_ISOLATION`. Logs/metrics may contain code, tier, manifest fingerprint, role class, and correlation ID only; never DSN, username, host, database name, SQL parameter, secret, or raw catalog result. External health exposes only unavailable/not-ready.
|
||||
|
||||
## 7. Safe DAG, activation, and rollback authority
|
||||
|
||||
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 | Complete, disjoint file/glob manifest and required test/evidence paths |
|
||||
| ----------------------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `KBN-101-00` platform bootstrap / IaC | contract | **Only:** `infra/pg-bootstrap/roles.sql`, `infra/pg-bootstrap/extensions.sql`, `infra/pg-bootstrap/README.md`, `infra/pg-bootstrap/tests/**`. It creates the extension-owner role/schema/extension interface and proves fresh, approved-owner, legacy-shadow, catalog/default-privilege, and direct-denial bootstrap cases. No renderer, runner, Compose, CI, or deployment path. |
|
||||
| `KBN-101-01` typed runtime config and verifier | 00 | **Only:** `packages/config/src/index.ts`, `packages/config/src/mosaic-config.ts`, `packages/config/src/mosaic-config.spec.ts`; `packages/db/src/client.ts`, `packages/db/src/defaults.ts`, `packages/db/src/connection-identity.ts`, `packages/db/src/client.spec.ts`, `packages/db/src/defaults.spec.ts`, `packages/db/src/connection-identity.spec.ts`; `apps/gateway/src/database/database.module.ts`, `apps/gateway/src/database/database.module.spec.ts`. It supplies runtime/migration/TLS DTO parsing plus runtime identity/search-path/readiness verification. No migrator, storage, installer, deploy, or CI path. |
|
||||
| `KBN-101-03` sole runner, manifest, and schema foundation | 00,01 | **Only:** `.gitattributes`; `packages/db/package.json`; `packages/db/drizzle.config.ts`; `packages/db/src/cli.ts`, `packages/db/src/cli.spec.ts`, `packages/db/src/index.ts`, `packages/db/src/index.import-negative.spec.ts`, `packages/db/src/migrate.ts`, `packages/db/src/migrate.test.ts`, `packages/db/src/schema.ts`, `packages/db/src/schema.spec.ts`; `packages/db/src/migrator/**`; `packages/db/drizzle/*.sql`, `packages/db/drizzle/meta/*.json`; `docker/db-migrator.Dockerfile`, `docker/db-migrator.Dockerfile.spec.ts`; `packages/db/package-bin.spec.ts`. It alone publishes `"mosaic-db-migrator": "./dist/cli.js"`, verifies source/build/pack/discovery, and sets `ENTRYPOINT ["mosaic-db-migrator"]`; it exclusively owns `packages/db/src/migrator/target-attestation.dto.ts`, `target-attestation-signer.ts`, and their specs: fixed-key reference validation, JCS canonical payload, Ed25519 signing, producer TLS/identity/manifest binding, atomic artifact emission, and producer tests. It owns journal/manifest/ledger/lock/relocation/shadow tests. Shipped `0009` bytes stay unchanged. |
|
||||
| `KBN-101-02` runtime DDL closure | 01,03 | **Only:** `docker/init-db.sql`, `infra/pg-init/01-extensions.sql`; `packages/storage/src/adapters/postgres.ts`, `packages/storage/src/adapters/postgres.spec.ts`, `packages/storage/src/factory.ts`, `packages/storage/src/factory.spec.ts`, `packages/storage/src/types.ts`, `packages/storage/src/tier-detection.ts`, `packages/storage/src/tier-detection.spec.ts`, `packages/storage/src/cli.ts`, `packages/storage/src/cli.spec.ts`, `packages/storage/src/migrate-tier.ts`, `packages/storage/src/migrate-tier.spec.ts`, `packages/storage/src/migrate-tier.integration.test.ts`; `apps/gateway/src/main.ts`, `apps/gateway/src/__tests__/integration/federated-boot.pg-unreachable.integration.test.ts`, `apps/gateway/src/__tests__/integration/federated-boot.success.integration.test.ts`, `apps/gateway/src/__tests__/integration/federated-pgvector.integration.test.ts`; `packages/db/src/federation.integration.test.ts`; `packages/mosaic/src/commands/fleet-backlog.ts`, `packages/mosaic/src/commands/fleet-backlog.spec.ts`. It consumes the -03 runner and exclusively owns importer verification/interface in `packages/storage/src/{cli,migrate-tier}.ts` and the named unit/integration specs: paired URL/attestation options, file/fd/TOCTOU checks, signature/key/expiry/replay/secret/digest/binding validation, post-TLS zero-DML comparison, and DDL classifier. It closes runtime/retired-init DDL only and excludes every -03 signer/runner, index, migrate, and Drizzle-config asset, and every deployment/CI/doc path. |
|
||||
| `KBN-101-04` installer/wizard | 01 | **Only:** `packages/mosaic/src/stages/gateway-config.ts`, `packages/mosaic/src/stages/gateway-config.spec.ts`, `packages/mosaic/src/stages/gateway-config-cors.spec.ts`, `packages/mosaic/src/stages/wizard-menu.spec.ts`, `packages/mosaic/src/wizard.ts`. It persists only non-secret references/injected-variable contracts; source inspection excludes `tools/install.sh`, which does not read/write the database DSN. |
|
||||
| `KBN-101-05` renderer and deployment | 00,03 | **Only:** `tools/db/render-postgres-secrets.ts`, `tools/db/render-postgres-secrets.spec.ts`; `apps/gateway/Dockerfile`, `apps/gateway/Dockerfile.spec.ts`; `docker-compose.yml`, `docker-compose.spec.ts`; `docker-compose.federated.yml`, `docker-compose.federated.spec.ts`; `deploy/portainer/federated-test.stack.yml`, `deploy/portainer/federated-test.stack.spec.ts`; `tools/federation-harness/docker-compose.two-gateways.yml`, `tools/federation-harness/docker-compose.two-gateways.spec.ts`. It consumes the -00 bootstrap interface and -03 immutable runner image, and exclusively renders/tests runner-only root-owned signing-key reference, importer-only public-key/key-ring, and controlled `0444` attestation artifact mount; it owns no bootstrap, runner, config, storage, or CI file. |
|
||||
| `KBN-101-07` operator/runbook/docs | 02,03,04,05 | **Only:** `README.md`, `CLAUDE.md`, `docs/guides/admin-guide.md`, `docs/guides/dev-guide.md`, `docs/guides/deployment.md`, **`docs/guides/migrate-tier.md`**, `docs/guides/user-guide.md`, `docs/federation/SETUP.md`, `docs/federation/TASKS.md`, `docs/fleet/backlog-conventions.md`, `docs/PERFORMANCE.md`, `docs/design/storage-abstraction-middleware.md`, `docs/plans/2026-03-15-agent-platform-architecture.md`, `docs/runbooks/kbn-101-database-role-split.md`, `docs/reports/native-kanban-sot/kbn-101-operator-readiness-report.md`, `docs/native-kanban-sot/tests/kbn-101-operator-docs.spec.ts`. It exclusively owns the active migrate-tier operator route and documents the interfaces produced by -02/-03/-04/-05, including both file references, signing-key isolation, attestation bindings, rotation/replay, and no-connection/no-DML errors; it owns no source, storage, CLI, runner, or CI file. |
|
||||
| `KBN-101-06` CI classifier and command matrix | 02,03,05,07 | **Only:** `.woodpecker/ci.yml`, `tools/ci/kbn101-ddl-inventory.ts`, `tools/ci/kbn101-ddl-inventory.spec.ts`, `tools/ci/fixtures/kbn101-ddl-inventory.json`, `tools/ci/kbn101-entrypoint-matrix.ts`, `tools/ci/kbn101-entrypoint-matrix.spec.ts`. It invokes the already-produced bin/image/deployment/doc artifacts and edits no producer file. Its inventory test enforces manifest overlap, ownerless, duplicate-owner, path-existence, allowlist, active-route field completeness, finite operator-document inventory, normative-contract non-masking, unknown-command, and historical/status-only masking failures; its matrix invokes the -02 secure target route and verifies every declared attestation refusal before target connection/DDL and post-connect mismatch with zero DML. |
|
||||
| `KBN-101-08` foundation certification and **atomic activation release** | 00…07 | **Only evidence:** `docs/reports/native-kanban-sot/kbn-101-foundation-activation-certificate.md`, `docs/reports/native-kanban-sot/kbn-101-foundation-activation-evidence.json`. It changes no implementation path. Independent review and terminal-green CI must verify prepared artifacts before Mosaic control plane/Jason authorizes backup → drain/scale-zero N-1 → TLS → roles → runner → verified readiness → rolling runtime; any red result aborts. |
|
||||
| `KBN-101-09` post-KBN-100 certification | KBN-100,08 | **Only evidence:** `docs/reports/native-kanban-sot/kbn-101-immutable-role-certificate.md`, `docs/reports/native-kanban-sot/kbn-101-immutable-role-evidence.json`. It changes no implementation path and records real deployed runtime INSERT/SELECT plus UPDATE/DELETE-denial evidence and independent security/Ultron approval. |
|
||||
| Card | Depends on | Complete, disjoint file/glob manifest and required test/evidence paths |
|
||||
| ----------------------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `KBN-101-00` platform bootstrap / IaC | contract | **Only:** `infra/pg-bootstrap/roles.sql`, `infra/pg-bootstrap/extensions.sql`, `infra/pg-bootstrap/README.md`, `infra/pg-bootstrap/tests/**`. It creates the extension-owner role/schema/extension interface and proves fresh, approved-owner, legacy-shadow, catalog/default-privilege, and direct-denial bootstrap cases. No renderer, runner, Compose, CI, or deployment path. |
|
||||
| `KBN-101-01` typed runtime config and verifier | 00 | **Only:** `packages/config/src/index.ts`, `packages/config/src/mosaic-config.ts`, `packages/config/src/mosaic-config.spec.ts`; `packages/db/src/client.ts`, `packages/db/src/defaults.ts`, `packages/db/src/connection-identity.ts`, `packages/db/src/client.spec.ts`, `packages/db/src/defaults.spec.ts`, `packages/db/src/connection-identity.spec.ts`; `apps/gateway/src/database/database.module.ts`, `apps/gateway/src/database/database.module.spec.ts`. It supplies runtime/migration/TLS DTO parsing plus runtime identity/search-path/readiness verification. No migrator, storage, installer, deploy, or CI path. |
|
||||
| `KBN-101-03` sole runner, manifest, and schema foundation | 00,01 | **Only:** `.gitattributes`; `packages/db/package.json`; `packages/db/drizzle.config.ts`; `packages/db/src/cli.ts`, `packages/db/src/cli.spec.ts`, `packages/db/src/index.ts`, `packages/db/src/index.import-negative.spec.ts`, `packages/db/src/migrate.ts`, `packages/db/src/migrate.test.ts`, `packages/db/src/schema.ts`, `packages/db/src/schema.spec.ts`; `packages/db/src/migrator/**`; `packages/db/drizzle/*.sql`, `packages/db/drizzle/meta/*.json`; `docker/db-migrator.Dockerfile`, `docker/db-migrator.Dockerfile.spec.ts`; `packages/db/package-bin.spec.ts`. It alone publishes `"mosaic-db-migrator": "./dist/cli.js"`, verifies source/build/pack/discovery, and sets `ENTRYPOINT ["mosaic-db-migrator"]`; it exclusively owns `packages/db/src/migrator/target-attestation.dto.ts`, `target-attestation-signer.ts`, and their specs: fixed-key reference validation, JCS canonical payload, Ed25519 signing, producer TLS/identity/manifest binding, atomic artifact emission, and producer tests. It owns journal/manifest/ledger/lock/relocation/shadow tests. Shipped `0009` bytes stay unchanged. |
|
||||
| `KBN-101-02` runtime DDL closure | 01,03 | **Only:** `docker/init-db.sql`, `infra/pg-init/01-extensions.sql`; `packages/storage/src/adapters/postgres.ts`, `packages/storage/src/adapters/postgres.spec.ts`, `packages/storage/src/factory.ts`, `packages/storage/src/factory.spec.ts`, `packages/storage/src/types.ts`, `packages/storage/src/tier-detection.ts`, `packages/storage/src/tier-detection.spec.ts`, `packages/storage/src/cli.ts`, `packages/storage/src/cli.spec.ts`, `packages/storage/src/migrate-tier.ts`, `packages/storage/src/migrate-tier.spec.ts`, `packages/storage/src/migrate-tier.integration.test.ts`; `apps/gateway/src/main.ts`, `apps/gateway/src/__tests__/integration/federated-boot.pg-unreachable.integration.test.ts`, `apps/gateway/src/__tests__/integration/federated-boot.success.integration.test.ts`, `apps/gateway/src/__tests__/integration/federated-pgvector.integration.test.ts`; `packages/db/src/federation.integration.test.ts`; `packages/mosaic/src/commands/fleet-backlog.ts`, `packages/mosaic/src/commands/fleet-backlog.spec.ts`. It consumes the -03 runner and exclusively owns importer verification/interface in `packages/storage/src/{cli,migrate-tier}.ts` and the named unit/integration specs: fixed URL/version/attestation/public-key safe-open fds (`O_RDONLY | O_CLOEXEC | O_NOFOLLOW` plus post-open regular-owner-mode-link-count validation), one-read protected-memory URL connection, fd zeroization/close, signature/key/expiry/replay/authenticated-provider-version/digest/generation/CA/binding validation, no forwarding/logging/oracle, post-TLS zero-DML comparison, consumer isolation, and DDL classifier. It closes runtime/retired-init DDL only and excludes every -03 signer/runner, index, migrate, and Drizzle-config asset, and every deployment/CI/doc path. |
|
||||
| `KBN-101-04` installer/wizard | 01 | **Only:** `packages/mosaic/src/stages/gateway-config.ts`, `packages/mosaic/src/stages/gateway-config.spec.ts`, `packages/mosaic/src/stages/gateway-config-cors.spec.ts`, `packages/mosaic/src/stages/wizard-menu.spec.ts`, `packages/mosaic/src/wizard.ts`. It persists only non-secret references/injected-variable contracts; source inspection excludes `tools/install.sh`, which does not read/write the database DSN. |
|
||||
| `KBN-101-05` renderer and deployment | 00,03 | **Only:** `tools/db/render-postgres-secrets.ts`, `tools/db/render-postgres-secrets.spec.ts`; `apps/gateway/Dockerfile`, `apps/gateway/Dockerfile.spec.ts`; `docker-compose.yml`, `docker-compose.spec.ts`; `docker-compose.federated.yml`, `docker-compose.federated.spec.ts`; `deploy/portainer/federated-test.stack.yml`, `deploy/portainer/federated-test.stack.spec.ts`; `tools/federation-harness/docker-compose.two-gateways.yml`, `tools/federation-harness/docker-compose.two-gateways.spec.ts`. It consumes the -00 bootstrap interface and -03 immutable runner image, and exclusively renders/tests fixed Gateway/importer/migrator UIDs; runner-only root-owned signing-key reference; KV-v2 importer URL plus same-response `data.metadata.version`; separate immutable generation-pinned URL/version mounts for `10003:10003` migrator and `10002:10002` importer; importer-only CA at `DATABASE_TLS_CA_CERT_PATH`, public-key/key-ring, and controlled producer-only-to-importer-only attestation handoff mount; privileged controller verification/copy/fsync/atomic-rename/seal-before-importer-start behavior; Compose generation-dir fsync/atomic-rename and Swarm versioned-secret/config no-mixed-generation behavior. It owns no bootstrap, runner, config, storage, or CI file. |
|
||||
| `KBN-101-07` operator/runbook/docs | 02,03,04,05 | **Only:** `README.md`, `CLAUDE.md`, `docs/guides/admin-guide.md`, `docs/guides/dev-guide.md`, `docs/guides/deployment.md`, **`docs/guides/migrate-tier.md`**, `docs/guides/user-guide.md`, `docs/federation/SETUP.md`, `docs/federation/TASKS.md`, `docs/fleet/backlog-conventions.md`, `docs/PERFORMANCE.md`, `docs/design/storage-abstraction-middleware.md`, `docs/plans/2026-03-15-agent-platform-architecture.md`, `docs/runbooks/kbn-101-database-role-split.md`, `docs/reports/native-kanban-sot/kbn-101-operator-readiness-report.md`, `docs/native-kanban-sot/tests/kbn-101-operator-docs.spec.ts`. It exclusively owns the active migrate-tier operator route and documents the interfaces produced by -02/-03/-04/-05, including both file references, signing-key isolation, attestation bindings, rotation/replay, and no-connection/no-DML errors; it owns no source, storage, CLI, runner, or CI file. |
|
||||
| `KBN-101-06` CI classifier and command matrix | 02,03,05,07 | **Only:** `.woodpecker/ci.yml`, `tools/ci/kbn101-ddl-inventory.ts`, `tools/ci/kbn101-ddl-inventory.spec.ts`, `tools/ci/fixtures/kbn101-ddl-inventory.json`, `tools/ci/kbn101-entrypoint-matrix.ts`, `tools/ci/kbn101-entrypoint-matrix.spec.ts`. It invokes the already-produced bin/image/deployment/doc artifacts and edits no producer file. Its inventory test enforces manifest overlap, ownerless, duplicate-owner, path-existence, allowlist, active-route field completeness, finite operator-document inventory, normative/status-only non-masking, unknown-command, and historical/status-only masking failures. Its semantic suite fails former `SETUP.md` automatic-first-boot/startup, Compose-up-before-runner, extension/schema/migration automatic wording, and init-script authority even when the path has an inventory record; it passes the rc.12 external-bootstrap → TLS/roles → `mosaic-db-migrator --run` → `--verify` → Gateway-readiness sequence. Its matrix invokes the -02 secure target route and verifies URL/version generation mismatch, provider rotation/revocation, consumer isolation, safe-open TOCTOU/link/mode/owner, absent/wrong importer CA, no log/oracle, every declared attestation refusal before target connection/DDL, and post-connect mismatch with zero DML. |
|
||||
| `KBN-101-08` foundation certification and **atomic activation release** | 00…07 | **Only evidence:** `docs/reports/native-kanban-sot/kbn-101-foundation-activation-certificate.md`, `docs/reports/native-kanban-sot/kbn-101-foundation-activation-evidence.json`. It changes no implementation path. Independent review and terminal-green CI must verify prepared artifacts before Mosaic control plane/Jason authorizes backup → drain/scale-zero N-1 → TLS → roles → runner → verified readiness → rolling runtime; any red result aborts. |
|
||||
| `KBN-101-09` post-KBN-100 certification | KBN-100,08 | **Only evidence:** `docs/reports/native-kanban-sot/kbn-101-immutable-role-certificate.md`, `docs/reports/native-kanban-sot/kbn-101-immutable-role-evidence.json`. It changes no implementation path and records real deployed runtime INSERT/SELECT plus UPDATE/DELETE-denial evidence and independent security/Ultron approval. |
|
||||
|
||||
The manifests above are the complete ownership universe for KBN-101 implementation paths; the KBN-101-06 inventory test fails on overlap, an ownerless in-scope path, or a nonexistent declared path. Cards `00`–`07` are prepared artifacts, not independently deployed releases: the immutable N-1 owner-runtime image stays live until KBN-101-08 control-plane atomic activation. No activation card edits a source-changing path, and no runtime bypass or broken deployed intermediate exists.
|
||||
|
||||
@@ -236,16 +238,16 @@ The manifests above are the complete ownership universe for KBN-101 implementati
|
||||
|
||||
## 8. Acceptance traceability
|
||||
|
||||
| Requirement / acceptance criterion | Required implementation evidence |
|
||||
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| K101-REQ-01 / AC-K101-01 | DTO/command matrix covers local/PGlite, standalone, federated, and both harness pairs; every finite classified §2 path rejects `DATABASE_URL`-only before connection/DDL; no runtime fallback/default; `--help`, argv, import-compile, and live-operator-route negatives pass. The active migrate-tier route proves runner-produced JCS/Ed25519 attestation, root-owned signing/private-key and importer-public-key isolation, atomic artifact, exact `--target-url-file /run/secrets/mosaic_migrate_target_url` plus `--target-attestation-file /run/mosaic-attestations/migrate-target.v1.json`, secret-version/digest/TLS/CA/server/database/role/manifest/schema bindings, expiry/replay/rotation/TOCTOU checks, bounded non-DDL importer DML, and missing/wrong/stale/replayed/tampered/substituted/mismatched no-connection versus zero-DML refusal. |
|
||||
| K101-REQ-02 / AC-K101-02 | KBN-101-03 one-session fixed two-int lock, `--run`/`--verify` exit-code, contention/crash/readiness/unrelated-key tests; manifest-v1 canonical bytes/digest and all reconciliation states; Gateway/replica DDL impossibility. |
|
||||
| K101-REQ-03 / AC-K101-03 | KBN-101-00 bootstrap schema/extension-owner/default-privilege and direct-denial proof against actual PostgreSQL 17 + pgvector 0.8.2 control metadata (`trusted` absent/untrusted, `relocatable=true`); external-superuser `SET ROLE` create/update/`RESET ROLE` audit proof; `rolcanlogin=false`, `rolsuper=true`, zero members/no runtime credential proof; KBN-101-03 catalog relocation and future-Drizzle-only-`mosaic` proof plus approved-owner/shadow runner integration; `pg_namespace.nspowner`, `pg_extension.extowner`, owner-bearing member/schema/version, and runtime/migrator/schema-owner/importer/all-service-role catalog plus `SET ROLE`/ALTER/DROP/member-update denials; KBN-101-01/03 role, path, TEMP, ledger/default-grant, and pool-reset tests. |
|
||||
| K101-REQ-04 / AC-K101-04 | KBN-101-00 bootstrap-interface and KBN-101-05 renderer/deployment tests; immutable-image exact Job commands and runner-before-readiness order; fresh/existing verified-TLS Compose/Swarm/two-gateway positives; both-pair CA/SAN/downgrade/key-permission negatives; exact UID/GID/mode and runtime/migrator secret-consumer rendering/CI negatives. |
|
||||
| K101-REQ-05 / AC-K101-05 | KBN-101-09 after KBN-100: real deployed runtime INSERT/SELECT success and UPDATE/DELETE denial for each frozen relation, with RESTRICT retention evidence. |
|
||||
| K101-REQ-06 / AC-K101-06 | KBN-101-00…08 prepared-card/no-intermediate-deploy evidence; one final activation authority record; N-1 drain/zero-plaintext-session/`hostssl`, backup/restore, CA overlap rotation, TLS-only rollback, Vault/redaction, and no-force-on-red evidence. |
|
||||
| K101-REQ-07 / KBN sequence | KBN-101-08 foundation certificate before KBN-100, KBN-101-09 real immutable-role certificate plus Ultron approval before KBN-105; KBN-100 rebases/restores Drizzle consistency and never bypasses the serial gates. |
|
||||
| Delivery integrity | One-card/one-PR DAG, exact file ownership, docs/link/contract checks, independent author≠reviewer re-review on the pushed exact head, and terminal-green CI for implementation cards. |
|
||||
| Requirement / acceptance criterion | Required implementation evidence |
|
||||
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| K101-REQ-01 / AC-K101-01 | DTO/command matrix covers local/PGlite, standalone, federated, and both harness pairs; every finite classified §2 path rejects `DATABASE_URL`-only before connection/DDL; no runtime fallback/default; `--help`, argv, import-compile, and live-operator-route negatives pass. The active migrate-tier route proves runner-produced JCS/Ed25519 attestation, root-owned signing/private-key and importer-public-key isolation, Vault KV-v2 `secret-{env}/mosaic-stack/database/importer` URL plus same-response authenticated `data.metadata.version`, separate immutable renderer generations, importer CA, exact `--target-url-file /run/secrets/mosaic-migrate-target-url` plus version file and `--target-attestation-file /run/mosaic-attestations/migrate-target.v1.json`, safe-fd/digest/TLS/server/database/role/manifest/schema bindings, expiry/replay/provider-rotation/revocation/TOCTOU checks, bounded non-DDL importer DML, and consumer-isolation/no-log-oracle plus no-connection versus zero-DML refusal. |
|
||||
| K101-REQ-02 / AC-K101-02 | KBN-101-03 one-session fixed two-int lock, `--run`/`--verify` exit-code, contention/crash/readiness/unrelated-key tests; manifest-v1 canonical bytes/digest and all reconciliation states; Gateway/replica DDL impossibility. |
|
||||
| K101-REQ-03 / AC-K101-03 | KBN-101-00 bootstrap schema/extension-owner/default-privilege and direct-denial proof against actual PostgreSQL 17 + pgvector 0.8.2 control metadata (`trusted` absent/untrusted, `relocatable=true`); external-superuser `SET ROLE` create/update/`RESET ROLE` audit proof; `rolcanlogin=false`, `rolsuper=true`, zero members/no runtime credential proof; KBN-101-03 catalog relocation and future-Drizzle-only-`mosaic` proof plus approved-owner/shadow runner integration; `pg_namespace.nspowner`, `pg_extension.extowner`, owner-bearing member/schema/version, and runtime/migrator/schema-owner/importer/all-service-role catalog plus `SET ROLE`/ALTER/DROP/member-update denials; KBN-101-01/03 role, path, TEMP, ledger/default-grant, and pool-reset tests. |
|
||||
| K101-REQ-04 / AC-K101-04 | KBN-101-00 bootstrap-interface and KBN-101-05 renderer/deployment tests; immutable-image exact Job commands and runner-before-readiness order; fresh/existing verified-TLS Compose/Swarm/two-gateway positives; both-pair CA/SAN/downgrade/key-permission negatives; exact UID/GID/mode and runtime/migrator secret-consumer rendering/CI negatives. |
|
||||
| K101-REQ-05 / AC-K101-05 | KBN-101-09 after KBN-100: real deployed runtime INSERT/SELECT success and UPDATE/DELETE denial for each frozen relation, with RESTRICT retention evidence. |
|
||||
| K101-REQ-06 / AC-K101-06 | KBN-101-00…08 prepared-card/no-intermediate-deploy evidence; one final activation authority record; N-1 drain/zero-plaintext-session/`hostssl`, backup/restore, CA overlap rotation, TLS-only rollback, Vault/redaction, and no-force-on-red evidence. |
|
||||
| K101-REQ-07 / KBN sequence | KBN-101-08 foundation certificate before KBN-100, KBN-101-09 real immutable-role certificate plus Ultron approval before KBN-105; KBN-100 rebases/restores Drizzle consistency and never bypasses the serial gates. |
|
||||
| Delivery integrity | One-card/one-PR DAG, exact file ownership, docs/link/contract checks, independent author≠reviewer re-review on the pushed exact head, and terminal-green CI for implementation cards. |
|
||||
|
||||
## 9. Non-goals and residual authority
|
||||
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
# Native Kanban/SOT — Remediated Shared Contract v1
|
||||
|
||||
**Status:** CONTROL-PLANE rc.11 KBN-101 target-bound importer-attestation and complete operator-inventory 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.11
|
||||
**Status:** CONTROL-PLANE rc.12 KBN-101 deployable importer-generation/material and non-operative federation-SETUP 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.12
|
||||
**Date:** 2026-07-15
|
||||
**Change authority:** Mosaic control plane/Jason only
|
||||
**SI-001 amendment authority:** `web1:mosaic-100` control-plane decision under issue #753
|
||||
|
||||
## Amendment record
|
||||
|
||||
### 1.0.0-rc.12 — Deployable importer generation and indirect-DDL-route closure
|
||||
|
||||
- **Authenticated generation:** KBN-101-05 owns one canonical Vault KV-v2 importer record, `secret-{env}/mosaic-stack/database/importer` key `url`, with its version taken only from the same successful `data.metadata.version` response. Value plus provider version are one generation, never inferred from DSN bytes. The renderer creates separate immutable `0400` URL/version copies for migrator `10003:10003` binding-only access and importer `10002:10002` access; it uses fsync/atomic generation replacement for Compose and distinct versioned secret/config references for Swarm, so deployment cannot mix generations.
|
||||
- **Bounded consumers:** importer alone receives its URL/version, CA at `DATABASE_TLS_CA_CERT_PATH`, pinned public key, and read-only attestation; migrator receives its own migration URL/CA, the URL/version only for no-connect/no-export binding, attestation output, and the root-wrapper-only private key. Safe fd open/fstat/digest/zeroize/close semantics, a privileged producer-only-to-importer-only attestation handoff controller (verify, exact-byte copy, fsync/atomic rename, `10002:10002` `0400` seal, then importer start), no shared writable file, no logging/oracle, provider rotation/revocation, CA/mount, consumer-isolation, and symlink/hardlink/owner/mode/TOCTOU negatives are mandatory.
|
||||
- **Indirect-DDL closure:** `docs/federation/SETUP.md` is non-operative until KBN-101 activation and documents only external bootstrap → TLS/roles → runner `--run` → `--verify` → Gateway readiness. The -06 scanner performs unsuppressible semantic checks for automatic first-boot/startup extension/schema/migration language, Compose-up-before-runner, and init-script authority; the former SETUP wording fails and the remediated sequence passes.
|
||||
|
||||
### 1.0.0-rc.11 — Target-bound importer attestation and exhaustive operator-route closure
|
||||
|
||||
- **Target-bound proof:** trusted `mosaic-db-migrator --verify` now produces the atomic, credential-free `migrate-target.v1.json` JCS/Ed25519 artifact from a runner-only root-owned signing-key reference; the importer receives only pinned public verification keys and the artifact. Its signed v1 fields bind issued/expiry/nonce, exact secret version and SHA-256 of high-entropy target-file bytes, canonical TLS host/port/database, CA/SPKI, PostgreSQL system identifier/database OID, expected importer role, manifest/schema fingerprints, and producer invocation/build/image/correlation. No DSN, username, password, credential bytes, or signing key enters the artifact, importer, runtime, logs, or output.
|
||||
- **Fail-closed importer:** `mosaic storage migrate-tier` requires both `--target-url-file /run/secrets/mosaic_migrate_target_url` and `--target-attestation-file /run/mosaic-attestations/migrate-target.v1.json`. Before target connection it validates files, signature/key/expiry/replay, secret version/digest, TLS/CA/role/manifest bindings and opens/digests/connects from the same in-memory URL bytes. After verified TLS but before transaction/DML it matches server ID, database OID, `current_user`, CA/SPKI, and manifest/schema; failure distinguishes zero connection from connection/zero-DML and DDL remains impossible. Rotation overlap/revocation, atomic rename, replay cache, secret rotation invalidation, and wrong/substituted/stale/tampered/file-change tests are mandatory.
|
||||
- **Fail-closed importer:** `mosaic storage migrate-tier` requires both `--target-url-file /run/secrets/mosaic-migrate-target-url` and `--target-attestation-file /run/mosaic-attestations/migrate-target.v1.json`. Before target connection it validates files, signature/key/expiry/replay, secret version/digest, TLS/CA/role/manifest bindings and opens/digests/connects from the same in-memory URL bytes. After verified TLS but before transaction/DML it matches server ID, database OID, `current_user`, CA/SPKI, and manifest/schema; failure distinguishes zero connection from connection/zero-DML and DDL remains impossible. Rotation overlap/revocation, atomic rename, replay cache, secret rotation invalidation, and wrong/substituted/stale/tampered/file-change tests are mandatory.
|
||||
- **Closed documentation surface:** KBN-101-06 inventories every current non-normative scanner hit, including `docs/guides/user-guide.md` and status-only `docs/federation/TASKS.md`; the latter is historical and cannot authorize DDL. The legacy `storage migrate` tier-copy syntax is unavailable. `storage migrate` is schema-wrapper delegation only; secure tier data copy is `migrate-tier`. Exact KBN PRD/contract/shared/task paths may be `normative-contract` scan class but are still scanned and cannot mask executable instructions. The normative detail remains [`KBN-101-DB-ROLE-SPLIT.md`](./KBN-101-DB-ROLE-SPLIT.md).
|
||||
- **Non-effect:** pgvector closure, manifest, lock, role graph, TLS, activation, and KBN-100/KBN-105 serial gates are unchanged.
|
||||
|
||||
@@ -19,7 +25,7 @@
|
||||
|
||||
- **Valid extension authority:** PostgreSQL 17 + pgvector 0.8.2 `vector` is untrusted (`trusted` absent; `relocatable=true`), so `mosaic_extension_owner` is exactly `NOLOGIN SUPERUSER`, not `NOSUPERUSER`. It is dedicated solely to `mosaic_extensions`, `vector`, and owner-bearing extension members; `rolcanlogin=false`, `rolsuper=true`, zero members, no runtime credential/Vault secret, and no app-container delivery are catalog and deployment proof. An externally controlled audited bootstrap-superuser session alone `SET ROLE`s for extension CREATE/UPDATE/SET SCHEMA, then `RESET ROLE`; fresh and shadow paths do so, while in-place existing work requires exact pre-existing `extowner`.
|
||||
- **Explicit superuser exception:** `GRANT`/`REVOKE` cannot privilege-limit a superuser. The containment is dedicated identity, no login, no membership, external control plane, audit, independent review, backup/rollback, and maintenance window—not a false least-privilege claim. Runtime, migrator, schema owner, importer, and every service role cannot assume the role or alter/update/drop/change extension membership. Managed targets without this exact role are ineligible unless a versioned provider-owned extension-owner profile is independently approved.
|
||||
- **Active secure data-migration route:** `docs/guides/migrate-tier.md` is exclusively KBN-101-07, is active rather than historical, and specifies runner-prepared/verified PostgreSQL destination plus a dedicated non-DDL importer. KBN-101-02 freezes `--target-url-file /run/secrets/mosaic_migrate_target_url`, never credential argv; raw `--target-url`, `DATABASE_URL` fallback, runtime owner, missing/unsafe file, wrong mode, and DDL all fail before target connection/DDL. KBN-101-06 inventory/matrix records the route and exact secure fields, then tests its finite operator-document closure.
|
||||
- **Active secure data-migration route:** `docs/guides/migrate-tier.md` is exclusively KBN-101-07, is active rather than historical, and specifies runner-prepared/verified PostgreSQL destination plus a dedicated non-DDL importer. KBN-101-02 freezes `--target-url-file /run/secrets/mosaic-migrate-target-url`, never credential argv; raw `--target-url`, `DATABASE_URL` fallback, runtime owner, missing/unsafe file, wrong mode, and DDL all fail before target connection/DDL. KBN-101-06 inventory/matrix records the route and exact secure fields, then tests its finite operator-document closure.
|
||||
- **Non-effect:** manifest, lock, `mosaic` application schema, TLS, activation, and KBN-100/KBN-105 serial gates remain unchanged. The normative detail remains [`KBN-101-DB-ROLE-SPLIT.md`](./KBN-101-DB-ROLE-SPLIT.md).
|
||||
|
||||
### 1.0.0-rc.9 — KBN-101 extension-schema boundary, disjoint manifests, and scanner mechanics
|
||||
@@ -70,7 +76,7 @@
|
||||
|
||||
## 1. Authority
|
||||
|
||||
Concrete contracts are the four `contracts/*.v1.ts` files. PostgreSQL/current-main Drizzle is the sole writable SOT. In PostgreSQL standalone/federated deployments, KBN-101 rc.11 DDL/ledger/TLS/role/attestation 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.12 DDL/ledger/TLS/role/attestation/generation 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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
- **Status:** IN PROGRESS — issue [#771](https://git.mosaicstack.dev/mosaicstack/stack/issues/771); rc.11 closes the two exact-head re-review HIGH findings: trusted runner-produced target-bound Ed25519 importer attestation and complete finite operator-document disposition including the user guide. It awaits independent exact-head re-review; implementation remains held.
|
||||
- **Status:** IN PROGRESS — issue [#771](https://git.mosaicstack.dev/mosaicstack/stack/issues/771); rc.12 closes the two exact-head re-review HIGH findings: deployable Vault-authenticated importer URL/version/CA generation with bounded migrator/importer consumers, and a non-operative federation SETUP route with indirect-DDL semantic scanner coverage. It awaits independent exact-head re-review; implementation remains held.
|
||||
- **Owner:** Mos integration control plane; independently reviewed by security/Ultron.
|
||||
- **Mode:** SERIAL foundation certificate blocks KBN-100; its post-KBN-100 real immutable-operation certificate blocks KBN-105.
|
||||
- **IN:** Exact `DATABASE_URL` non-owner runtime versus `DATABASE_MIGRATION_URL` owner/migrator connection contract; sole published `mosaic-db-migrator --run|--verify` PostgreSQL DDL path and all legacy/future entrypoint closure; active migrate-tier destination only after runner prepare/verify through exact `--target-url-file /run/secrets/mosaic_migrate_target_url` plus signed `--target-attestation-file /run/mosaic-attestations/migrate-target.v1.json`, runner-only signing key/public-key isolation, target secret/TLS/CA/server/database/role/manifest/schema binding, expiry/replay/rotation/TOCTOU/no-DML controls, and dedicated non-DDL importer; finite exact-path scanner/allowlist/active-route 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/`NOLOGIN SUPERUSER` extension-owner/migrator/importer/runtime roles; approved-owner versus legacy-owner shadow pgvector transition; ownership, zero membership/no runtime secret, 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; active migrate-tier destination only after runner prepare/verify through exact `--target-url-file /run/secrets/mosaic-migrate-target-url`, paired authenticated provider-version file, and signed `--target-attestation-file /run/mosaic-attestations/migrate-target.v1.json`; runner-only signing key/public-key isolation; canonical Vault KV-v2 target URL/version, generation-pinned renderer, importer CA/public-key/attestation plus privileged sealed producer-to-importer handoff, safe-fd/consumer-isolation/no-log-oracle, TLS/server/database/role/manifest/schema binding, expiry/replay/provider-rotation/TOCTOU/no-DML controls, and dedicated non-DDL importer; finite exact-path scanner/allowlist/active-route review plus unsuppressible automatic-startup/init/Compose-before-runner semantic negatives 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/`NOLOGIN SUPERUSER` extension-owner/migrator/importer/runtime roles; approved-owner versus legacy-owner shadow pgvector transition; ownership, zero membership/no runtime secret, TEMP/ledger-read/default privilege and immutable grant proof; N-1 inactive prepared cards then atomic activation/rollback authority; Vault/redaction/observability/operator runbooks; one-card/one-PR implementation DAG.
|
||||
- **OUT:** Production mutation in this planning card; KBN-100 tables/data backfill; application API behavior; KBN-105 route/DTO freeze.
|
||||
- **Depends on:** KBN-010 completed.
|
||||
- **Contract surfaces:** [`KBN-101-DB-ROLE-SPLIT.md`](./KBN-101-DB-ROLE-SPLIT.md); `SHARED-CONTRACT.md` rc.11 amendment.
|
||||
- **Evidence:** foundation: exact `--help|--run|--verify`/exit/argv/import-negative plus DTO entrypoint negatives for every finite classified current DDL/static-bypass path (including `DATABASE_URL`-only, runner fixture, retired init, sanitized current operator guidance, both harness pairs, and `db:push` refusal); active migrate-tier paired URL-file/attestation-file, signing/public-key isolation, atomic JCS/Ed25519, secret-version/digest/TLS/CA/server/database/role/manifest/schema binding, expiry/replay/rotation/TOCTOU, zero-connection versus zero-DML, prepared-target/importer/no-DDL negatives; 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; actual pgvector 0.8.2 control metadata, fresh/approved-owner existing/legacy-owner shadow/partial-resume-rollback/N-1 pgvector evidence with `rolcanlogin=false`, `rolsuper=true`, zero members, external-superuser `SET ROLE`/`RESET ROLE` audit, `pg_extension.extowner`, owner-bearing member/schema/version and runtime/migrator/schema-owner/importer/all-service-role `SET ROLE`/ALTER/DROP/member-update 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.
|
||||
- **Contract surfaces:** [`KBN-101-DB-ROLE-SPLIT.md`](./KBN-101-DB-ROLE-SPLIT.md); `SHARED-CONTRACT.md` rc.12 amendment.
|
||||
- **Evidence:** foundation: exact `--help|--run|--verify`/exit/argv/import-negative plus DTO entrypoint negatives for every finite classified current DDL/static-bypass path (including `DATABASE_URL`-only, runner fixture, retired init, sanitized current operator guidance, both harness pairs, and `db:push` refusal); active migrate-tier paired URL/version/attestation files, signing/public-key isolation, canonical Vault KV-v2 authenticated version, generation-pinned renderer, importer CA, safe fd/TOCTOU/consumer-isolation/no-log-oracle, atomic JCS/Ed25519, digest/TLS/server/database/role/manifest/schema binding, expiry/replay/provider rotation/revocation, zero-connection versus zero-DML, prepared-target/importer/no-DDL negatives; 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; actual pgvector 0.8.2 control metadata, fresh/approved-owner existing/legacy-owner shadow/partial-resume-rollback/N-1 pgvector evidence with `rolcanlogin=false`, `rolsuper=true`, zero members, external-superuser `SET ROLE`/`RESET ROLE` audit, `pg_extension.extowner`, owner-bearing member/schema/version and runtime/migrator/schema-owner/importer/all-service-role `SET ROLE`/ALTER/DROP/member-update 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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user