ADR-0001: Split the sprint reconciliation log from the sprint plan
- Status: accepted (2026-07-14)
- Deciders: TPM (CDP), with the change applied repo-wide to the sprint-layer doctrine
- Scope: repo-wide sprint-doc shape (doctrine lives in
.claude/reference/sprint-layer.md/sprint-resync.md); CDP Sprint 1 is the reference migration.
Context
sprint-resync was specified to append a dated ## Jira reconciliation — recheck (<date>)
section to the sprint doc on every pass, with each pass re-narrating every prior finding
(STILL OPEN prose). At the observed cadence this destroyed the sprint doc as a dev-facing
source of truth: by 2026-07-14, cdp/delivery/sprints/2026-07-07-sprint-01.md was 855 lines,
~590 of them (69%) six appended reconciliation passes written over 7 days — the actual plan
(envelope, initiative index, per-engineer queues, deviations, blockers) was the first ~255 lines.
Growth was superlinear (every pass restates all prior open findings), and at the intended
daily-ish cadence a sprint would close carrying ~12 passes with the plan under 15% of its own
file. The bloat had also leaked into the sprint_goal frontmatter (a 6-line amendment narrative),
violating the doctrine's own "sprint_goal stays fixed" rule.
The append-forever shape also contradicted the layer's first principle — "a sprint is a render + an envelope, never a fourth source of truth" — by making the sprint file the de facto system of record for drift history.
Decision
Split state from log (the snapshot + event-stream pattern):
- One immutable dated file per reconciliation pass at
<team>/delivery/reconciliations/<sprint-basename>/<YYYY-MM-DD>-pass-NN.md(frontmattertitle+status+type: Sprint Reconciliation; latest passstatus: active, prior passes flipped toarchived— the same latest-=-truth convention asdelivery/status/<date>.md). Full narrative, engine output, and the per-pass downstream propagation worklist live there. - The sprint doc keeps a single
## Jira reconciliation — findings ledger (<date>)section, rewritten in place each pass: a numbered list of currently-open findings with stableF-<n>ids (never reused), each row carrying type,STILL OPEN (<n>th pass)/⛔ ESCALATEDmarker, owner, routed home, and its origin pass link — plus a bounded bulleted "Resolved" list linking each closing pass. No re-narration; resolution detail lives in the pass files. sprint_goalstays fixed. Mid-window absorptions are recorded in## Deviations from roadmap priority(or the Expedite render), never appended to the goal.
Compatibility with the pinned linter (why no upstream change is required)
lint-delivery.mjs CHECK GROUP K (pinned SYSTEM_REF 8837118) scans the last
## Jira reconciliation…-headed section of an active sprint doc and counts numbered-list
items marked STILL OPEN/STILL PRESENT or ⛔. The ledger deliberately keeps that contract —
heading prefix ## Jira reconciliation — findings ledger (<date>), numbered-list rows, the same
markers — so JIRA_RECONCILE_OPEN / JIRA_RECONCILE_ESCALATED keep firing unchanged. The pass
files live outside sprints/ (in delivery/reconciliations/) because the delivery model's
sprint collection (teamSprints → walkMarkdown) is recursive — anything under sprints/ is
parsed as a Sprint Plan (verified: it fired SPRINT_GOAL_MISSING on a trial in-sprints/
layout). In reconciliations/ they lint as plain delivery docs (title + status).
Consequences
- Dev-facing sprint doc stays bounded (~plan size + ~1 ledger line per open finding) regardless of reconciliation cadence; auditors read exactly the pass they care about.
sprint-layer.md,sprint-resync.md§1/§5, thesprint-resyncskill, andtemplates/delivery-sprint-template.mdupdated to the ledger + pass-file shape (this repo is the authority for all four — repo-local extension, to be upstreamed to AI-SDLC with the rest of the sprint layer).- Migration: CDP Sprint 1 migrated 2026-07-14 (six passes →
reconciliations/, ledger F-1…F-9 seeded from the pass-6 carry-forward; historical pass files keep their per-pass finding numbering, cited asp<pass>#<n>). Bifrost2026-07-06-sprint-01.mdand chatbot2026-07-13-sprint-01.mdmigrated the same day, same method. Any future legacy sprint doc migrates on its nextsprint-resyncpass (the skill instructs this). - Optional future upstream improvement (not required): CHECK GROUP K could learn the
reconciliations/directory explicitly; if that lands, bumpSYSTEM_REFand append to.claude/reference/system-ref-history.mdper the usual provenance rule.
References (pattern precedent)
- Martin Fowler, Event Sourcing — append-only event log kept separate from a compact current-state projection/snapshot.
- Michael Nygard, Documenting Architecture Decisions (ADR / MADR) — immutable dated records +
a lightweight current index; already this repo's
delivery/decisions/convention. - Atlassian Atlas / Jira Align status updates — stable project brief, separate dated update
stream; already this repo's
delivery/status/<date>.mdconvention. Sprints were the one delivery artifact not following it. - Kubernetes KEPs — the proposal document is the spec; per-release status tracking lives outside it.