@substrate-ai/sdlc 0.19.54

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 (166) hide show
  1. package/dist/events.d.ts +336 -0
  2. package/dist/events.d.ts.map +1 -0
  3. package/dist/events.js +11 -0
  4. package/dist/events.js.map +1 -0
  5. package/dist/gating/conflict-detector.d.ts +59 -0
  6. package/dist/gating/conflict-detector.d.ts.map +1 -0
  7. package/dist/gating/conflict-detector.js +101 -0
  8. package/dist/gating/conflict-detector.js.map +1 -0
  9. package/dist/gating/dispatch-gate.d.ts +42 -0
  10. package/dist/gating/dispatch-gate.d.ts.map +1 -0
  11. package/dist/gating/dispatch-gate.js +197 -0
  12. package/dist/gating/dispatch-gate.js.map +1 -0
  13. package/dist/gating/index.d.ts +9 -0
  14. package/dist/gating/index.d.ts.map +1 -0
  15. package/dist/gating/index.js +8 -0
  16. package/dist/gating/index.js.map +1 -0
  17. package/dist/gating/types.d.ts +98 -0
  18. package/dist/gating/types.d.ts.map +1 -0
  19. package/dist/gating/types.js +8 -0
  20. package/dist/gating/types.js.map +1 -0
  21. package/dist/handlers/event-bridge.d.ts +56 -0
  22. package/dist/handlers/event-bridge.d.ts.map +1 -0
  23. package/dist/handlers/event-bridge.js +140 -0
  24. package/dist/handlers/event-bridge.js.map +1 -0
  25. package/dist/handlers/index.d.ts +15 -0
  26. package/dist/handlers/index.d.ts.map +1 -0
  27. package/dist/handlers/index.js +14 -0
  28. package/dist/handlers/index.js.map +1 -0
  29. package/dist/handlers/sdlc-code-review-handler.d.ts +119 -0
  30. package/dist/handlers/sdlc-code-review-handler.d.ts.map +1 -0
  31. package/dist/handlers/sdlc-code-review-handler.js +131 -0
  32. package/dist/handlers/sdlc-code-review-handler.js.map +1 -0
  33. package/dist/handlers/sdlc-create-story-handler.d.ts +97 -0
  34. package/dist/handlers/sdlc-create-story-handler.d.ts.map +1 -0
  35. package/dist/handlers/sdlc-create-story-handler.js +91 -0
  36. package/dist/handlers/sdlc-create-story-handler.js.map +1 -0
  37. package/dist/handlers/sdlc-dev-story-handler.d.ts +121 -0
  38. package/dist/handlers/sdlc-dev-story-handler.d.ts.map +1 -0
  39. package/dist/handlers/sdlc-dev-story-handler.js +288 -0
  40. package/dist/handlers/sdlc-dev-story-handler.js.map +1 -0
  41. package/dist/handlers/sdlc-phase-handler.d.ts +32 -0
  42. package/dist/handlers/sdlc-phase-handler.d.ts.map +1 -0
  43. package/dist/handlers/sdlc-phase-handler.js +166 -0
  44. package/dist/handlers/sdlc-phase-handler.js.map +1 -0
  45. package/dist/handlers/types.d.ts +132 -0
  46. package/dist/handlers/types.d.ts.map +1 -0
  47. package/dist/handlers/types.js +10 -0
  48. package/dist/handlers/types.js.map +1 -0
  49. package/dist/index.d.ts +8 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +14 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/learning/failure-classifier.d.ts +23 -0
  54. package/dist/learning/failure-classifier.d.ts.map +1 -0
  55. package/dist/learning/failure-classifier.js +75 -0
  56. package/dist/learning/failure-classifier.js.map +1 -0
  57. package/dist/learning/finding-classifier.d.ts +25 -0
  58. package/dist/learning/finding-classifier.d.ts.map +1 -0
  59. package/dist/learning/finding-classifier.js +37 -0
  60. package/dist/learning/finding-classifier.js.map +1 -0
  61. package/dist/learning/finding-lifecycle.d.ts +69 -0
  62. package/dist/learning/finding-lifecycle.d.ts.map +1 -0
  63. package/dist/learning/finding-lifecycle.js +162 -0
  64. package/dist/learning/finding-lifecycle.js.map +1 -0
  65. package/dist/learning/finding-store.d.ts +16 -0
  66. package/dist/learning/finding-store.d.ts.map +1 -0
  67. package/dist/learning/finding-store.js +26 -0
  68. package/dist/learning/finding-store.js.map +1 -0
  69. package/dist/learning/findings-injector.d.ts +34 -0
  70. package/dist/learning/findings-injector.d.ts.map +1 -0
  71. package/dist/learning/findings-injector.js +140 -0
  72. package/dist/learning/findings-injector.js.map +1 -0
  73. package/dist/learning/index.d.ts +8 -0
  74. package/dist/learning/index.d.ts.map +1 -0
  75. package/dist/learning/index.js +10 -0
  76. package/dist/learning/index.js.map +1 -0
  77. package/dist/learning/relevance-scorer.d.ts +25 -0
  78. package/dist/learning/relevance-scorer.d.ts.map +1 -0
  79. package/dist/learning/relevance-scorer.js +49 -0
  80. package/dist/learning/relevance-scorer.js.map +1 -0
  81. package/dist/learning/types.d.ts +55 -0
  82. package/dist/learning/types.d.ts.map +1 -0
  83. package/dist/learning/types.js +36 -0
  84. package/dist/learning/types.js.map +1 -0
  85. package/dist/orchestrator/graph-orchestrator.d.ts +208 -0
  86. package/dist/orchestrator/graph-orchestrator.d.ts.map +1 -0
  87. package/dist/orchestrator/graph-orchestrator.js +213 -0
  88. package/dist/orchestrator/graph-orchestrator.js.map +1 -0
  89. package/dist/run-manifest/cli-flags.d.ts +11 -0
  90. package/dist/run-manifest/cli-flags.d.ts.map +1 -0
  91. package/dist/run-manifest/cli-flags.js +10 -0
  92. package/dist/run-manifest/cli-flags.js.map +1 -0
  93. package/dist/run-manifest/index.d.ts +10 -0
  94. package/dist/run-manifest/index.d.ts.map +1 -0
  95. package/dist/run-manifest/index.js +10 -0
  96. package/dist/run-manifest/index.js.map +1 -0
  97. package/dist/run-model/cli-flags.d.ts +27 -0
  98. package/dist/run-model/cli-flags.d.ts.map +1 -0
  99. package/dist/run-model/cli-flags.js +31 -0
  100. package/dist/run-model/cli-flags.js.map +1 -0
  101. package/dist/run-model/index.d.ts +21 -0
  102. package/dist/run-model/index.d.ts.map +1 -0
  103. package/dist/run-model/index.js +19 -0
  104. package/dist/run-model/index.js.map +1 -0
  105. package/dist/run-model/per-story-state.d.ts +62 -0
  106. package/dist/run-model/per-story-state.d.ts.map +1 -0
  107. package/dist/run-model/per-story-state.js +70 -0
  108. package/dist/run-model/per-story-state.js.map +1 -0
  109. package/dist/run-model/recovery-history.d.ts +56 -0
  110. package/dist/run-model/recovery-history.d.ts.map +1 -0
  111. package/dist/run-model/recovery-history.js +83 -0
  112. package/dist/run-model/recovery-history.js.map +1 -0
  113. package/dist/run-model/run-manifest.d.ts +146 -0
  114. package/dist/run-model/run-manifest.d.ts.map +1 -0
  115. package/dist/run-model/run-manifest.js +481 -0
  116. package/dist/run-model/run-manifest.js.map +1 -0
  117. package/dist/run-model/schemas.d.ts +117 -0
  118. package/dist/run-model/schemas.d.ts.map +1 -0
  119. package/dist/run-model/schemas.js +83 -0
  120. package/dist/run-model/schemas.js.map +1 -0
  121. package/dist/run-model/supervisor-lock.d.ts +104 -0
  122. package/dist/run-model/supervisor-lock.d.ts.map +1 -0
  123. package/dist/run-model/supervisor-lock.js +284 -0
  124. package/dist/run-model/supervisor-lock.js.map +1 -0
  125. package/dist/run-model/types.d.ts +74 -0
  126. package/dist/run-model/types.d.ts.map +1 -0
  127. package/dist/run-model/types.js +8 -0
  128. package/dist/run-model/types.js.map +1 -0
  129. package/dist/run-model/verification-result.d.ts +60 -0
  130. package/dist/run-model/verification-result.d.ts.map +1 -0
  131. package/dist/run-model/verification-result.js +55 -0
  132. package/dist/run-model/verification-result.js.map +1 -0
  133. package/dist/verification/checks/acceptance-criteria-evidence-check.d.ts +21 -0
  134. package/dist/verification/checks/acceptance-criteria-evidence-check.d.ts.map +1 -0
  135. package/dist/verification/checks/acceptance-criteria-evidence-check.js +159 -0
  136. package/dist/verification/checks/acceptance-criteria-evidence-check.js.map +1 -0
  137. package/dist/verification/checks/build-check.d.ts +52 -0
  138. package/dist/verification/checks/build-check.d.ts.map +1 -0
  139. package/dist/verification/checks/build-check.js +160 -0
  140. package/dist/verification/checks/build-check.js.map +1 -0
  141. package/dist/verification/checks/index.d.ts +15 -0
  142. package/dist/verification/checks/index.d.ts.map +1 -0
  143. package/dist/verification/checks/index.js +15 -0
  144. package/dist/verification/checks/index.js.map +1 -0
  145. package/dist/verification/checks/phantom-review-check.d.ts +29 -0
  146. package/dist/verification/checks/phantom-review-check.d.ts.map +1 -0
  147. package/dist/verification/checks/phantom-review-check.js +70 -0
  148. package/dist/verification/checks/phantom-review-check.js.map +1 -0
  149. package/dist/verification/checks/trivial-output-check.d.ts +47 -0
  150. package/dist/verification/checks/trivial-output-check.d.ts.map +1 -0
  151. package/dist/verification/checks/trivial-output-check.js +72 -0
  152. package/dist/verification/checks/trivial-output-check.js.map +1 -0
  153. package/dist/verification/index.d.ts +13 -0
  154. package/dist/verification/index.d.ts.map +1 -0
  155. package/dist/verification/index.js +13 -0
  156. package/dist/verification/index.js.map +1 -0
  157. package/dist/verification/types.d.ts +149 -0
  158. package/dist/verification/types.d.ts.map +1 -0
  159. package/dist/verification/types.js +12 -0
  160. package/dist/verification/types.js.map +1 -0
  161. package/dist/verification/verification-pipeline.d.ts +65 -0
  162. package/dist/verification/verification-pipeline.d.ts.map +1 -0
  163. package/dist/verification/verification-pipeline.js +149 -0
  164. package/dist/verification/verification-pipeline.js.map +1 -0
  165. package/graphs/sdlc-pipeline.dot +42 -0
  166. package/package.json +22 -0
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Type definitions for the SDLC handler module.
3
+ * Story 43-2.
4
+ *
5
+ * All types are defined locally — structurally compatible with monolith types
6
+ * but not compile-time coupled to the monolith or @substrate-ai/factory.
7
+ * See ADR-003: sdlc must NOT import from @substrate-ai/factory.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/handlers/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,8 @@
1
+ export * from './events.js';
2
+ export * from './handlers/index.js';
3
+ export * from './orchestrator/graph-orchestrator.js';
4
+ export * from './verification/index.js';
5
+ export * from './run-model/index.js';
6
+ export * from './learning/index.js';
7
+ export * from './gating/index.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAA;AAC3B,cAAc,qBAAqB,CAAA;AAEnC,cAAc,sCAAsC,CAAA;AAEpD,cAAc,yBAAyB,CAAA;AAEvC,cAAc,sBAAsB,CAAA;AAEpC,cAAc,qBAAqB,CAAA;AAEnC,cAAc,mBAAmB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ // @substrate-ai/sdlc — public API (populated in stories 40-3 through 40-8)
2
+ export * from './events.js';
3
+ export * from './handlers/index.js';
4
+ // Story 43-7/43-8: graph-based orchestrator and config mapping
5
+ export * from './orchestrator/graph-orchestrator.js';
6
+ // Story 51-1: Verification pipeline framework
7
+ export * from './verification/index.js';
8
+ // Story 52-1: RunManifest — atomic file-backed run state
9
+ export * from './run-model/index.js';
10
+ // Story 53-5: Learning loop — root cause taxonomy and failure classification
11
+ export * from './learning/index.js';
12
+ // Story 53-9: Dispatch pre-condition gating
13
+ export * from './gating/index.js';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,cAAc,aAAa,CAAA;AAC3B,cAAc,qBAAqB,CAAA;AACnC,+DAA+D;AAC/D,cAAc,sCAAsC,CAAA;AACpD,8CAA8C;AAC9C,cAAc,yBAAyB,CAAA;AACvC,yDAAyD;AACzD,cAAc,sBAAsB,CAAA;AACpC,6EAA6E;AAC7E,cAAc,qBAAqB,CAAA;AACnC,4CAA4C;AAC5C,cAAc,mBAAmB,CAAA"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Learning loop — deterministic failure classifier.
3
+ *
4
+ * Story 53-5: Root Cause Taxonomy and Failure Classification
5
+ *
6
+ * classifyFailure applies a rule chain in strict priority order (§3.4).
7
+ * buildFinding constructs a validated Finding from a classification result.
8
+ */
9
+ import type { Finding, RootCauseCategory, StoryFailureContext } from './types.js';
10
+ /**
11
+ * Deterministic, synchronous rule chain that maps a StoryFailureContext to a
12
+ * RootCauseCategory. Rules are evaluated in order; the first match wins.
13
+ */
14
+ export declare function classifyFailure(ctx: StoryFailureContext): RootCauseCategory;
15
+ /**
16
+ * Construct a validated Finding from a StoryFailureContext and classification result.
17
+ *
18
+ * - confidence: 'low' for 'unclassified', 'high' for all other categories
19
+ * - description: raw ctx.error for 'unclassified'; human-readable text otherwise
20
+ * - expires_after_runs: 5 (default)
21
+ */
22
+ export declare function buildFinding(ctx: StoryFailureContext, rootCause: RootCauseCategory, runId: string): Finding;
23
+ //# sourceMappingURL=failure-classifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failure-classifier.d.ts","sourceRoot":"","sources":["../../src/learning/failure-classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAMjF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,mBAAmB,GAAG,iBAAiB,CAS3E;AAsBD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,mBAAmB,EACxB,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,MAAM,GACZ,OAAO,CAmBT"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Learning loop — deterministic failure classifier.
3
+ *
4
+ * Story 53-5: Root Cause Taxonomy and Failure Classification
5
+ *
6
+ * classifyFailure applies a rule chain in strict priority order (§3.4).
7
+ * buildFinding constructs a validated Finding from a classification result.
8
+ */
9
+ import { FindingSchema } from './types.js';
10
+ // ---------------------------------------------------------------------------
11
+ // Classification rule chain — canonical priority order, do not reorder
12
+ // ---------------------------------------------------------------------------
13
+ /**
14
+ * Deterministic, synchronous rule chain that maps a StoryFailureContext to a
15
+ * RootCauseCategory. Rules are evaluated in order; the first match wins.
16
+ */
17
+ export function classifyFailure(ctx) {
18
+ if (ctx.error?.includes('already exists'))
19
+ return 'namespace-collision';
20
+ if (ctx.error?.includes('depends on') || ctx.error?.includes('not found'))
21
+ return 'dependency-ordering';
22
+ if ((ctx.outputTokens ?? Infinity) < 100)
23
+ return 'resource-exhaustion';
24
+ if (ctx.buildFailed === true)
25
+ return 'build-failure';
26
+ if (ctx.testsFailed === true)
27
+ return 'test-failure';
28
+ if (ctx.adapterError === true)
29
+ return 'adapter-format';
30
+ if (/heap out of memory|ENOSPC|EACCES|SIGKILL/.test(ctx.error ?? ''))
31
+ return 'infrastructure';
32
+ return 'unclassified';
33
+ }
34
+ // ---------------------------------------------------------------------------
35
+ // Human-readable descriptions per category
36
+ // ---------------------------------------------------------------------------
37
+ const CATEGORY_DESCRIPTIONS = {
38
+ 'namespace-collision': 'Identifier or namespace collision detected during story dispatch',
39
+ 'dependency-ordering': 'Story depends on a missing or not-yet-available dependency',
40
+ 'spec-staleness': 'Story spec references outdated or stale interface definitions',
41
+ 'adapter-format': 'Adapter output format was not recognized or could not be parsed',
42
+ 'build-failure': 'Build failed after story dispatch',
43
+ 'test-failure': 'Tests failed after story implementation',
44
+ 'resource-exhaustion': 'Story produced fewer than 100 output tokens (resource exhaustion suspected)',
45
+ 'infrastructure': 'System-level infrastructure error (OOM, disk, permissions, or SIGKILL)',
46
+ 'unclassified': 'No error text available', // overridden in buildFinding with raw ctx.error when present
47
+ };
48
+ // ---------------------------------------------------------------------------
49
+ // Finding builder
50
+ // ---------------------------------------------------------------------------
51
+ /**
52
+ * Construct a validated Finding from a StoryFailureContext and classification result.
53
+ *
54
+ * - confidence: 'low' for 'unclassified', 'high' for all other categories
55
+ * - description: raw ctx.error for 'unclassified'; human-readable text otherwise
56
+ * - expires_after_runs: 5 (default)
57
+ */
58
+ export function buildFinding(ctx, rootCause, runId) {
59
+ const confidence = rootCause === 'unclassified' ? 'low' : 'high';
60
+ const description = rootCause === 'unclassified'
61
+ ? (ctx.error ?? 'No error text available')
62
+ : CATEGORY_DESCRIPTIONS[rootCause];
63
+ return FindingSchema.parse({
64
+ id: crypto.randomUUID(),
65
+ run_id: runId,
66
+ story_key: ctx.storyKey,
67
+ root_cause: rootCause,
68
+ affected_files: ctx.affectedFiles ?? [],
69
+ description,
70
+ confidence,
71
+ created_at: new Date().toISOString(),
72
+ expires_after_runs: 5,
73
+ });
74
+ }
75
+ //# sourceMappingURL=failure-classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failure-classifier.js","sourceRoot":"","sources":["../../src/learning/failure-classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG1C,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAwB;IACtD,IAAI,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,gBAAgB,CAAC;QAAE,OAAO,qBAAqB,CAAA;IACvE,IAAI,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,qBAAqB,CAAA;IACvG,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,QAAQ,CAAC,GAAG,GAAG;QAAE,OAAO,qBAAqB,CAAA;IACtE,IAAI,GAAG,CAAC,WAAW,KAAK,IAAI;QAAE,OAAO,eAAe,CAAA;IACpD,IAAI,GAAG,CAAC,WAAW,KAAK,IAAI;QAAE,OAAO,cAAc,CAAA;IACnD,IAAI,GAAG,CAAC,YAAY,KAAK,IAAI;QAAE,OAAO,gBAAgB,CAAA;IACtD,IAAI,0CAA0C,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;QAAE,OAAO,gBAAgB,CAAA;IAC7F,OAAO,cAAc,CAAA;AACvB,CAAC;AAED,8EAA8E;AAC9E,2CAA2C;AAC3C,8EAA8E;AAE9E,MAAM,qBAAqB,GAAsC;IAC/D,qBAAqB,EAAE,kEAAkE;IACzF,qBAAqB,EAAE,4DAA4D;IACnF,gBAAgB,EAAE,+DAA+D;IACjF,gBAAgB,EAAE,iEAAiE;IACnF,eAAe,EAAE,mCAAmC;IACpD,cAAc,EAAE,yCAAyC;IACzD,qBAAqB,EAAE,6EAA6E;IACpG,gBAAgB,EAAE,wEAAwE;IAC1F,cAAc,EAAE,yBAAyB,EAAE,6DAA6D;CACzG,CAAA;AAED,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,GAAwB,EACxB,SAA4B,EAC5B,KAAa;IAEb,MAAM,UAAU,GAAG,SAAS,KAAK,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAA;IAEhE,MAAM,WAAW,GACf,SAAS,KAAK,cAAc;QAC1B,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,yBAAyB,CAAC;QAC1C,CAAC,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAA;IAEtC,OAAO,aAAa,CAAC,KAAK,CAAC;QACzB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,MAAM,EAAE,KAAK;QACb,SAAS,EAAE,GAAG,CAAC,QAAQ;QACvB,UAAU,EAAE,SAAS;QACrB,cAAc,EAAE,GAAG,CAAC,aAAa,IAAI,EAAE;QACvC,WAAW;QACX,UAAU;QACV,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,kBAAkB,EAAE,CAAC;KACtB,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Learning loop — top-level classify-and-persist orchestrator.
3
+ *
4
+ * Story 53-5: Root Cause Taxonomy and Failure Classification
5
+ *
6
+ * classifyAndPersist is the primary entry point for the learning loop:
7
+ * it classifies a story failure, constructs a Finding, and persists it to
8
+ * Dolt — all non-fatally (persistence errors are swallowed so the in-memory
9
+ * result is always returned to the caller).
10
+ */
11
+ import type { DatabaseAdapter } from '@substrate-ai/core';
12
+ import type { Finding, StoryFailureContext } from './types.js';
13
+ /**
14
+ * Classify a story failure, build a Finding, and attempt to persist it.
15
+ *
16
+ * Persistence is non-fatal: if `db` is null or the persist call rejects,
17
+ * the Finding is still returned. This ensures that Dolt unavailability
18
+ * never blocks the learning loop from producing an in-memory classification.
19
+ *
20
+ * @param ctx - Contextual failure information from the orchestrator
21
+ * @param db - DatabaseAdapter to persist to, or null if unavailable
22
+ * @returns A validated Finding with root_cause, confidence, and metadata
23
+ */
24
+ export declare function classifyAndPersist(ctx: StoryFailureContext, db: DatabaseAdapter | null): Promise<Finding>;
25
+ //# sourceMappingURL=finding-classifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-classifier.d.ts","sourceRoot":"","sources":["../../src/learning/finding-classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAGzD,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAM9D;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,mBAAmB,EACxB,EAAE,EAAE,eAAe,GAAG,IAAI,GACzB,OAAO,CAAC,OAAO,CAAC,CAWlB"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Learning loop — top-level classify-and-persist orchestrator.
3
+ *
4
+ * Story 53-5: Root Cause Taxonomy and Failure Classification
5
+ *
6
+ * classifyAndPersist is the primary entry point for the learning loop:
7
+ * it classifies a story failure, constructs a Finding, and persists it to
8
+ * Dolt — all non-fatally (persistence errors are swallowed so the in-memory
9
+ * result is always returned to the caller).
10
+ */
11
+ import { classifyFailure, buildFinding } from './failure-classifier.js';
12
+ import { persistFinding } from './finding-store.js';
13
+ // ---------------------------------------------------------------------------
14
+ // Classify and persist a story failure
15
+ // ---------------------------------------------------------------------------
16
+ /**
17
+ * Classify a story failure, build a Finding, and attempt to persist it.
18
+ *
19
+ * Persistence is non-fatal: if `db` is null or the persist call rejects,
20
+ * the Finding is still returned. This ensures that Dolt unavailability
21
+ * never blocks the learning loop from producing an in-memory classification.
22
+ *
23
+ * @param ctx - Contextual failure information from the orchestrator
24
+ * @param db - DatabaseAdapter to persist to, or null if unavailable
25
+ * @returns A validated Finding with root_cause, confidence, and metadata
26
+ */
27
+ export async function classifyAndPersist(ctx, db) {
28
+ const rootCause = classifyFailure(ctx);
29
+ const finding = buildFinding(ctx, rootCause, ctx.runId);
30
+ if (db !== null) {
31
+ persistFinding(finding, db).catch(() => {
32
+ // Non-fatal: Dolt may be unavailable; in-memory finding is always returned
33
+ });
34
+ }
35
+ return finding;
36
+ }
37
+ //# sourceMappingURL=finding-classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-classifier.js","sourceRoot":"","sources":["../../src/learning/finding-classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAGnD,8EAA8E;AAC9E,uCAAuC;AACvC,8EAA8E;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAwB,EACxB,EAA0B;IAE1B,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;IACtC,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,CAAA;IAEvD,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;QAChB,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACrC,2EAA2E;QAC7E,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * FindingLifecycleManager — validation, deduplication, expiry, and retirement
3
+ * for learning loop findings.
4
+ *
5
+ * Story 53-7: Finding Validation, Deduplication, and Expiry
6
+ */
7
+ import type { DatabaseAdapter } from '@substrate-ai/core';
8
+ import type { Finding } from './types.js';
9
+ /** Context supplied when a story completes successfully. */
10
+ export interface SuccessContext {
11
+ modifiedFiles: string[];
12
+ runId: string;
13
+ }
14
+ export declare class FindingLifecycleManager {
15
+ /**
16
+ * Validate file existence for a finding's affected_files.
17
+ *
18
+ * - Returns finding unchanged if affected_files is empty or all files exist.
19
+ * - Returns finding with confidence: 'low' if some files are missing.
20
+ * - Returns finding with confidence: 'low' + contradicted_by: 'all-files-deleted'
21
+ * if ALL files are missing.
22
+ *
23
+ * AC1: pure synchronous function — no I/O beyond fs.existsSync
24
+ */
25
+ static validateFiles(finding: Finding, projectRoot: string): Finding;
26
+ /**
27
+ * Deduplicate findings by fingerprint: `${root_cause}:${affected_files.sort().join(',')}`.
28
+ *
29
+ * For each group of duplicates, only the most recently created finding
30
+ * (highest created_at lexicographically) is retained.
31
+ *
32
+ * AC2: pure synchronous function — no I/O
33
+ */
34
+ static deduplicate(findings: Finding[]): Finding[];
35
+ /**
36
+ * Count the number of distinct pipeline runs since this finding was created.
37
+ *
38
+ * Returns 0 on any DB error (non-fatal — never marks as expired on error).
39
+ *
40
+ * AC3: async — interacts with the DB
41
+ */
42
+ static countRunsSinceCreation(finding: Finding, db: DatabaseAdapter): Promise<number>;
43
+ /**
44
+ * Check if a finding has expired based on the run count since its creation.
45
+ *
46
+ * AC3: pure synchronous function — no I/O
47
+ */
48
+ static isExpired(finding: Finding, runCount: number): boolean;
49
+ /**
50
+ * Archive a finding by persisting a tombstone record in the decisions table.
51
+ *
52
+ * Non-fatal — any DB error is swallowed silently.
53
+ *
54
+ * AC4: async — interacts with the DB
55
+ */
56
+ static archiveFinding(finding: Finding, currentRunId: string, db: DatabaseAdapter): Promise<void>;
57
+ /**
58
+ * Retire findings that are contradicted by a successful story run.
59
+ *
60
+ * Loads all findings from Dolt, checks each for file overlap with the
61
+ * success context, and persists a tombstone for overlapping findings.
62
+ *
63
+ * Entirely non-fatal — DB errors and parse failures are swallowed silently.
64
+ *
65
+ * AC5: async — interacts with the DB
66
+ */
67
+ static retireContradictedFindings(successContext: SuccessContext, db: DatabaseAdapter): Promise<void>;
68
+ }
69
+ //# sourceMappingURL=finding-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-lifecycle.d.ts","sourceRoot":"","sources":["../../src/learning/finding-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAEzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAOzC,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;CACd;AAMD,qBAAa,uBAAuB;IAClC;;;;;;;;;OASG;IACH,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO;IAkBpE;;;;;;;OAOG;IACH,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE;IAuBlD;;;;;;OAMG;WACU,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAc3F;;;;OAIG;IACH,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI7D;;;;;;OAMG;WACU,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAcvG;;;;;;;;;OASG;WACU,0BAA0B,CAAC,cAAc,EAAE,cAAc,EAAE,EAAE,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAuC5G"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * FindingLifecycleManager — validation, deduplication, expiry, and retirement
3
+ * for learning loop findings.
4
+ *
5
+ * Story 53-7: Finding Validation, Deduplication, and Expiry
6
+ */
7
+ import { existsSync } from 'node:fs';
8
+ import { join } from 'node:path';
9
+ import { createDecision, getDecisionsByCategory, LEARNING_FINDING } from '@substrate-ai/core';
10
+ import { FindingSchema } from './types.js';
11
+ // ---------------------------------------------------------------------------
12
+ // FindingLifecycleManager
13
+ // ---------------------------------------------------------------------------
14
+ export class FindingLifecycleManager {
15
+ /**
16
+ * Validate file existence for a finding's affected_files.
17
+ *
18
+ * - Returns finding unchanged if affected_files is empty or all files exist.
19
+ * - Returns finding with confidence: 'low' if some files are missing.
20
+ * - Returns finding with confidence: 'low' + contradicted_by: 'all-files-deleted'
21
+ * if ALL files are missing.
22
+ *
23
+ * AC1: pure synchronous function — no I/O beyond fs.existsSync
24
+ */
25
+ static validateFiles(finding, projectRoot) {
26
+ if (finding.affected_files.length === 0) {
27
+ return finding;
28
+ }
29
+ const existingCount = finding.affected_files.filter((f) => existsSync(join(projectRoot, f))).length;
30
+ if (existingCount === 0) {
31
+ return { ...finding, confidence: 'low', contradicted_by: 'all-files-deleted' };
32
+ }
33
+ if (existingCount < finding.affected_files.length) {
34
+ return { ...finding, confidence: 'low' };
35
+ }
36
+ return finding;
37
+ }
38
+ /**
39
+ * Deduplicate findings by fingerprint: `${root_cause}:${affected_files.sort().join(',')}`.
40
+ *
41
+ * For each group of duplicates, only the most recently created finding
42
+ * (highest created_at lexicographically) is retained.
43
+ *
44
+ * AC2: pure synchronous function — no I/O
45
+ */
46
+ static deduplicate(findings) {
47
+ const groups = new Map();
48
+ for (const finding of findings) {
49
+ const fingerprint = `${finding.root_cause}:${[...finding.affected_files].sort().join(',')}`;
50
+ const group = groups.get(fingerprint);
51
+ if (group === undefined) {
52
+ groups.set(fingerprint, [finding]);
53
+ }
54
+ else {
55
+ group.push(finding);
56
+ }
57
+ }
58
+ const result = [];
59
+ for (const group of groups.values()) {
60
+ // Keep the finding with the highest created_at (ISO strings compare correctly lexicographically)
61
+ const best = group.reduce((a, b) => (a.created_at >= b.created_at ? a : b));
62
+ result.push(best);
63
+ }
64
+ return result;
65
+ }
66
+ /**
67
+ * Count the number of distinct pipeline runs since this finding was created.
68
+ *
69
+ * Returns 0 on any DB error (non-fatal — never marks as expired on error).
70
+ *
71
+ * AC3: async — interacts with the DB
72
+ */
73
+ static async countRunsSinceCreation(finding, db) {
74
+ try {
75
+ const result = await db.query(`SELECT COUNT(DISTINCT pipeline_run_id) AS cnt
76
+ FROM decisions
77
+ WHERE created_at > ? AND pipeline_run_id != ?`, [finding.created_at, finding.run_id]);
78
+ return Number(result[0]?.cnt ?? 0);
79
+ }
80
+ catch {
81
+ return 0;
82
+ }
83
+ }
84
+ /**
85
+ * Check if a finding has expired based on the run count since its creation.
86
+ *
87
+ * AC3: pure synchronous function — no I/O
88
+ */
89
+ static isExpired(finding, runCount) {
90
+ return runCount >= finding.expires_after_runs;
91
+ }
92
+ /**
93
+ * Archive a finding by persisting a tombstone record in the decisions table.
94
+ *
95
+ * Non-fatal — any DB error is swallowed silently.
96
+ *
97
+ * AC4: async — interacts with the DB
98
+ */
99
+ static async archiveFinding(finding, currentRunId, db) {
100
+ try {
101
+ await createDecision(db, {
102
+ category: LEARNING_FINDING,
103
+ key: `${finding.id}:archived`,
104
+ pipeline_run_id: currentRunId,
105
+ phase: 'implementation',
106
+ value: JSON.stringify({ ...finding, contradicted_by: 'expired' }),
107
+ });
108
+ }
109
+ catch {
110
+ // Non-fatal: swallow DB errors per AC4
111
+ }
112
+ }
113
+ /**
114
+ * Retire findings that are contradicted by a successful story run.
115
+ *
116
+ * Loads all findings from Dolt, checks each for file overlap with the
117
+ * success context, and persists a tombstone for overlapping findings.
118
+ *
119
+ * Entirely non-fatal — DB errors and parse failures are swallowed silently.
120
+ *
121
+ * AC5: async — interacts with the DB
122
+ */
123
+ static async retireContradictedFindings(successContext, db) {
124
+ try {
125
+ const rows = await getDecisionsByCategory(db, LEARNING_FINDING);
126
+ for (const row of rows) {
127
+ try {
128
+ const parsed = JSON.parse(row.value);
129
+ const result = FindingSchema.safeParse(parsed);
130
+ if (!result.success)
131
+ continue;
132
+ const finding = result.data;
133
+ // Only retire findings that have not yet been contradicted/archived
134
+ // AND have at least one file overlapping the success context
135
+ const hasOverlap = finding.contradicted_by === undefined &&
136
+ finding.affected_files.some((f) => successContext.modifiedFiles.includes(f));
137
+ if (!hasOverlap)
138
+ continue;
139
+ try {
140
+ await createDecision(db, {
141
+ category: LEARNING_FINDING,
142
+ key: `${finding.id}:archived`,
143
+ pipeline_run_id: successContext.runId,
144
+ phase: 'implementation',
145
+ value: JSON.stringify({ ...finding, contradicted_by: successContext.runId }),
146
+ });
147
+ }
148
+ catch {
149
+ // Non-fatal: swallow individual write errors per AC5
150
+ }
151
+ }
152
+ catch {
153
+ // Non-fatal: swallow parse failures per AC5
154
+ }
155
+ }
156
+ }
157
+ catch {
158
+ // Non-fatal: swallow outer DB/load errors per AC5
159
+ }
160
+ }
161
+ }
162
+ //# sourceMappingURL=finding-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-lifecycle.js","sourceRoot":"","sources":["../../src/learning/finding-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Learning loop — finding persistence to the Dolt decisions table.
3
+ *
4
+ * Story 53-5: Root Cause Taxonomy and Failure Classification
5
+ */
6
+ import type { DatabaseAdapter } from '@substrate-ai/core';
7
+ import type { Finding } from './types.js';
8
+ /**
9
+ * Persist a classified Finding to the decisions table using the LEARNING_FINDING
10
+ * category. Key format: '{story_key}:{run_id}'.
11
+ *
12
+ * @param finding - The Finding to persist (from buildFinding)
13
+ * @param db - A live DatabaseAdapter (Dolt or InMemory)
14
+ */
15
+ export declare function persistFinding(finding: Finding, db: DatabaseAdapter): Promise<void>;
16
+ //# sourceMappingURL=finding-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-store.d.ts","sourceRoot":"","sources":["../../src/learning/finding-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAMzC;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAQzF"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Learning loop — finding persistence to the Dolt decisions table.
3
+ *
4
+ * Story 53-5: Root Cause Taxonomy and Failure Classification
5
+ */
6
+ import { createDecision, LEARNING_FINDING } from '@substrate-ai/core';
7
+ // ---------------------------------------------------------------------------
8
+ // Persist a Finding to the decisions table
9
+ // ---------------------------------------------------------------------------
10
+ /**
11
+ * Persist a classified Finding to the decisions table using the LEARNING_FINDING
12
+ * category. Key format: '{story_key}:{run_id}'.
13
+ *
14
+ * @param finding - The Finding to persist (from buildFinding)
15
+ * @param db - A live DatabaseAdapter (Dolt or InMemory)
16
+ */
17
+ export async function persistFinding(finding, db) {
18
+ await createDecision(db, {
19
+ category: LEARNING_FINDING,
20
+ key: `${finding.story_key}:${finding.run_id}`,
21
+ phase: 'implementation',
22
+ pipeline_run_id: finding.run_id,
23
+ value: JSON.stringify(finding),
24
+ });
25
+ }
26
+ //# sourceMappingURL=finding-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-store.js","sourceRoot":"","sources":["../../src/learning/finding-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAIrE,8EAA8E;AAC9E,2CAA2C;AAC3C,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAgB,EAAE,EAAmB;IACxE,MAAM,cAAc,CAAC,EAAE,EAAE;QACvB,QAAQ,EAAE,gBAAgB;QAC1B,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE;QAC7C,KAAK,EAAE,gBAAgB;QACvB,eAAe,EAAE,OAAO,CAAC,MAAM;QAC/B,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;KAC/B,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * FindingsInjector — relevance-scored learning findings injector.
3
+ *
4
+ * Story 53-6: Findings Injector with Relevance Scoring
5
+ *
6
+ * Queries structured findings from the decisions table, scores each finding
7
+ * against an injection context, applies threshold/saturation guards, and
8
+ * serializes the top-ranked findings with budget enforcement.
9
+ */
10
+ import type { DatabaseAdapter } from '@substrate-ai/core';
11
+ import type { InjectionContext } from './relevance-scorer.js';
12
+ export interface FindingsInjectorConfig {
13
+ threshold?: number;
14
+ maxChars?: number;
15
+ saturationLimit?: number;
16
+ }
17
+ export declare class FindingsInjector {
18
+ /**
19
+ * Query relevance-scored findings from the decisions table and serialize
20
+ * them as a prompt-injection string within the given character budget.
21
+ *
22
+ * Returns '' if no findings survive filtering or on any DB error.
23
+ */
24
+ static inject(db: DatabaseAdapter, context: InjectionContext, config?: FindingsInjectorConfig): Promise<string>;
25
+ }
26
+ /**
27
+ * Extract file paths referenced in a story document for use as targetFiles
28
+ * in relevance scoring.
29
+ *
30
+ * Matches paths starting with `packages/` or `src/` with common code extensions.
31
+ * Returns up to 30 unique paths.
32
+ */
33
+ export declare function extractTargetFilesFromStoryContent(storyContent: string): string[];
34
+ //# sourceMappingURL=findings-injector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findings-injector.d.ts","sourceRoot":"","sources":["../../src/learning/findings-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAIzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAQ7D,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAMD,qBAAa,gBAAgB;IAC3B;;;;;OAKG;WACU,MAAM,CACjB,EAAE,EAAE,eAAe,EACnB,OAAO,EAAE,gBAAgB,EACzB,MAAM,CAAC,EAAE,sBAAsB,GAC9B,OAAO,CAAC,MAAM,CAAC;CAsGnB;AAMD;;;;;;GAMG;AACH,wBAAgB,kCAAkC,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAMjF"}