docs(#753): clear KBN-010 schema gate
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
This commit is contained in:
@@ -1,23 +1,34 @@
|
|||||||
# KBN-010 — Threat, Authorization, and Constraint-Impact Gate
|
# KBN-010 — Threat, Authorization, and Constraint-Impact Gate
|
||||||
|
|
||||||
- **Issue:** [#753](https://git.mosaicstack.dev/mosaicstack/stack/issues/753)
|
- **Issue:** [#753](https://git.mosaicstack.dev/mosaicstack/stack/issues/753)
|
||||||
- **Gate status:** **BLOCKED**
|
- **Gate status:** **PASS / GO**
|
||||||
- **Reviewed baseline:** `origin/main` at `49e8a54` (2026-07-14)
|
- **Reviewed baseline:** `origin/main` at `49e8a54` (2026-07-14)
|
||||||
- **Frozen target:** `SHARED-CONTRACT.md` v1.0.0-rc.3 and `contracts/*.v1.ts`
|
- **Frozen target:** `SHARED-CONTRACT.md` v1.0.0-rc.4 and `contracts/*.v1.ts`
|
||||||
|
- **Disposition input:** contract commit `3f6a3387b419eb99453ee10dd25ba888faaab0b5`, tree `7ebab8fa530a7180036928cea9527f808548aa14`
|
||||||
- **Scope:** documentation and future-test planning only; no runtime, schema, migration, API, configuration, dependency, CI, or deployment change
|
- **Scope:** documentation and future-test planning only; no runtime, schema, migration, API, configuration, dependency, CI, or deployment change
|
||||||
|
|
||||||
## 1. Decision
|
## 1. Decision
|
||||||
|
|
||||||
KBN-010 cannot pass. The frozen schema contract has one unresolved schema impact:
|
KBN-010 is **PASS / GO** against frozen contract rc.4. The original rc.3 finding remains historical detection evidence:
|
||||||
|
|
||||||
- **KBN010-SI-001 — invalid mission composite-FK candidate key.** `missionsV1` declares a primary key on `id` and a unique key on `(workspace_id, project_id, id)`, but not a candidate key on `(workspace_id, id)`. Both `artifacts_workspace_mission_fk` and `approval_decisions_workspace_mission_fk` reference exactly `(missions.workspace_id, missions.id)`. PostgreSQL requires the referenced column list of a foreign key to match a non-partial unique/primary candidate key; uniqueness of `id` alone does not satisfy a two-column `(workspace_id, id)` reference. KBN-100 therefore cannot create the frozen DDL as written.
|
- **KBN010-SI-001 — rc.3 invalid mission composite-FK candidate key.** At rc.3, `missionsV1` declared a primary key on `id` and a unique key on `(workspace_id, project_id, id)`, but not a candidate key on `(workspace_id, id)`. Both `artifacts_workspace_mission_fk` and `approval_decisions_workspace_mission_fk` referenced exactly `(missions.workspace_id, missions.id)`. PostgreSQL requires the referenced column list of a foreign key to match a non-partial unique/primary candidate key; uniqueness of `id` alone did not satisfy that two-column reference. The rc.3 DDL was therefore invalid, and KBN-010 correctly blocked it.
|
||||||
|
|
||||||
The contract authority must choose and version one of these semantics before KBN-100 starts:
|
Contract rc.4 resolves SI-001 by adding the non-partial `missions_workspace_id_uidx` candidate key on `(workspace_id, id)` while retaining the global `id` primary key and the project-congruent `(workspace_id, project_id, id)` key. Both polymorphic child FKs retain their exact workspace-safe ordered columns and `ON DELETE RESTRICT`; no target, tenancy, project-congruence, exactly-one-target, N-1, rollback, no-cascade, identity, approval, or fencing authority is weakened.
|
||||||
|
|
||||||
1. add a frozen unique candidate key on `missions(workspace_id, id)`; or
|
Independent Homelab non-author schema/security review returned **APPROVE** for the exact rc.4 commit/tree/content and found no collision with #757 connector fencing. SI-001 has no unresolved contract/schema-design impact.
|
||||||
2. add `project_id` to each child relation and use project-congruent `(workspace_id, project_id, mission_id)` foreign keys.
|
|
||||||
|
|
||||||
This document does **not** choose or apply either amendment. All other findings below are mapped to controls and future evidence, but the gate remains blocked until the frozen contract is amended and independently re-reviewed.
|
This GO completes the KBN-010 analysis/review prerequisite only. It does **not** claim that runtime schema or migration DDL exists. KBN-100 remains held and may be released only after this PR squash-merges, the merged change reaches terminal-green CI on `main`, and issue #753 closes.
|
||||||
|
|
||||||
|
### 1.1 Independent rc.4 evidence identity
|
||||||
|
|
||||||
|
- **Commit:** `3f6a3387b419eb99453ee10dd25ba888faaab0b5`
|
||||||
|
- **Tree:** `7ebab8fa530a7180036928cea9527f808548aa14`
|
||||||
|
- **Stable full-index SHA-256:** `6b40a76265c4f3e6d1d30a7f262a2dd16e0d51997e99c146b59f527e6524cd42`
|
||||||
|
- **Stable patch-id:** `058cf98026fcd1043703c866aee047c8bb144740`
|
||||||
|
- **Verdict:** Homelab independent non-author schema/security review **APPROVE**.
|
||||||
|
- **Reviewed conclusions:** the candidate key repairs both dependent FKs; tenant safety, polymorphic exactly-one-target semantics, RESTRICT/no-cascade behavior, and N-1/rollback semantics remain valid; #757 uses separate tables/indexes/FKs/identity/fence authority and has no collision.
|
||||||
|
|
||||||
|
A command-rendered patch SHA may differ when Git rendering options, headers, or command form differ. That rendering digest is non-authoritative. Canonical review identity is the Git commit object plus tree and exact file content; the stable full-index digest and stable patch-id above are corroborating identities.
|
||||||
|
|
||||||
## 2. Method and trust boundaries
|
## 2. Method and trust boundaries
|
||||||
|
|
||||||
@@ -67,60 +78,60 @@ The exact route/DTO freeze belongs to KBN-105. This matrix fixes the minimum aut
|
|||||||
|
|
||||||
Every disposition is against the frozen target, not a claim about current-main behavior.
|
Every disposition is against the frozen target, not a claim about current-main behavior.
|
||||||
|
|
||||||
| ID | Attacker or failure | Asset | Precondition and abuse path | Frozen preventive/detective control | Required schema/API/negative-test evidence | Future owner | Residual risk | Disposition |
|
| ID | Attacker or failure | Asset | Precondition and abuse path | Frozen preventive/detective control | Required schema/API/negative-test evidence | Future owner | Residual risk | Disposition |
|
||||||
| --- | --------------------------------------------------------------------------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ------------------------------------------------------------------- | ----------------------------------- |
|
| --- | --------------------------------------------------------------------------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
||||||
| T01 | Authenticated user supplies a foreign workspace/resource ID | Tenant confidentiality and integrity | Caller knows or guesses project/task/mission/team IDs and probes REST, MCP, WebSocket, repository, or Coordinator paths | `workspace_id` on every canonical row; composite relations; server-derived tenant; uniform no-oracle denial | Composite FK/unique DDL; every repository predicate includes workspace; N100-01/02, N110-01..05, N130-01 | KBN-100, 105, 110, 130 | Timing/volume side channels require operational review | Controlled after evidence |
|
| T01 | Authenticated user supplies a foreign workspace/resource ID | Tenant confidentiality and integrity | Caller knows or guesses project/task/mission/team IDs and probes REST, MCP, WebSocket, repository, or Coordinator paths | `workspace_id` on every canonical row; composite relations; server-derived tenant; uniform no-oracle denial | Composite FK/unique DDL; every repository predicate includes workspace; N100-01/02, N110-01..05, N130-01 | KBN-100, 105, 110, 130 | Timing/volume side channels require operational review | Controlled after evidence |
|
||||||
| T02 | Revoked or inactive member retains an old session | Ownership and mutation authority | Authentication remains valid after workspace membership revocation | Active membership rechecked in the authoritative transaction for owners, principals, proposers, and decision actors | Active/inactive membership fixtures; N100-03, N110-06/07; no cached membership authority | KBN-100, 110 | Better Auth session may remain valid for unrelated features | Controlled after evidence |
|
| T02 | Revoked or inactive member retains an old session | Ownership and mutation authority | Authentication remains valid after workspace membership revocation | Active membership rechecked in the authoritative transaction for owners, principals, proposers, and decision actors | Active/inactive membership fixtures; N100-03, N110-06/07; no cached membership authority | KBN-100, 110 | Better Auth session may remain valid for unrelated features | Controlled after evidence |
|
||||||
| T03 | User joins/forges a team relation outside its workspace | Team-owned projects and tasks | Global-current-main team behavior or a stale membership is reused | Team is intra-workspace only; workspace/team composites; active workspace membership precedes team authorization | Cross-workspace team/member/owner insert and command denials; N100-04/05, N110-08 | KBN-100, 110 | Team-role policy mistakes remain possible | Controlled after evidence |
|
| T03 | User joins/forges a team relation outside its workspace | Team-owned projects and tasks | Global-current-main team behavior or a stale membership is reused | Team is intra-workspace only; workspace/team composites; active workspace membership precedes team authorization | Cross-workspace team/member/owner insert and command denials; N100-04/05, N110-08 | KBN-100, 110 | Team-role policy mistakes remain possible | Controlled after evidence |
|
||||||
| T04 | Same-workspace IDs from a different project are combined | Planning hierarchy integrity | Valid mission/milestone/parent/current-milestone UUIDs are substituted | Project-congruent composite relations and serialized hierarchy validation | Mission/milestone/parent/current milestone mismatch and parent-cycle tests; N100-06..10, N110-09 | KBN-100, 110 | Deep hierarchy checks can be expensive | Controlled after evidence |
|
| T04 | Same-workspace IDs from a different project are combined | Planning hierarchy integrity | Valid mission/milestone/parent/current-milestone UUIDs are substituted | Project-congruent composite relations and serialized hierarchy validation | Mission/milestone/parent/current milestone mismatch and parent-cycle tests; N100-06..10, N110-09 | KBN-100, 110 | Deep hierarchy checks can be expensive | Controlled after evidence |
|
||||||
| T05 | Foreign or unrelated evidence/link/artifact IDs are attached | Review and audit truth | Caller has a valid same-workspace or foreign artifact UUID | Workspace-aware joins; immutable artifact digest/revision; semantic same-target validation in authoritative transaction | Mixed-workspace and same-workspace wrong-task/mission checkpoint/approval evidence tests; N100-11..14, N210-15/16 | KBN-100, 110, 210 | Same-workspace semantic validation is application-enforced | Controlled after evidence |
|
| T05 | Foreign or unrelated evidence/link/artifact IDs are attached | Review and audit truth | Caller has a valid same-workspace or foreign artifact UUID | Workspace-aware joins; immutable artifact digest/revision; semantic same-target validation in authoritative transaction | Mixed-workspace and same-workspace wrong-task/mission checkpoint/approval evidence tests; N100-11..14, N210-15/16 | KBN-100, 110, 210 | Same-workspace semantic validation is application-enforced | Controlled after evidence |
|
||||||
| T06 | Stolen, over-scoped, or replayed service token | Coordinator and task mutation authority | Service credential is accepted as admin/user or claims are trusted without DB state | Command-family least privilege; agent/session workspace binding; no raw DB credentials; enabled/live state checked per command | Auth registry fixtures prove audience/expiry/role/capability; revoked agent and ended session denials; N105-01, N110-10..13, N210-01/02 | KBN-105, 110, 210 | Credential theft until expiry/revocation check | Controlled after evidence |
|
| T06 | Stolen, over-scoped, or replayed service token | Coordinator and task mutation authority | Service credential is accepted as admin/user or claims are trusted without DB state | Command-family least privilege; agent/session workspace binding; no raw DB credentials; enabled/live state checked per command | Auth registry fixtures prove audience/expiry/role/capability; revoked agent and ended session denials; N105-01, N110-10..13, N210-01/02 | KBN-105, 110, 210 | Credential theft until expiry/revocation check | Controlled after evidence |
|
||||||
| T07 | Caller forges public `healthy` or replays a stale health response | Sole-writer/fail-closed invariant | Public health body or caller field reaches mutation context | Public DTO is observation only; public DTOs reject proof/health fields; Gateway mints internal proof after live PG transaction probe | Contradictory union and forbidden-field tests; N105-02, N110-14..17 | KBN-105, 110, 140 | Health endpoint can still be used for reconnaissance | Controlled after evidence |
|
| T07 | Caller forges public `healthy` or replays a stale health response | Sole-writer/fail-closed invariant | Public health body or caller field reaches mutation context | Public DTO is observation only; public DTOs reject proof/health fields; Gateway mints internal proof after live PG transaction probe | Contradictory union and forbidden-field tests; N105-02, N110-14..17 | KBN-105, 110, 140 | Health endpoint can still be used for reconnaissance | Controlled after evidence |
|
||||||
| T08 | Internal stale, wrong-policy, or wrong-transaction proof is reused | Transaction integrity | A branded value leaks or an adapter fails to revalidate it | Non-exported brand; transaction identity, `checkedAt <= now < validUntil`, and policy revision revalidated immediately before mutation | Wrong transaction, expiry boundary, future timestamp, policy mismatch, commit-after-expiry tests; N110-18..22 | KBN-110, 140 | In-process code can bypass TypeScript; runtime checks are mandatory | Controlled after evidence |
|
| T08 | Internal stale, wrong-policy, or wrong-transaction proof is reused | Transaction integrity | A branded value leaks or an adapter fails to revalidate it | Non-exported brand; transaction identity, `checkedAt <= now < validUntil`, and policy revision revalidated immediately before mutation | Wrong transaction, expiry boundary, future timestamp, policy mismatch, commit-after-expiry tests; N110-18..22 | KBN-110, 140 | In-process code can bypass TypeScript; runtime checks are mandatory | Controlled after evidence |
|
||||||
| T09 | DB/transport uncertainty is mislabeled as deliberate denial or conflict | Safe retry and exactly-once result | Timeout occurs before/after commit and client changes key or retries 503 | Exact 503/502/504/timeout/409 union; unknown outcome retries only with same idempotency key | Exhaustive fixture mapping and commit-before-timeout replay; N105-03, N110-23..27, N120-01/02 | KBN-105, 110, 120, 140 | External client may ignore retry rules | Controlled after evidence |
|
| T09 | DB/transport uncertainty is mislabeled as deliberate denial or conflict | Safe retry and exactly-once result | Timeout occurs before/after commit and client changes key or retries 503 | Exact 503/502/504/timeout/409 union; unknown outcome retries only with same idempotency key | Exhaustive fixture mapping and commit-before-timeout replay; N105-03, N110-23..27, N120-01/02 | KBN-105, 110, 120, 140 | External client may ignore retry rules | Controlled after evidence |
|
||||||
| T10 | Assignment payload forges task version, target agent/session, role, expiry, or proposer | Work routing authority | Lease service trusts command DTO rather than persisted assignment | Persisted assignment identity; exactly-one principal/proposer; exact agent/session composite; acquire accepts IDs then reloads+locks | Cross-workspace and same-workspace target substitutions, stale task version, invalid role, expired assignment; N100-15..18, N210-03..08 | KBN-100, 200, 210 | Compromised authorized proposer can make harmful proposals | Controlled by approval/audit |
|
| T10 | Assignment payload forges task version, target agent/session, role, expiry, or proposer | Work routing authority | Lease service trusts command DTO rather than persisted assignment | Persisted assignment identity; exactly-one principal/proposer; exact agent/session composite; acquire accepts IDs then reloads+locks | Cross-workspace and same-workspace target substitutions, stale task version, invalid role, expired assignment; N100-15..18, N210-03..08 | KBN-100, 200, 210 | Compromised authorized proposer can make harmful proposals | Controlled by approval/audit |
|
||||||
| T11 | Approval proof is forged by value or borrowed from another assignment | Gate integrity | Caller submits `approved=true`, unrelated decision ID, stale policy, or self-approval | Relational approval bound to assignment; lock/reload; policy revision; author≠reviewer and mandatory SecReview | No proof-by-value DTO; wrong assignment/task/workspace/policy/actor/decision tests; N105-04, N210-09..14, N230-01 | KBN-105, 210, 230 | Colluding principals remain an organizational risk | Controlled after evidence |
|
| T11 | Approval proof is forged by value or borrowed from another assignment | Gate integrity | Caller submits `approved=true`, unrelated decision ID, stale policy, or self-approval | Relational approval bound to assignment; lock/reload; policy revision; author≠reviewer and mandatory SecReview | No proof-by-value DTO; wrong assignment/task/workspace/policy/actor/decision tests; N105-04, N210-09..14, N230-01 | KBN-105, 210, 230 | Colluding principals remain an organizational risk | Controlled after evidence |
|
||||||
| T12 | Revoked policy or expired proposal/assignment is raced against lease acquisition | Routing policy | Approval and lease transactions do not lock/revalidate current rows | Lock assignment, approval, task, target session; compare current policy and expiry inside fresh-proof transaction | Concurrent revoke/expire/acquire tests with one valid terminal result; N210-17..19 | KBN-210, 230 | Clock skew if DB time is not canonical | Controlled after evidence |
|
| T12 | Revoked policy or expired proposal/assignment is raced against lease acquisition | Routing policy | Approval and lease transactions do not lock/revalidate current rows | Lock assignment, approval, task, target session; compare current policy and expiry inside fresh-proof transaction | Concurrent revoke/expire/acquire tests with one valid terminal result; N210-17..19 | KBN-210, 230 | Clock skew if DB time is not canonical | Controlled after evidence |
|
||||||
| T13 | Stale worker sends ack/heartbeat/checkpoint/review after reassignment | Canonical task and evidence state | Old process retains task/session IDs | Task-row-locked atomic monotonic bigint fence; every worker command carries exact lease/session/fence | Lower, expired, future, and other-task fences denied; old worker loses after new lease; N100-19/20, N210-20..24 | KBN-100, 210, 230 | Signed bigint exhaustion is theoretical | Controlled after evidence |
|
| T13 | Stale worker sends ack/heartbeat/checkpoint/review after reassignment | Canonical task and evidence state | Old process retains task/session IDs | Task-row-locked atomic monotonic bigint fence; every worker command carries exact lease/session/fence | Lower, expired, future, and other-task fences denied; old worker loses after new lease; N100-19/20, N210-20..24 | KBN-100, 210, 230 | Signed bigint exhaustion is theoretical | Controlled after evidence |
|
||||||
| T14 | JavaScript precision truncates a fence | Stale-worker exclusion | bigint token is serialized as number above `2^53-1` | Drizzle bigint and decimal-string wire type only | `9007199254740993` and near-`int8` boundary round trips; numeric JSON rejected; N105-05, N210-25 | KBN-105, 210 | Nonconforming external clients | Controlled after evidence |
|
| T14 | JavaScript precision truncates a fence | Stale-worker exclusion | bigint token is serialized as number above `2^53-1` | Drizzle bigint and decimal-string wire type only | `9007199254740993` and near-`int8` boundary round trips; numeric JSON rejected; N105-05, N210-25 | KBN-105, 210 | Nonconforming external clients | Controlled after evidence |
|
||||||
| T15 | Checkpoint/evidence from another lease/task/session is submitted | Recovery and certification evidence | Same-workspace valid IDs are mixed | Exact lease composite binds workspace+task+assignment/session+fence; checkpoint composite binds lease+fence; evidence join plus semantic artifact-owner check | Same-workspace mismatched task/assignment/lease/session/checkpoint/artifact tests; N100-21..23, N210-26..31 | KBN-100, 210 | Artifact URI target may disappear outside DB | Controlled with digest/retention |
|
| T15 | Checkpoint/evidence from another lease/task/session is submitted | Recovery and certification evidence | Same-workspace valid IDs are mixed | Exact lease composite binds workspace+task+assignment/session+fence; checkpoint composite binds lease+fence; evidence join plus semantic artifact-owner check | Same-workspace mismatched task/assignment/lease/session/checkpoint/artifact tests; N100-21..23, N210-26..31 | KBN-100, 210 | Artifact URI target may disappear outside DB | Controlled with digest/retention |
|
||||||
| T16 | Outage note or pending/rejected proposal mutates/orders work | Sole SOT and gate integrity | Importer/UI treats note/proposal as task state | Proposals are inert; only explicit accept invokes normal typed command after recovery | Row/outbox/task counts unchanged for pending/rejected; no readiness/dependency/lease effect; N110-28..31 | KBN-110, 140 | Humans may act outside Mosaic operationally | Accepted as attributable residual |
|
| T16 | Outage note or pending/rejected proposal mutates/orders work | Sole SOT and gate integrity | Importer/UI treats note/proposal as task state | Proposals are inert; only explicit accept invokes normal typed command after recovery | Row/outbox/task counts unchanged for pending/rejected; no readiness/dependency/lease effect; N110-28..31 | KBN-110, 140 | Humans may act outside Mosaic operationally | Accepted as attributable residual |
|
||||||
| T17 | Submission event is missing, foreign, or for another proposal | Proposal audit chain | Caller supplies an existing event UUID | Preallocated proposal ID; event-first same transaction; workspace composite FK; exact event type/aggregate/version semantic check | Missing/foreign/wrong-type/wrong-proposal event rolls back event+proposal; N100-24/25, N110-32..36 | KBN-100, 110 | Semantic checks are transaction code, not only FK | Controlled after evidence |
|
| T17 | Submission event is missing, foreign, or for another proposal | Proposal audit chain | Caller supplies an existing event UUID | Preallocated proposal ID; event-first same transaction; workspace composite FK; exact event type/aggregate/version semantic check | Missing/foreign/wrong-type/wrong-proposal event rolls back event+proposal; N100-24/25, N110-32..36 | KBN-100, 110 | Semantic checks are transaction code, not only FK | Controlled after evidence |
|
||||||
| T18 | Acceptance borrows an unrelated command event | Proposal and target integrity | Same-workspace event exists for another target/command/proposal | Accept locks proposal+target, executes normal command, requires workspace/target match, causation=submission event, payload proposal ID | Foreign, wrong target/type/command/causation/payload event aborts target/event/proposal atomically; N100-26, N110-37..43 | KBN-100, 110 | Event payload schema drift | Controlled by KBN-105 fixtures |
|
| T18 | Acceptance borrows an unrelated command event | Proposal and target integrity | Same-workspace event exists for another target/command/proposal | Accept locks proposal+target, executes normal command, requires workspace/target match, causation=submission event, payload proposal ID | Foreign, wrong target/type/command/causation/payload event aborts target/event/proposal atomically; N100-26, N110-37..43 | KBN-100, 110 | Event payload schema drift | Controlled by KBN-105 fixtures |
|
||||||
| T19 | Application role updates/deletes audit, approval evidence, checkpoint, or artifact | Nonrepudiation | Broad DB grants or parent cascade exists | INSERT/SELECT-only application roles; RESTRICT parent deletes; archive/cancel normal lifecycle | Role-level UPDATE/DELETE denied; parent delete RESTRICT; digest unchanged; N100-27..31 | KBN-100 | DB superuser can alter state | Break-glass/infra audit residual |
|
| T19 | Application role updates/deletes audit, approval evidence, checkpoint, or artifact | Nonrepudiation | Broad DB grants or parent cascade exists | INSERT/SELECT-only application roles; RESTRICT parent deletes; archive/cancel normal lifecycle | Role-level UPDATE/DELETE denied; parent delete RESTRICT; digest unchanged; N100-27..31 | KBN-100 | DB superuser can alter state | Break-glass/infra audit residual |
|
||||||
| T20 | Break-glass purge is used as routine deletion or erases its own evidence | Retention and incident forensics | Elevated credential available | Separate audited retention procedure, bounded scope, reason, pre/post evidence, authority separation | Normal role denied; expired/missing approval denied; purge cannot delete its authorizing audit package; N115-01, N230-02/03 | KBN-115, 230 | Privileged DBA compromise | Accepted operational residual |
|
| T20 | Break-glass purge is used as routine deletion or erases its own evidence | Retention and incident forensics | Elevated credential available | Separate audited retention procedure, bounded scope, reason, pre/post evidence, authority separation | Normal role denied; expired/missing approval denied; purge cannot delete its authorizing audit package; N115-01, N230-02/03 | KBN-115, 230 | Privileged DBA compromise | Accepted operational residual |
|
||||||
| T21 | PostgreSQL unavailable or partitioned | Canonical state | Public health/Valkey remains live while transaction probe fails | Fail closed; no alternate writer/hidden queue; 503 only for proven not-applied; transport uncertainty remains unknown | Fault injection proves DB rows/outbox/files/Valkey unchanged on deliberate denial; commit-unknown replay; N110-44..48, N140-01 | KBN-110, 140, 230 | Availability loss is intentional | Accepted by Option A |
|
| T21 | PostgreSQL unavailable or partitioned | Canonical state | Public health/Valkey remains live while transaction probe fails | Fail closed; no alternate writer/hidden queue; 503 only for proven not-applied; transport uncertainty remains unknown | Fault injection proves DB rows/outbox/files/Valkey unchanged on deliberate denial; commit-unknown replay; N110-44..48, N140-01 | KBN-110, 140, 230 | Availability loss is intentional | Accepted by Option A |
|
||||||
| T22 | Valkey unavailable, duplicated, stale, or partitioned | Scheduling notifications | Queue wake is treated as truth or publication fails | Valkey derived/expendable; transactional outbox in PG; idempotent publisher; recovery from PG | Commit with Valkey down leaves pending outbox; replay publishes once logically; stale wake reloads PG; N110-49, N140-02, N230-04..06 | KBN-110, 210, 230 | Duplicate at-least-once delivery | Consumers must be idempotent |
|
| T22 | Valkey unavailable, duplicated, stale, or partitioned | Scheduling notifications | Queue wake is treated as truth or publication fails | Valkey derived/expendable; transactional outbox in PG; idempotent publisher; recovery from PG | Commit with Valkey down leaves pending outbox; replay publishes once logically; stale wake reloads PG; N110-49, N140-02, N230-04..06 | KBN-110, 210, 230 | Duplicate at-least-once delivery | Consumers must be idempotent |
|
||||||
| T23 | Coordinator restarts between assignment, lease, checkpoint, or outbox steps | Durable orchestration truth | Process-local cache is treated as authority | PostgreSQL stores assignments, execution state, leases, fences, checkpoints, events, outbox; `recoverFromPostgres` | Restart at every transaction boundary reconstructs identical active/expired/pending sets without Valkey/files; N210-32..36, N230-07 | KBN-210, 230 | Recovery latency | Controlled after evidence |
|
| T23 | Coordinator restarts between assignment, lease, checkpoint, or outbox steps | Durable orchestration truth | Process-local cache is treated as authority | PostgreSQL stores assignments, execution state, leases, fences, checkpoints, events, outbox; `recoverFromPostgres` | Restart at every transaction boundary reconstructs identical active/expired/pending sets without Valkey/files; N210-32..36, N230-07 | KBN-210, 230 | Recovery latency | Controlled after evidence |
|
||||||
| T24 | Dependency cycle or concurrent reciprocal edge | Readiness and dispatch safety | Two transactions each see an acyclic graph before inserting | Unique directed edge; no self-edge; serialized recursive cycle check; readiness evaluates all blockers | Self/duplicate/cycle and concurrent A→B/B→A tests; all predecessor property test; N100-32..35, N200-01/02 | KBN-100, 200, 230 | Very large DAG performance | Bounded operational residual |
|
| T24 | Dependency cycle or concurrent reciprocal edge | Readiness and dispatch safety | Two transactions each see an acyclic graph before inserting | Unique directed edge; no self-edge; serialized recursive cycle check; readiness evaluates all blockers | Self/duplicate/cycle and concurrent A→B/B→A tests; all predecessor property test; N100-32..35, N200-01/02 | KBN-100, 200, 230 | Very large DAG performance | Bounded operational residual |
|
||||||
| T25 | Parent-task cycle or project-incongruent relation | Planning hierarchy | Valid same-workspace IDs are arranged into an invalid tree | Project-congruent composites; serialized parent-cycle/orphan validation required by REQ-PLAN-001 | Self/indirect parent cycle, orphan, and cross-project mission/milestone/parent tests; N100-06..10 | KBN-100, 110 | Cycle validation is service/transaction enforced | Controlled after evidence |
|
| T25 | Parent-task cycle or project-incongruent relation | Planning hierarchy | Valid same-workspace IDs are arranged into an invalid tree | Project-congruent composites; serialized parent-cycle/orphan validation required by REQ-PLAN-001 | Self/indirect parent cycle, orphan, and cross-project mission/milestone/parent tests; N100-06..10 | KBN-100, 110 | Cycle validation is service/transaction enforced | Controlled after evidence |
|
||||||
| T26 | Concurrent update, duplicate retry, or idempotency payload drift | Aggregate consistency | Two clients use same version/key with different payloads | Expected-version check; semantic event and outbox in same transaction; key returns prior immutable result only for identical command | One update wins; stale gets 409; duplicate identical returns prior; payload drift rejected; N110-50..54, N140-03 | KBN-105, 110, 140 | Long-lived clients face visible conflicts | Intentional user-visible residual |
|
| T26 | Concurrent update, duplicate retry, or idempotency payload drift | Aggregate consistency | Two clients use same version/key with different payloads | Expected-version check; semantic event and outbox in same transaction; key returns prior immutable result only for identical command | One update wins; stale gets 409; duplicate identical returns prior; payload drift rejected; N110-50..54, N140-03 | KBN-105, 110, 140 | Long-lived clients face visible conflicts | Intentional user-visible residual |
|
||||||
| T27 | State/event/outbox partial commit | Audit and notification consistency | Separate transactions or exception after state write | One PostgreSQL transaction for state+semantic event+outbox | Failure injected after each insert rolls all three back; success revisions align; N110-55..58 | KBN-110, 140 | Outbox publication remains asynchronous | Controlled after evidence |
|
| T27 | State/event/outbox partial commit | Audit and notification consistency | Separate transactions or exception after state write | One PostgreSQL transaction for state+semantic event+outbox | Failure injected after each insert rolls all three back; success revisions align; N110-55..58 | KBN-110, 140 | Outbox publication remains asynchronous | Controlled after evidence |
|
||||||
| T28 | Malicious/incorrect importer injects foreign workspace data or dispatchable work | Migration integrity | Source keys collide, lineage is absent, or importer has direct DB authority | Immutable source snapshots/checksums; one-way Gateway/migration-only port; workspace-safe idempotent modes; shadow records cannot dispatch | Foreign/malformed/duplicate/partial-resume/lineage checksum and no-dispatch tests; N300-01..08 | KBN-300, 330 | Source data may be semantically ambiguous | Quarantine and owner sign-off |
|
| T28 | Malicious/incorrect importer injects foreign workspace data or dispatchable work | Migration integrity | Source keys collide, lineage is absent, or importer has direct DB authority | Immutable source snapshots/checksums; one-way Gateway/migration-only port; workspace-safe idempotent modes; shadow records cannot dispatch | Foreign/malformed/duplicate/partial-resume/lineage checksum and no-dispatch tests; N300-01..08 | KBN-300, 330 | Source data may be semantically ambiguous | Quarantine and owner sign-off |
|
||||||
| T29 | Cutover leaves legacy writer or forward/reverse sync active | Sole-writer invariant | Credentials/processes survive switch or rollback is improvised | Writer inventory, freeze, final delta, Gateway switch, credential shutdown, no dual write; rollback authority changes after first DB mutation | Process/credential inventory; concurrent-writer assertion; before/after-mutation rollback rehearsal; N320-01..06, N330-01 | KBN-320, 330, 340 | Missed external automation | Owner-gated residual |
|
| T29 | Cutover leaves legacy writer or forward/reverse sync active | Sole-writer invariant | Credentials/processes survive switch or rollback is improvised | Writer inventory, freeze, final delta, Gateway switch, credential shutdown, no dual write; rollback authority changes after first DB mutation | Process/credential inventory; concurrent-writer assertion; before/after-mutation rollback rehearsal; N320-01..06, N330-01 | KBN-320, 330, 340 | Missed external automation | Owner-gated residual |
|
||||||
| T30 | Generated `TASKS.md`/`mission.json` is edited or parsed into DB | Canonical state | Current-main parser/writer remains reachable or file watcher imports changes | Generated non-authoritative header/IDs/time/revision; no production importer; regenerate/overwrite only | Static import search, tamper/regeneration, read-only permission, source-revision parity; N120-03..07, N140-04 | KBN-120, 140 | Humans may mistake snapshots for live data | Header and docs mitigate |
|
| T30 | Generated `TASKS.md`/`mission.json` is edited or parsed into DB | Canonical state | Current-main parser/writer remains reachable or file watcher imports changes | Generated non-authoritative header/IDs/time/revision; no production importer; regenerate/overwrite only | Static import search, tamper/regeneration, read-only permission, source-revision parity; N120-03..07, N140-04 | KBN-120, 140 | Humans may mistake snapshots for live data | Header and docs mitigate |
|
||||||
| T31 | N-1 compatibility copies legacy ambiguity into canonical authority | Data integrity | Nullable/global/current-main fields are guessed during backfill | Nullable-first expand; deterministic mapping or quarantine; checksums; no new-only status before switch; legacy fields retained | Production-shape, ambiguous owner/assignee, status shadow, JSON/config/digest, rollback tests; N100-36..44 | KBN-100 | Quarantined records require human decision | Controlled by signed reconciliation |
|
| T31 | N-1 compatibility copies legacy ambiguity into canonical authority | Data integrity | Nullable/global/current-main fields are guessed during backfill | Nullable-first expand; deterministic mapping or quarantine; checksums; no new-only status before switch; legacy fields retained | Production-shape, ambiguous owner/assignee, status shadow, JSON/config/digest, rollback tests; N100-36..44 | KBN-100 | Quarantined records require human decision | Controlled by signed reconciliation |
|
||||||
| T32 | Recovery posture claims durability not provided by mechanisms | Availability and audit retention | Shape-only validation or optimistic RPO is accepted | Normative validator; WAL/PITR/RPO/storage/high-assurance constraints; mechanism and restore evidence | Unknown/impossible/weakened configuration plus actual mechanism/restore tests; N115-02..08 | KBN-115 | Backup operator or storage compromise | Separate failure domain residual |
|
| T32 | Recovery posture claims durability not provided by mechanisms | Availability and audit retention | Shape-only validation or optimistic RPO is accepted | Normative validator; WAL/PITR/RPO/storage/high-assurance constraints; mechanism and restore evidence | Unknown/impossible/weakened configuration plus actual mechanism/restore tests; N115-02..08 | KBN-115 | Backup operator or storage compromise | Separate failure domain residual |
|
||||||
| T33 | Frozen DDL cannot create mission-scoped evidence/approval FKs | Tenant/evidence relational integrity | KBN-100 generates DDL from current contract | Intended workspace-aware mission FKs exist, but referenced `(workspace_id,id)` candidate key is absent | PostgreSQL migration test must fail before amendment; after amendment, empty/prod migration and cross-workspace FK tests must pass | Contract authority, then KBN-100 | None acceptable before schema release | **BLOCKER KBN010-SI-001** |
|
| T33 | rc.3 frozen DDL could not create mission-scoped evidence/approval FKs | Tenant/evidence relational integrity | KBN-100 generated DDL from the rc.3 contract without an exact composite candidate key | rc.4 adds non-partial `missions_workspace_id_uidx(workspace_id,id)` before both dependent FKs while retaining global and project-congruent keys | KBN-100 must execute N100-45..50: exact-key reconciliation, candidate-before-FKs, duplicate feasibility, empty/prod/N-1/rollback, and both-child foreign-workspace negatives | KBN-100 after PR/CI/#753 release | Runtime DDL remains unimplemented and must prove the frozen order | **Resolved by rc.4 + independent APPROVE; implementation evidence remains required** |
|
||||||
|
|
||||||
## 5. Constraint-impact matrix
|
## 5. Constraint-impact matrix
|
||||||
|
|
||||||
| Impact ID | Required invariant | Frozen schema impact | API/transaction impact | Required evidence | Owner | Status |
|
| Impact ID | Required invariant | Frozen schema impact | API/transaction impact | Required evidence | Owner | Status |
|
||||||
| --------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- | ------------------------------------------- | ------------------------------------- |
|
| --------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | --------------------------------------------------------------------------------- |
|
||||||
| CI-01 | Hard workspace tenancy and no oracle | `workspace_id`, workspace-aware unique/FKs on all canonical rows | Server-derived workspace; uniform denial on all surfaces | N100-01..14; N110-01..09; N130-01 | KBN-100/105/110/130 | Resolved by frozen controls |
|
| CI-01 | Hard workspace tenancy and no oracle | `workspace_id`, workspace-aware unique/FKs on all canonical rows | Server-derived workspace; uniform denial on all surfaces | N100-01..14; N110-01..09; N130-01 | KBN-100/105/110/130 | Resolved by frozen controls |
|
||||||
| CI-02 | Active user membership | Membership row plus unique `(workspace_id,user_id)`; active state retained | Recheck active membership in same authoritative transaction | N100-03; N110-06/07 | KBN-100/110 | Resolved; not FK-only |
|
| CI-02 | Active user membership | Membership row plus unique `(workspace_id,user_id)`; active state retained | Recheck active membership in same authoritative transaction | N100-03; N110-06/07 | KBN-100/110 | Resolved; not FK-only |
|
||||||
| CI-03 | Service identity least privilege/revocation | Agent/session workspace, lifecycle, state, roles, capabilities | Token maps to exact agent/session; command-family allowlist; DB recheck; no admin/raw DB fallback | N105-01; N110-10..13; N210-01/02 | KBN-105/110/210 | Resolved at auth/API layer |
|
| CI-03 | Service identity least privilege/revocation | Agent/session workspace, lifecycle, state, roles, capabilities | Token maps to exact agent/session; command-family allowlist; DB recheck; no admin/raw DB fallback | N105-01; N110-10..13; N210-01/02 | KBN-105/110/210 | Resolved at auth/API layer |
|
||||||
| CI-04 | Project-congruent hierarchy | Composite project/mission/milestone/parent/current-milestone relations | Lock/serialized parent-cycle and orphan validation | N100-06..10 | KBN-100/110 | Resolved; cycle behavior required |
|
| CI-04 | Project-congruent hierarchy | Composite project/mission/milestone/parent/current-milestone relations | Lock/serialized parent-cycle and orphan validation | N100-06..10 | KBN-100/110 | Resolved; cycle behavior required |
|
||||||
| CI-05 | Health-proof authority | Internal branded proof has transaction/time/policy fields | Probe and revalidate on same PG transaction; no public field | N105-02/03; N110-14..27 | KBN-105/110 | Resolved by frozen controls |
|
| CI-05 | Health-proof authority | Internal branded proof has transaction/time/policy fields | Probe and revalidate on same PG transaction; no public field | N105-02/03; N110-14..27 | KBN-105/110 | Resolved by frozen controls |
|
||||||
| CI-06 | Assignment/approval identity | Exactly-one principal/proposer, exact agent/session assignment, relational approval | Reload+lock all IDs; compare version/target/state/expiry/policy/decision | N100-15..18; N210-03..19 | KBN-100/210 | Resolved by frozen controls |
|
| CI-06 | Assignment/approval identity | Exactly-one principal/proposer, exact agent/session assignment, relational approval | Reload+lock all IDs; compare version/target/state/expiry/policy/decision | N100-15..18; N210-03..19 | KBN-100/210 | Resolved by frozen controls |
|
||||||
| CI-07 | Monotonic bigint fencing | Durable bigint counter, exact lease/fence keys, one active lease | Atomic increment/RETURNING; decimal-string DTO; reject every stale worker command | N100-19..23; N210-20..31 | KBN-100/105/210 | Resolved by frozen controls |
|
| CI-07 | Monotonic bigint fencing | Durable bigint counter, exact lease/fence keys, one active lease | Atomic increment/RETURNING; decimal-string DTO; reject every stale worker command | N100-19..23; N210-20..31 | KBN-100/105/210 | Resolved by frozen controls |
|
||||||
| CI-08 | Proposal event chain | Both workspace-aware event FKs; event table created first | Exact submission/acceptance semantic checks in one transaction | N100-24..26; N110-28..43 | KBN-100/110 | Resolved; semantic checks not FK-only |
|
| CI-08 | Proposal event chain | Both workspace-aware event FKs; event table created first | Exact submission/acceptance semantic checks in one transaction | N100-24..26; N110-28..43 | KBN-100/110 | Resolved; semantic checks not FK-only |
|
||||||
| CI-09 | Immutable audit/evidence retention | RESTRICT parents; INSERT/SELECT-only immutable tables | Archive/cancel normal flow; separately authorized purge | N100-27..31; N115-01; N230-02/03 | KBN-100/115/230 | Resolved by frozen controls |
|
| CI-09 | Immutable audit/evidence retention | RESTRICT parents; INSERT/SELECT-only immutable tables | Archive/cancel normal flow; separately authorized purge | N100-27..31; N115-01; N230-02/03 | KBN-100/115/230 | Resolved by frozen controls |
|
||||||
| CI-10 | DB/Valkey/outbox/restart semantics | PG outbox and durable orchestration rows | Fail closed; same-key uncertainty retry; Valkey reloads PG; restart from PG | N110-44..49; N140-01/02; N230-04..07 | KBN-110/210/230 | Resolved by frozen controls |
|
| CI-10 | DB/Valkey/outbox/restart semantics | PG outbox and durable orchestration rows | Fail closed; same-key uncertainty retry; Valkey reloads PG; restart from PG | N110-44..49; N140-01/02; N230-04..07 | KBN-110/210/230 | Resolved by frozen controls |
|
||||||
| CI-11 | DAG/race/idempotency/version | Unique edge; self check; event idempotency; aggregate versions | Serialized recursive cycle check; payload binding; expected-version conflict | N100-32..35; N110-50..58; N200-01/02 | KBN-100/110/200 | Resolved by frozen controls |
|
| CI-11 | DAG/race/idempotency/version | Unique edge; self check; event idempotency; aggregate versions | Serialized recursive cycle check; payload binding; expected-version conflict | N100-32..35; N110-50..58; N200-01/02 | KBN-100/110/200 | Resolved by frozen controls |
|
||||||
| CI-12 | Import/cutover trust boundary | Lineage/artifact/event fields; shadow state cannot dispatch | One-way scoped importer, freeze, no direct DB/file authority, no dual writer | N300-01..08; N320-01..06 | KBN-300/320/330 | Resolved by frozen controls |
|
| CI-12 | Import/cutover trust boundary | Lineage/artifact/event fields; shadow state cannot dispatch | One-way scoped importer, freeze, no direct DB/file authority, no dual writer | N300-01..08; N320-01..06 | KBN-300/320/330 | Resolved by frozen controls |
|
||||||
| CI-13 | Generated-file no-import | No canonical file schema/import contract | Projection-only package; static reachability check removes current parser from production Kanban paths | N120-03..07; N140-04 | KBN-120/140 | Resolved by frozen controls |
|
| CI-13 | Generated-file no-import | No canonical file schema/import contract | Projection-only package; static reachability check removes current parser from production Kanban paths | N120-03..07; N140-04 | KBN-120/140 | Resolved by frozen controls |
|
||||||
| CI-14 | Mission-scoped artifact and approval FKs | **Missing unique candidate key `(workspace_id,id)` on `missionsV1` for two frozen composite FKs** | No API control can make invalid migration DDL creatable | Amendment plus empty/prod migration proof and foreign-workspace tests | Contract authority; KBN-100 after amendment | **UNRESOLVED / BLOCKER** |
|
| CI-14 | Mission-scoped artifact and approval FKs | rc.4 adds non-partial `missions_workspace_id_uidx(workspace_id,id)` and retains global/project-congruent keys | KBN-100 must emit the candidate before both exact RESTRICT FKs and preserve N-1/rollback order | N100-45..50: exact reconciliation, duplicate feasibility, empty/prod/N-1/rollback, and separate artifact/approval foreign-workspace negatives | KBN-100 after PR/CI/#753 release | **Resolved by rc.4 and independent APPROVE; future executable evidence required** |
|
||||||
|
|
||||||
## 6. Exact future negative-test catalog
|
## 6. Exact future negative-test catalog
|
||||||
|
|
||||||
@@ -172,7 +183,12 @@ These names are normative evidence identifiers for future slices. Equivalent tes
|
|||||||
- **N100-42** tags/assignee/date/mission JSON/config/description/agent fields reconcile without loss.
|
- **N100-42** tags/assignee/date/mission JSON/config/description/agent fields reconcile without loss.
|
||||||
- **N100-43** claimed fleet backlog rows are quarantined and imported rows cannot dispatch.
|
- **N100-43** claimed fleet backlog rows are quarantined and imported rows cannot dispatch.
|
||||||
- **N100-44** pre-switch rollback works while post-first-mutation rollback requires freeze/reconciliation.
|
- **N100-44** pre-switch rollback works while post-first-mutation rollback requires freeze/reconciliation.
|
||||||
- **N100-45** before amendment, PostgreSQL rejects both mission composite FKs for lack of a matching `(workspace_id,id)` candidate key; after amendment, both DDL relations and foreign-workspace denials pass.
|
- **N100-45** reconcile both exact child FK column lists to the rc.4 `(workspace_id,id)` mission candidate while retaining the global `id` primary key and `(workspace_id,project_id,id)` key.
|
||||||
|
- **N100-46** empty-DB migration creates `missions_workspace_id_uidx` before `artifacts_workspace_mission_fk` and `approval_decisions_workspace_mission_fk`.
|
||||||
|
- **N100-47** production-shape preflight finds no duplicate `(workspace_id,id)` groups, preserves global `id` uniqueness, and applies the candidate before both dependent FKs.
|
||||||
|
- **N100-48** N-1 startup/read/write remains unchanged; pre-switch rollback drops both dependents before the candidate and preserves the global/project-congruent keys.
|
||||||
|
- **N100-49** artifact insert using a valid mission ID paired with a foreign workspace fails before commit.
|
||||||
|
- **N100-50** approval-decision insert using a valid mission ID paired with a foreign workspace fails before commit.
|
||||||
|
|
||||||
### KBN-105/KBN-110/KBN-120/KBN-130/KBN-140 — API and P1
|
### KBN-105/KBN-110/KBN-120/KBN-130/KBN-140 — API and P1
|
||||||
|
|
||||||
@@ -335,7 +351,7 @@ These names are normative evidence identifiers for future slices. Equivalent tes
|
|||||||
| REQ-SOT-002 | T07, T08, T09, T21 | N105-02/03, N110-14..27, N110-44..48 |
|
| REQ-SOT-002 | T07, T08, T09, T21 | N105-02/03, N110-14..27, N110-44..48 |
|
||||||
| REQ-SOT-003 | T30 | N120-03..07, N140-04 |
|
| REQ-SOT-003 | T30 | N120-03..07, N140-04 |
|
||||||
| REQ-SOT-004 | T16..18 | N100-24..26, N110-28..43 |
|
| REQ-SOT-004 | T16..18 | N100-24..26, N110-28..43 |
|
||||||
| REQ-TEN-001 | T01..05, T15, T33 | N100-01..14, N110-01..09, N210-15/16, N100-45 |
|
| REQ-TEN-001 | T01..05, T15, T33 | N100-01..14, N100-45..50, N110-01..09, N210-15/16 |
|
||||||
| REQ-ID-001 | T02, T03, T06, T10..12 | N105-01, N110-06..13, N210-01..19 |
|
| REQ-ID-001 | T02, T03, T06, T10..12 | N105-01, N110-06..13, N210-01..19 |
|
||||||
| REQ-PLAN-001 | T04, T25 | N100-06..10 |
|
| REQ-PLAN-001 | T04, T25 | N100-06..10 |
|
||||||
| REQ-TASK-001 | T13, T26, T31 | N100-20, N100-37..42, N110-50..54 |
|
| REQ-TASK-001 | T13, T26, T31 | N100-20, N100-37..42, N110-50..54 |
|
||||||
@@ -357,38 +373,43 @@ REQ-UI-001 and REQ-UI-004 are downstream functional/accessibility requirements r
|
|||||||
|
|
||||||
## 8. Issue #753 acceptance mapping
|
## 8. Issue #753 acceptance mapping
|
||||||
|
|
||||||
| Issue requirement/criterion | Evidence in this document | Result |
|
| Issue requirement/criterion | Evidence in this document | Result |
|
||||||
| --------------------------------------------------------------- | ----------------------------------------------- | ------------------------- |
|
| --------------------------------------------------------------- | --------------------------------------------------- | ---------------------------------------------- |
|
||||||
| Cross-workspace owners, principals, evidence, project hierarchy | T01–T05, T15, T25; CI-01–04 | Mapped |
|
| Cross-workspace owners, principals, evidence, project hierarchy | T01–T05, T15, T25; CI-01–04 | Mapped |
|
||||||
| Active membership and service-token boundaries | Authorization matrix; T02, T03, T06; CI-02/03 | Mapped |
|
| Active membership and service-token boundaries | Authorization matrix; T02, T03, T06; CI-02/03 | Mapped |
|
||||||
| Stale/forged health and transaction-local proof | T07–T09, T21; CI-05 | Mapped |
|
| Stale/forged health and transaction-local proof | T07–T09, T21; CI-05 | Mapped |
|
||||||
| Assignment/approval forgery and monotonic fencing | T10–T15; CI-06/07 | Mapped |
|
| Assignment/approval forgery and monotonic fencing | T10–T15; CI-06/07 | Mapped |
|
||||||
| Change-proposal abuse and event binding | T16–T18; CI-08 | Mapped |
|
| Change-proposal abuse and event binding | T16–T18; CI-08 | Mapped |
|
||||||
| Immutable audit and break-glass | T19/T20; CI-09 | Mapped |
|
| Immutable audit and break-glass | T19/T20; CI-09 | Mapped |
|
||||||
| PostgreSQL/Valkey failures | T21–T23; CI-10 | Mapped |
|
| PostgreSQL/Valkey failures | T21–T23; CI-10 | Mapped |
|
||||||
| Dependency/idempotency/version races | T24–T27; CI-11 | Mapped |
|
| Dependency/idempotency/version races | T24–T27; CI-11 | Mapped |
|
||||||
| Import/cutover and generated-file boundary | T28–T31; CI-12/13 | Mapped |
|
| Import/cutover and generated-file boundary | T28–T31; CI-12/13 | Mapped |
|
||||||
| Every schema/API/test impact explicit | Constraint matrix and negative-test catalog | Mapped |
|
| Every schema/API/test impact explicit | Constraint matrix and negative-test catalog | Mapped |
|
||||||
| No unresolved schema impact | CI-14 / KBN010-SI-001 | **Failed — blocker** |
|
| No unresolved schema impact | CI-14; rc.4 resolved-impact record | **PASS — none unresolved** |
|
||||||
| Independent SecReview | Must occur after contract-authority disposition | Pending; gate cannot pass |
|
| Independent SecReview | Homelab non-author exact commit/tree/content review | **PASS / APPROVE** |
|
||||||
|
| PR merge, terminal-green main CI, and #753 closure | Orchestrator-owned post-worker gates | Pending; KBN-100 remains held until completion |
|
||||||
|
|
||||||
## 9. UNRESOLVED SCHEMA IMPACTS
|
## 9. UNRESOLVED SCHEMA IMPACTS
|
||||||
|
|
||||||
**KBN010-SI-001 — `missions(workspace_id,id)` is not a declared candidate key for two frozen composite foreign keys.**
|
none
|
||||||
|
|
||||||
Affected frozen declarations in `contracts/kanban-schema.v1.ts`:
|
### Resolved-impact record — KBN010-SI-001
|
||||||
|
|
||||||
- `missions_workspace_project_id_uidx` is `(workspace_id, project_id, id)`.
|
- **Historical detection:** rc.3 lacked an exact `(workspace_id,id)` candidate key for the artifact and approval-decision mission FKs. This document's original BLOCKED verdict was correct and remains preserved in §1 and T33.
|
||||||
- `artifacts_workspace_mission_fk` references `(workspace_id, mission_id)` → `missions(workspace_id, id)`.
|
- **Resolution:** rc.4 adds non-partial `missions_workspace_id_uidx(workspace_id,id)` before both exact dependent FKs while retaining the global primary key and project-congruent key.
|
||||||
- `approval_decisions_workspace_mission_fk` references `(workspace_id, mission_id)` → `missions(workspace_id, id)`.
|
- **Reviewed object:** commit `3f6a3387b419eb99453ee10dd25ba888faaab0b5`, tree `7ebab8fa530a7180036928cea9527f808548aa14`.
|
||||||
|
- **Corroborating identities:** full-index SHA-256 `6b40a76265c4f3e6d1d30a7f262a2dd16e0d51997e99c146b59f527e6524cd42`; stable patch-id `058cf98026fcd1043703c866aee047c8bb144740`.
|
||||||
**Required disposition:** contract authority must amend/version the frozen schema, update this gate's frozen-input digest/reference, and obtain independent schema/SecReview. KBN-100 remains held. No worker may silently add an index or alter child keys during implementation.
|
- **Independent verdict:** Homelab non-author schema/security review **APPROVE**. It confirmed PostgreSQL candidate/FK validity, unchanged tenant and polymorphic exactly-one-target safety, RESTRICT/no-cascade semantics, N-1/rollback validity, and no shared table/index/FK/identity/fence authority collision with #757.
|
||||||
|
- **Digest interpretation:** a command-rendered patch digest varied with rendering command/options and is non-authoritative. Git commit + tree + exact file content are canonical; stable full-index SHA-256 and stable patch-id corroborate that identity.
|
||||||
|
- **Residual implementation obligations:** KBN-100 must create the candidate before both dependent FKs; prove production-shape duplicate feasibility without weakening global uniqueness; pass empty/prod/N-1/rollback tests; reconcile both exact FK targets; and separately reject foreign-workspace mission references for artifacts and approval decisions (N100-45..50).
|
||||||
|
- **Implementation status:** no runtime schema, migration, API, or deployment implementation is claimed by this gate disposition.
|
||||||
|
|
||||||
## 10. Residual risk and handoff
|
## 10. Residual risk and handoff
|
||||||
|
|
||||||
- Even after schema amendment, active membership, polymorphic targets, same-task evidence semantics, parent/DAG cycle checks, token scope, and no-oracle behavior depend on authoritative transaction code and must not be treated as FK-only guarantees.
|
- Active membership, polymorphic targets, same-task evidence semantics, parent/DAG cycle checks, token scope, and no-oracle behavior depend on authoritative transaction code and must not be treated as FK-only guarantees.
|
||||||
- DB superuser and break-glass compromise cannot be eliminated by application constraints; separation of duties, immutable external backup/audit evidence, drills, and monitoring remain required.
|
- DB superuser and break-glass compromise cannot be eliminated by application constraints; separation of duties, immutable external backup/audit evidence, drills, and monitoring remain required.
|
||||||
- PostgreSQL unavailability intentionally sacrifices writes for integrity. Transport-unknown outcomes remain safe only when clients preserve the exact idempotency key.
|
- PostgreSQL unavailability intentionally sacrifices writes for integrity. Transport-unknown outcomes remain safe only when clients preserve the exact idempotency key.
|
||||||
- Imported ambiguous records remain quarantined until owner sign-off; no automated mapping may convert ambiguity into authority.
|
- Imported ambiguous records remain quarantined until owner sign-off; no automated mapping may convert ambiguity into authority.
|
||||||
|
- SI-001 is resolved at frozen contract/design-review level only. KBN-100 still owes N100-45..50 executable migration evidence.
|
||||||
|
|
||||||
**Handoff status:** BLOCKED. Contract authority action is required before independent SecReview can return PASS and before KBN-100 is released.
|
**Handoff status:** KBN-010 **PASS / GO** at rc.4. KBN-100 remains held until this PR squash-merges, terminal-green CI completes on `main`, and issue #753 closes; the orchestrator owns those remaining gates.
|
||||||
|
|||||||
@@ -73,3 +73,29 @@ Pending worker validation, independent SecReview, Ultron gate, PR merge, post-me
|
|||||||
- Independent Codex security review — PASS, zero critical/high/medium/low findings; tenant isolation is preserved.
|
- Independent Codex security review — PASS, zero critical/high/medium/low findings; tenant isolation is preserved.
|
||||||
- Independent Codex code review confirmed the candidate key repairs both FK targets and reported no blocker on the authorized delta. Its initial request to rewrite the historical KBN-010 verdict conflicts with the exclusive scope and was resolved by documenting the immutable-evidence boundary in rc.4; its remaining finding concerns pre-existing live `.mosaic` session files, which are untouched and excluded from this commit.
|
- Independent Codex code review confirmed the candidate key repairs both FK targets and reported no blocker on the authorized delta. Its initial request to rewrite the historical KBN-010 verdict conflicts with the exclusive scope and was resolved by documenting the immutable-evidence boundary in rc.4; its remaining finding concerns pre-existing live `.mosaic` session files, which are untouched and excluded from this commit.
|
||||||
- Scoped diff: only the two frozen contract files and this append-only scratchpad amendment are staged for delivery; no runtime schema, migration, task plan, gate verdict, provider artifact, or #757-owned file is included.
|
- Scoped diff: only the two frozen contract files and this append-only scratchpad amendment are staged for delivery; no runtime schema, migration, task plan, gate verdict, provider artifact, or #757-owned file is included.
|
||||||
|
|
||||||
|
## 2026-07-14 final rc.4 KBN-010 disposition
|
||||||
|
|
||||||
|
- Control-plane direction authorized final disposition edits only to `docs/native-kanban-sot/KBN-010-THREAT-AUTH-CONSTRAINT-GATE.md` and this append-only scratchpad; contract author `web1:kbn-contract` remained idle and undisturbed.
|
||||||
|
- Exact reviewed contract object: commit `3f6a3387b419eb99453ee10dd25ba888faaab0b5`, tree `7ebab8fa530a7180036928cea9527f808548aa14`.
|
||||||
|
- Corroborating review identities: full-index SHA-256 `6b40a76265c4f3e6d1d30a7f262a2dd16e0d51997e99c146b59f527e6524cd42`; stable patch-id `058cf98026fcd1043703c866aee047c8bb144740`. A command-rendered patch digest varied by Git rendering command/options and is non-authoritative; commit+tree+exact file content are canonical.
|
||||||
|
- Independent Homelab non-author schema/security review verdict: **APPROVE**. It confirmed the rc.4 `missions_workspace_id_uidx(workspace_id,id)` repairs both dependent FKs while retaining the global PK and project-congruent key; tenant, polymorphic exactly-one-target, RESTRICT/no-cascade, N-1/rollback semantics remain valid.
|
||||||
|
- Read-only #757 cross-check: no shared table, index, FK, identity, fence, or authority collision with connector lease/CAS fencing.
|
||||||
|
- Final KBN-010 gate decision: **PASS / GO** at rc.4 with `UNRESOLVED SCHEMA IMPACTS` equal to exact `none`. Historical SI-001 detection remains in the gate document as evidence that rc.3 was invalid.
|
||||||
|
- No runtime schema/migration/API/config/dependency/CI/deployment implementation is claimed. KBN-100 must still implement candidate-before-dependent-FK ordering, duplicate feasibility, empty/prod/N-1/rollback evidence, exact FK reconciliation, and separate artifact/approval foreign-workspace negatives (N100-45..50).
|
||||||
|
- TDD remains not applicable because this continuation changes only documentation/evidence disposition and no runtime behavior.
|
||||||
|
- Remaining orchestrator-owned sequence: worker validation/commit/push → PR open/update → Ultron review → squash merge → terminal-green post-main CI → close #753 → release KBN-100. KBN-100 is not released earlier.
|
||||||
|
|
||||||
|
### Final worker validation
|
||||||
|
|
||||||
|
- Changed-doc Prettier and link checks — PASS; issue #753 external link returned successfully.
|
||||||
|
- Static future-test catalog check — PASS: all prefixes are individually enumerated, contiguous, and duplicate-free; N100 now spans N100-01..50.
|
||||||
|
- rc.4 disposition assertions — PASS: gate status PASS/GO, frozen target rc.4, exact `none` unresolved section, independent APPROVE, review identities, and N100-50 are present.
|
||||||
|
- Review identity reproduction — PASS: commit tree `7ebab8fa530a7180036928cea9527f808548aa14`, full-index SHA-256 `6b40a76265c4f3e6d1d30a7f262a2dd16e0d51997e99c146b59f527e6524cd42`, and stable patch-id `058cf98026fcd1043703c866aee047c8bb144740` match.
|
||||||
|
- rc.4 frozen-contract static check — PASS: the candidate key is unique in the declaration and precedes both dependent FKs; frozen contract files remain byte-identical to commit `3f6a3387b419eb99453ee10dd25ba888faaab0b5`.
|
||||||
|
- `pnpm exec tsc -p docs/native-kanban-sot/tsconfig.json --noEmit` — PASS.
|
||||||
|
- `pnpm format:check` — PASS.
|
||||||
|
- `pnpm lint` — PASS (23 tasks successful).
|
||||||
|
- `pnpm typecheck` — PASS (42 tasks successful).
|
||||||
|
- Scoped diff — PASS: only the gate document and this scratchpad are authored changes; contracts, TASKS, requirements, runtime/schema/migration/config/dependency/CI/deployment and #757-owned files are unchanged. Live `.mosaic` session state remains untouched and excluded.
|
||||||
|
- Remaining worker steps: final formatting/scoped staging, commit `docs(#753): clear KBN-010 schema gate`, queue guard, push, and control-plane notification.
|
||||||
|
|||||||
Reference in New Issue
Block a user