@papi-ai/adapter-md 0.1.0-alpha → 0.1.1-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/LICENSE +98 -0
  2. package/dist/index.d.ts +368 -187
  3. package/dist/index.js +278 -417
  4. package/package.json +2 -2
package/dist/index.d.ts CHANGED
@@ -1,24 +1,7 @@
1
- import { TaskStatus as TaskStatus$1, TaskPriority as TaskPriority$1, EffortSize as EffortSize$1, ReviewStage as ReviewStage$1, ReviewVerdict as ReviewVerdict$1, TaskComplexity as TaskComplexity$1, TaskType as TaskType$1, isValidStatus as isValidStatus$1, isValidTransition as isValidTransition$1, validateTransition as validateTransition$1 } from '@papi-ai/shared';
1
+ import { TaskStatus as TaskStatus$1, TaskPriority as TaskPriority$1, EffortSize as EffortSize$1, TaskComplexity as TaskComplexity$1, TaskType as TaskType$1, ReviewStage as ReviewStage$1, ReviewVerdict as ReviewVerdict$1, isValidStatus as isValidStatus$1, isValidTransition as isValidTransition$1, validateTransition as validateTransition$1 } from '@papi-ai/shared';
2
2
 
3
3
  /** Valid phase statuses in the product brief. */
4
4
  type PhaseStatus = 'Not Started' | 'In Progress' | 'Done' | 'Deferred';
5
- /** Feature lifecycle status. */
6
- type FeatureStatus = 'Not Started' | 'In Progress' | 'Done' | 'Deferred';
7
- /** A workstream or capability being built. Replaces Phase as the primary planning construct (AD-23). */
8
- interface Feature {
9
- id: string;
10
- displayId: string;
11
- slug: string;
12
- name: string;
13
- description: string;
14
- status: FeatureStatus;
15
- roadmapPosition: number;
16
- createdAt: string;
17
- completedAt?: string;
18
- commitDate?: string;
19
- createdSprint: number;
20
- completedSprint?: number;
21
- }
22
5
  /** A development phase defined in the product brief. */
23
6
  interface Phase {
24
7
  id: string;
@@ -27,21 +10,52 @@ interface Phase {
27
10
  description: string;
28
11
  status: PhaseStatus;
29
12
  order: number;
13
+ /** The stage this phase belongs to (AD-14 hierarchy). */
14
+ stageId?: string;
15
+ }
16
+ /** Horizon status in the project hierarchy (AD-14). */
17
+ type HorizonStatus = 'active' | 'completed' | 'deferred';
18
+ /** A horizon — the highest level of the project hierarchy (AD-14: Horizon → Stage → Phase → Task). */
19
+ interface Horizon {
20
+ id: string;
21
+ slug: string;
22
+ label: string;
23
+ description?: string;
24
+ status: HorizonStatus;
25
+ sortOrder: number;
26
+ projectId: string;
27
+ createdAt: string;
28
+ updatedAt: string;
30
29
  }
31
- /** Sprint lifecycle status. */
32
- type SprintStatus = 'planning' | 'active' | 'complete';
33
- /** A sprint entity giving sprints first-class identity. */
34
- /** Per-section SHA-256 hashes for context diff optimisation between sprints. */
30
+ /** Stage status in the project hierarchy (AD-14). */
31
+ type StageStatus = 'active' | 'completed' | 'deferred';
32
+ /** A stage sits between Horizon and Phase in the hierarchy (AD-14: Horizon → Stage → Phase → Task). */
33
+ interface Stage {
34
+ id: string;
35
+ slug: string;
36
+ label: string;
37
+ description?: string;
38
+ status: StageStatus;
39
+ sortOrder: number;
40
+ horizonId: string;
41
+ projectId: string;
42
+ createdAt: string;
43
+ updatedAt: string;
44
+ }
45
+ /** Cycle lifecycle status (renamed from CycleStatus per AD-14). */
46
+ type CycleStatus = 'planning' | 'active' | 'complete';
47
+ /** Per-section SHA-256 hashes for context diff optimisation between cycles. */
35
48
  interface ContextHashes {
36
49
  productBrief?: string;
37
50
  activeDecisions?: string;
38
51
  reviews?: string;
39
52
  [key: string]: string | undefined;
40
53
  }
41
- interface Sprint {
54
+ /** A cycle entity — the methodology loop (renamed from Cycle per AD-14). */
55
+ interface Cycle {
42
56
  id: string;
43
57
  number: number;
44
- status: SprintStatus;
58
+ status: CycleStatus;
45
59
  startDate: string;
46
60
  endDate?: string;
47
61
  goals: string[];
@@ -63,7 +77,7 @@ declare const validateTransition: typeof validateTransition$1;
63
77
  declare const isValidStatus: typeof isValidStatus$1;
64
78
  /**
65
79
  * Context tiers control which tasks the planner sees:
66
- * Tier 1 (Sprint-eligible): Bug, Task — fed to planner for scheduling
80
+ * Tier 1 (Cycle-eligible): Bug, Task — fed to planner for scheduling
67
81
  * Tier 2 (Plannable): Research — scheduled but output is knowledge not code
68
82
  * Tier 3 (Pre-triage): Idea, Feedback — invisible to planner until promoted
69
83
  */
@@ -83,7 +97,7 @@ interface DecisionEvent {
83
97
  id: string;
84
98
  decisionId: string;
85
99
  eventType: DecisionEventType;
86
- sprint: number;
100
+ cycle: number;
87
101
  source: DecisionEventSource;
88
102
  sourceRef?: string;
89
103
  detail?: string;
@@ -93,7 +107,7 @@ interface DecisionEvent {
93
107
  interface DecisionScore {
94
108
  id: string;
95
109
  decisionId: string;
96
- sprint: number;
110
+ cycle: number;
97
111
  effort: number;
98
112
  risk: number;
99
113
  reversibility: number;
@@ -103,11 +117,11 @@ interface DecisionScore {
103
117
  rationale?: string;
104
118
  createdAt: string;
105
119
  }
106
- /** Sprint health metadata from PLANNING_LOG.md header. */
107
- interface SprintHealth {
108
- totalSprints: number;
109
- latestSprintStatus?: string;
110
- sprintsSinceLastStrategyReview: number;
120
+ /** Cycle health metadata from PLANNING_LOG.md header. */
121
+ interface CycleHealth {
122
+ totalCycles: number;
123
+ latestCycleStatus?: string;
124
+ cyclesSinceLastStrategyReview: number;
111
125
  strategyReviewDue: string;
112
126
  boardHealth: string;
113
127
  strategicDirection: string;
@@ -122,14 +136,16 @@ interface ActiveDecision {
122
136
  confidence: Confidence;
123
137
  superseded: boolean;
124
138
  supersededBy?: string;
125
- createdSprint?: number;
126
- modifiedSprint?: number;
139
+ createdCycle?: number;
140
+ modifiedCycle?: number;
127
141
  body: string;
142
+ outcome?: 'pending' | 'validated' | 'revised' | 'abandoned' | 'superseded';
143
+ revisionCount?: number;
128
144
  }
129
- /** A single sprint entry in the planning log. */
130
- interface SprintLogEntry {
145
+ /** A single cycle entry in the planning log. */
146
+ interface CycleLogEntry {
131
147
  uuid: string;
132
- sprintNumber: number;
148
+ cycleNumber: number;
133
149
  title: string;
134
150
  content: string;
135
151
  carryForward?: string;
@@ -137,31 +153,47 @@ interface SprintLogEntry {
137
153
  }
138
154
  /** A strategy review entry stored in its own table (not planning_log_entries). */
139
155
  interface StrategyReviewEntry {
140
- sprintNumber: number;
141
- sprintRange?: string;
156
+ cycleNumber: number;
157
+ cycleRange?: string;
142
158
  title: string;
143
159
  content: string;
144
160
  notes?: string;
145
161
  boardHealth?: string;
146
162
  strategicDirection?: string;
147
163
  recommendations?: unknown;
164
+ fullAnalysis?: string;
165
+ velocityAssessment?: string;
166
+ /** Full ReviewStructuredOutput from the strategy review LLM, stored as JSONB for dashboard querying */
167
+ structuredData?: Record<string, unknown>;
168
+ createdAt?: string;
169
+ }
170
+ /** A dogfood observation captured during strategy reviews or releases. */
171
+ interface DogfoodEntry {
172
+ id?: string;
173
+ projectId?: string;
174
+ cycleNumber: number;
175
+ category: 'friction' | 'methodology' | 'signal' | 'commercial';
176
+ content: string;
177
+ sourceTool?: string;
178
+ status?: 'observed' | 'backlog-created' | 'resolved';
179
+ linkedTaskId?: string;
148
180
  createdAt?: string;
149
181
  }
150
182
  /** Full parsed contents of PLANNING_LOG.md. */
151
183
  interface PlanningLog {
152
- sprintHealth: SprintHealth;
184
+ cycleHealth: CycleHealth;
153
185
  northStar: string;
154
186
  activeDecisions: ActiveDecision[];
155
187
  deferred: string[];
156
- sprintLog: SprintLogEntry[];
188
+ cycleLog: CycleLogEntry[];
157
189
  }
158
190
  /** A single state transition entry recording when a task changed status. */
159
191
  interface StateTransition {
160
192
  status: TaskStatus;
161
193
  timestamp: string;
162
194
  }
163
- /** A task on the sprint board (parsed from SPRINT_BOARD.md YAML). */
164
- interface SprintTask {
195
+ /** A task on the board (parsed from CYCLE_BOARD.md YAML). */
196
+ interface CycleTask {
165
197
  uuid: string;
166
198
  id: string;
167
199
  displayId: string;
@@ -170,12 +202,15 @@ interface SprintTask {
170
202
  priority: TaskPriority;
171
203
  complexity: TaskComplexity;
172
204
  module: string;
173
- epic: string;
205
+ /** @deprecated (AD-14): Use phase + stageId instead. Will be removed after taxonomy migration. */
206
+ epic?: string;
174
207
  phase: string;
208
+ /** Stage FK for AD-14 hierarchy (Horizon → Stage → Phase → Task). */
209
+ stageId?: string;
175
210
  owner: string;
176
211
  reviewed: boolean;
177
- sprint?: number;
178
- createdSprint?: number;
212
+ cycle?: number;
213
+ createdCycle?: number;
179
214
  createdAt?: string;
180
215
  why?: string;
181
216
  dependsOn?: string;
@@ -187,6 +222,19 @@ interface SprintTask {
187
222
  taskType?: TaskType;
188
223
  maturity?: TaskMaturity;
189
224
  }
225
+ /** Structured handoff accuracy — replaces coarse scope_accuracy text. */
226
+ interface HandoffAccuracy {
227
+ scopeMatch: boolean;
228
+ filesMatch: 'exact' | 'partial' | 'missed';
229
+ effortMatch: boolean;
230
+ notes?: string;
231
+ }
232
+ /** Brief implications from a build — discovery learnings that feed back into planning. */
233
+ interface BriefImplication {
234
+ canvasSection: 'landscape' | 'journeys' | 'mvpBoundary' | 'assumptions' | 'successSignals';
235
+ type: 'confirm' | 'contradict' | 'new';
236
+ detail: string;
237
+ }
190
238
  /** A build report entry from BUILD_REPORTS.md. */
191
239
  interface BuildReport {
192
240
  uuid: string;
@@ -195,7 +243,7 @@ interface BuildReport {
195
243
  taskId: string;
196
244
  taskName: string;
197
245
  date: string;
198
- sprint: number;
246
+ cycle: number;
199
247
  completed: 'Yes' | 'No' | 'Partial';
200
248
  actualEffort: EffortSize;
201
249
  estimatedEffort: EffortSize;
@@ -206,6 +254,27 @@ interface BuildReport {
206
254
  commitSha?: string;
207
255
  filesChanged?: string[];
208
256
  relatedDecisions?: string[];
257
+ handoffAccuracy?: HandoffAccuracy;
258
+ correctionsCount?: number;
259
+ briefImplications?: BriefImplication[];
260
+ deadEnds?: string;
261
+ }
262
+ /** Aggregated recommendation effectiveness row from v_recommendation_effectiveness. */
263
+ interface RecommendationEffectivenessRow {
264
+ type: string;
265
+ total: number;
266
+ actioned: number;
267
+ dismissed: number;
268
+ pending: number;
269
+ acceptanceRate: string;
270
+ avgCyclesToAction: string | null;
271
+ }
272
+ /** Aggregated estimation calibration row from v_estimation_accuracy. */
273
+ interface EstimationCalibrationRow {
274
+ estimatedEffort: string;
275
+ actualEffort: string;
276
+ accuracyLabel: string;
277
+ count: number;
209
278
  }
210
279
  /** A single tool call metric entry from METRICS.md. */
211
280
  interface ToolCallMetric {
@@ -216,8 +285,8 @@ interface ToolCallMetric {
216
285
  outputTokens?: number;
217
286
  estimatedCostUsd?: number;
218
287
  model?: string;
219
- /** Sprint number when this metric was recorded. Absent on legacy rows. */
220
- sprintNumber?: number;
288
+ /** Cycle number when this metric was recorded. Absent on legacy rows. */
289
+ cycleNumber?: number;
221
290
  /** Context size in bytes for plan tool calls. Absent on non-plan tools. */
222
291
  contextBytes?: number;
223
292
  /** Context utilisation ratio (0.0–1.0). Fraction of input entities referenced in output. */
@@ -241,8 +310,32 @@ interface CostSummary {
241
310
  avgCostPerCall: number;
242
311
  }
243
312
  /** A cost snapshot persisted in the Cost Summary section of METRICS.md. */
313
+ /** Discovery canvas — progressive discovery sections on product brief. */
314
+ interface DiscoveryCanvas {
315
+ landscapeReferences?: {
316
+ name: string;
317
+ url?: string;
318
+ notes?: string;
319
+ }[];
320
+ userJourneys?: {
321
+ persona: string;
322
+ journey: string;
323
+ priority?: string;
324
+ }[];
325
+ mvpBoundary?: string;
326
+ assumptionsOpenQuestions?: {
327
+ text: string;
328
+ status: string;
329
+ evidence?: string;
330
+ }[];
331
+ successSignals?: {
332
+ signal: string;
333
+ metric?: string;
334
+ target?: string;
335
+ }[];
336
+ }
244
337
  interface CostSnapshot {
245
- sprint: number;
338
+ cycle: number;
246
339
  date: string;
247
340
  totalCostUsd: number;
248
341
  totalInputTokens: number;
@@ -268,7 +361,7 @@ type TextClusterer = (entries: ClusterEntry[]) => Promise<ClusterResult[]>;
268
361
  interface RecurringSurprise {
269
362
  text: string;
270
363
  count: number;
271
- sprints: number[];
364
+ cycles: number[];
272
365
  }
273
366
  /** Build pattern detection results from analyzing recent build reports. */
274
367
  interface BuildPatterns {
@@ -278,28 +371,28 @@ interface BuildPatterns {
278
371
  scopeAccuracyBreakdown: Record<string, number>;
279
372
  untriagedIssues: string[];
280
373
  }
281
- /** Per-sprint estimation accuracy stats. */
282
- interface SprintEstimationAccuracy {
283
- sprint: number;
374
+ /** Per-cycle estimation accuracy stats. */
375
+ interface CycleEstimationAccuracy {
376
+ cycle: number;
284
377
  reports: number;
285
378
  matchRate: number;
286
379
  mae: number;
287
380
  bias: number;
288
381
  }
289
- /** Per-sprint velocity stats. */
290
- interface SprintVelocity {
291
- sprint: number;
382
+ /** Per-cycle velocity stats. */
383
+ interface CycleVelocity {
384
+ cycle: number;
292
385
  completed: number;
293
386
  partial: number;
294
387
  failed: number;
295
388
  effortPoints: number;
296
389
  }
297
- /** A sprint methodology metrics snapshot stored in SPRINT_METRICS.md. */
298
- interface SprintMetricsSnapshot {
299
- sprint: number;
390
+ /** A cycle methodology metrics snapshot stored in CYCLE_METRICS.md. */
391
+ interface CycleMetricsSnapshot {
392
+ cycle: number;
300
393
  date: string;
301
- accuracy: SprintEstimationAccuracy[];
302
- velocity: SprintVelocity[];
394
+ accuracy: CycleEstimationAccuracy[];
395
+ velocity: CycleVelocity[];
303
396
  }
304
397
  /** A recurring feedback theme detected across human reviews. */
305
398
  interface RecurringFeedback {
@@ -313,6 +406,21 @@ interface ReviewPatterns {
313
406
  verdictBreakdown: Record<string, number>;
314
407
  requestChangesRate: number;
315
408
  }
409
+ /** Auto-review verdict from automated code review. */
410
+ type AutoReviewVerdict = 'pass' | 'warn' | 'fail';
411
+ /** A single finding from an automated code review. */
412
+ interface AutoReviewFinding {
413
+ severity: 'error' | 'warning' | 'info';
414
+ file?: string;
415
+ line?: number;
416
+ message: string;
417
+ }
418
+ /** Automated code review results — supplements human review. */
419
+ interface AutoReview {
420
+ verdict: AutoReviewVerdict;
421
+ findings: AutoReviewFinding[];
422
+ summary: string;
423
+ }
316
424
  /** A human review entry stored in REVIEWS.md. */
317
425
  interface HumanReview {
318
426
  uuid: string;
@@ -321,11 +429,13 @@ interface HumanReview {
321
429
  stage: ReviewStage;
322
430
  reviewer: string;
323
431
  verdict: ReviewVerdict;
324
- sprint: number;
432
+ cycle: number;
325
433
  date: string;
326
434
  comments: string;
327
435
  handoffRevision?: number;
328
436
  buildCommitSha?: string;
437
+ /** Optional automated code review results attached to this review. */
438
+ autoReview?: AutoReview;
329
439
  }
330
440
  /** A structured BUILD HANDOFF parsed from the markdown handoff block. */
331
441
  interface BuildHandoff {
@@ -334,7 +444,7 @@ interface BuildHandoff {
334
444
  createdAt?: string;
335
445
  taskId: string;
336
446
  taskTitle: string;
337
- sprint: number;
447
+ cycle: number;
338
448
  whyNow: string;
339
449
  scope: string[];
340
450
  scopeBoundary: string[];
@@ -358,8 +468,9 @@ interface StrategyRecommendation {
358
468
  type: RecommendationType;
359
469
  status: RecommendationStatus;
360
470
  content: string;
361
- createdSprint: number;
362
- actionedSprint?: number;
471
+ createdCycle: number;
472
+ actionedCycle?: number;
473
+ target?: string;
363
474
  }
364
475
  /** Entity reference — tracks which decisions/entities are used in tool calls. */
365
476
  interface EntityReference {
@@ -368,22 +479,30 @@ interface EntityReference {
368
479
  entityId: string;
369
480
  referenceContext: 'plan_input' | 'plan_output' | 'strategy_input' | 'strategy_output';
370
481
  toolName: string;
371
- sprintNumber: number;
482
+ cycleNumber: number;
372
483
  createdAt: string;
373
484
  }
485
+ /** Per-tool context utilisation summary from v_context_utilisation. */
486
+ interface ContextUtilisationSummary {
487
+ tool: string;
488
+ cycleNumber: number;
489
+ callCount: number;
490
+ avgUtilisation: number;
491
+ avgContextBytes: number;
492
+ }
374
493
  /** Per-AD usage summary returned by getDecisionUsage. */
375
494
  interface DecisionUsageSummary {
376
495
  decisionId: string;
377
496
  referenceCount: number;
378
- lastReferencedSprint: number;
379
- sprintsSinceLastReference: number;
497
+ lastReferencedCycle: number;
498
+ cyclesSinceLastReference: number;
380
499
  }
381
500
  /** Options for updateTask to control validation behaviour. */
382
501
  interface UpdateTaskOptions {
383
502
  /** Skip state-machine transition validation when true. */
384
503
  force?: boolean;
385
504
  }
386
- /** Filter options for querying the sprint board. */
505
+ /** Filter options for querying the cycle board. */
387
506
  interface BoardQueryOptions {
388
507
  status?: TaskStatus[];
389
508
  priority?: TaskPriority[];
@@ -391,31 +510,39 @@ interface BoardQueryOptions {
391
510
  reviewed?: boolean;
392
511
  module?: string;
393
512
  epic?: string;
394
- /** Filter by context tier (1=sprint-eligible, 2=plannable, 3=pre-triage). */
513
+ /** Filter by context tier (1=cycle-eligible, 2=plannable, 3=pre-triage). */
395
514
  contextTier?: ContextTier;
515
+ /** Filter to tasks assigned to this cycle or later (cycle >= N). */
516
+ cycleSince?: number;
396
517
  }
397
518
  /** Core adapter interface for reading/writing .papi/ markdown files. */
398
519
  interface PapiAdapter {
399
520
  readPlanningLog(): Promise<PlanningLog>;
400
- getSprintHealth(): Promise<SprintHealth>;
521
+ getCycleHealth(): Promise<CycleHealth>;
401
522
  getActiveDecisions(): Promise<ActiveDecision[]>;
402
- getSprintLog(limit?: number): Promise<SprintLogEntry[]>;
403
- getSprintLogSince(sprintNumber: number): Promise<SprintLogEntry[]>;
404
- setSprintHealth(updates: Partial<SprintHealth>): Promise<void>;
405
- writeSprintLogEntry(entry: SprintLogEntry): Promise<void>;
406
- updateActiveDecision(id: string, body: string, sprintNumber?: number): Promise<void>;
407
- queryBoard(options?: BoardQueryOptions): Promise<SprintTask[]>;
408
- getTask(id: string): Promise<SprintTask | null>;
409
- getTasks(ids: string[]): Promise<SprintTask[]>;
410
- createTask(task: Omit<SprintTask, 'id'>): Promise<SprintTask>;
411
- updateTask(id: string, updates: Partial<Omit<SprintTask, 'id'>>, options?: UpdateTaskOptions): Promise<void>;
523
+ getCycleLog(limit?: number): Promise<CycleLogEntry[]>;
524
+ getCycleLogSince(cycleNumber: number): Promise<CycleLogEntry[]>;
525
+ setCycleHealth(updates: Partial<CycleHealth>): Promise<void>;
526
+ writeCycleLogEntry(entry: CycleLogEntry): Promise<void>;
527
+ updateActiveDecision(id: string, body: string, cycleNumber?: number): Promise<void>;
528
+ /** Upsert an AD — creates if display_id doesn't exist, updates if it does. */
529
+ upsertActiveDecision?(id: string, body: string, title: string, confidence: string, cycleNumber: number): Promise<void>;
530
+ /** Delete an AD permanently by display_id. */
531
+ deleteActiveDecision?(id: string): Promise<void>;
532
+ queryBoard(options?: BoardQueryOptions): Promise<CycleTask[]>;
533
+ getTask(id: string): Promise<CycleTask | null>;
534
+ getTasks(ids: string[]): Promise<CycleTask[]>;
535
+ createTask(task: Omit<CycleTask, 'id'>): Promise<CycleTask>;
536
+ updateTask(id: string, updates: Partial<Omit<CycleTask, 'id'>>, options?: UpdateTaskOptions): Promise<void>;
412
537
  updateTaskStatus(id: string, status: TaskStatus): Promise<void>;
538
+ /** Record a task status transition for audit trail. */
539
+ recordTransition(taskId: string, fromStatus: string, toStatus: string, changedBy?: string): Promise<void>;
413
540
  appendBuildReport(report: BuildReport): Promise<void>;
414
541
  getRecentBuildReports(count: number): Promise<BuildReport[]>;
415
- getBuildReportsSince(sprintNumber: number): Promise<BuildReport[]>;
542
+ getBuildReportsSince(cycleNumber: number): Promise<BuildReport[]>;
416
543
  getRecentReviews(count?: number): Promise<HumanReview[]>;
417
544
  writeReview(review: HumanReview): Promise<void>;
418
- compressSprintLog(threshold: number, summary: string): Promise<void>;
545
+ compressCycleLog(threshold: number, summary: string): Promise<void>;
419
546
  compressBuildReports(threshold: number, summary: string): Promise<void>;
420
547
  archiveTasks(phases: string[], statuses?: string[]): Promise<{
421
548
  archivedCount: number;
@@ -423,38 +550,97 @@ interface PapiAdapter {
423
550
  }>;
424
551
  readProductBrief(): Promise<string>;
425
552
  updateProductBrief(content: string): Promise<void>;
553
+ /** Read discovery canvas sections from product brief. */
554
+ readDiscoveryCanvas(): Promise<DiscoveryCanvas>;
555
+ /** Update discovery canvas sections on product brief. */
556
+ updateDiscoveryCanvas(canvas: Partial<DiscoveryCanvas>): Promise<void>;
426
557
  readPhases(): Promise<Phase[]>;
427
558
  writePhases(phases: Phase[]): Promise<void>;
428
- readFeatures(): Promise<Feature[]>;
429
- getFeature(id: string): Promise<Feature | null>;
430
- createFeature(feature: Omit<Feature, 'id'>): Promise<Feature>;
431
- updateFeature(id: string, updates: Partial<Omit<Feature, 'id'>>): Promise<void>;
559
+ /** Read all horizons for the project (AD-14 hierarchy). */
560
+ readHorizons?(): Promise<Horizon[]>;
561
+ /** Read all stages for the project, optionally filtered by horizon (AD-14 hierarchy). */
562
+ readStages?(horizonId?: string): Promise<Stage[]>;
563
+ /** Update a stage's status (e.g. 'Active' → 'Complete'). */
564
+ updateStageStatus?(stageId: string, status: string): Promise<void>;
565
+ /** Update a horizon's status (e.g. 'Active' → 'Complete'). */
566
+ updateHorizonStatus?(horizonId: string, status: string): Promise<void>;
567
+ /** Get the currently active stage for the project. */
568
+ getActiveStage?(): Promise<Stage | undefined>;
569
+ /** Create a new horizon (AD-14 hierarchy). Returns the created horizon's ID. */
570
+ createHorizon?(horizon: {
571
+ slug: string;
572
+ label: string;
573
+ description?: string;
574
+ status: HorizonStatus;
575
+ sortOrder: number;
576
+ }): Promise<string>;
577
+ /** Create a new stage (AD-14 hierarchy). Returns the created stage's ID. */
578
+ createStage?(stage: {
579
+ slug: string;
580
+ label: string;
581
+ description?: string;
582
+ status: StageStatus;
583
+ sortOrder: number;
584
+ horizonId: string;
585
+ }): Promise<string>;
586
+ /** Link phases to a stage by setting their stage_id. */
587
+ linkPhasesToStage?(stageId: string): Promise<void>;
432
588
  appendToolMetric(metric: ToolCallMetric): Promise<void>;
433
589
  readToolMetrics(): Promise<ToolCallMetric[]>;
434
- getCostSummary(sprintNumber?: number): Promise<CostSummary>;
590
+ getCostSummary(cycleNumber?: number): Promise<CostSummary>;
435
591
  writeCostSnapshot(snapshot: CostSnapshot): Promise<void>;
436
592
  getCostSnapshots(): Promise<CostSnapshot[]>;
437
- appendSprintMetrics(snapshot: SprintMetricsSnapshot): Promise<void>;
438
- readSprintMetrics(): Promise<SprintMetricsSnapshot[]>;
439
- readSprints(): Promise<Sprint[]>;
440
- createSprint(sprint: Sprint): Promise<void>;
441
- getContextHashes?(sprintNumber: number): Promise<Record<string, string> | null>;
593
+ appendCycleMetrics(snapshot: CycleMetricsSnapshot): Promise<void>;
594
+ readCycleMetrics(): Promise<CycleMetricsSnapshot[]>;
595
+ readCycles(): Promise<Cycle[]>;
596
+ createCycle(cycle: Cycle): Promise<void>;
597
+ getContextHashes?(cycleNumber: number): Promise<Record<string, string> | null>;
442
598
  readRegistries(): Promise<Registries>;
443
599
  updateRegistries(registries: Registries): Promise<void>;
444
600
  writeRecommendation(rec: Omit<StrategyRecommendation, 'id'>): Promise<StrategyRecommendation>;
445
601
  getPendingRecommendations(): Promise<StrategyRecommendation[]>;
446
- actionRecommendation(id: string, sprintNumber: number): Promise<void>;
602
+ actionRecommendation(id: string, cycleNumber: number): Promise<void>;
447
603
  appendDecisionEvent(event: Omit<DecisionEvent, 'id' | 'createdAt'>): Promise<DecisionEvent>;
448
604
  getDecisionEvents(decisionId: string, limit?: number): Promise<DecisionEvent[]>;
449
- getDecisionEventsSince(sprint: number): Promise<DecisionEvent[]>;
605
+ getDecisionEventsSince(cycle: number): Promise<DecisionEvent[]>;
450
606
  writeDecisionScore(score: Omit<DecisionScore, 'id' | 'createdAt' | 'totalScore'>): Promise<DecisionScore>;
451
607
  getDecisionScores(decisionId: string): Promise<DecisionScore[]>;
452
608
  getLatestDecisionScores(): Promise<DecisionScore[]>;
453
609
  logEntityReferences(refs: Omit<EntityReference, 'id' | 'createdAt'>[]): Promise<void>;
454
- getDecisionUsage(currentSprint: number): Promise<DecisionUsageSummary[]>;
610
+ getDecisionUsage(currentCycle: number): Promise<DecisionUsageSummary[]>;
611
+ /** Get context utilisation summary from v_context_utilisation view. Optional — pg adapter only. */
612
+ getContextUtilisation?(): Promise<ContextUtilisationSummary[]>;
455
613
  writeStrategyReview(review: StrategyReviewEntry): Promise<void>;
456
- getLastStrategyReviewSprint(): Promise<number>;
457
- getStrategyReviews(limit?: number): Promise<StrategyReviewEntry[]>;
614
+ getLastStrategyReviewCycle(): Promise<number>;
615
+ getStrategyReviews(limit?: number, includeFullAnalysis?: boolean): Promise<StrategyReviewEntry[]>;
616
+ writeDogfoodEntries?(entries: DogfoodEntry[]): Promise<void>;
617
+ getDogfoodLog?(limit?: number): Promise<DogfoodEntry[]>;
618
+ getUnactionedDogfoodEntries?(limit?: number): Promise<DogfoodEntry[]>;
619
+ updateDogfoodEntryStatus?(id: string, status: DogfoodEntry['status'], linkedTaskId?: string): Promise<void>;
620
+ /**
621
+ * Optional: return the current (unsuperseded) North Star statement.
622
+ * When implemented, plan and strategy_review use this instead of relying
623
+ * on the North Star embedded in PLANNING_LOG.md (which may be stale).
624
+ */
625
+ getCurrentNorthStar?(): Promise<string | null>;
626
+ /**
627
+ * Optional: return the cycle number when the current North Star was set.
628
+ * Used for drift detection — flags when North Star hasn't been validated in 10+ cycles.
629
+ */
630
+ getNorthStarSetCycle?(): Promise<number | null>;
631
+ /**
632
+ * Optional: return both cycle number and set_at date for the current North Star.
633
+ * Used for hybrid drift detection — warns only when both cycle gap AND time gap exceed thresholds.
634
+ */
635
+ getNorthStarStaleness?(): Promise<{
636
+ setCycle: number;
637
+ setAt: string;
638
+ } | null>;
639
+ /**
640
+ * Optional: return aggregated estimation calibration data from v_estimation_accuracy.
641
+ * Used by the planner to adjust effort estimates based on historical patterns.
642
+ */
643
+ getEstimationCalibration?(): Promise<EstimationCalibrationRow[]>;
458
644
  /**
459
645
  * Optional: return recent task comments for plan context.
460
646
  * Returns up to `limit` comments across all active tasks, newest first.
@@ -465,6 +651,11 @@ interface PapiAdapter {
465
651
  content: string;
466
652
  createdAt: string;
467
653
  }[]>;
654
+ /**
655
+ * Optional: return recommendation effectiveness data from v_recommendation_effectiveness.
656
+ * Used by strategy review to assess whether past recommendations were followed.
657
+ */
658
+ getRecommendationEffectiveness?(): Promise<RecommendationEffectivenessRow[]>;
468
659
  /**
469
660
  * Optional: return a lean pre-formatted plan context summary.
470
661
  * When implemented (e.g. by pg adapter with SQL aggregates), assembleContext
@@ -472,6 +663,12 @@ interface PapiAdapter {
472
663
  * Return undefined to fall back to the default assembly path.
473
664
  */
474
665
  getPlanContextSummary?(): Promise<PlanContextSummary | undefined>;
666
+ /**
667
+ * Optional: check if the project exists in the data store.
668
+ * Returns true if the project is found, false otherwise.
669
+ * When not implemented, defaults to true (assumes project exists).
670
+ */
671
+ projectExists?(): Promise<boolean>;
475
672
  }
476
673
  /** Lean plan context returned by adapters that support SQL aggregation. */
477
674
  interface PlanContextSummary {
@@ -479,25 +676,25 @@ interface PlanContextSummary {
479
676
  board: string;
480
677
  /** Pre-computed build intelligence: accuracy %, velocity trend, top surprises. */
481
678
  buildIntelligence: string;
482
- /** Last 3 sprint entries with carry-forward. */
483
- sprintLog: string;
679
+ /** Last 3 cycle entries with carry-forward. */
680
+ cycleLog: string;
484
681
  /** One-liner per active decision: id, title, confidence. */
485
682
  activeDecisions: string;
486
683
  }
487
684
  /** Everything the plan write-back needs to persist in a single transaction. */
488
685
  interface PlanWriteBackPayload {
489
- /** The NEW sprint number (current + 1). */
490
- sprintNumber: number;
491
- /** Sprint log entry to upsert. */
492
- sprintLog: SprintLogEntry;
686
+ /** The NEW cycle number (current + 1). */
687
+ cycleNumber: number;
688
+ /** Cycle log entry to upsert. */
689
+ cycleLog: CycleLogEntry;
493
690
  /** Health updates: boardHealth, strategicDirection, etc. */
494
- healthUpdates: Partial<SprintHealth>;
691
+ healthUpdates: Partial<CycleHealth>;
495
692
  /** New tasks to create (already deduplicated by plan service). */
496
- newTasks: Array<Omit<SprintTask, 'id' | 'uuid' | 'displayId'>>;
693
+ newTasks: Array<Omit<CycleTask, 'id' | 'uuid' | 'displayId'>>;
497
694
  /** Board corrections: taskId + partial updates. */
498
695
  boardCorrections: Array<{
499
696
  taskId: string;
500
- updates: Partial<Omit<SprintTask, 'id'>>;
697
+ updates: Partial<Omit<CycleTask, 'id'>>;
501
698
  }>;
502
699
  /** Phases parsed from product brief update. Empty array = no phase changes. */
503
700
  phases: Phase[];
@@ -513,10 +710,8 @@ interface PlanWriteBackPayload {
513
710
  taskId: string;
514
711
  handoff: BuildHandoff;
515
712
  }>;
516
- /** Sprint entity to create. */
517
- sprint: Sprint;
518
- /** Whether to run feature sync from phases. */
519
- featureSync: boolean;
713
+ /** Cycle entity to create. */
714
+ cycle: Cycle;
520
715
  /** IDs of tasks whose reviewed status should be checked before allowing priority changes. */
521
716
  reviewedTaskIds: string[];
522
717
  }
@@ -540,33 +735,33 @@ declare class MdFileAdapter implements PapiAdapter {
540
735
  private read;
541
736
  /** Write UTF-8 text to a .papi/ file. */
542
737
  private write;
543
- /** Parse the full planning context into structured sections (reads from PLANNING_LOG.md + ACTIVE_DECISIONS.md + SPRINT_LOG.md). */
738
+ /** Parse the full planning context into structured sections (reads from PLANNING_LOG.md + ACTIVE_DECISIONS.md + CYCLE_LOG.md). */
544
739
  readPlanningLog(): Promise<PlanningLog>;
545
- /** Read the Sprint Health table from PLANNING_LOG.md. */
546
- getSprintHealth(): Promise<SprintHealth>;
740
+ /** Read the Cycle Health table from PLANNING_LOG.md. */
741
+ getCycleHealth(): Promise<CycleHealth>;
547
742
  /** Read all Active Decisions from ACTIVE_DECISIONS.md. */
548
743
  getActiveDecisions(): Promise<ActiveDecision[]>;
549
- /** Read sprint log entries (newest first), optionally limited to {@link limit} entries. */
550
- getSprintLog(limit?: number): Promise<SprintLogEntry[]>;
551
- getSprintLogSince(sprintNumber: number): Promise<SprintLogEntry[]>;
552
- /** Merge partial updates into the Sprint Health table and write back. */
553
- setSprintHealth(updates: Partial<SprintHealth>): Promise<void>;
554
- /** Prepend a new sprint log entry at the top of the Sprint Log section. */
555
- writeSprintLogEntry(entry: SprintLogEntry): Promise<void>;
556
- /** Write a strategy review — for md adapter, delegates to sprint log. */
744
+ /** Read cycle log entries (newest first), optionally limited to {@link limit} entries. */
745
+ getCycleLog(limit?: number): Promise<CycleLogEntry[]>;
746
+ getCycleLogSince(cycleNumber: number): Promise<CycleLogEntry[]>;
747
+ /** Merge partial updates into the Cycle Health table and write back. */
748
+ setCycleHealth(updates: Partial<CycleHealth>): Promise<void>;
749
+ /** Prepend a new cycle log entry at the top of the Cycle Log section. */
750
+ writeCycleLogEntry(entry: CycleLogEntry): Promise<void>;
751
+ /** Write a strategy review — for md adapter, delegates to cycle log. */
557
752
  writeStrategyReview(review: StrategyReviewEntry): Promise<void>;
558
- /** Get the sprint number of the last strategy review. */
559
- getLastStrategyReviewSprint(): Promise<number>;
560
- /** Get strategy reviews — md adapter returns empty (reviews live in sprint log). */
561
- getStrategyReviews(_limit?: number): Promise<StrategyReviewEntry[]>;
753
+ /** Get the cycle number of the last strategy review. */
754
+ getLastStrategyReviewCycle(): Promise<number>;
755
+ /** Get strategy reviews — md adapter returns empty (reviews live in cycle log). */
756
+ getStrategyReviews(_limit?: number, _includeFullAnalysis?: boolean): Promise<StrategyReviewEntry[]>;
562
757
  /** Update or insert an Active Decision block by ID. */
563
- updateActiveDecision(id: string, body: string, sprintNumber?: number): Promise<void>;
564
- /** Query the sprint board, optionally filtering by status/priority/phase/etc. */
565
- queryBoard(options?: BoardQueryOptions): Promise<SprintTask[]>;
758
+ updateActiveDecision(id: string, body: string, cycleNumber?: number): Promise<void>;
759
+ /** Query the cycle board, optionally filtering by status/priority/phase/etc. */
760
+ queryBoard(options?: BoardQueryOptions): Promise<CycleTask[]>;
566
761
  /** Look up a single task by ID, returning null if not found. */
567
- getTask(id: string): Promise<SprintTask | null>;
762
+ getTask(id: string): Promise<CycleTask | null>;
568
763
  /** Look up multiple tasks by ID in a single board read. */
569
- getTasks(ids: string[]): Promise<SprintTask[]>;
764
+ getTasks(ids: string[]): Promise<CycleTask[]>;
570
765
  /** Warn if a phase name doesn't match any known phase label from PRODUCT_BRIEF.md. */
571
766
  private warnInvalidPhase;
572
767
  /** Warn if a module name doesn't match any registered module in REGISTRIES.md. */
@@ -574,32 +769,33 @@ declare class MdFileAdapter implements PapiAdapter {
574
769
  /** Warn if an epic name doesn't match any registered epic in REGISTRIES.md. */
575
770
  private warnInvalidEpic;
576
771
  /** Create a new task on the board with an auto-generated sequential ID. */
577
- createTask(task: Omit<SprintTask, 'id'>): Promise<SprintTask>;
772
+ createTask(task: Omit<CycleTask, 'id'>): Promise<CycleTask>;
578
773
  /** Update one or more fields on an existing task. Throws if the task ID is not found. */
579
- updateTask(id: string, updates: Partial<Omit<SprintTask, 'id'>>, options?: UpdateTaskOptions): Promise<void>;
774
+ updateTask(id: string, updates: Partial<Omit<CycleTask, 'id'>>, options?: UpdateTaskOptions): Promise<void>;
580
775
  /** Shorthand to update only the status field of a task. */
581
776
  updateTaskStatus(id: string, status: TaskStatus): Promise<void>;
777
+ recordTransition(_taskId: string, _fromStatus: string, _toStatus: string, _changedBy?: string): Promise<void>;
582
778
  /** Insert a new build report at the top of BUILD_REPORTS.md. */
583
779
  appendBuildReport(report: BuildReport): Promise<void>;
584
780
  /** Return the most recent {@link count} build reports. */
585
781
  getRecentBuildReports(count: number): Promise<BuildReport[]>;
586
- /** Return all build reports from sprints >= {@link sprintNumber}. */
587
- getBuildReportsSince(sprintNumber: number): Promise<BuildReport[]>;
782
+ /** Return all build reports from cycles >= {@link cycleNumber}. */
783
+ getBuildReportsSince(cycleNumber: number): Promise<BuildReport[]>;
588
784
  /** Return recent human reviews from REVIEWS.md (newest first), optionally limited to {@link count}. */
589
785
  getRecentReviews(count?: number): Promise<HumanReview[]>;
590
786
  /** Write a new human review to REVIEWS.md. */
591
787
  writeReview(review: HumanReview): Promise<void>;
592
- /** Compress old sprint log entries below {@link threshold} into a summary block. */
593
- compressSprintLog(threshold: number, summary: string): Promise<void>;
788
+ /** Compress old cycle log entries below {@link threshold} into a summary block. */
789
+ compressCycleLog(threshold: number, summary: string): Promise<void>;
594
790
  /** Compress old build reports below {@link threshold} into a summary block. */
595
791
  compressBuildReports(threshold: number, summary: string): Promise<void>;
596
792
  /** Read a .papi/ file, returning empty string if it doesn't exist. */
597
793
  private readOptional;
598
794
  /** Strip build_handoff and build_report from a task before archiving — these are already in BUILD_REPORTS.md. */
599
795
  private stripHeavyFields;
600
- /** Append tasks to ARCHIVE_SPRINT_BOARD.md, stripping heavy fields and deduplicating by ID. */
796
+ /** Append tasks to ARCHIVE_CYCLE_BOARD.md, stripping heavy fields and deduplicating by ID. */
601
797
  private appendToArchive;
602
- /** Archive tasks matching phases and/or statuses to ARCHIVE_SPRINT_BOARD.md and remove them from active board. */
798
+ /** Archive tasks matching phases and/or statuses to ARCHIVE_CYCLE_BOARD.md and remove them from active board. */
603
799
  archiveTasks(phases: string[], statuses?: string[]): Promise<{
604
800
  archivedCount: number;
605
801
  taskIds: string[];
@@ -608,38 +804,30 @@ declare class MdFileAdapter implements PapiAdapter {
608
804
  readProductBrief(): Promise<string>;
609
805
  /** Overwrite PRODUCT_BRIEF.md with new content. */
610
806
  updateProductBrief(content: string): Promise<void>;
807
+ readDiscoveryCanvas(): Promise<DiscoveryCanvas>;
808
+ updateDiscoveryCanvas(_canvas: Partial<DiscoveryCanvas>): Promise<void>;
611
809
  /** Read all phases from PHASES.md (falls back to PRODUCT_BRIEF.md for migration). */
612
810
  readPhases(): Promise<Phase[]>;
613
811
  /** Write phases to PHASES.md. */
614
812
  writePhases(phases: Phase[]): Promise<void>;
615
- /** Read all features from FEATURES.md. */
616
- readFeatures(): Promise<Feature[]>;
617
- /** Get a single feature by UUID. */
618
- getFeature(id: string): Promise<Feature | null>;
619
- /** Create a new feature and append it to FEATURES.md. */
620
- createFeature(feature: Omit<Feature, 'id'>): Promise<Feature>;
621
- /** Update an existing feature by UUID. */
622
- updateFeature(id: string, updates: Partial<Omit<Feature, 'id'>>): Promise<void>;
623
- /** Write all features to FEATURES.md. */
624
- private writeFeatures;
625
813
  /** Append a tool call metric entry to METRICS.md. */
626
814
  appendToolMetric(metric: ToolCallMetric): Promise<void>;
627
815
  /** Read all tool call metrics from METRICS.md. */
628
816
  readToolMetrics(): Promise<ToolCallMetric[]>;
629
- /** Aggregate tool call metrics into a cost summary, optionally filtered by sprint. */
630
- getCostSummary(sprintNumber?: number): Promise<CostSummary>;
817
+ /** Aggregate tool call metrics into a cost summary, optionally filtered by cycle. */
818
+ getCostSummary(cycleNumber?: number): Promise<CostSummary>;
631
819
  /** Write a cost snapshot to the Cost Summary section of METRICS.md. */
632
820
  writeCostSnapshot(snapshot: CostSnapshot): Promise<void>;
633
821
  /** Read all cost snapshots from the Cost Summary section of METRICS.md. */
634
822
  getCostSnapshots(): Promise<CostSnapshot[]>;
635
- /** Append a sprint metrics snapshot to SPRINT_METRICS.md. */
636
- appendSprintMetrics(snapshot: SprintMetricsSnapshot): Promise<void>;
637
- /** Read all sprint metrics snapshots from SPRINT_METRICS.md. */
638
- readSprintMetrics(): Promise<SprintMetricsSnapshot[]>;
639
- /** Read all Sprint entities from SPRINTS.md (newest first). */
640
- readSprints(): Promise<Sprint[]>;
641
- /** Write a new Sprint entity to SPRINTS.md. */
642
- createSprint(sprint: Sprint): Promise<void>;
823
+ /** Append a cycle metrics snapshot to CYCLE_METRICS.md. */
824
+ appendCycleMetrics(snapshot: CycleMetricsSnapshot): Promise<void>;
825
+ /** Read all cycle metrics snapshots from CYCLE_METRICS.md. */
826
+ readCycleMetrics(): Promise<CycleMetricsSnapshot[]>;
827
+ /** Read all Cycle entities from CYCLES.md (newest first). */
828
+ readCycles(): Promise<Cycle[]>;
829
+ /** Write a new Cycle entity to CYCLES.md. */
830
+ createCycle(cycle: Cycle): Promise<void>;
643
831
  /** Read module and epic registries from REGISTRIES.md. */
644
832
  readRegistries(): Promise<Registries>;
645
833
  /** Overwrite REGISTRIES.md with updated registries. */
@@ -652,17 +840,17 @@ declare class MdFileAdapter implements PapiAdapter {
652
840
  /** Read all pending (unactioned) strategy recommendations. */
653
841
  getPendingRecommendations(): Promise<StrategyRecommendation[]>;
654
842
  /** Mark a recommendation as actioned. */
655
- actionRecommendation(id: string, sprintNumber: number): Promise<void>;
843
+ actionRecommendation(id: string, cycleNumber: number): Promise<void>;
656
844
  appendDecisionEvent(event: Omit<DecisionEvent, 'id' | 'createdAt'>): Promise<DecisionEvent>;
657
845
  getDecisionEvents(decisionId: string, limit?: number): Promise<DecisionEvent[]>;
658
- getDecisionEventsSince(sprint: number): Promise<DecisionEvent[]>;
846
+ getDecisionEventsSince(cycle: number): Promise<DecisionEvent[]>;
659
847
  private parseDecisionEvents;
660
848
  writeDecisionScore(score: Omit<DecisionScore, 'id' | 'createdAt' | 'totalScore'>): Promise<DecisionScore>;
661
849
  getDecisionScores(decisionId: string): Promise<DecisionScore[]>;
662
850
  getLatestDecisionScores(): Promise<DecisionScore[]>;
663
851
  private parseDecisionScores;
664
852
  logEntityReferences(_refs: Omit<EntityReference, 'id' | 'createdAt'>[]): Promise<void>;
665
- getDecisionUsage(_currentSprint: number): Promise<DecisionUsageSummary[]>;
853
+ getDecisionUsage(_currentCycle: number): Promise<DecisionUsageSummary[]>;
666
854
  }
667
855
 
668
856
  /** Validate and normalise an effort string to EffortSize. Returns the value or undefined if invalid. */
@@ -676,10 +864,10 @@ declare function parseBuildHandoff(markdown: string): BuildHandoff | null;
676
864
  /** Serialize a BuildHandoff object back into the standard markdown format. */
677
865
  declare function serializeBuildHandoff(handoff: BuildHandoff): string;
678
866
 
679
- /** Calculate Tier 1 sprint metrics from build reports. */
680
- declare function calculateSprintMetrics(reports: BuildReport[], currentSprint: number, window?: number): {
681
- accuracy: SprintEstimationAccuracy[];
682
- velocity: SprintVelocity[];
867
+ /** Calculate Tier 1 cycle metrics from build reports. */
868
+ declare function calculateCycleMetrics(reports: BuildReport[], currentCycle: number, window?: number): {
869
+ accuracy: CycleEstimationAccuracy[];
870
+ velocity: CycleVelocity[];
683
871
  };
684
872
  /**
685
873
  * Detect recurring patterns across build reports.
@@ -687,7 +875,7 @@ declare function calculateSprintMetrics(reports: BuildReport[], currentSprint: n
687
875
  * When a TextClusterer is provided, uses LLM-based semantic clustering for surprises
688
876
  * instead of normalised string matching.
689
877
  */
690
- declare function detectBuildPatterns(reports: BuildReport[], currentSprint: number, window?: number, clusterer?: TextClusterer): Promise<BuildPatterns>;
878
+ declare function detectBuildPatterns(reports: BuildReport[], currentCycle: number, window?: number, clusterer?: TextClusterer): Promise<BuildPatterns>;
691
879
  /** Returns true if the patterns contain any actionable findings. */
692
880
  declare function hasBuildPatterns(patterns: BuildPatterns): boolean;
693
881
 
@@ -704,7 +892,7 @@ declare function prependReview(review: HumanReview, content: string): string;
704
892
  * When a TextClusterer is provided, uses LLM-based semantic clustering for feedback
705
893
  * instead of normalised string matching.
706
894
  */
707
- declare function detectReviewPatterns(reviews: HumanReview[], currentSprint: number, window?: number, clusterer?: TextClusterer): Promise<ReviewPatterns>;
895
+ declare function detectReviewPatterns(reviews: HumanReview[], currentCycle: number, window?: number, clusterer?: TextClusterer): Promise<ReviewPatterns>;
708
896
  /** Returns true if the patterns contain any actionable findings. */
709
897
  declare function hasReviewPatterns(patterns: ReviewPatterns): boolean;
710
898
 
@@ -714,8 +902,8 @@ declare function parseToolMetrics(content: string): ToolCallMetric[];
714
902
  declare function serializeToolMetric(metric: ToolCallMetric): string;
715
903
  /** Append a tool metric row to METRICS.md content. Creates the file template if content is empty. */
716
904
  declare function appendToolMetricToContent(metric: ToolCallMetric, content: string): string;
717
- /** Aggregate tool call metrics into a cost summary, optionally filtered by sprint. */
718
- declare function aggregateCostSummary(metrics: ToolCallMetric[], sprintNumber?: number): CostSummary;
905
+ /** Aggregate tool call metrics into a cost summary, optionally filtered by cycle. */
906
+ declare function aggregateCostSummary(metrics: ToolCallMetric[], cycleNumber?: number): CostSummary;
719
907
 
720
908
  /** Parse the PHASES YAML section from PRODUCT_BRIEF.md content. */
721
909
  declare function parsePhases(content: string): Phase[];
@@ -724,21 +912,14 @@ declare function serializePhases(phases: Phase[]): string;
724
912
  /** Serialize phases and write them into the PHASES section of PRODUCT_BRIEF.md content. */
725
913
  declare function writePhasesToContent(phases: Phase[], content: string): string;
726
914
 
727
- /** Parse the FEATURES YAML section from FEATURES.md content. */
728
- declare function parseFeatures(content: string): Feature[];
729
- /** Serialize an array of features to a YAML block. */
730
- declare function serializeFeatures(features: Feature[]): string;
731
- /** Serialize features and write them into the FEATURES section of FEATURES.md content. */
732
- declare function writeFeaturesToContent(features: Feature[], content: string): string;
733
-
734
- /** Parse SPRINTS.md content into an array of Sprint objects (newest first). */
735
- declare function parseSprints(content: string): Sprint[];
736
- /** Serialize sprints to a complete SPRINTS.md file content. */
737
- declare function serializeSprints(sprints: Sprint[], content: string): string;
738
- /** Serialize a single Sprint to a YAML string (for display/export). */
739
- declare function serializeSprint(sprint: Sprint): string;
740
- /** Add a new sprint to SPRINTS.md (prepended to the array so newest is first). */
741
- declare function prependSprint(sprint: Sprint, content: string): string;
915
+ /** Parse CYCLES.md content into an array of Cycle objects (newest first). */
916
+ declare function parseCycles(content: string): Cycle[];
917
+ /** Serialize cycles to a complete CYCLES.md file content. */
918
+ declare function serializeCycles(cycles: Cycle[], content: string): string;
919
+ /** Serialize a single Cycle to a YAML string (for display/export). */
920
+ declare function serializeCycle(cycle: Cycle): string;
921
+ /** Add a new cycle to CYCLES.md (prepended to the array so newest is first). */
922
+ declare function prependCycle(cycle: Cycle, content: string): string;
742
923
 
743
924
  /** Parse REGISTRIES.md content into a Registries object. */
744
925
  declare function parseRegistries(content: string): Registries;
@@ -901,4 +1082,4 @@ interface ConflictAlert {
901
1082
  resolved_at?: string;
902
1083
  }
903
1084
 
904
- export { type Acknowledgement, type AcknowledgementStatus, type ActiveDecision, type BoardQueryOptions, type BuildHandoff, type BuildPatterns, type BuildReport, type ClusterEntry, type ClusterResult, type CommandCost, type Confidence, type ConflictAlert, type ConflictAlertStatus, type ConflictRaisedBy, type ConflictType, type ContextHashes, type ContextTier, type CostSnapshot, type CostSummary, type DecisionEvent, type DecisionEventSource, type DecisionEventType, type DecisionScore, type DecisionUsageSummary, type EffortSize, type EntityReference, type Feature, type FeatureStatus, type HumanReview, MdFileAdapter, type MilestoneDependency, type NorthStar, type PapiAdapter, type Phase, type PhaseStatus, type PlanContextSummary, type PlanWriteBackPayload, type PlanWriteBackResult, type PlanningLog, type Project, type ProjectContribution, type ProjectContributionStatus, type RecommendationStatus, type RecommendationType, type RecurringFeedback, type RecurringSurprise, type Registries, type ReviewPatterns, type ReviewStage, type ReviewVerdict, type SharedDecision, type SharedDecisionConfidence, type SharedDecisionStatus, type SharedMilestone, type SharedMilestoneStatus, type Sprint, type SprintEstimationAccuracy, type SprintHealth, type SprintLogEntry, type SprintMetricsSnapshot, type SprintStatus, type SprintTask, type SprintVelocity, type StateTransition, type StrategyRecommendation, type StrategyReviewEntry, TASK_TYPE_TIERS, type TaskComplexity, type TaskMaturity, type TaskPriority, type TaskStatus, type TaskType, type TextClusterer, type ToolCallMetric, type UpdateTaskOptions, VALID_TRANSITIONS, aggregateCostSummary, appendToolMetricToContent, calculateSprintMetrics, detectBuildPatterns, detectReviewPatterns, hasBuildPatterns, hasReviewPatterns, isValidStatus, isValidTransition, parseBuildHandoff, parseEffortSize, parseFeatures, parsePhases, parseRegistries, parseReviews, parseSprints, parseToolMetrics, prependReview, prependSprint, serializeBuildHandoff, serializeFeatures, serializePhases, serializeRegistries, serializeReview, serializeSprint, serializeSprints, serializeToolMetric, validateTransition, writeFeaturesToContent, writePhasesToContent };
1085
+ export { type Acknowledgement, type AcknowledgementStatus, type ActiveDecision, type AutoReview, type AutoReviewFinding, type AutoReviewVerdict, type BoardQueryOptions, type BriefImplication, type BuildHandoff, type BuildPatterns, type BuildReport, type ClusterEntry, type ClusterResult, type CommandCost, type Confidence, type ConflictAlert, type ConflictAlertStatus, type ConflictRaisedBy, type ConflictType, type ContextHashes, type ContextTier, type ContextUtilisationSummary, type CostSnapshot, type CostSummary, type Cycle, type CycleEstimationAccuracy, type CycleHealth, type CycleLogEntry, type CycleMetricsSnapshot, type CycleStatus, type CycleTask, type CycleVelocity, type DecisionEvent, type DecisionEventSource, type DecisionEventType, type DecisionScore, type DecisionUsageSummary, type DiscoveryCanvas, type DogfoodEntry, type EffortSize, type EntityReference, type EstimationCalibrationRow, type Horizon, type HorizonStatus, type HumanReview, MdFileAdapter, type MilestoneDependency, type NorthStar, type PapiAdapter, type Phase, type PhaseStatus, type PlanContextSummary, type PlanWriteBackPayload, type PlanWriteBackResult, type PlanningLog, type Project, type ProjectContribution, type ProjectContributionStatus, type RecommendationEffectivenessRow, type RecommendationStatus, type RecommendationType, type RecurringFeedback, type RecurringSurprise, type Registries, type ReviewPatterns, type ReviewStage, type ReviewVerdict, type SharedDecision, type SharedDecisionConfidence, type SharedDecisionStatus, type SharedMilestone, type SharedMilestoneStatus, type Stage, type StageStatus, type StateTransition, type StrategyRecommendation, type StrategyReviewEntry, TASK_TYPE_TIERS, type TaskComplexity, type TaskMaturity, type TaskPriority, type TaskStatus, type TaskType, type TextClusterer, type ToolCallMetric, type UpdateTaskOptions, VALID_TRANSITIONS, aggregateCostSummary, appendToolMetricToContent, calculateCycleMetrics, detectBuildPatterns, detectReviewPatterns, hasBuildPatterns, hasReviewPatterns, isValidStatus, isValidTransition, parseBuildHandoff, parseCycles, parseEffortSize, parsePhases, parseRegistries, parseReviews, parseToolMetrics, prependCycle, prependReview, serializeBuildHandoff, serializeCycle, serializeCycles, serializePhases, serializeRegistries, serializeReview, serializeToolMetric, validateTransition, writePhasesToContent };