# KBN-010 — Threat, Authorization, and Constraint-Impact Gate

- **Issue:** [#753](https://git.mosaicstack.dev/mosaicstack/stack/issues/753)
- **Gate status:** **PASS / GO**
- **Reviewed baseline:** `origin/main` at `49e8a54` (2026-07-14)
- **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

## 1. Decision

KBN-010 is **PASS / GO** against frozen contract rc.4. The original rc.3 finding remains historical detection evidence:

- **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.

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.

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.

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.1 Inputs inspected

- Canonical requirements: `docs/requirements/native-kanban-sot.md`.
- Workstream manifest and read-only task plan.
- Frozen health, schema, Mechanical Coordinator, and recovery contracts in full.
- Actual current-main schema, Better Auth guard/scope helpers, project/task/mission/team controllers and repositories, fleet backlog, and `TASKS.md` parser/writer.
- Issue #753 through the Mosaic provider wrapper.

### 2.2 Current-main exposure that the target must replace, not inherit

| Current-main fact                                                                                                                                         | Constraint on future implementation                                                                                               |
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| Teams are global; projects, missions, tasks, agents, and fleet backlog have no `workspace_id`.                                                            | KBN-100 must add the workspace boundary and KBN-110 must query by server-derived workspace in every repository operation.         |
| `AuthGuard` authenticates a Better Auth user, while `scopeFromUser` falls back through optional tenant/team/org claims and finally user ID.               | Kanban tenancy must derive from an authenticated **active workspace membership**, not this compatibility fallback or caller data. |
| Team list/get/member endpoints return global team data to any authenticated user.                                                                         | New Kanban endpoints must use a uniform no-oracle denial and must not reuse global team lookup as authorization.                  |
| Project/task repositories load and mutate by bare IDs; controller checks are separate and sometimes distinguish not-found from forbidden.                 | Workspace predicates and authorization must be inside the authoritative transaction/repository command path.                      |
| Tasks can have nullable project/mission links, free-text assignee, JSON tags, no aggregate version, and no fence.                                         | Expand/backfill/quarantine must precede NOT NULL/composite constraints; new commands cannot trust legacy fields.                  |
| `mission_tasks.status` is a second status writer.                                                                                                         | Pre-expand must prohibit it as a write source and later retire it only after N-1 evidence.                                        |
| Fleet `backlog` has global JSON dependencies and TTL claims without workspace, assignment, approval, session, or fencing.                                 | It must be frozen and imported as non-dispatching shadow data; it cannot be adapted into the canonical lease path.                |
| `packages/coord/src/tasks-file.ts` parses and mutates `TASKS.md`.                                                                                         | KBN-120 must replace production use with generated, read-only projection code and prove there is no import/mutation path.         |
| No Kanban transaction-local health proof, semantic audit/event chain, change proposals, canonical outbox, approval binding, or fenced lease model exists. | These are new frozen invariants, not behaviors that may be inferred from current endpoints.                                       |

## 3. Authorization matrix

The exact route/DTO freeze belongs to KBN-105. This matrix fixes the minimum authorization behavior that freeze and later implementation must preserve.

| Principal/state                                    | Permitted authority                                                                   | Required authoritative checks                                                                                                                     | Explicit denials                                                                                                |
| -------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| Unauthenticated caller                             | Public health observation only, if deployment exposes it                              | Health DTO validation; no proof field accepted                                                                                                    | All canonical reads/mutations; health observation never authorizes a write                                      |
| Active workspace `owner`/`admin` user              | Policy-allowed workspace administration and domain commands                           | Better Auth session; active membership; server-derived workspace; command-family role; expected version/idempotency                               | Foreign workspace, suspended workspace, revoked membership, caller workspace override                           |
| Active workspace `member` user                     | Policy-allowed project/task/proposal commands                                         | Active membership plus project/team capability and target checks in the same transaction                                                          | Admin, approval, purge, service-only Coordinator, and unrelated project commands                                |
| Active workspace `auditor` user                    | Workspace-scoped reads and audit/evidence inspection                                  | Active membership and read capability                                                                                                             | Every mutation, approval, lease, token issuance, purge                                                          |
| Active workspace `service` identity                | Only explicitly issued command families                                               | Credential maps to workspace+agent+session; agent enabled; session live; role/capability allowlist; token expiry/audience; DB recheck per command | Raw DB credentials, user/admin fallback, cross-workspace scope, command families absent from token and registry |
| Enabled agent with live session                    | Agent commands matching its declared and policy-approved specialist role/capabilities | Exact workspace+agent+session binding, heartbeat/state, assignment target, lease, current decimal-string fence                                    | Ended/offline/degraded session where policy disallows; disabled agent; another assignment/session/fence         |
| Mechanical Coordinator engine                      | Pure eligibility/order/expiry decisions from immutable snapshots                      | Complete workspace-local snapshot and policy revision                                                                                             | Authentication, ID loading, SQL, proof minting, scope invention, approval, certification, merge                 |
| Coordinator persistence service                    | Service-only assignment/lease/checkpoint/recovery commands                            | Fresh transaction-local proof; locks; current assignment/approval/task/session/policy/fence                                                       | Public/user proof-by-value, stale approval/policy, direct completion/certification/merge                        |
| Reviewer/SecReview/Certifier                       | Attributable evidence decisions allowed by gate policy                                | Active authority, author differs from reviewer, mandatory SecReview classification, immutable artifacts                                           | Self-review; missing evidence; Certifier merge/issue-close/release                                              |
| Break-glass retention operator                     | Narrow, time-bounded purge procedure only                                             | Separate break-glass authority, reason, scope, approvals, immutable pre-purge evidence, semantic audit, post-action reconciliation                | Normal application role DELETE/UPDATE, bulk unscoped purge, unaudited hard delete                               |
| Revoked/expired/disabled identity or ended session | None beyond policy-permitted public observation                                       | Revocation/lifecycle checked from PostgreSQL on every command                                                                                     | Cached token/Valkey state cannot preserve authority                                                             |

**No-oracle rule:** authentication may return 401, but once authenticated, a foreign-workspace, nonexistent, inaccessible, or wrong-project identifier must follow the one KBN-105-frozen 404/403 policy with the same response shape and no foreign metadata, timing-derived detail, or WebSocket/MCP discrepancy.

## 4. Threat matrix

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                                                                          |
| --- | --------------------------------------------------------------------------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| 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                                                            |
| 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                                                            |
| 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                                                            |
| 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                                                            |
| 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                                                         |
| 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                                                            |
| 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                                                            |
| 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                                                    |
| 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                                                       |
| 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                                                        |
| 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                                                         |
| 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                                                         |
| 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                                                    |
| 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                                                        |
| 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                                                             |
| 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                                                     |
| 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

| 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-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-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-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-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-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-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-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

These names are normative evidence identifiers for future slices. Equivalent test-file names are acceptable only if traceability retains these IDs and expected outcomes.

### KBN-100 — schema and migration

- **N100-01** reject every canonical child row whose `workspace_id` differs from its parent.
- **N100-02** reject foreign-workspace link, artifact, proposal target, dependency, assignment, lease, checkpoint, approval, and event relationships.
- **N100-03** reject an inactive/revoked member as accountable owner, proposer, decision actor, archive actor, or user principal in the authoritative command transaction.
- **N100-04** reject a team/project relation crossing workspaces.
- **N100-05** reject a team authorization path when the user lacks active membership in the team's workspace.
- **N100-06** reject task→mission project mismatch.
- **N100-07** reject task→milestone and project→current-milestone project mismatch.
- **N100-08** reject task→parent project mismatch and self-parent.
- **N100-09** reject indirect parent cycles under concurrent transactions.
- **N100-10** reject mission→milestone project mismatch/orphan.
- **N100-11** reject checkpoint artifact from another workspace.
- **N100-12** reject checkpoint artifact owned by another same-workspace task/mission unless an explicitly frozen evidence rule permits it.
- **N100-13** reject approval evidence from another workspace.
- **N100-14** reject same-workspace approval evidence unrelated to the approval target.
- **N100-15** reject zero/multiple assignment principals and zero/multiple proposers.
- **N100-16** reject target session without its exact target agent.
- **N100-17** reject assignment task/agent/session crossing workspaces.
- **N100-18** reject non-positive task version and expired assignment acquisition.
- **N100-19** concurrent lease insert permits one active lease and returns one winner.
- **N100-20** successive leases return strictly increasing bigint fences.
- **N100-21** reject checkpoint with another task, lease, or fence.
- **N100-22** reject duplicate/non-monotonic checkpoint sequence.
- **N100-23** reject evidence join for a mismatched checkpoint/task.
- **N100-24** proposal insert without exact submission event fails atomically.
- **N100-25** foreign/wrong-type/wrong-proposal submission event fails atomically.
- **N100-26** foreign/wrong-target/unrelated acceptance event fails atomically.
- **N100-27** application role cannot UPDATE/DELETE `task_events`.
- **N100-28** application role cannot UPDATE/DELETE checkpoints/artifacts/evidence joins.
- **N100-29** parent hard delete is RESTRICTed while audit/evidence children exist.
- **N100-30** archive does not alter canonical lifecycle status.
- **N100-31** purge without break-glass authority/evidence is denied.
- **N100-32** reject dependency self-edge and duplicate directed pair regardless of type.
- **N100-33** reject direct and indirect dependency cycles.
- **N100-34** concurrent reciprocal dependency inserts cannot both commit.
- **N100-35** readiness remains false until every blocking predecessor and completion condition passes.
- **N100-36** empty DB migration succeeds after the contract amendment.
- **N100-37** production-shape expand retains all legacy declarations.
- **N100-38** crash/resume backfill is idempotent and checksum-stable.
- **N100-39** ambiguous workspace/owner/assignee is quarantined, never guessed.
- **N100-40** no `ready`/`in_review` status is emitted to N-1 readers before switch.
- **N100-41** `mission_tasks.status` cannot remain a write source.
- **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-44** pre-switch rollback works while post-first-mutation rollback requires freeze/reconciliation.
- **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

- **N105-01** every route has an explicit user/service command-family policy; user/admin tokens cannot call service-only Coordinator mutations.
- **N105-02** public DTO validation rejects `writeProof`, internal context, body `workspaceId`, and caller-asserted health.
- **N105-03** fixture exhaustiveness prevents 503, 502/504/timeout, and 409 cross-mapping.
- **N105-04** approval DTO accepts an ID and decision command only, never approval proof-by-value.
- **N105-05** all fence fields accept/emit decimal strings and reject JSON numbers.
- **N110-01** listing with a foreign `workspaceId` or foreign filter ID follows the frozen no-oracle denial and returns no rows/counts/cursors.
- **N110-02** get by foreign or nonexistent aggregate ID has the same frozen denial shape and no foreign metadata.
- **N110-03** create/update/archive with a foreign owner, parent, project, mission, milestone, tag, or target ID is denied before mutation.
- **N110-04** dependency/proposal commands with foreign target IDs are denied with unchanged state/event/outbox counts.
- **N110-05** REST, MCP, WebSocket, and internal Coordinator paths produce equivalent no-oracle behavior for the same foreign ID.
- **N110-06** a revoked/inactive owner is denied even with a still-valid Better Auth session.
- **N110-07** stale membership/team cache cannot authorize a proposer, decision actor, archive actor, or principal after revocation.
- **N110-08** a team ID from another workspace cannot authorize or own the command target.
- **N110-09** same-workspace but wrong-project mission/milestone/parent IDs are denied inside the transaction.
- **N110-10** an expired service token is denied before repository access.
- **N110-11** an audience- or workspace-mismatched service token is denied without an existence oracle.
- **N110-12** an over-scoped service token cannot call a command family absent from its role/capability allowlist.
- **N110-13** disabled agent or ended session revokes service-token command authority immediately on PostgreSQL recheck.
- **N110-14** contradictory public health state/boolean combinations fail validation.
- **N110-15** Valkey-only liveness cannot mint or substitute a PostgreSQL write proof.
- **N110-16** caller-forged public `healthy` cannot enter internal mutation context.
- **N110-17** public REST/MCP/CLI bodies containing health/proof fields are rejected.
- **N110-18** an expired internal proof produces no state/event/outbox write.
- **N110-19** a future-dated or not-yet-valid proof produces no write.
- **N110-20** a policy-revision-mismatched proof produces no write.
- **N110-21** a proof minted on another transaction/connection produces no write.
- **N110-22** a proof that expires before the final pre-mutation check produces no write.
- **N110-23** deliberate read-only/write-unavailable denial maps only to authoritative 503/not-applied/non-retryable.
- **N110-24** timeout before commit maps to transport-unknown and permits only same-key retry.
- **N110-25** timeout after commit maps to transport-unknown and same-key retry returns the committed canonical result once.
- **N110-26** expected-version mismatch maps only to 409/not-applied/non-retryable.
- **N110-27** recovery replay with a changed idempotency key cannot masquerade as the original uncertain request.
- **N110-28** pending proposal cannot alter target fields/status/rank/version.
- **N110-29** rejected proposal cannot affect readiness, dependencies, or gates.
- **N110-30** pending/rejected proposal cannot create an assignment or lease.
- **N110-31** direct proposal-row state manipulation cannot bypass normal command execution.
- **N110-32** proposal submission without a submission event rolls back fully.
- **N110-33** foreign-workspace submission event rolls back fully.
- **N110-34** wrong aggregate/event type submission event rolls back fully.
- **N110-35** same-workspace event for another proposal rolls back fully.
- **N110-36** submission event with wrong previous/new version semantics rolls back fully.
- **N110-37** foreign-workspace acceptance event rolls back proposal, target, event, and outbox.
- **N110-38** same-workspace event for another target aggregate rolls back acceptance.
- **N110-39** event from an unrelated normal command rolls back acceptance.
- **N110-40** event caused by a different submission event rolls back acceptance.
- **N110-41** event whose payload lacks or changes `changeProposalId` rolls back acceptance.
- **N110-42** event for another proposal with the same target/command rolls back acceptance.
- **N110-43** missing accepted-command event after target handling rolls back the entire transaction.
- **N110-44** read-only-degraded denial changes no DB row/outbox/file/Valkey/provider state.
- **N110-45** write-unavailable denial changes no DB row/outbox/file/Valkey/provider state.
- **N110-46** PostgreSQL disconnect cannot redirect a command to any fallback writer.
- **N110-47** commit uncertainty remains `unknown` and never becomes a fabricated 503/not-applied result.
- **N110-48** same-key replay after recovery returns one canonical result with no duplicate event/outbox row.
- **N110-49** Valkey publication failure leaves committed PG outbox pending and replayable.
- **N110-50** two same-version updates produce one winner and one visible 409 loser.
- **N110-51** identical duplicate key+payload returns the prior immutable result without another event/outbox row.
- **N110-52** same key with payload/command drift is rejected as an idempotency conflict.
- **N110-53** the same key in another workspace cannot reveal or reuse the first workspace's result.
- **N110-54** stale reconnect/update cannot silently overwrite a newer aggregate revision.
- **N110-55** failure after state write but before semantic event rolls back state.
- **N110-56** failure after semantic event but before outbox rolls back state and event.
- **N110-57** failure after outbox insert but before commit rolls back state, event, and outbox.
- **N110-58** success commits matching aggregate/event/outbox revisions and correlation/causation.
- **N120-01** CLI never retries an authoritative 503 deliberate denial.
- **N120-02** CLI retries only transport-unknown outcomes and preserves the exact idempotency key.
- **N120-03** generated projection header contains non-authoritative warning, workspace/project IDs, generated time, and source revision.
- **N120-04** projection revision and records match the API snapshot revision exactly.
- **N120-05** hand-tampering is overwritten or rejected by regeneration and never mutates PostgreSQL.
- **N120-06** static/runtime reachability finds no parser/import path from `TASKS.md`, `mission.json`, or another export.
- **N120-07** projection writer has no domain mutation/raw SQL/Valkey authority.
- **N130-01** UI foreign/no-access/not-found state follows the frozen no-oracle response and renders no stale foreign data.
- **N140-01** real-Gateway DB fault journey proves fail-closed no-fallback behavior.
- **N140-02** real-Gateway Valkey-loss journey proves pending outbox replay.
- **N140-03** real-Gateway concurrent update/retry journey proves version and idempotency semantics.
- **N140-04** generated-file tamper journey proves projection parity and no import.

### KBN-115/KBN-200/KBN-210/KBN-230 — recovery and coordination

- **N115-01** retention purge without current break-glass authority, reason, immutable evidence, or bounded scope is denied and audited.
- **N115-02** recovery posture with an unknown top-level or storage field is rejected.
- **N115-03** PITR retention without WAL archival is rejected.
- **N115-04** WAL archival with zero PITR retention is rejected.
- **N115-05** claimed RPO better than the configured backup/WAL mechanism is rejected.
- **N115-06** unencrypted, optional, or same-failure-domain storage is rejected.
- **N115-07** weakened high-assurance values are rejected.
- **N115-08** shape-only validation cannot pass without normative mechanism and restore evidence.
- **N200-01** cyclic/incomplete dependency snapshots never become eligible.
- **N200-02** identical immutable snapshot+policy+time returns identical ordering and explanation with no I/O/model import.
- **N210-01** disabled agent cannot claim, ack, heartbeat, checkpoint, or submit review.
- **N210-02** ended/offline/mismatched session cannot claim, ack, heartbeat, checkpoint, or submit review.
- **N210-03** foreign-workspace task is rejected after lock/reload without an oracle.
- **N210-04** stale task version is rejected before fence increment.
- **N210-05** assignment target agent mismatch is rejected.
- **N210-06** target session mismatch is rejected.
- **N210-07** expired assignment is rejected.
- **N210-08** assignment in rejected/released/expired/superseded/leased-invalid state is rejected.
- **N210-09** missing approval is rejected.
- **N210-10** rejected/escalated/requested approval is rejected as approval authority.
- **N210-11** stale policy-revision approval is rejected.
- **N210-12** foreign-workspace approval is rejected without an oracle.
- **N210-13** approval for another assignment is rejected.
- **N210-14** author self-approval/review is rejected when independence is required.
- **N210-15** foreign-workspace artifact evidence is rejected.
- **N210-16** same-workspace artifact unrelated to the assignment/task/gate is rejected.
- **N210-17** concurrent policy revocation versus acquire cannot produce a lease under the revoked revision.
- **N210-18** concurrent assignment expiry versus acquire cannot produce a lease after expiry.
- **N210-19** concurrent session end versus acquire cannot produce a lease for the ended session.
- **N210-20** lower fencing token is rejected without writes.
- **N210-21** token from an older lease is rejected without writes.
- **N210-22** token paired with another task is rejected without writes.
- **N210-23** token paired with another session is rejected without writes.
- **N210-24** token on an expired/revoked/released lease is rejected without writes.
- **N210-25** fences above JavaScript safe integer round-trip exactly as decimal strings.
- **N210-26** lease task does not match assignment task and is rejected.
- **N210-27** lease agent/session does not match assignment target and is rejected.
- **N210-28** checkpoint task does not match lease task and is rejected.
- **N210-29** checkpoint fence does not match exact lease fence and is rejected.
- **N210-30** checkpoint sequence duplicate/regression is rejected.
- **N210-31** checkpoint artifact does not match workspace/task/evidence semantics and is rejected.
- **N210-32** restart after assignment persistence reconstructs the pending assignment.
- **N210-33** restart after lease commit reconstructs exact active lease and fence.
- **N210-34** restart after checkpoint commit reconstructs checkpoint/recovery state.
- **N210-35** restart during expiry/retry/quarantine reconstructs durable disposition and eligibility.
- **N210-36** restart with pending outbox reconstructs publication work without Valkey/files.
- **N230-01** author=self-review and missing mandatory SecReview cannot certify or complete.
- **N230-02** normal application role cannot execute retention purge.
- **N230-03** break-glass purge cannot delete or alter its own authorization/evidence chain.
- **N230-04** Valkey down leaves canonical work in PostgreSQL/outbox.
- **N230-05** duplicate wake produces one logical effect after PostgreSQL reload/idempotency.
- **N230-06** stale wake cannot revive an expired/revoked assignment or lease.
- **N230-07** restart with no Valkey/files reconstructs leases/retry/quarantine/outbox exactly.

### KBN-300/KBN-320/KBN-330/KBN-340 — migration and cutover

- **N300-01** source record targeting another workspace is denied/quarantined without an oracle.
- **N300-02** malformed source record is rejected with attributable reject evidence.
- **N300-03** duplicate source system/key/batch replay is idempotent.
- **N300-04** source snapshot/checksum drift aborts apply/verify.
- **N300-05** partial import resumes from durable lineage without duplicating state/events.
- **N300-06** imported shadow record cannot become ready, assigned, or leased automatically.
- **N300-07** missing source key/file/checksum/batch lineage prevents apply/sign-off.
- **N300-08** importer cannot use direct DB, generated file, Valkey, or provider issue as canonical write authority.
- **N320-01** cutover without a verified write freeze fails safe.
- **N320-02** active legacy writer process or credential blocks cutover.
- **N320-03** reverse and forward synchronization cannot run concurrently.
- **N320-04** failed final delta/reconciliation blocks client switch.
- **N320-05** rollback before first canonical DB mutation may switch authority back only after freeze assertion.
- **N320-06** rollback after first canonical mutation requires freeze, DB-delta export/reconciliation, and owner decision.
- **N330-01** rehearsal cannot sign off while counts/checksums/exceptions/writer inventory differ.
- **N340-01** cutover cannot proceed without owner authorization, terminal evidence, scoped identities, and zero active legacy writers.

## 7. Requirements traceability

| Requirement      | Threats/impacts              | Planned evidence                                                |
| ---------------- | ---------------------------- | --------------------------------------------------------------- |
| REQ-SOT-001      | T16, T21, T22, T27, T29, T30 | N110-28..31, N110-44..49, N110-55..58, N120-03..07, N320-01..06 |
| 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-004      | T16..18                      | N100-24..26, N110-28..43                                        |
| 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-PLAN-001     | T04, T25                     | N100-06..10                                                     |
| REQ-TASK-001     | T13, T26, T31                | N100-20, N100-37..42, N110-50..54                               |
| REQ-TASK-002     | T16, T24                     | N110-28..31, N100-35, N200-01                                   |
| REQ-DEP-001      | T24                          | N100-32..35, N200-01                                            |
| REQ-ASN-001      | T10..12                      | N100-15..18, N210-03..19                                        |
| REQ-AUD-001      | T17..20, T22, T27            | N100-24..31, N110-32..43, N110-49, N110-55..58                  |
| REQ-API-001      | T01, T06..18, T26            | N105-01..05 plus KBN-110 catalog                                |
| REQ-UI-002/003   | T01, T15, T26                | N130-01 and real-Gateway KBN-140 journeys                       |
| REQ-COORD-001    | T22..24                      | N200-01/02, N210-32..36                                         |
| REQ-COORD-002    | T10..12, T16                 | N210-03..19, N110-28..31                                        |
| REQ-COORD-003    | T13..15, T23                 | N100-19..23, N210-20..36                                        |
| REQ-COORD-004    | T23, T26                     | N210-32..36, N230-07                                            |
| REQ-GATE-001/002 | T11, T19, T20                | N210-09..14, N230-01..03                                        |
| REQ-REC-001      | T20, T32                     | N115-01..08                                                     |
| REQ-MIG-001/002  | T28, T29, T31                | N100-37..44, N300-01..08, N320-01..06, N330-01, N340-01         |

REQ-UI-001 and REQ-UI-004 are downstream functional/accessibility requirements rather than schema-threat controls; they remain owned by KBN-130/KBN-140. Their security-relevant tenancy, conflict, and stale-reconnect portions are covered above.

## 8. Issue #753 acceptance mapping

| Issue requirement/criterion                                     | Evidence in this document                           | Result                                         |
| --------------------------------------------------------------- | --------------------------------------------------- | ---------------------------------------------- |
| 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                                         |
| 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                                         |
| Change-proposal abuse and event binding                         | T16–T18; CI-08                                      | Mapped                                         |
| Immutable audit and break-glass                                 | T19/T20; CI-09                                      | Mapped                                         |
| PostgreSQL/Valkey failures                                      | T21–T23; CI-10                                      | Mapped                                         |
| Dependency/idempotency/version races                            | T24–T27; CI-11                                      | 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                                         |
| No unresolved schema impact                                     | CI-14; rc.4 resolved-impact record                  | **PASS — none unresolved**                     |
| 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

none

### Resolved-impact record — KBN010-SI-001

- **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.
- **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.
- **Reviewed object:** commit `3f6a3387b419eb99453ee10dd25ba888faaab0b5`, tree `7ebab8fa530a7180036928cea9527f808548aa14`.
- **Corroborating identities:** full-index SHA-256 `6b40a76265c4f3e6d1d30a7f262a2dd16e0d51997e99c146b59f527e6524cd42`; stable patch-id `058cf98026fcd1043703c866aee047c8bb144740`.
- **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

- 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.
- 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.
- SI-001 is resolved at frozen contract/design-review level only. KBN-100 still owes N100-45..50 executable migration evidence.

**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.
