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

6.8 KiB
Raw Blame History

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.