Files
stack/docs/fleet/proposals/mosaic-platform-prd/PRD-backlog-providers.md
Jarvis 2708de55b9
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
docs(prd): fold 2026-07-09 debate-pass findings into Mosaic Platform PRD
All 24 panel findings (P0#1-5, P1#6-13, P2/P3#14-24) accepted and folded:
- DEBATE-FINDINGS.md: disposition record + open-disagreement judgment calls
- north-star: NS-14, J2a/J2b split, J6 wake router, K3 push pipeline,
  M1 memory subsystem, workstream L (MALS lineage), real DAG edges
- J: workspace lease J-R16, resume protocol J-R18, write-side trust,
  needs-decision lifecycle, atomic card publish
- P: CAS approval state machine, gateway-only credentials, default-closed
  gating, principal resolution + policy snapshot (Codex #2/#7)
- W: butt-in exclusive lease, structured control plane, break-glass
  doctrine, trial metric panels
- Q: external_refs table, pending-link, echo-loop guard, crash barriers
- X: storage authority (Postgres sole record), machine-generated census,
  memory retrieval-eval retirement gate, honest rollback scope,
  4 artifact-existence machine gates, bounded day-30 review
- README: Gate Zero, conflict register, DoD line, silent-roster rule

One item OPEN for Jason at ratification: gate superstructure (§3.1).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RMoEx7hfdFGjUiCHuN1RRi
2026-07-09 16:29:37 -05:00

59 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PRD — Backlog Provider Sync Adapters · Workstream Q
> **Status:** DRAFT for ratification · **Goals:** Q1Q3 · **Doctrine:** NS-12 (ratified D3)
> **Debate pass 2026-07-09:** panel findings folded — see `DEBATE-FINDINGS.md`.
## Mission
Users choose where they _see and touch_ work — Gitea, GitHub, a local kanban — while the **Mosaic Backlog on native Postgres stays the sole record and dispatch engine** (upholds ASM-1; NS-3/NS-4/NS-5 guarantees never depend on an external provider). Providers attach as bidirectional sync adapters.
## Requirements
### Adapter interface + Gitea (Q1)
| ID | Requirement |
| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Q-R1 | A `BacklogProviderAdapter` interface: map card ⇄ external item (create/update/close/comment/label), with stable external-id linkage stored on the card. |
| Q-R2 | Sync is bidirectional and conflict-safe: native record wins on divergence; external edits arrive as proposed mutations (applied if non-conflicting, else surfaced). |
| Q-R3 | Claims, TTLs, depends_on DAG, and dispatch state live **only** in the native record; adapters project them (e.g. as labels/comments) but never own them. |
| Q-R4 | Gitea adapter first (webhook + API), configured per workspace: repo mapping, label conventions, direction (mirror-out / mirror-in / full). |
| Q-R5 | Adapter enable/disable is workspace configuration; zero adapters is a fully supported mode. |
### GitHub (Q2)
| ID | Requirement |
| ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Q-R6 | Same interface, GitHub Issues backend. Existing `packages/cli-tools` platform detection informs but does not implement this (that is dev tooling, not product runtime). |
### Local kanban (Q3)
| ID | Requirement |
| ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Q-R7 | A webUI kanban board over the native backlog (no external provider needed) — the "local kanban" choice. Builds on W3's card views and/or the existing `KanbanBoard` component upgraded from demo-grade to live data. |
## Debate-accepted deltas (2026-07-09) — normative
| ID | Requirement |
| ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Q-R8 | **External-ref linkage is one shared mechanism:** a unique-indexed `external_refs(entity_id, system, external_id)` table serves adapter linkage (Q-R1), migration idempotency (X-R4 anti-join), and re-point verification (X-R6) — built once, three consumers. Idempotent upsert; a violated unique index is a converge signal, never an overwrite. |
| Q-R9 | **Crash-safe external creates:** the adapter writes a `pending-link` row **before** any external create and embeds a deterministic card-id marker in the created item, so a crash between create and link-back is recovered by scan, never by duplicate creation. |
| Q-R10 | **Echo-loop guard:** both directions carry revision counters; adapter-authored external edits are tagged (marker/actor) and skipped on read-back. A sync cycle that would re-import its own write is a hard test failure. |
| Q-R11 | The sync engine is a **level-triggered reconciler** over desired-vs-observed state (same doctrine as J6), not a webhook-only event chase: webhooks accelerate convergence, the reconciler guarantees it. Missed webhooks are a latency event, not a correctness event. |
| Q-R12 | Card spec immutability (J-R20) projects cleanly: the mirrored issue body is the pinned spec revision; amendments append as **ordered provider comments**, never body rewrites, so external watchers see the same amendment history as the native record. |
## Acceptance criteria
1. A card created by Jarvis (J3) appears as a Gitea issue within one sync interval; closing the issue in Gitea marks the card for review, not silent closure; dispatch/claims never round-trip through Gitea.
2. Killing the adapter mid-mission: dispatch continues unaffected (record is native); on restart, sync converges without duplicates.
3. The same mission can be mirrored to Gitea and viewed on the local kanban simultaneously without state divergence.
4. **Named crash barriers** at every external-call boundary (`before_external_create`, `after_create_before_link`, `after_link_before_ack`): kill the adapter at each; zero duplicate external items, zero orphaned cards. CI rule: a new external call site without a named barrier + kill test **fails the build**. Residual randomized soak is trace-directed (§3.6 disposition).
## Non-goals
- External provider AS the backlog (vetoed — "truly swappable backends" option declined 2026-07-09).
- Two-way sync of claims/TTL semantics (external systems can't express them; projection only).
## Assumptions
- ASSUMPTION: the delivery fleet's _engineering_ PR/issue flow on the stack repo itself continues to use `cli-tools`/Gitea directly — workstream Q is the product feature for user workspaces, not a replacement for the dev workflow.