@ai-sdlc/orchestrator 0.6.0 → 0.9.0

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 (203) hide show
  1. package/dist/admission-composite.d.ts +67 -0
  2. package/dist/admission-composite.js +158 -0
  3. package/dist/admission-enrichment.d.ts +142 -0
  4. package/dist/admission-enrichment.js +331 -0
  5. package/dist/admission-hc.d.ts +62 -0
  6. package/dist/admission-hc.js +83 -0
  7. package/dist/admission-score.d.ts +95 -5
  8. package/dist/admission-score.js +84 -11
  9. package/dist/analysis/analyzer.js +3 -2
  10. package/dist/analysis/convention-detector.d.ts +85 -2
  11. package/dist/analysis/convention-detector.js +375 -70
  12. package/dist/analysis/diff-analyzer.d.ts +33 -0
  13. package/dist/analysis/diff-analyzer.js +122 -0
  14. package/dist/analysis/hotspot-analyzer.js +3 -1
  15. package/dist/analysis/index.d.ts +2 -1
  16. package/dist/analysis/index.js +2 -1
  17. package/dist/artifacts/index.d.ts +65 -0
  18. package/dist/artifacts/index.js +142 -0
  19. package/dist/backlog-adapter.d.ts +121 -0
  20. package/dist/backlog-adapter.js +438 -0
  21. package/dist/calibration.d.ts +43 -0
  22. package/dist/calibration.js +76 -0
  23. package/dist/cli/commands/agents.d.ts +24 -0
  24. package/dist/cli/commands/agents.js +66 -1
  25. package/dist/cli/commands/git-remote.d.ts +49 -0
  26. package/dist/cli/commands/git-remote.js +91 -0
  27. package/dist/cli/commands/health.d.ts +4 -0
  28. package/dist/cli/commands/health.js +13 -1
  29. package/dist/cli/commands/init.d.ts +26 -0
  30. package/dist/cli/commands/init.js +164 -22
  31. package/dist/cli/commands/mcp-setup.d.ts +31 -0
  32. package/dist/cli/commands/mcp-setup.js +78 -8
  33. package/dist/cli/formatters/table.js +15 -2
  34. package/dist/cli/index.d.ts +14 -1
  35. package/dist/cli/index.js +81 -20
  36. package/dist/cli/versions.d.ts +57 -0
  37. package/dist/cli/versions.js +128 -0
  38. package/dist/code-area-classifier.d.ts +21 -0
  39. package/dist/code-area-classifier.js +48 -0
  40. package/dist/config.d.ts +33 -1
  41. package/dist/config.js +78 -8
  42. package/dist/database/adapters/external.d.ts +24 -0
  43. package/dist/database/adapters/external.js +80 -0
  44. package/dist/database/adapters/neon.d.ts +41 -0
  45. package/dist/database/adapters/neon.js +98 -0
  46. package/dist/database/adapters/pg-snapshot-restore.d.ts +28 -0
  47. package/dist/database/adapters/pg-snapshot-restore.js +68 -0
  48. package/dist/database/adapters/sqlite-copy.d.ts +32 -0
  49. package/dist/database/adapters/sqlite-copy.js +145 -0
  50. package/dist/database/connection-injection.d.ts +35 -0
  51. package/dist/database/connection-injection.js +93 -0
  52. package/dist/database/index.d.ts +12 -0
  53. package/dist/database/index.js +23 -0
  54. package/dist/database/registry.d.ts +13 -0
  55. package/dist/database/registry.js +27 -0
  56. package/dist/database/topology.d.ts +52 -0
  57. package/dist/database/topology.js +44 -0
  58. package/dist/database/types.d.ts +89 -0
  59. package/dist/database/types.js +26 -0
  60. package/dist/design-authority.d.ts +40 -0
  61. package/dist/design-authority.js +71 -0
  62. package/dist/design-lookahead.d.ts +64 -0
  63. package/dist/design-lookahead.js +86 -0
  64. package/dist/design-quality-trend.d.ts +87 -0
  65. package/dist/design-quality-trend.js +190 -0
  66. package/dist/design-system-context.d.ts +46 -0
  67. package/dist/design-system-context.js +80 -0
  68. package/dist/design-system-correction-loop.d.ts +64 -0
  69. package/dist/design-system-correction-loop.js +128 -0
  70. package/dist/design-system-metrics.d.ts +61 -0
  71. package/dist/design-system-metrics.js +104 -0
  72. package/dist/design-system-stewardship.d.ts +22 -0
  73. package/dist/design-system-stewardship.js +85 -0
  74. package/dist/design-system-validation.d.ts +37 -0
  75. package/dist/design-system-validation.js +88 -0
  76. package/dist/dispatch/index.d.ts +4 -0
  77. package/dist/dispatch/index.js +4 -0
  78. package/dist/dispatch/merge-gate.d.ts +46 -0
  79. package/dist/dispatch/merge-gate.js +90 -0
  80. package/dist/dispatch/requeue.d.ts +57 -0
  81. package/dist/dispatch/requeue.js +131 -0
  82. package/dist/dispatch/worker-pool.d.ts +62 -0
  83. package/dist/dispatch/worker-pool.js +60 -0
  84. package/dist/execute.d.ts +40 -0
  85. package/dist/execute.js +185 -15
  86. package/dist/fix-ci.js +8 -1
  87. package/dist/fix-review.js +8 -1
  88. package/dist/harness/adapters/claude-code.d.ts +29 -0
  89. package/dist/harness/adapters/claude-code.js +191 -0
  90. package/dist/harness/adapters/codex.d.ts +25 -0
  91. package/dist/harness/adapters/codex.js +61 -0
  92. package/dist/harness/independence.d.ts +51 -0
  93. package/dist/harness/independence.js +67 -0
  94. package/dist/harness/index.d.ts +14 -0
  95. package/dist/harness/index.js +20 -0
  96. package/dist/harness/registry.d.ts +17 -0
  97. package/dist/harness/registry.js +31 -0
  98. package/dist/harness/types.d.ts +123 -0
  99. package/dist/harness/types.js +8 -0
  100. package/dist/harness/version-probe.d.ts +14 -0
  101. package/dist/harness/version-probe.js +123 -0
  102. package/dist/index.d.ts +30 -4
  103. package/dist/index.js +35 -2
  104. package/dist/models/classifier.d.ts +76 -0
  105. package/dist/models/classifier.js +221 -0
  106. package/dist/models/index.d.ts +3 -0
  107. package/dist/models/index.js +3 -0
  108. package/dist/models/registry.d.ts +97 -0
  109. package/dist/models/registry.js +173 -0
  110. package/dist/pillar-breakdown.d.ts +63 -0
  111. package/dist/pillar-breakdown.js +153 -0
  112. package/dist/priority.d.ts +5 -0
  113. package/dist/priority.js +18 -5
  114. package/dist/review-meta.d.ts +65 -0
  115. package/dist/review-meta.js +149 -0
  116. package/dist/review.d.ts +4 -0
  117. package/dist/review.js +12 -2
  118. package/dist/runners/claude-code-sdk.d.ts +31 -0
  119. package/dist/runners/claude-code-sdk.js +238 -0
  120. package/dist/runners/claude-code.d.ts +3 -0
  121. package/dist/runners/claude-code.js +30 -66
  122. package/dist/runners/codex.js +4 -1
  123. package/dist/runners/copilot.js +4 -1
  124. package/dist/runners/cursor.js +4 -1
  125. package/dist/runners/git-utils.d.ts +81 -0
  126. package/dist/runners/git-utils.js +201 -0
  127. package/dist/runners/index.d.ts +3 -0
  128. package/dist/runners/index.js +3 -0
  129. package/dist/runners/review-agent.d.ts +20 -0
  130. package/dist/runners/review-agent.js +171 -41
  131. package/dist/runners/runner-registry.js +10 -0
  132. package/dist/runners/sdk-review-runner.d.ts +65 -0
  133. package/dist/runners/sdk-review-runner.js +185 -0
  134. package/dist/runners/security-triage.d.ts +20 -4
  135. package/dist/runners/security-triage.js +39 -15
  136. package/dist/runners/types.d.ts +6 -0
  137. package/dist/runtime/attestations.d.ts +274 -0
  138. package/dist/runtime/attestations.js +460 -0
  139. package/dist/runtime/git-env.d.ts +53 -0
  140. package/dist/runtime/git-env.js +60 -0
  141. package/dist/runtime/index.d.ts +7 -0
  142. package/dist/runtime/index.js +7 -0
  143. package/dist/runtime/parallelism-flag.d.ts +10 -0
  144. package/dist/runtime/parallelism-flag.js +18 -0
  145. package/dist/runtime/port-allocator.d.ts +21 -0
  146. package/dist/runtime/port-allocator.js +66 -0
  147. package/dist/runtime/worktree-pool.d.ts +86 -0
  148. package/dist/runtime/worktree-pool.js +204 -0
  149. package/dist/runtime/worktree.d.ts +25 -0
  150. package/dist/runtime/worktree.js +111 -0
  151. package/dist/sa-scoring/auto-calibrate.d.ts +69 -0
  152. package/dist/sa-scoring/auto-calibrate.js +107 -0
  153. package/dist/sa-scoring/c1-sa2-computable.d.ts +42 -0
  154. package/dist/sa-scoring/c1-sa2-computable.js +59 -0
  155. package/dist/sa-scoring/composite.d.ts +107 -0
  156. package/dist/sa-scoring/composite.js +139 -0
  157. package/dist/sa-scoring/depparse-client.d.ts +79 -0
  158. package/dist/sa-scoring/depparse-client.js +187 -0
  159. package/dist/sa-scoring/did-compiler.d.ts +122 -0
  160. package/dist/sa-scoring/did-compiler.js +286 -0
  161. package/dist/sa-scoring/drift-monitor.d.ts +84 -0
  162. package/dist/sa-scoring/drift-monitor.js +186 -0
  163. package/dist/sa-scoring/exemplar-bank.d.ts +78 -0
  164. package/dist/sa-scoring/exemplar-bank.js +154 -0
  165. package/dist/sa-scoring/feedback-store.d.ts +100 -0
  166. package/dist/sa-scoring/feedback-store.js +156 -0
  167. package/dist/sa-scoring/index.d.ts +71 -0
  168. package/dist/sa-scoring/index.js +158 -0
  169. package/dist/sa-scoring/layer1-deterministic.d.ts +115 -0
  170. package/dist/sa-scoring/layer1-deterministic.js +298 -0
  171. package/dist/sa-scoring/layer2-structural.d.ts +71 -0
  172. package/dist/sa-scoring/layer2-structural.js +151 -0
  173. package/dist/sa-scoring/layer3-llm.d.ts +86 -0
  174. package/dist/sa-scoring/layer3-llm.js +282 -0
  175. package/dist/sa-scoring/rescore-orchestrator.d.ts +52 -0
  176. package/dist/sa-scoring/rescore-orchestrator.js +47 -0
  177. package/dist/scheduling/burn-down.d.ts +27 -0
  178. package/dist/scheduling/burn-down.js +43 -0
  179. package/dist/scheduling/calibration.d.ts +42 -0
  180. package/dist/scheduling/calibration.js +150 -0
  181. package/dist/scheduling/index.d.ts +8 -0
  182. package/dist/scheduling/index.js +8 -0
  183. package/dist/scheduling/ledger.d.ts +59 -0
  184. package/dist/scheduling/ledger.js +216 -0
  185. package/dist/scheduling/off-peak.d.ts +27 -0
  186. package/dist/scheduling/off-peak.js +112 -0
  187. package/dist/scheduling/schedule-decision.d.ts +39 -0
  188. package/dist/scheduling/schedule-decision.js +89 -0
  189. package/dist/scheduling/tier-analysis.d.ts +47 -0
  190. package/dist/scheduling/tier-analysis.js +81 -0
  191. package/dist/scheduling/types.d.ts +140 -0
  192. package/dist/scheduling/types.js +11 -0
  193. package/dist/shared.d.ts +13 -0
  194. package/dist/shared.js +32 -0
  195. package/dist/state/schema.d.ts +5 -1
  196. package/dist/state/schema.js +223 -1
  197. package/dist/state/store.d.ts +55 -1
  198. package/dist/state/store.js +342 -7
  199. package/dist/state/types.d.ts +139 -0
  200. package/dist/types.d.ts +1 -1
  201. package/dist/validate-agent-output.js +4 -1
  202. package/dist/watch.js +6 -0
  203. package/package.json +2 -2
@@ -0,0 +1,87 @@
1
+ /**
2
+ * DesignQualityTrendDegrading detector (RFC-0008 Addendum A §A.8).
3
+ *
4
+ * Periodic monitor that analyses rolling windows over
5
+ * `code_area_metrics` (designMetricsJson) and `token_compliance_history`
6
+ * to catch degradation *before* it shows up in the admission hot path
7
+ * via the C3 defect-risk factor. Emits one event per code area on
8
+ * first detection and is hysteretic — does not re-fire until recovery.
9
+ */
10
+ import type { DesignSystemBinding } from '@ai-sdlc/reference';
11
+ import type { StateStore } from './state/store.js';
12
+ import type { CodeAreaMetricsRecord, TokenComplianceRecord } from './state/types.js';
13
+ export interface TrendAnalysisConfig {
14
+ /** Minimum number of data points in the recent window. */
15
+ windowPrs: number;
16
+ /** Maximum age of measurements to include (days). */
17
+ windowDays: number;
18
+ /** Drop in designCIPassRate (absolute) that triggers the condition. */
19
+ ciDropThreshold: number;
20
+ /** Rise in designReviewRejectionRate (absolute) that triggers. */
21
+ reviewIncreaseThreshold: number;
22
+ /** Minimum consecutive 'declining' compliance trends to trigger. */
23
+ consecutiveNegativeCompliance: number;
24
+ }
25
+ export declare const DEFAULT_TREND_CONFIG: TrendAnalysisConfig;
26
+ export type TrendCondition = 'designCIPassRate' | 'designReviewRejectionRate' | 'tokenComplianceTrend';
27
+ /**
28
+ * Partition the history into `recent` (newest `windowPrs` records or
29
+ * anything inside `windowDays`) and `baseline` (everything older). The
30
+ * recent window fills by whichever bound hits first — that gives us a
31
+ * consistent signal whether activity is sparse or bursty.
32
+ *
33
+ * History is assumed to be in descending `computed_at` order (as returned
34
+ * by `getCodeAreaMetricsHistory`).
35
+ */
36
+ export declare function splitHistoryByWindow<T extends {
37
+ computedAt?: string;
38
+ }>(history: readonly T[], config: Pick<TrendAnalysisConfig, 'windowPrs' | 'windowDays'>, nowMs: number): {
39
+ recent: T[];
40
+ baseline: T[];
41
+ };
42
+ export interface ConditionEvaluation {
43
+ triggered: boolean;
44
+ recentValue?: number;
45
+ baselineValue?: number;
46
+ delta?: number;
47
+ }
48
+ export declare function evaluateCiPassRate(recent: readonly CodeAreaMetricsRecord[], baseline: readonly CodeAreaMetricsRecord[], threshold: number): ConditionEvaluation;
49
+ export declare function evaluateReviewRejectionRate(recent: readonly CodeAreaMetricsRecord[], baseline: readonly CodeAreaMetricsRecord[], threshold: number): ConditionEvaluation;
50
+ export declare function evaluateTokenComplianceTrend(history: readonly TokenComplianceRecord[], minConsecutive: number): ConditionEvaluation;
51
+ export interface TrendAnalysisResult {
52
+ codeArea: string;
53
+ triggered: boolean;
54
+ conditions: Partial<Record<TrendCondition, ConditionEvaluation>>;
55
+ }
56
+ export declare function analyzeTrend(codeArea: string, codeAreaHistory: readonly CodeAreaMetricsRecord[], tokenComplianceHistory: readonly TokenComplianceRecord[], nowMs: number, overrides?: Partial<TrendAnalysisConfig>): TrendAnalysisResult;
57
+ export interface DesignQualityTrendDegradingEvent {
58
+ type: 'DesignQualityTrendDegrading';
59
+ codeArea: string;
60
+ bindingName?: string;
61
+ triggeredAt: string;
62
+ triggeredConditions: TrendCondition[];
63
+ conditions: TrendAnalysisResult['conditions'];
64
+ notifiedPrincipals: string[];
65
+ issueBodyMarkdown: string;
66
+ }
67
+ export interface DesignQualityTrendDetectorDeps {
68
+ stateStore: StateStore;
69
+ /** Resolve a code area to its owning DSB, if any. */
70
+ getBindingForCodeArea?: (codeArea: string) => DesignSystemBinding | undefined;
71
+ /** Timestamp of the last emission for this area (hysteresis state). */
72
+ getLastTriggerAt?: (codeArea: string) => string | undefined;
73
+ /** Required quiet window (ms) with no trigger before re-firing. */
74
+ hysteresisRecoveryMs?: number;
75
+ /** Clock injection (defaults to `Date.now`). */
76
+ now?: () => number;
77
+ /** Partial config override. */
78
+ config?: Partial<TrendAnalysisConfig>;
79
+ }
80
+ /**
81
+ * Run the trend analysis for one code area. Returns an event when the
82
+ * trend is currently degrading AND the hysteresis quiet window has
83
+ * elapsed since the last trigger (or no prior trigger). Returns
84
+ * undefined otherwise.
85
+ */
86
+ export declare function detectDesignQualityTrendDegrading(codeArea: string, deps: DesignQualityTrendDetectorDeps): DesignQualityTrendDegradingEvent | undefined;
87
+ //# sourceMappingURL=design-quality-trend.d.ts.map
@@ -0,0 +1,190 @@
1
+ /**
2
+ * DesignQualityTrendDegrading detector (RFC-0008 Addendum A §A.8).
3
+ *
4
+ * Periodic monitor that analyses rolling windows over
5
+ * `code_area_metrics` (designMetricsJson) and `token_compliance_history`
6
+ * to catch degradation *before* it shows up in the admission hot path
7
+ * via the C3 defect-risk factor. Emits one event per code area on
8
+ * first detection and is hysteretic — does not re-fire until recovery.
9
+ */
10
+ export const DEFAULT_TREND_CONFIG = {
11
+ windowPrs: 10,
12
+ windowDays: 30,
13
+ ciDropThreshold: 0.15,
14
+ reviewIncreaseThreshold: 0.2,
15
+ consecutiveNegativeCompliance: 5,
16
+ };
17
+ function parseDesignMetrics(json) {
18
+ if (!json)
19
+ return undefined;
20
+ try {
21
+ return JSON.parse(json);
22
+ }
23
+ catch {
24
+ return undefined;
25
+ }
26
+ }
27
+ // ── Window selection ───────────────────────────────────────────────────
28
+ /**
29
+ * Partition the history into `recent` (newest `windowPrs` records or
30
+ * anything inside `windowDays`) and `baseline` (everything older). The
31
+ * recent window fills by whichever bound hits first — that gives us a
32
+ * consistent signal whether activity is sparse or bursty.
33
+ *
34
+ * History is assumed to be in descending `computed_at` order (as returned
35
+ * by `getCodeAreaMetricsHistory`).
36
+ */
37
+ export function splitHistoryByWindow(history, config, nowMs) {
38
+ const cutoffMs = nowMs - config.windowDays * 24 * 60 * 60 * 1000;
39
+ const recent = [];
40
+ for (const row of history) {
41
+ if (recent.length >= config.windowPrs)
42
+ break;
43
+ const ts = row.computedAt ? Date.parse(row.computedAt) : NaN;
44
+ if (Number.isNaN(ts))
45
+ continue;
46
+ if (ts < cutoffMs)
47
+ break;
48
+ recent.push(row);
49
+ }
50
+ const baseline = history.slice(recent.length);
51
+ return { recent, baseline };
52
+ }
53
+ export function evaluateCiPassRate(recent, baseline, threshold) {
54
+ const recentMean = meanDesignMetric(recent, 'designCIPassRate');
55
+ const baselineMean = meanDesignMetric(baseline, 'designCIPassRate');
56
+ if (recentMean === undefined || baselineMean === undefined) {
57
+ return { triggered: false };
58
+ }
59
+ const delta = baselineMean - recentMean; // positive ⇒ dropped
60
+ return {
61
+ triggered: delta >= threshold,
62
+ recentValue: recentMean,
63
+ baselineValue: baselineMean,
64
+ delta,
65
+ };
66
+ }
67
+ export function evaluateReviewRejectionRate(recent, baseline, threshold) {
68
+ const recentMean = meanDesignMetric(recent, 'designReviewRejectionRate');
69
+ const baselineMean = meanDesignMetric(baseline, 'designReviewRejectionRate');
70
+ if (recentMean === undefined || baselineMean === undefined) {
71
+ return { triggered: false };
72
+ }
73
+ const delta = recentMean - baselineMean; // positive ⇒ rejections rising
74
+ return {
75
+ triggered: delta >= threshold,
76
+ recentValue: recentMean,
77
+ baselineValue: baselineMean,
78
+ delta,
79
+ };
80
+ }
81
+ export function evaluateTokenComplianceTrend(history, minConsecutive) {
82
+ // history is descending (newest first). Walk newest→oldest, counting
83
+ // a run of declining coverages.
84
+ let streak = 0;
85
+ for (let i = 0; i < history.length - 1; i++) {
86
+ if (history[i].coveragePercent < history[i + 1].coveragePercent)
87
+ streak++;
88
+ else
89
+ break;
90
+ }
91
+ return {
92
+ triggered: streak >= minConsecutive,
93
+ recentValue: streak,
94
+ };
95
+ }
96
+ function meanDesignMetric(rows, key) {
97
+ const values = [];
98
+ for (const row of rows) {
99
+ const blob = parseDesignMetrics(row.designMetricsJson);
100
+ const value = blob?.[key];
101
+ if (typeof value === 'number' && !Number.isNaN(value))
102
+ values.push(value);
103
+ }
104
+ if (values.length === 0)
105
+ return undefined;
106
+ return values.reduce((a, b) => a + b, 0) / values.length;
107
+ }
108
+ export function analyzeTrend(codeArea, codeAreaHistory, tokenComplianceHistory, nowMs, overrides = {}) {
109
+ const config = { ...DEFAULT_TREND_CONFIG, ...overrides };
110
+ const { recent, baseline } = splitHistoryByWindow(codeAreaHistory, config, nowMs);
111
+ const ci = evaluateCiPassRate(recent, baseline, config.ciDropThreshold);
112
+ const review = evaluateReviewRejectionRate(recent, baseline, config.reviewIncreaseThreshold);
113
+ const compliance = evaluateTokenComplianceTrend(tokenComplianceHistory, config.consecutiveNegativeCompliance);
114
+ const conditions = {};
115
+ if (ci.triggered)
116
+ conditions.designCIPassRate = ci;
117
+ if (review.triggered)
118
+ conditions.designReviewRejectionRate = review;
119
+ if (compliance.triggered)
120
+ conditions.tokenComplianceTrend = compliance;
121
+ return {
122
+ codeArea,
123
+ triggered: Object.keys(conditions).length > 0,
124
+ conditions,
125
+ };
126
+ }
127
+ /**
128
+ * Run the trend analysis for one code area. Returns an event when the
129
+ * trend is currently degrading AND the hysteresis quiet window has
130
+ * elapsed since the last trigger (or no prior trigger). Returns
131
+ * undefined otherwise.
132
+ */
133
+ export function detectDesignQualityTrendDegrading(codeArea, deps) {
134
+ const nowMs = (deps.now ?? (() => Date.now()))();
135
+ // Hysteresis: skip if we've emitted recently within the recovery window.
136
+ const lastTriggerAt = deps.getLastTriggerAt?.(codeArea);
137
+ if (lastTriggerAt) {
138
+ const lastMs = Date.parse(lastTriggerAt);
139
+ const recoveryMs = deps.hysteresisRecoveryMs ?? 7 * 24 * 60 * 60 * 1000; // 7d default
140
+ if (!Number.isNaN(lastMs) && nowMs - lastMs < recoveryMs)
141
+ return undefined;
142
+ }
143
+ const history = deps.stateStore.getCodeAreaMetricsHistory(codeArea, { limit: 100 });
144
+ const binding = deps.getBindingForCodeArea?.(codeArea);
145
+ const tokenHistory = binding
146
+ ? deps.stateStore.getTokenComplianceHistory(binding.metadata.name)
147
+ : [];
148
+ const result = analyzeTrend(codeArea, history, tokenHistory, nowMs, deps.config);
149
+ if (!result.triggered)
150
+ return undefined;
151
+ const principals = binding ? gatherPrincipals(binding) : [];
152
+ const triggeredConditions = Object.keys(result.conditions);
153
+ return {
154
+ type: 'DesignQualityTrendDegrading',
155
+ codeArea,
156
+ bindingName: binding?.metadata.name,
157
+ triggeredAt: new Date(nowMs).toISOString(),
158
+ triggeredConditions,
159
+ conditions: result.conditions,
160
+ notifiedPrincipals: principals,
161
+ issueBodyMarkdown: renderIssueBody(result, binding),
162
+ };
163
+ }
164
+ function gatherPrincipals(binding) {
165
+ const design = binding.spec.stewardship.designAuthority.principals;
166
+ const engineering = binding.spec.stewardship.engineeringAuthority.principals;
167
+ const unique = new Set([...design, ...engineering]);
168
+ return Array.from(unique);
169
+ }
170
+ function renderIssueBody(result, binding) {
171
+ const lines = [
172
+ `## DesignQualityTrendDegrading — ${result.codeArea}`,
173
+ '',
174
+ binding
175
+ ? `Linked DesignSystemBinding: **${binding.metadata.name}**`
176
+ : 'No linked DesignSystemBinding',
177
+ '',
178
+ '### Triggered conditions',
179
+ '',
180
+ ];
181
+ for (const [name, evaluation] of Object.entries(result.conditions)) {
182
+ const baseline = evaluation.baselineValue !== undefined ? evaluation.baselineValue.toFixed(3) : 'n/a';
183
+ const current = evaluation.recentValue !== undefined ? evaluation.recentValue.toFixed(3) : 'n/a';
184
+ const delta = evaluation.delta !== undefined ? evaluation.delta.toFixed(3) : 'n/a';
185
+ lines.push(`- **${name}** — baseline ${baseline}, recent ${current}, delta ${delta}`);
186
+ }
187
+ lines.push('', '---', 'Investigate the code area and file follow-up tasks as needed.');
188
+ return lines.join('\n');
189
+ }
190
+ //# sourceMappingURL=design-quality-trend.js.map
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Context strategy selection for design-system-aware agents (RFC-0006 §7.2).
3
+ *
4
+ * Implements the 5-step decision tree that determines how much design
5
+ * system context an agent receives.
6
+ */
7
+ import type { ContextStrategy, DesignSystemBinding } from '@ai-sdlc/reference';
8
+ export interface TaskContext {
9
+ /** The trigger event type (e.g., 'design-token.changed', 'issue.assigned'). */
10
+ triggerEvent?: string;
11
+ /** Whether the task involves modifying existing components. */
12
+ modifiesComponents?: boolean;
13
+ /** Whether the task creates a new component. */
14
+ createsNewComponent?: boolean;
15
+ /** Whether the task involves both tokens AND component composition. */
16
+ touchesTokensAndComponents?: boolean;
17
+ /** Reusability score from the design-context stage (0.0-1.0). */
18
+ reusabilityScore?: number;
19
+ }
20
+ export interface ContextStrategyResult {
21
+ strategy: ContextStrategy;
22
+ reason: string;
23
+ }
24
+ /**
25
+ * Select the context strategy using the 5-step decision tree from RFC-0006 §7.2.
26
+ *
27
+ * 1. Token-change trigger with no component mods → tokens-only
28
+ * 2. Modifying/composing existing components → manifest-first
29
+ * 3. Creating new component → full
30
+ * 4. Both tokens AND composition → full
31
+ * 5. Reusability score < 0.5 → full
32
+ *
33
+ * Falls back to manifest-first as the default.
34
+ */
35
+ export declare function selectContextStrategy(task: TaskContext, binding: DesignSystemBinding): ContextStrategyResult;
36
+ /**
37
+ * Re-evaluate context strategy after scope change (RFC-0006 §7.2 bottom).
38
+ * Called after design impact review if the approved scope differs from
39
+ * the initial scope.
40
+ */
41
+ export declare function reEvaluateStrategy(originalTask: TaskContext, updatedTask: TaskContext, binding: DesignSystemBinding): {
42
+ changed: boolean;
43
+ result: ContextStrategyResult;
44
+ reason?: string;
45
+ };
46
+ //# sourceMappingURL=design-system-context.d.ts.map
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Context strategy selection for design-system-aware agents (RFC-0006 §7.2).
3
+ *
4
+ * Implements the 5-step decision tree that determines how much design
5
+ * system context an agent receives.
6
+ */
7
+ /**
8
+ * Select the context strategy using the 5-step decision tree from RFC-0006 §7.2.
9
+ *
10
+ * 1. Token-change trigger with no component mods → tokens-only
11
+ * 2. Modifying/composing existing components → manifest-first
12
+ * 3. Creating new component → full
13
+ * 4. Both tokens AND composition → full
14
+ * 5. Reusability score < 0.5 → full
15
+ *
16
+ * Falls back to manifest-first as the default.
17
+ */
18
+ export function selectContextStrategy(task, binding) {
19
+ const agentConfig = binding.spec;
20
+ // If contextStrategyOverride is 'fixed', use the declared strategy
21
+ if (agentConfig.designSystem?.contextStrategyOverride === 'fixed') {
22
+ const fixed = (agentConfig.designSystem?.contextStrategy ??
23
+ 'manifest-first');
24
+ return { strategy: fixed, reason: 'Fixed strategy override — using declared contextStrategy' };
25
+ }
26
+ // Step 1: Token-change trigger with no component modifications
27
+ if (task.triggerEvent === 'design-token.changed' &&
28
+ !task.modifiesComponents &&
29
+ !task.createsNewComponent) {
30
+ return {
31
+ strategy: 'tokens-only',
32
+ reason: 'Token-change trigger with no component modifications',
33
+ };
34
+ }
35
+ // Step 2: Modifying/composing existing components only
36
+ if (task.modifiesComponents && !task.createsNewComponent && !task.touchesTokensAndComponents) {
37
+ return {
38
+ strategy: 'manifest-first',
39
+ reason: 'Modifying existing components — manifest sufficient',
40
+ };
41
+ }
42
+ // Step 3: Creating a new component
43
+ if (task.createsNewComponent) {
44
+ return { strategy: 'full', reason: 'New component creation requires full context' };
45
+ }
46
+ // Step 4: Both tokens AND component composition
47
+ if (task.touchesTokensAndComponents) {
48
+ return {
49
+ strategy: 'full',
50
+ reason: 'Task touches both tokens and components — escalating to full',
51
+ };
52
+ }
53
+ // Step 5: Low reusability score
54
+ if (task.reusabilityScore !== undefined && task.reusabilityScore < 0.5) {
55
+ return {
56
+ strategy: 'full',
57
+ reason: `Reusability score ${task.reusabilityScore} < 0.5 — catalog insufficient`,
58
+ };
59
+ }
60
+ // Default
61
+ return { strategy: 'manifest-first', reason: 'Default strategy' };
62
+ }
63
+ /**
64
+ * Re-evaluate context strategy after scope change (RFC-0006 §7.2 bottom).
65
+ * Called after design impact review if the approved scope differs from
66
+ * the initial scope.
67
+ */
68
+ export function reEvaluateStrategy(originalTask, updatedTask, binding) {
69
+ const original = selectContextStrategy(originalTask, binding);
70
+ const updated = selectContextStrategy(updatedTask, binding);
71
+ if (original.strategy !== updated.strategy) {
72
+ return {
73
+ changed: true,
74
+ result: updated,
75
+ reason: 'scope-changed-at-impact-review',
76
+ };
77
+ }
78
+ return { changed: false, result: original };
79
+ }
80
+ //# sourceMappingURL=design-system-context.js.map
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Autonomous correction loop for design system gates (RFC-0006 §8.4)
3
+ * and Design Review feedback pipeline (RFC-0006 §8.5).
4
+ */
5
+ import type { VisualRegressionFailure } from '@ai-sdlc/reference';
6
+ export interface CorrectionIteration {
7
+ attempt: number;
8
+ failures: VisualRegressionFailure[];
9
+ codeDiff?: string;
10
+ visualDiff?: string;
11
+ costUsd: number;
12
+ tokenReferencesChanged: boolean;
13
+ timestamp: string;
14
+ }
15
+ export interface CorrectionLoopConfig {
16
+ maxRetries: number;
17
+ costSoftLimitUsd: number;
18
+ }
19
+ export type CorrectionExitReason = 'max-retries' | 'token-reference-changed' | 'cost-limit-exceeded' | 'design-review-triggered' | 'success';
20
+ export interface CorrectionLoopResult {
21
+ converged: boolean;
22
+ exitReason: CorrectionExitReason;
23
+ iterations: CorrectionIteration[];
24
+ totalCostUsd: number;
25
+ }
26
+ /**
27
+ * Check whether the correction loop should exit.
28
+ */
29
+ export declare function checkExitConditions(iterations: CorrectionIteration[], config: CorrectionLoopConfig, designReviewTriggered: boolean): CorrectionExitReason | null;
30
+ /**
31
+ * Run the autonomous correction loop.
32
+ *
33
+ * @param runAttempt - Function that executes the agent and returns failures + cost
34
+ * @param config - Loop configuration (maxRetries, cost limit)
35
+ * @param checkDesignReviewTrigger - Function that checks if design review conditions are met
36
+ */
37
+ export declare function runCorrectionLoop(runAttempt: (failures: VisualRegressionFailure[], attempt: number) => Promise<{
38
+ failures: VisualRegressionFailure[];
39
+ costUsd: number;
40
+ tokenReferencesChanged: boolean;
41
+ codeDiff?: string;
42
+ }>, config: CorrectionLoopConfig, checkDesignReviewTrigger?: () => boolean): Promise<CorrectionLoopResult>;
43
+ export type FeedbackSignal = 'accepted' | 'dismissed' | 'overridden' | 'escalated';
44
+ export interface FeedbackEntry {
45
+ prNumber: number;
46
+ category: string;
47
+ signal: FeedbackSignal;
48
+ reviewer: string;
49
+ comment?: string;
50
+ timestamp: string;
51
+ }
52
+ export interface CategoryAnalysis {
53
+ category: string;
54
+ dismissRate: number;
55
+ }
56
+ export interface DesignReviewFeedbackStore {
57
+ record(entry: FeedbackEntry): void;
58
+ precision(): number;
59
+ highFalsePositiveCategories(): CategoryAnalysis[];
60
+ falseNegativeCategories(): CategoryAnalysis[];
61
+ getEntries(): FeedbackEntry[];
62
+ }
63
+ export declare function createDesignReviewFeedbackStore(): DesignReviewFeedbackStore;
64
+ //# sourceMappingURL=design-system-correction-loop.d.ts.map
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Autonomous correction loop for design system gates (RFC-0006 §8.4)
3
+ * and Design Review feedback pipeline (RFC-0006 §8.5).
4
+ */
5
+ /**
6
+ * Check whether the correction loop should exit.
7
+ */
8
+ export function checkExitConditions(iterations, config, designReviewTriggered) {
9
+ // Condition 1: maxRetries reached
10
+ if (iterations.length >= config.maxRetries) {
11
+ return 'max-retries';
12
+ }
13
+ // Condition 2: agent changed a token reference
14
+ const last = iterations[iterations.length - 1];
15
+ if (last?.tokenReferencesChanged) {
16
+ return 'token-reference-changed';
17
+ }
18
+ // Condition 3: cumulative cost exceeds soft limit
19
+ const totalCost = iterations.reduce((sum, it) => sum + it.costUsd, 0);
20
+ if (totalCost >= config.costSoftLimitUsd) {
21
+ return 'cost-limit-exceeded';
22
+ }
23
+ // Condition 4: design review trigger conditions met
24
+ if (designReviewTriggered) {
25
+ return 'design-review-triggered';
26
+ }
27
+ return null;
28
+ }
29
+ /**
30
+ * Run the autonomous correction loop.
31
+ *
32
+ * @param runAttempt - Function that executes the agent and returns failures + cost
33
+ * @param config - Loop configuration (maxRetries, cost limit)
34
+ * @param checkDesignReviewTrigger - Function that checks if design review conditions are met
35
+ */
36
+ export async function runCorrectionLoop(runAttempt, config, checkDesignReviewTrigger = () => false) {
37
+ const iterations = [];
38
+ let currentFailures = [];
39
+ for (let attempt = 0; attempt < config.maxRetries; attempt++) {
40
+ const result = await runAttempt(currentFailures, attempt);
41
+ iterations.push({
42
+ attempt,
43
+ failures: result.failures,
44
+ codeDiff: result.codeDiff,
45
+ costUsd: result.costUsd,
46
+ tokenReferencesChanged: result.tokenReferencesChanged,
47
+ timestamp: new Date().toISOString(),
48
+ });
49
+ // Check if converged (no more failures)
50
+ if (result.failures.length === 0) {
51
+ return {
52
+ converged: true,
53
+ exitReason: 'success',
54
+ iterations,
55
+ totalCostUsd: iterations.reduce((s, it) => s + it.costUsd, 0),
56
+ };
57
+ }
58
+ currentFailures = result.failures;
59
+ // Check exit conditions
60
+ const exitReason = checkExitConditions(iterations, config, checkDesignReviewTrigger());
61
+ if (exitReason) {
62
+ return {
63
+ converged: false,
64
+ exitReason,
65
+ iterations,
66
+ totalCostUsd: iterations.reduce((s, it) => s + it.costUsd, 0),
67
+ };
68
+ }
69
+ }
70
+ return {
71
+ converged: false,
72
+ exitReason: 'max-retries',
73
+ iterations,
74
+ totalCostUsd: iterations.reduce((s, it) => s + it.costUsd, 0),
75
+ };
76
+ }
77
+ export function createDesignReviewFeedbackStore() {
78
+ const entries = [];
79
+ return {
80
+ record(entry) {
81
+ entries.push(entry);
82
+ },
83
+ precision() {
84
+ const accepted = entries.filter((e) => e.signal === 'accepted').length;
85
+ const dismissed = entries.filter((e) => e.signal === 'dismissed').length;
86
+ const total = accepted + dismissed;
87
+ return total > 0 ? accepted / total : 1;
88
+ },
89
+ highFalsePositiveCategories() {
90
+ const categoryStats = new Map();
91
+ for (const entry of entries) {
92
+ const stats = categoryStats.get(entry.category) ?? { dismissed: 0, total: 0 };
93
+ stats.total++;
94
+ if (entry.signal === 'dismissed')
95
+ stats.dismissed++;
96
+ categoryStats.set(entry.category, stats);
97
+ }
98
+ return [...categoryStats.entries()]
99
+ .map(([category, stats]) => ({
100
+ category,
101
+ dismissRate: stats.total > 0 ? stats.dismissed / stats.total : 0,
102
+ }))
103
+ .filter((c) => c.dismissRate > 0)
104
+ .sort((a, b) => b.dismissRate - a.dismissRate);
105
+ },
106
+ falseNegativeCategories() {
107
+ const categoryStats = new Map();
108
+ for (const entry of entries) {
109
+ const stats = categoryStats.get(entry.category) ?? { escalated: 0, total: 0 };
110
+ stats.total++;
111
+ if (entry.signal === 'escalated')
112
+ stats.escalated++;
113
+ categoryStats.set(entry.category, stats);
114
+ }
115
+ return [...categoryStats.entries()]
116
+ .map(([category, stats]) => ({
117
+ category,
118
+ dismissRate: stats.total > 0 ? stats.escalated / stats.total : 0,
119
+ }))
120
+ .filter((c) => c.dismissRate > 0)
121
+ .sort((a, b) => b.dismissRate - a.dismissRate);
122
+ },
123
+ getEntries() {
124
+ return [...entries];
125
+ },
126
+ };
127
+ }
128
+ //# sourceMappingURL=design-system-correction-loop.js.map
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Design system metrics for autonomy promotion/demotion (RFC-0006 §13.2, §A.10).
3
+ *
4
+ * Computes six design review metrics from state store data and integrates
5
+ * them into the autonomy evaluation system.
6
+ */
7
+ import type { DesignReviewEventRecord, TokenComplianceRecord, VisualRegressionResultRecord, UsabilitySimulationResultRecord } from './state/types.js';
8
+ export interface DesignMetrics {
9
+ /** Percentage of Design CI runs that pass on first attempt. */
10
+ designCiPassRate: number;
11
+ /** Percentage of usability simulations that complete successfully. */
12
+ usabilitySimulationPassRate: number;
13
+ /** Percentage of design reviews approved (any decision except rejected). */
14
+ designReviewApprovalRate: number;
15
+ /** Percentage of design reviews approved without any rejection cycle. */
16
+ designReviewFirstPassRate: number;
17
+ /** Percentage of Design CI failures auto-fixed by correction loop. */
18
+ designCiAutoFixRate: number;
19
+ /** Precision of usability findings (accepted / (accepted + dismissed)). */
20
+ usabilityFindingAccuracy: number;
21
+ }
22
+ /**
23
+ * Compute design review approval rate from review events.
24
+ */
25
+ export declare function computeDesignReviewApprovalRate(events: DesignReviewEventRecord[]): number;
26
+ /**
27
+ * Compute design review first-pass rate (approved without rejection cycles).
28
+ * Groups events by PR and checks if the first review for each PR was an approval.
29
+ */
30
+ export declare function computeDesignReviewFirstPassRate(events: DesignReviewEventRecord[]): number;
31
+ /**
32
+ * Compute usability simulation pass rate from simulation results.
33
+ */
34
+ export declare function computeUsabilitySimulationPassRate(results: UsabilitySimulationResultRecord[]): number;
35
+ /**
36
+ * Compute token compliance trend from compliance history.
37
+ */
38
+ export declare function computeTokenComplianceTrend(history: TokenComplianceRecord[]): {
39
+ current: number;
40
+ trend: 'improving' | 'stable' | 'declining';
41
+ };
42
+ /**
43
+ * Compute visual regression pass rate from results.
44
+ */
45
+ export declare function computeVisualRegressionPassRate(results: VisualRegressionResultRecord[]): number;
46
+ /**
47
+ * Compute all six design metrics from state store data.
48
+ */
49
+ export declare function computeDesignMetrics(data: {
50
+ reviewEvents: DesignReviewEventRecord[];
51
+ complianceHistory: TokenComplianceRecord[];
52
+ visualRegressionResults: VisualRegressionResultRecord[];
53
+ usabilitySimulationResults: UsabilitySimulationResultRecord[];
54
+ designCiPassCount?: number;
55
+ designCiTotalCount?: number;
56
+ designCiAutoFixCount?: number;
57
+ designCiFailCount?: number;
58
+ findingsAccepted?: number;
59
+ findingsDismissed?: number;
60
+ }): DesignMetrics;
61
+ //# sourceMappingURL=design-system-metrics.d.ts.map