44 KiB
Native Kanban/SOT — Remediated Shared Contract v1
Status: CONTROL-PLANE rc.6 DB role/connection remediation pending independent exact-head re-review; prior KCR-001–016 and rc.4 SI-001 decisions retained; KBN-101 foundation certification precedes KBN-100 and real immutable-operation certification precedes KBN-105
Version: 1.0.0-rc.6
Date: 2026-07-15
Change authority: Mosaic control plane/Jason only
SI-001 amendment authority: web1:mosaic-100 control-plane decision under issue #753
Amendment record
1.0.0-rc.6 — KBN-101 closed DDL/TLS/ledger activation remediation
- Choice:
mosaic-db-migratoris the sole application/CI/test PostgreSQL DDL control plane. Every legacy entrypoint is routed or denied, rejectsDATABASE_URL-only before connection/DDL, anddb:pushis unavailable outside an allowlisted disposable developer target. The runner holds onemax:1session with fixedpg_try_advisory_lock(1297044289,1262636593)across preflight through release. - Exact ledger: manifest v1 canonically serializes journal logical index/tag and SHA-256 of exact shipped migration bytes. It maps each observed ledger hash to one tuple; physical insertion order is non-normative, while missing/unknown/duplicate/ambiguous/corrupt/stale states fail closed. Shipped
0009bytes remain unchanged; a missing/effects-absent0009runs normally, an applied-late hash maps normally, and partial/full effects with missing hash require backup restoration or separately reviewed repair—not manual adoption. - TLS/search path: operator/IaC owns CA and server leaf lifecycle, exact compose/Swarm secret mounts, server TLS activation, service-DNS SANs, verified-TLS readiness, transition, CA overlap rotation, and rollback. Runtime/migrator use
verify-full; PGlite is not PostgreSQL TLS evidence. Application sessions use onlypg_catalog,mosaic; no URL/config-derived identifier reaches SQL. - Safe release: cards 00–07 land prepared but inactive; owner-runtime deployments remain N-1. Mosaic control plane/Jason alone authorizes one atomic TLS/roles → runner → readiness → runtime activation or rollback. No runtime-operator compatibility switch, bypass, plaintext interval, or force-on-red exists; all temporary support is removed before KBN-101-08.
- Non-effect: role graph, immutable certification after KBN-100, KBN-105 gate, rc.5’s preserved rc.4 SI-001 invariants, and all KCR-001–016 decisions remain unchanged. Exact detail is normative in
KBN-101-DB-ROLE-SPLIT.md.
1.0.0-rc.5 — KBN-101 role/connection split
- Choice: PostgreSQL
standaloneandfederatedruntime usesDATABASE_URLonly as a non-ownermosaic_runtimelogin; an explicit migration phase usesDATABASE_MIGRATION_URLonly asmosaic_migrator, whichSET ROLEs to non-loginmosaic_schema_ownerfor DDL. Local PGlite remains an explicit embedded exception. - No fallback / no startup DDL: missing migration URL fails the migration phase; it never falls back to runtime URL/default/config. Gateway replicas do not run migrations. An advisory-locked migration phase verifies the exact ordered Drizzle ledger fingerprint before replicas may become ready.
- Privilege model: non-login
mosaic_platform_database_owneris outside application paths;mosaic_schema_ownerowns only application/ledger schemas.mosaic_runtimehas onlymosaic_runtime_capability, owns no object/schema, cannot assume owner/migrator, has no TEMPORARY privilege, has only read access to the Drizzle ledger, and must fail startup if effective identity, unsafe attributes, authenticated TLS, search path, schema version, grants, or immutable relation privileges differ from the frozen contract.task_events,artifacts,task_checkpoints,task_checkpoint_artifacts, andapproval_decision_artifactsgrant runtime only INSERT/SELECT; KBN-100 retains RESTRICT/no-cascade semantics. - Non-effect: rc.4 SI-001 candidate-key/FK order and all KCR-001–016 tenancy, SOT, proposal-audit, approval, fence, recovery, no-cascade, endpoint, and wire invariants are unchanged. This amendment neither creates roles/secrets nor changes production deployment.
- Gate: KBN-101’s role/schema-boundary foundation certificate, Vault/redaction/rotation, N-1/rollback, and independent security GO are mandatory before KBN-100. After KBN-100 creates the immutable relations, KBN-101 real deployed-role immutable-operation certification plus Ultron GO is mandatory before KBN-105; synthetic test-role success alone is insufficient. Exact implementation detail is normative in
KBN-101-DB-ROLE-SPLIT.md.
1.0.0-rc.4 — KBN010-SI-001 (preserved)
- Choice: add the explicitly named, non-partial unique candidate key
missions_workspace_id_uidxonmissions(workspace_id, id)and retainmissions_workspace_project_id_uidxon(workspace_id, project_id, id). - Rationale: mission
idremains globally unique, while the composite candidate key makes the frozen tenant-safe generic mission relations valid.artifactsandapproval_decisionsare polymorphic exactly-one-target records and do not consistently carryproject_id; widening both children would unnecessarily broaden v1 and its target semantics. - Exact effect:
artifacts_workspace_mission_fkandapproval_decisions_workspace_mission_fkcontinue to reference the exact ordered columnsmissions(workspace_id, id)with RESTRICT deletion, now backed by a matching candidate key. - Non-effect: no SOT, tenancy, project-congruence, proposal-audit, approval, fencing, immutability, no-cascade, API, or wire-version invariant changes. The
SuccessEnvelopeV1.contractVersionremains1.0.0. - Historical evidence boundary:
KBN-010-THREAT-AUTH-CONSTRAINT-GATE.mdintentionally remains the immutable rc.3 blocker verdict that detected SI-001; this rc.4 record and the #753 scratchpad append are the authorized disposition. Rewriting the gate verdict is outside this amendment's exclusive scope. - Gate: this amendment resolves the DDL defect identified by KBN010-SI-001 but does not itself lift KBN-100; independent schema/SecReview remains required.
1. Authority
Concrete contracts are the four contracts/*.v1.ts files. PostgreSQL/current-main Drizzle is the sole writable SOT. In PostgreSQL standalone/federated deployments, KBN-101 rc.6 DDL/ledger/TLS/role separation is a precondition to schema implementation and certification. Public health, Valkey, files, exports, providers, browser state, and outage notes cannot authorize/reconstruct writes. Mechanical Coordinator is non-LLM with no scope/gate/certification/merge authority. Certifier is final independent gate with no merge authority. No feature lane starts until this canon merges and the KBN-010/KBN-105 prerequisites are satisfied.
2. Health proof and exact failures
KanbanHealthResponseV1 is a discriminated union:
| State | read | write | Capability |
|---|---|---|---|
healthy |
true | true | reads; public state still cannot authorize mutation |
read-only-degraded |
true | false | reads only |
write-unavailable |
false | false | diagnostics only |
Every response has checkedAt, validUntil, policyRevision; contradictory booleans fail validation.
For a mutation, Gateway opens the PostgreSQL transaction, executes the live write probe on that transaction/connection, mints the internal branded PostgresWriteHealthProofV1, and revalidates time/policy/transaction identity immediately before mutation. Public REST/MCP/CLI DTOs never accept health/proof fields. Valkey/caller assertions cannot mint proof. Pure Coordinator takes KanbanEvaluationContextV1; persistence takes InternalKanbanMutationContextV1 or probes internally.
| Case | HTTP | Frozen result | Retry |
|---|---|---|---|
| degraded write | 503 | KANBAN_WRITE_HEALTH_UNPROVEN, read-only-degraded, not_applied |
false |
| write unavailable | 503 | KANBAN_WRITE_UNAVAILABLE, write-unavailable, not_applied |
false |
| version conflict | 409 | AGGREGATE_VERSION_CONFLICT, actual version, not_applied |
false |
| timeout/unreachable | timeout/502/504 | retryable_transport_error, unknown |
same idempotency key |
| stale fence/session/approval | coordinator rejection union | not_applied |
false |
Required negatives: contradictory state, expired/policy-mismatched/wrong-transaction proof, Valkey-only health, forged healthy, and exhaustive non-cross-mapping of 503 vs 502/504/timeout vs 409.
3. Canonical schema invariants
Complete declaration: contracts/kanban-schema.v1.ts.
- Tables: tenant/identity (
workspaces, members, teams/members, agents/sessions); planning (projects,milestones, current-milestone join,missions, mission-milestones,tasks, normalized tags, dependencies); orchestration (task_assignments, durable execution state, leases, checkpoints/evidence); governance (change_proposals, immutable artifacts/evidence, events, approvals, outbox, external links). - Task statuses:
backlog | ready | in_progress | blocked | in_review | done | cancelled. - Assignment states everywhere:
awaiting_approval | policy_pre_authorized | approved | rejected | leased | released | expired | superseded. - Specialist roles everywhere:
planning | enhance | coder | review | security-review | pr-monitor | certifier. - Owner uses exactly-one user/team; assignment principal exactly-one user/team/agent; users require active membership; agent/session and all evidence are workspace-bound.
- Task→mission/milestone/parent, mission→milestone, and project→current-milestone are project-congruent composite relations.
- Mission
idremains globally unique. The additional non-partialmissions_workspace_id_uidxcandidate key on(workspace_id, id)exists only to support the frozen workspace-safe polymorphic artifact and approval-decision mission relations; the project-congruent(workspace_id, project_id, id)key remains authoritative whereverproject_idis present. - Dependency identity is workspace+predecessor+successor independent of type.
- Approval evidence and checkpoint evidence are workspace-scoped joins to immutable artifacts, never JSON ID arrays.
- Proposal audit links are composite relations:
(workspace_id, submitted_audit_event_id)and(workspace_id, accepted_command_audit_event_id)referencetask_events(workspace_id, id)with RESTRICT deletion. - Assignment is persisted with task/version, exact target/session, expiry/state/policy/proposer/reason. Approval relates to assignment. Lease acquisition accepts IDs, then reloads/locks and validates every relation.
tasks.fencing_counteris bigint; locked atomic increment/RETURNING creates a decimal-string lease token. Lease/checkpoint composites bind exact workspace+task+assignment/session+fence.task_execution_statesdurably records retry/quarantine/exhaustion.- Tags are normalized; legacy
tasks.tagsremains through N-1. Archive is explicit actor/reason/time and does not change lifecycle. - Canonical parents use RESTRICT. Events/checkpoints/artifacts/evidence are INSERT/SELECT-only for application roles. Normal flow archives/cancels; purge is audited break-glass retention work.
4. Outage proposal contract
change_proposals stores workspace, active-member proposer, source-note digest, target/version, typed command/payload, idempotency, lifecycle, decision actor/reason/time, proposal version, and submit/accepted event IDs. Both event IDs are workspace-aware composite foreign keys to task_events(workspace_id, id); a bare UUID is never sufficient.
Submission preallocates the proposal ID. One transaction inserts change_proposal.submitted with the proposal workspace, aggregate_type='change_proposal', aggregate_id=<new proposal ID>, previous_version=NULL, and new_version=1, then inserts the proposal referencing that event. Missing, foreign-workspace, wrong-type, or unrelated-proposal events abort the transaction.
Submit/list/get/accept/reject are explicit Gateway commands. Pending/rejected proposals are inert: no scheduling, dependency/gate satisfaction, or direct target mutation. Acceptance locks proposal+target, obtains fresh transaction-local proof, verifies pending/expected version, invokes the normal command handler, and atomically stores the emitted normal-command event ID. That event must share the proposal workspace, match target_aggregate_type and target_aggregate_id, use causation_id=submitted_audit_event_id, and carry payload.changeProposalId=<locked proposal ID>. Missing, foreign-workspace, unrelated-target, unrelated-proposal, or unrelated-command events abort acceptance.
5. Concrete current-main N-1 migration delta
Inspected: origin/main:packages/db/src/schema.ts at e72388b2cbfe400842fe940fa6cabf984ed43711 (2026-07-13). It has global teams/no workspace keys, legacy project/mission/task statuses, nullable task project/mission, tasks.assignee/tags/due_date, mission JSON/config, duplicated mission_tasks.status, legacy agent fields, and separate fleet backlog claims.
Legacy columns remain declared in unified schema.ts for expand + full N-1/rollback window. Generation must not infer early drops.
5.1 Ordered phases
- Pre-expand: N-1 patch stops
mission_tasks.statusas write source; inventory writers; backup/checksum. - Expand: add enums/tables and nullable-first columns; retain legacy declarations/uniques; emit no v1-only status.
- Backfill: bootstrap workspace; bounded idempotent cursor/checksum batches; quarantine ambiguous rows.
- Validate: no null tenant, cross-project link, ambiguous owner; status/tag/date/config retention; then constraints/NOT NULL.
- Compatibility: N-1 reads legacy; same-DB transaction mirrors only unavoidable fields; never file/Valkey dual write.
- Switch: stop N-1 writers; Gateway sole command boundary; enable canonical statuses.
- Contract release: later release after rollback/N-1; remove compatibility/global uniques/legacy fields.
5.2 Mission candidate-key and dependent-FK DDL order
KBN-100 migration DDL must execute the SI-001 portion in this order:
- expand/backfill
missions.workspace_idandmissions.project_idwhile preserving the globalmissions.idprimary key and the project-congruentmissions_workspace_project_id_uidxkey; - prove duplicate-key feasibility on the production-shape dataset:
(workspace_id, id)has no duplicate groups and globaliduniqueness remains intact; - create the non-partial unique index
missions_workspace_id_uidxon exact ordered columns(workspace_id, id); - only after step 3, create/alter
artifactsand addartifacts_workspace_mission_fkfrom(workspace_id, mission_id)to exactmissions(workspace_id, id)withON DELETE RESTRICT; - only after step 3, create/alter
approval_decisionsand addapproval_decisions_workspace_mission_fkfrom(workspace_id, mission_id)to exactmissions(workspace_id, id)withON DELETE RESTRICT; - validate both constraints and prove a mission ID paired with a foreign workspace is rejected for each child.
The candidate key is intentionally redundant with globally unique missions.id, but PostgreSQL requires a matching unique candidate key for the exact two-column FK target. It is additive and N-1-safe. Pre-switch rollback drops the two dependent FKs/tables before dropping this candidate key, preserves the global primary key and project-congruent key, and follows the existing freeze/reconciliation rule after the first canonical mutation.
5.3 New audit/proposal DDL order
KBN-100 migration DDL may begin only after KBN-101 foundation role/schema-boundary certification. It runs in the explicit migrator/owner phase—not Gateway startup—and its generated Drizzle declaration/snapshot/journal must be mutually consistent. It must execute in this order:
- create
task_eventsand its unique(workspace_id, id)key; - create
change_proposalswith nullable acceptance-event ID and required submission-event ID; - add
change_proposals_workspace_submitted_event_fkfrom(workspace_id, submitted_audit_event_id)totask_events(workspace_id, id)withON DELETE RESTRICT; - add
change_proposals_workspace_accepted_command_event_fkfrom(workspace_id, accepted_command_audit_event_id)to the same composite key withON DELETE RESTRICT; - install application-role immutability privileges and same-transaction semantic validation before enabling proposal commands.
The submission transaction inserts the event first using a preallocated proposal UUID, then the proposal. Acceptance inserts the normal command event before updating the locked proposal. Neither FK is omitted or replaced by a bare UUID/index check.
5.4 Field map
| Current | Expand/backfill | N-1 compatibility | Switch/contract |
|---|---|---|---|
global teams, team_members |
add workspace nullable; bootstrap; validate active owners | retain global slug/FKs | workspace composites; global unique contracts later |
projects.status |
add canonical_status; map active/paused/completed/archived |
mirror representable values; no planning |
canonical authority; legacy contracts later |
project owner_id/team_id/owner_type |
add exact accountable user/team; deterministic map or quarantine | preserve old reads and compare drift | canonical exact-one; remove legacy after parity |
| current milestone | create milestones then join table (no circular DDL) | absent to N-1 | join is authority |
nullable missions.project_id |
derive workspace/project; null/orphan exception, never guess | keep nullable legacy read | canonical required; validate/set NOT NULL later |
| mission relational candidate keys | retain global id PK and project-congruent key; add non-partial (workspace_id,id) key before artifact/approval FKs |
additive key is ignored safely by N-1 readers/writers | retain both composite keys; generic mission children use exact workspace+ID target |
mission description |
add objective; preserve description; reviewed nonblank mapping | N-1 description | objective authority; retain until signed review |
missions.status |
add canonical; planning→draft, active/paused/completed/failed same | no new-only statuses emitted | canonical authority |
mission milestones JSON |
normalize with source digest; preserve malformed/original | N-1 reads JSON; no reverse sync | normalized authority; JSON removed after checksum sign-off |
| mission config/metadata/phase/user | retain all; map known typed policy only | all remain declared | remove only by signed consumer inventory |
nullable tasks.project_id |
derive explicit/mission project; orphan quarantine | retain nullable read/write during compatibility | canonical required; NOT NULL later |
tasks.mission_id |
add project-congruent composite | old relation readable | composite authority |
tasks.status |
canonical: not-started→backlog, in-progress→in_progress, others same | no ready/in_review emission | canonical authority |
tasks.assignee |
deterministic active user/team/agent assignment; raw value preserved if ambiguous | mirror text only if unambiguous | canonical owner/assignment; remove after no-loss sign-off |
tasks.tags JSON |
normalize trim/case/dedupe with original digest | transactionally mirror normalized rows | normalized authority; JSON later removed |
tasks.due_date |
copy exactly to due_at |
mirror | due_at authority; legacy later |
| task common fields | preserve metadata byte-for-byte; add criteria/rank/retry/archive/version/fence | old reads valid | new fields canonical |
mission_tasks.status |
keep; prohibit as write source; linked status ignored; unlinked becomes task or reject | read-only compatibility value | membership uses task mission; status dropped after no readers |
| mission-task notes/PR/user | map to metadata/artifact/event/link/attribution; preserve | read-only | remove after parity |
agents.status |
add workspace/lifecycle/runtime/roles; status remains presence | retain all legacy fields | lifecycle/roles authority; status may remain telemetry |
| agent project/owner/prompt/tools/skills/config | preserve; validate tenant; derive typed capabilities without loss | N-1 reads | removal only by separate inventory |
fleet backlog |
map to designated-project tasks; edges; claimed rows quarantine | freeze claims before switch; read-only compare | task/lease authority; retire after stabilization |
5.5 Required migration tests
Empty DB; exact production-shape snapshot; crash/resume; rollback before switch; N-1 startup/read/write; workspace/member negatives; status-shadow/no premature new status; mission_tasks.status write prohibition; tags/assignee/date/mission JSON/config/description/agent checksum; project congruence/current-milestone order; backlog freeze/no dispatch; and proof legacy declarations persist until contract release.
SI-001 adds frozen future executable evidence: empty and production-shape migrations create missions_workspace_id_uidx before either dependent FK; duplicate-key feasibility preflight returns no (workspace_id,id) duplicate groups without weakening global id uniqueness; N-1 startup/read/write behavior is unchanged; pre-switch rollback removes dependents before the candidate key; both exact FK column lists reconcile to the candidate key; and foreign-workspace mission references fail for both artifacts and approval decisions. TDD is not applicable to this design-only amendment; KBN-100 must implement these negative migration tests before runtime schema release.
Proposal-specific negatives must attempt: missing submission event, foreign-workspace submission event, foreign-workspace acceptance event, same-workspace event for another proposal, event for another target aggregate, and unrelated normal-command event. Every attempt must fail atomically with no accepted proposal and no target mutation.
6. Ownership and Coordinator split
coder2 solely owns packages/db/src/schema.ts, packages/db/drizzle/**, journal/metadata, and migration tests. No other lane generates migrations. Expand is additive; no drop/rename/narrow; constraints validate before NOT NULL; compatibility is same-DB only; contract is later.
KBN-200/coder4 owns pure MechanicalCoordinatorDecisionEngineV1: complete immutable snapshots in, deterministic eligibility/proposal/retry decisions out; no ID loading, SQL, Gateway, Valkey, proof, persistence, restart I/O, or LLM.
KBN-210/coder3 owns MechanicalCoordinatorServicePortV1: ID loading, locks, fresh proof, assignment/approval persistence, atomic fencing, lease/checkpoint/outbox, Valkey wakes, durable retry/quarantine, and recoverFromPostgres. Cycle: load snapshots → pure decision → persist assignment → authoritative approval/policy → acquire by IDs/locks → increment fence → lease → ack/heartbeat/checkpoint → submit to review or durable retry/quarantine. No completion/certification/merge method exists.
7. Exact Gateway/DTO freeze for KBN-105
7.1 Common wire rules
Base is /api/v1/workspaces/:workspaceId. Mutations require header Idempotency-Key (1–128 chars). Existing-aggregate mutations also require If-Match-Version (positive integer); create and privileged assignment-cycle requests are the only exceptions, while proposal submission carries expectedTargetVersion in its body. Body workspace fields are forbidden. Tenant denial follows one 404/403 policy without foreign existence detail.
interface SuccessEnvelopeV1<T> {
contractVersion: '1.0.0';
data: T;
aggregateRevision: string;
correlationId: string;
}
interface ListEnvelopeV1<T> extends SuccessEnvelopeV1<T[]> {
page: { cursor: string | null; nextCursor: string | null; limit: number };
}
Errors are the exact health/transport/version unions in §2 plus validation/auth/not-found. Public DTOs never expose/accept internal write proof.
7.2 Exact route registry
| Method/path | Request body/query | Success data |
|---|---|---|
GET /kanban-health |
none | KanbanHealthResponseV1 |
GET /projects |
status,ownerUserId,ownerTeamId,cursor,limit |
project list |
POST /projects |
name,key,description,status,priority,ownerUserId XOR ownerTeamId,metadata |
project |
GET /projects/:projectId |
none | project |
PATCH /projects/:projectId |
editable create fields + expected header | project |
POST /projects/:projectId/archive |
reason |
project |
GET /tasks |
projectId,missionId,milestoneId,status,priority,ownerUserId,ownerTeamId,specialistRole,tag,dueState,archived,cursor,limit |
task summary list |
POST /tasks |
projectId,missionId?,milestoneId?,parentTaskId?,title,description?,acceptanceCriteria[],status,priority,rank,ownerUserId XOR ownerTeamId,specialistRole?,dueAt?,notBeforeAt?,estimateMinutes?,retryPolicy?,tagIds[],metadata |
task detail |
GET /tasks/:taskId |
none | task detail including readiness/dependencies/assignment/lease/events |
PATCH /tasks/:taskId |
editable non-transition fields | task detail |
POST /tasks/:taskId/transition |
toStatus,reason? |
task detail |
POST /tasks/:taskId/move |
toStatus?,beforeTaskId?,afterTaskId? |
task detail with persisted rank |
POST /tasks/:taskId/archive |
reason |
task detail |
PUT /tasks/:taskId/tags |
tagIds[] |
task detail |
POST /tasks/:taskId/dependencies |
predecessorTaskId,type |
dependency |
DELETE /tasks/:taskId/dependencies/:predecessorTaskId |
no body | deleted dependency ID |
GET /tasks/:taskId/events |
cursor,limit |
event list |
GET /tags |
query,cursor,limit |
tag list |
POST /tags |
name,color? |
tag |
GET /change-proposals |
state,targetType,targetId,cursor,limit |
proposal list |
POST /change-proposals |
sourceNoteDigest,targetType,targetId,expectedTargetVersion,commandType,commandPayload |
inert proposal |
GET /change-proposals/:proposalId |
none | proposal |
POST /change-proposals/:proposalId/accept |
reason |
proposal + normal command result |
POST /change-proposals/:proposalId/reject |
reason |
proposal |
GET /coordinator/eligibility |
projectId?,missionId?,cursor,limit |
EligibilityDecisionV1[] |
POST /coordinator/assignment-cycles |
limit |
assignment proposals; privileged internal |
POST /coordinator/assignments/:assignmentId/approve |
decision,reason,policyRevision,artifactIds[] |
approval decision |
POST /coordinator/leases/acquire |
taskId,assignmentId,approvalDecisionId,targetSessionId,leaseTtlSeconds |
lease with decimal-string fence |
POST /coordinator/leases/:leaseId/ack |
taskId,sessionId,fencingToken |
lease |
POST /coordinator/leases/:leaseId/heartbeat |
taskId,sessionId,fencingToken,extendSeconds |
lease |
POST /coordinator/leases/:leaseId/checkpoints |
taskId,sessionId,fencingToken,sequence,resumableSummary,artifactIds[],contextUsagePercent |
checkpoint |
POST /coordinator/leases/:leaseId/submit-review |
taskId,sessionId,fencingToken,artifactIds[],summary |
task in in_review |
All Coordinator mutations except human approval are service-identity-only. Generic task PATCH cannot perform claim/heartbeat/checkpoint/review/certification/completion shortcuts. Completion after certification uses a separately gated lifecycle command owned by the Portfolio/Sub-Orchestrator flow, not the Coordinator.
7.3 DTO invariants
Task summary/detail use exact schema vocabularies, owner union, version: number, fencingCounter: string, explicit archivedAt/by/reason, normalized tags, computed readiness, and separate assignment/lease. Assignment DTO includes one persisted ID, task/version, exact principal/agent/session, role, state, expiry, policy, proposer/reason. Lease/checkpoint DTOs serialize every fence as decimal string. Proposal DTO exposes no hidden write authority.
7.4 MCP ownership and mapping
coder3 exclusively owns:
apps/gateway/src/mcp/mcp.dto.tsmcp.controller.tsmcp.service.tsmcp.module.tsmcp.tokens.tsmcp.service.spec.ts
MCP tools are thin maps: mosaic_projects_{list,get,create,update,archive}, mosaic_tasks_{list,get,create,update,transition,move,archive,set_tags,add_dependency,remove_dependency}, and mosaic_change_proposals_{list,get,submit,accept,reject} to the exact routes above. coder4 owns CLI/projection clients only and must not edit Gateway MCP files.
KBN-105 publishes route+DTO fixture digest before KBN-110/120/130. Every web/CLI/MCP call must match this registry and the generated client.
8. Recovery contract and bounded delivery slice
Runtime must invoke normative validateRecoveryPostureV1; JSON Schema alone is insufficient. It rejects unknown fields, PITR/WAL mismatch, RPO better than mechanism, unsafe storage, and weakened High-assurance. High-assurance is RPO 15m/RTO 4h, WAL ≤5m, PITR ≥35d, base ≤24h, restore test ≤30d, break-glass ≤90d, encrypted separate-failure-domain storage.
KBN-115/coder2 owns packages/config/src/recovery-posture.ts, tests, and recovery runbook. It wires parser/refinement, override audit, mechanism assertions, restore test, and break-glass evidence. Any deployment manifest is separately enumerated and Mos-serialized. Recovery config has no SOT/gate/Coordinator authority fields.
9. Integration, security, and hold
Required release evidence includes KBN-101 foundation role/schema-boundary and post-KBN-100 real immutable-operation deployed-role certificates (not synthetic roles), empty/prod/partial/rollback/N-1 migration tests; cross-workspace and same-workspace wrong-project negatives; active-membership owners/principals; proposal inertness/normal acceptance; exact failure mapping; concurrent monotonic bigint fences; relational lease/checkpoint/evidence mismatch; immutability privileges/RESTRICT; recovery validation/mechanism evidence; endpoint registry alignment; accessible web journeys; author≠reviewer; mandatory SecReview; final Certifier pass/no merge authority.
9.1 SI-001 amendment gate and #757 boundary
- KBN-100 must provide the §5.2 candidate-key ordering, duplicate-feasibility, exact-FK reconciliation, empty/prod/N-1/rollback, and two-child foreign-workspace evidence before SI-001 can be certified closed.
- All prior KCR-001–016 decisions and fixed SOT/tenant/authority, proposal-audit, approval, task-fencing, immutability, and no-cascade invariants remain unchanged.
- Read-only PR #757 cross-check: its logical-agent connector lease/CAS fencing uses separate runtime tables/contracts and
lease_epoch; rc.4 changes only the frozenmissionscandidate key. There is no shared table, index, FK, identity, fence, or authority semantic to consume or reconcile, and #757 remains owned by its existing lane.
The build hold remains active until independent re-review reports GO for KCR-001–016 and the rc.4 SI-001 amendment. Mos alone releases waves and serializes integration roots.