@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,89 @@
1
+ /**
2
+ * Schedule-aware dispatch decision per RFC §14.3. Implements the four schedule modes
3
+ * (now, off-peak, quota-permitting, defer-if-low-priority) on top of the
4
+ * SubscriptionLedger admission decision.
5
+ */
6
+ import { isOffPeakAt, nextOffPeakStart } from './off-peak.js';
7
+ const DEFAULT_OFF_PEAK_MAX_WAIT_MS = 8 * 60 * 60 * 1000; // PT8H
8
+ export function evaluateSchedule(schedule, ctx) {
9
+ const now = ctx.now ?? (() => new Date());
10
+ const admission = ctx.ledger.admit(ctx.ledgerKey, ctx.plan, ctx.estimate);
11
+ switch (schedule) {
12
+ case 'now':
13
+ return interpretNow(admission);
14
+ case 'off-peak':
15
+ return interpretOffPeak(admission, ctx, now());
16
+ case 'quota-permitting':
17
+ return interpretQuotaPermitting(admission);
18
+ case 'defer-if-low-priority':
19
+ return interpretDeferIfLowPriority(admission, ctx, now());
20
+ default:
21
+ throw new Error(`Unknown schedule mode: ${String(schedule)}`);
22
+ }
23
+ }
24
+ function interpretNow(admission) {
25
+ if (admission.kind === 'yes')
26
+ return { kind: 'dispatch-now', reason: admission.reason };
27
+ if (admission.kind === 'wait-until')
28
+ return { kind: 'wait-until', until: admission.until, reason: admission.reason };
29
+ return { kind: 'denied', reason: admission.reason, blockedBy: admission.blockedBy };
30
+ }
31
+ function interpretOffPeak(admission, ctx, now) {
32
+ if (!ctx.plan.offPeak || !ctx.plan.offPeak.enabled) {
33
+ // No off-peak configured; behave as 'now'.
34
+ return interpretNow(admission);
35
+ }
36
+ if (isOffPeakAt(ctx.plan.offPeak, now)) {
37
+ return interpretNow(admission);
38
+ }
39
+ const next = nextOffPeakStart(ctx.plan.offPeak, now);
40
+ if (!next)
41
+ return interpretNow(admission);
42
+ const maxWaitMs = parseDurationMs(ctx.offPeakMaxWait) ?? DEFAULT_OFF_PEAK_MAX_WAIT_MS;
43
+ if (next.getTime() - now.getTime() <= maxWaitMs) {
44
+ return {
45
+ kind: 'wait-until',
46
+ until: next,
47
+ reason: 'next off-peak window within offPeakMaxWait',
48
+ };
49
+ }
50
+ // Off-peak too far in the future; fall through to dispatch-on-peak with a warning.
51
+ return { kind: 'dispatch-now', reason: 'OffPeakDeferralExceeded — dispatching on-peak' };
52
+ }
53
+ function interpretQuotaPermitting(admission) {
54
+ if (admission.kind === 'yes')
55
+ return { kind: 'dispatch-now', reason: admission.reason };
56
+ return { kind: 'requeue', reason: admission.reason };
57
+ }
58
+ function interpretDeferIfLowPriority(admission, ctx, now) {
59
+ // Top quartile of queue → dispatch immediately.
60
+ const isTopQuartile = ctx.ppaScore !== undefined && ctx.queueScores && isInTopQuartile(ctx.ppaScore, ctx.queueScores);
61
+ if (isTopQuartile)
62
+ return interpretNow(admission);
63
+ // >30% window headroom → dispatch immediately.
64
+ const ws = ctx.ledger.windowState(ctx.ledgerKey, ctx.plan);
65
+ const headroomFraction = 1 - ws.utilizationFraction;
66
+ if (headroomFraction > 0.3)
67
+ return interpretNow(admission);
68
+ // Otherwise behave as 'off-peak'.
69
+ return interpretOffPeak(admission, ctx, now);
70
+ }
71
+ function isInTopQuartile(score, queueScores) {
72
+ if (queueScores.length === 0)
73
+ return true;
74
+ const sorted = [...queueScores].sort((a, b) => b - a);
75
+ const cutoff = sorted[Math.floor(sorted.length / 4)] ?? sorted[0];
76
+ return score >= cutoff;
77
+ }
78
+ function parseDurationMs(duration) {
79
+ if (!duration)
80
+ return null;
81
+ const m = duration.match(/^P(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?)?$/);
82
+ if (!m)
83
+ return null;
84
+ const days = Number.parseInt(m[1] ?? '0', 10);
85
+ const hours = Number.parseInt(m[2] ?? '0', 10);
86
+ const minutes = Number.parseInt(m[3] ?? '0', 10);
87
+ return ((days * 24 + hours) * 60 + minutes) * 60 * 1000;
88
+ }
89
+ //# sourceMappingURL=schedule-decision.js.map
@@ -0,0 +1,47 @@
1
+ /**
2
+ * TierAnalysis aggregator per RFC §14.13. Aggregates QuotaContention events per
3
+ * billing window and produces upgrade/downgrade recommendations consumed by the
4
+ * Slack daily digest and cli-tier-recommendation.
5
+ */
6
+ import type { LedgerKey, SubscriptionPlan } from './types.js';
7
+ export type Confidence = 'low' | 'medium' | 'high';
8
+ export interface ContentionEvent {
9
+ timestamp: string;
10
+ /** Cumulative duration the high-PPA stage waited on hardCap. */
11
+ contentionDurationMs: number;
12
+ }
13
+ export interface TierAnalysisInput {
14
+ billingPeriod: string;
15
+ ledgerKey: LedgerKey;
16
+ currentPlan: SubscriptionPlan;
17
+ contentionEvents: ContentionEvent[];
18
+ issuesDeferredOffPeak: number;
19
+ issuesBlockedOnHardCap: number;
20
+ /** Candidate plans (typically: registered SubscriptionPlan resources). */
21
+ candidates: SubscriptionPlan[];
22
+ }
23
+ export interface TierAnalysisResult {
24
+ billingPeriod: string;
25
+ ledgerKey: LedgerKey;
26
+ currentPlan: string;
27
+ currentPlanCostUsd: number;
28
+ contentionEvents: number;
29
+ cumulativeContentionDurationMs: number;
30
+ issuesDeferredOffPeak: number;
31
+ issuesBlockedOnHardCap: number;
32
+ recommendedPlan: string;
33
+ recommendedPlanCostUsd: number;
34
+ projectedTimeSavedMs: number;
35
+ projectedAdditionalIssuesProcessed: number;
36
+ projectedSpilloverSavingsUsd: number;
37
+ confidence: Confidence;
38
+ reasoning: string;
39
+ }
40
+ /**
41
+ * Reference plan-cost table — the orchestrator typically has these populated from the
42
+ * SubscriptionPlan resources, but ships with sensible defaults so cli-tier-recommendation
43
+ * can produce useful output even on a fresh deployment.
44
+ */
45
+ export declare const PLAN_COSTS_USD: Record<string, number>;
46
+ export declare function analyzeTier(input: TierAnalysisInput): TierAnalysisResult;
47
+ //# sourceMappingURL=tier-analysis.d.ts.map
@@ -0,0 +1,81 @@
1
+ /**
2
+ * TierAnalysis aggregator per RFC §14.13. Aggregates QuotaContention events per
3
+ * billing window and produces upgrade/downgrade recommendations consumed by the
4
+ * Slack daily digest and cli-tier-recommendation.
5
+ */
6
+ /**
7
+ * Reference plan-cost table — the orchestrator typically has these populated from the
8
+ * SubscriptionPlan resources, but ships with sensible defaults so cli-tier-recommendation
9
+ * can produce useful output even on a fresh deployment.
10
+ */
11
+ export const PLAN_COSTS_USD = {
12
+ 'claude-code-pro': 20,
13
+ 'claude-code-max-5x': 100,
14
+ 'claude-code-max-20x': 200,
15
+ 'codex-plus': 20,
16
+ 'codex-pro': 200,
17
+ 'pay-per-token': 0,
18
+ };
19
+ const HIGH_CONTENTION_THRESHOLD = 20;
20
+ const MEDIUM_CONTENTION_THRESHOLD = 5;
21
+ export function analyzeTier(input) {
22
+ const cumulative = input.contentionEvents.reduce((a, e) => a + e.contentionDurationMs, 0);
23
+ const confidence = confidenceFor(input.contentionEvents.length);
24
+ const currentPlanCost = PLAN_COSTS_USD[input.currentPlan.name] ?? 0;
25
+ // Find the candidate that minimizes expected contention, conservative for downgrades.
26
+ let recommended = input.currentPlan;
27
+ let recommendedCost = currentPlanCost;
28
+ if (input.contentionEvents.length > 0) {
29
+ // Upgrade direction: pick the next plan up.
30
+ const upgrade = nextPlanUp(input.currentPlan, input.candidates);
31
+ if (upgrade) {
32
+ recommended = upgrade;
33
+ recommendedCost = PLAN_COSTS_USD[upgrade.name] ?? currentPlanCost;
34
+ }
35
+ }
36
+ else if (confidence === 'high') {
37
+ // Possibly recommend downgrade if utilization is consistently low — we don't have
38
+ // utilization in this aggregation; defer to caller to set issuesBlockedOnHardCap=0
39
+ // and contentionEvents=0 explicitly. For now keep currentPlan as the recommendation.
40
+ }
41
+ const reasoning = buildReasoning(input, cumulative, recommended);
42
+ return {
43
+ billingPeriod: input.billingPeriod,
44
+ ledgerKey: input.ledgerKey,
45
+ currentPlan: input.currentPlan.name,
46
+ currentPlanCostUsd: currentPlanCost,
47
+ contentionEvents: input.contentionEvents.length,
48
+ cumulativeContentionDurationMs: cumulative,
49
+ issuesDeferredOffPeak: input.issuesDeferredOffPeak,
50
+ issuesBlockedOnHardCap: input.issuesBlockedOnHardCap,
51
+ recommendedPlan: recommended.name,
52
+ recommendedPlanCostUsd: recommendedCost,
53
+ projectedTimeSavedMs: cumulative * 0.75, // heuristic: upgrade reclaims ~75% of contention
54
+ projectedAdditionalIssuesProcessed: Math.floor(cumulative / (60 * 60 * 1000)), // 1 issue per hour saved
55
+ projectedSpilloverSavingsUsd: input.issuesBlockedOnHardCap * 1.5,
56
+ confidence,
57
+ reasoning,
58
+ };
59
+ }
60
+ function nextPlanUp(current, candidates) {
61
+ const sameHarness = candidates.filter((c) => c.harness === current.harness);
62
+ const ordered = sameHarness.sort((a, b) => (PLAN_COSTS_USD[a.name] ?? 0) - (PLAN_COSTS_USD[b.name] ?? 0));
63
+ const idx = ordered.findIndex((p) => p.name === current.name);
64
+ if (idx < 0 || idx === ordered.length - 1)
65
+ return null;
66
+ return ordered[idx + 1];
67
+ }
68
+ function confidenceFor(count) {
69
+ if (count > HIGH_CONTENTION_THRESHOLD)
70
+ return 'high';
71
+ if (count >= MEDIUM_CONTENTION_THRESHOLD)
72
+ return 'medium';
73
+ return 'low';
74
+ }
75
+ function buildReasoning(input, cumulativeMs, recommended) {
76
+ if (recommended.name === input.currentPlan.name) {
77
+ return `Current plan ${input.currentPlan.name} appears appropriately sized for observed contention (${input.contentionEvents.length} events, ${(cumulativeMs / 1000 / 60 / 60).toFixed(1)}h cumulative).`;
78
+ }
79
+ return `${input.currentPlan.name} hit hardCap on ${input.issuesBlockedOnHardCap} issues this period, totaling ${(cumulativeMs / 1000 / 60 / 60).toFixed(1)}h of cumulative wait. ${recommended.name} would project to keep utilization below pacingTarget at current dispatch rate.`;
80
+ }
81
+ //# sourceMappingURL=tier-analysis.js.map
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Subscription-aware scheduling types per RFC-0010 §14. The dispatcher consults a
3
+ * SubscriptionLedger keyed by (harness, accountId, tenant) on every admission decision
4
+ * so parallel agents on the same vendor account correctly share quota.
5
+ */
6
+ export type BillingMode = 'session-window' | 'monthly-cap' | 'pay-per-token';
7
+ export type QuotaSource = 'self-tracked' | 'authoritative-api' | 'authoritative-with-fallback';
8
+ export interface OffPeakSchedule {
9
+ enabled: boolean;
10
+ multiplier: number;
11
+ schedule: Array<{
12
+ /** IANA timezone (e.g., 'America/Los_Angeles'). */
13
+ tz: string;
14
+ /** Hour range like '22-06' (wraps midnight). */
15
+ hours: string;
16
+ /** Optional comma-separated days like 'Sat,Sun'. */
17
+ daysOfWeek?: string;
18
+ }>;
19
+ /** ISO 8601 date the operator last verified the schedule against vendor docs. */
20
+ lastVerified?: string;
21
+ }
22
+ export interface SubscriptionPlan {
23
+ /** Resource metadata.name. */
24
+ name: string;
25
+ /** Harness this plan applies to. */
26
+ harness: string;
27
+ billingMode: BillingMode;
28
+ /** Required when billingMode is session-window. ISO 8601 duration (e.g., 'PT5H'). */
29
+ windowDuration?: string;
30
+ /** Required when billingMode is session-window or monthly-cap. */
31
+ windowQuotaTokens?: number;
32
+ offPeak?: OffPeakSchedule;
33
+ pacingTarget: number;
34
+ hardCap: number;
35
+ quotaSource: QuotaSource;
36
+ }
37
+ export type Schedule = 'now' | 'off-peak' | 'quota-permitting' | 'defer-if-low-priority';
38
+ export interface TokenEstimate {
39
+ input: number;
40
+ output: number;
41
+ /** When true, rolling updates do NOT supersede the operator-declared values. */
42
+ frozen?: boolean;
43
+ }
44
+ export interface LedgerKey {
45
+ harness: string;
46
+ accountId: string;
47
+ tenant: string;
48
+ }
49
+ export declare const DEFAULT_TENANT = "__default__";
50
+ export declare const COLD_START_DEFAULT_INPUT = 50000;
51
+ export declare const COLD_START_DEFAULT_OUTPUT = 10000;
52
+ export declare const ESTIMATE_VARIANCE_THRESHOLD = 0.5;
53
+ export declare const ROLLING_WINDOW_SIZE = 20;
54
+ export interface WindowState {
55
+ windowStart: Date;
56
+ windowEnd: Date;
57
+ consumedTokens: number;
58
+ quotaTokens: number;
59
+ multiplier: number;
60
+ utilizationFraction: number;
61
+ pacingTarget: number;
62
+ hardCap: number;
63
+ }
64
+ export type AdmissionDecision = {
65
+ kind: 'yes';
66
+ reason: string;
67
+ } | {
68
+ kind: 'wait-until';
69
+ until: Date;
70
+ reason: string;
71
+ } | {
72
+ kind: 'no';
73
+ reason: string;
74
+ blockedBy: 'hardCap' | 'cost-budget' | 'maxBudgetUsd';
75
+ };
76
+ export interface BurnDownReport {
77
+ harness: string;
78
+ ledgerKey: LedgerKey;
79
+ windowEnd: string;
80
+ subscriptionTokensConsumed: number;
81
+ quotaTokens: number;
82
+ subscriptionUtilizationFraction: number;
83
+ dollarsSpent: number;
84
+ shadowCostUsd: number;
85
+ pacingTarget: number;
86
+ projectedUtilization: number;
87
+ queueDepth: number;
88
+ recommendation: 'under-pacing' | 'on-pace' | 'over-pacing';
89
+ }
90
+ export type LedgerEvent = {
91
+ type: 'AdmissionDenied';
92
+ ledgerKey: LedgerKey;
93
+ blockedBy: string;
94
+ detail: string;
95
+ } | {
96
+ type: 'OffPeakDeferralExceeded';
97
+ ledgerKey: LedgerKey;
98
+ stage: string;
99
+ } | {
100
+ type: 'BurnDownReport';
101
+ report: BurnDownReport;
102
+ } | {
103
+ type: 'EstimateBootstrapped';
104
+ stage: string;
105
+ coldStartDefault: TokenEstimate;
106
+ firstRunActual: TokenEstimate;
107
+ newRollingEstimate: TokenEstimate;
108
+ } | {
109
+ type: 'EstimateVariance';
110
+ stage: string;
111
+ declared: TokenEstimate;
112
+ observed: TokenEstimate;
113
+ ratio: number;
114
+ } | {
115
+ type: 'MissingEstimate';
116
+ stage: string;
117
+ } | {
118
+ type: 'LedgerReconciliation';
119
+ ledgerKey: LedgerKey;
120
+ previousSource: QuotaSource;
121
+ newSource: QuotaSource;
122
+ selfTracked: number;
123
+ authoritative: number;
124
+ absoluteDivergence: number;
125
+ relativeDivergence: number;
126
+ } | {
127
+ type: 'LedgerPooled';
128
+ ledgerKey: LedgerKey;
129
+ pipelines: string[];
130
+ } | {
131
+ type: 'LedgerKeyAmbiguous';
132
+ harness: string;
133
+ pipeline: string;
134
+ } | {
135
+ type: 'TenantShareInvalid';
136
+ harness: string;
137
+ accountId: string;
138
+ sumOfShares: number;
139
+ };
140
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Subscription-aware scheduling types per RFC-0010 §14. The dispatcher consults a
3
+ * SubscriptionLedger keyed by (harness, accountId, tenant) on every admission decision
4
+ * so parallel agents on the same vendor account correctly share quota.
5
+ */
6
+ export const DEFAULT_TENANT = '__default__';
7
+ export const COLD_START_DEFAULT_INPUT = 50_000;
8
+ export const COLD_START_DEFAULT_OUTPUT = 10_000;
9
+ export const ESTIMATE_VARIANCE_THRESHOLD = 0.5;
10
+ export const ROLLING_WINDOW_SIZE = 20;
11
+ //# sourceMappingURL=types.js.map
package/dist/shared.d.ts CHANGED
@@ -12,6 +12,19 @@ export declare function execFileAsync(cmd: string, args: string[], opts?: Record
12
12
  * Unknown keys are left as-is.
13
13
  */
14
14
  export declare function interpolate(text: string, vars: Record<string, string>): string;
15
+ /**
16
+ * Build the standard set of template vars for branch / PR / notification interpolation.
17
+ * Provides backward-compatible {issueNumber} + {issueTitle} alongside backlog-friendly
18
+ * {issueId}, {issueIdLower}, {slug}.
19
+ */
20
+ export declare function buildIssueTemplateVars(issueId: string, issueTitle: string): Record<string, string>;
21
+ /**
22
+ * Convert an arbitrary string to a kebab-case slug suitable for branch names.
23
+ * Lowercases, replaces non-alphanumerics with single dashes, trims dashes from
24
+ * start/end, and truncates to 40 chars at a word boundary so the resulting
25
+ * branch name stays under git's path-component limits.
26
+ */
27
+ export declare function slugify(input: string, maxLen?: number): string;
15
28
  /**
16
29
  * Interpolate a branch name pattern by replacing `{key}` placeholders.
17
30
  * Falls back to `ai-sdlc/issue-{issueNumber}` when no pattern is provided.
package/dist/shared.js CHANGED
@@ -24,6 +24,38 @@ export function execFileAsync(cmd, args, opts) {
24
24
  export function interpolate(text, vars) {
25
25
  return text.replace(/\{(\w+)\}/g, (_, key) => vars[key] ?? `{${key}}`);
26
26
  }
27
+ /**
28
+ * Build the standard set of template vars for branch / PR / notification interpolation.
29
+ * Provides backward-compatible {issueNumber} + {issueTitle} alongside backlog-friendly
30
+ * {issueId}, {issueIdLower}, {slug}.
31
+ */
32
+ export function buildIssueTemplateVars(issueId, issueTitle) {
33
+ return {
34
+ issueNumber: issueId,
35
+ issueTitle,
36
+ issueId,
37
+ issueIdLower: issueId.toLowerCase(),
38
+ slug: slugify(issueTitle),
39
+ };
40
+ }
41
+ /**
42
+ * Convert an arbitrary string to a kebab-case slug suitable for branch names.
43
+ * Lowercases, replaces non-alphanumerics with single dashes, trims dashes from
44
+ * start/end, and truncates to 40 chars at a word boundary so the resulting
45
+ * branch name stays under git's path-component limits.
46
+ */
47
+ export function slugify(input, maxLen = 40) {
48
+ const cleaned = input
49
+ .toLowerCase()
50
+ .replace(/[^a-z0-9]+/g, '-')
51
+ .replace(/^-+|-+$/g, '');
52
+ if (cleaned.length <= maxLen)
53
+ return cleaned;
54
+ // Truncate at the last dash before maxLen so we don't cut a word in half.
55
+ const truncated = cleaned.slice(0, maxLen);
56
+ const lastDash = truncated.lastIndexOf('-');
57
+ return lastDash > maxLen / 2 ? truncated.slice(0, lastDash) : truncated;
58
+ }
27
59
  /**
28
60
  * Interpolate a branch name pattern by replacing `{key}` placeholders.
29
61
  * Falls back to `ai-sdlc/issue-{issueNumber}` when no pattern is provided.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * SQLite DDL and migrations for the state store.
3
3
  */
4
- export declare const CURRENT_SCHEMA_VERSION = 9;
4
+ export declare const CURRENT_SCHEMA_VERSION = 12;
5
5
  export declare const SCHEMA_DDL = "\nCREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER PRIMARY KEY,\n applied_at TEXT DEFAULT (datetime('now'))\n);\n\nCREATE TABLE IF NOT EXISTS complexity_profile (\n id INTEGER PRIMARY KEY,\n repo_path TEXT NOT NULL,\n score REAL NOT NULL,\n files_count INTEGER,\n modules_count INTEGER,\n dependency_count INTEGER,\n analyzed_at TEXT DEFAULT (datetime('now')),\n raw_data TEXT\n);\n\nCREATE TABLE IF NOT EXISTS episodic_memory (\n id INTEGER PRIMARY KEY,\n issue_number INTEGER,\n pr_number INTEGER,\n pipeline_type TEXT NOT NULL,\n outcome TEXT NOT NULL,\n duration_ms INTEGER,\n files_changed INTEGER,\n error_message TEXT,\n metadata TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n);\n\nCREATE TABLE IF NOT EXISTS autonomy_ledger (\n id INTEGER PRIMARY KEY,\n agent_name TEXT NOT NULL UNIQUE,\n current_level INTEGER DEFAULT 0,\n total_tasks INTEGER DEFAULT 0,\n success_count INTEGER DEFAULT 0,\n failure_count INTEGER DEFAULT 0,\n last_task_at TEXT,\n metrics TEXT\n);\n\nCREATE TABLE IF NOT EXISTS pipeline_runs (\n id INTEGER PRIMARY KEY,\n run_id TEXT NOT NULL UNIQUE,\n issue_number INTEGER,\n pr_number INTEGER,\n pipeline_type TEXT NOT NULL,\n status TEXT NOT NULL,\n current_stage TEXT,\n started_at TEXT DEFAULT (datetime('now')),\n completed_at TEXT,\n result TEXT,\n gate_results TEXT\n);\n\nCREATE TABLE IF NOT EXISTS conventions (\n id INTEGER PRIMARY KEY,\n category TEXT NOT NULL,\n pattern TEXT NOT NULL,\n confidence REAL,\n examples TEXT,\n detected_at TEXT DEFAULT (datetime('now'))\n);\n";
6
6
  export interface Migration {
7
7
  version: number;
@@ -15,5 +15,9 @@ export declare const MIGRATION_V6 = "\n-- Cost governance: add stage_name and ca
15
15
  export declare const MIGRATION_V7 = "\n-- String issue IDs\nALTER TABLE pipeline_runs ADD COLUMN issue_id TEXT;\nALTER TABLE episodic_memory ADD COLUMN issue_id TEXT;\nALTER TABLE cost_ledger ADD COLUMN issue_id TEXT;\nALTER TABLE routing_history ADD COLUMN issue_id TEXT;\n";
16
16
  export declare const MIGRATION_V8 = "\n-- Priority calibration table (RFC-0005 PPA)\nCREATE TABLE IF NOT EXISTS priority_calibration (\n id INTEGER PRIMARY KEY,\n issue_id TEXT NOT NULL,\n priority_composite REAL NOT NULL,\n priority_confidence REAL NOT NULL,\n priority_dimensions TEXT,\n actual_complexity INTEGER,\n files_changed INTEGER,\n outcome TEXT,\n sampled_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_priority_calibration_issue ON priority_calibration(issue_id);\nCREATE INDEX IF NOT EXISTS idx_priority_calibration_sampled ON priority_calibration(sampled_at);\n\n-- Extend episodic_memory with priority columns\nALTER TABLE episodic_memory ADD COLUMN priority_composite REAL;\nALTER TABLE episodic_memory ADD COLUMN priority_confidence REAL;\n";
17
17
  export declare const MIGRATION_V9 = "\n-- Workflow pattern detection tables\n\n-- Tool sequence events captured by PostToolUse hook\nCREATE TABLE IF NOT EXISTS tool_sequence_events (\n id INTEGER PRIMARY KEY,\n session_id TEXT NOT NULL,\n tool_name TEXT NOT NULL,\n action_canonical TEXT NOT NULL,\n project_path TEXT,\n timestamp TEXT NOT NULL,\n ingested_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_tool_seq_session ON tool_sequence_events(session_id);\nCREATE INDEX IF NOT EXISTS idx_tool_seq_ts ON tool_sequence_events(timestamp);\n\n-- Detected workflow patterns (from n-gram mining)\nCREATE TABLE IF NOT EXISTS workflow_patterns (\n id INTEGER PRIMARY KEY,\n pattern_hash TEXT NOT NULL UNIQUE,\n pattern_type TEXT NOT NULL,\n sequence_json TEXT NOT NULL,\n frequency INTEGER NOT NULL,\n session_count INTEGER NOT NULL,\n confidence REAL NOT NULL,\n first_seen TEXT,\n last_seen TEXT,\n status TEXT DEFAULT 'detected',\n detected_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_workflow_patterns_status ON workflow_patterns(status);\n\n-- Automation proposals for human review\nCREATE TABLE IF NOT EXISTS pattern_proposals (\n id INTEGER PRIMARY KEY,\n pattern_id INTEGER NOT NULL,\n proposal_type TEXT NOT NULL,\n artifact_type TEXT NOT NULL,\n artifact_path TEXT,\n draft_content TEXT NOT NULL,\n confidence REAL NOT NULL,\n status TEXT DEFAULT 'pending',\n reviewed_at TEXT,\n reviewer_reason TEXT,\n created_at TEXT DEFAULT (datetime('now')),\n FOREIGN KEY (pattern_id) REFERENCES workflow_patterns(id)\n);\nCREATE INDEX IF NOT EXISTS idx_pattern_proposals_status ON pattern_proposals(status);\n";
18
+ export declare const MIGRATION_V10 = "\n-- Design System Governance tables (RFC-0006)\n\nCREATE TABLE IF NOT EXISTS design_token_events (\n id INTEGER PRIMARY KEY,\n binding_name TEXT NOT NULL,\n event_type TEXT NOT NULL,\n tokens_affected INTEGER DEFAULT 0,\n diff_json TEXT,\n actor TEXT,\n pipeline_run_id TEXT,\n design_review_decision TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_design_token_events_binding ON design_token_events(binding_name);\nCREATE INDEX IF NOT EXISTS idx_design_token_events_type ON design_token_events(event_type);\nCREATE INDEX IF NOT EXISTS idx_design_token_events_run ON design_token_events(pipeline_run_id);\n\nCREATE TABLE IF NOT EXISTS design_review_events (\n id INTEGER PRIMARY KEY,\n binding_name TEXT NOT NULL,\n pr_number INTEGER,\n component_name TEXT,\n reviewer TEXT NOT NULL,\n decision TEXT NOT NULL,\n categories_json TEXT,\n actionable_notes TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_design_review_events_binding ON design_review_events(binding_name);\nCREATE INDEX IF NOT EXISTS idx_design_review_events_pr ON design_review_events(pr_number);\nCREATE INDEX IF NOT EXISTS idx_design_review_events_decision ON design_review_events(decision);\n\nCREATE TABLE IF NOT EXISTS token_compliance_history (\n id INTEGER PRIMARY KEY,\n binding_name TEXT NOT NULL,\n coverage_percent REAL NOT NULL,\n violations_count INTEGER NOT NULL DEFAULT 0,\n scanned_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_token_compliance_binding ON token_compliance_history(binding_name);\n\nCREATE TABLE IF NOT EXISTS visual_regression_results (\n id INTEGER PRIMARY KEY,\n binding_name TEXT NOT NULL,\n story_name TEXT NOT NULL,\n viewport INTEGER,\n diff_percentage REAL NOT NULL,\n approved INTEGER DEFAULT 0,\n approver TEXT,\n baseline_url TEXT,\n current_url TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_visual_regression_binding ON visual_regression_results(binding_name);\nCREATE INDEX IF NOT EXISTS idx_visual_regression_story ON visual_regression_results(story_name);\n\nCREATE TABLE IF NOT EXISTS usability_simulation_results (\n id INTEGER PRIMARY KEY,\n binding_name TEXT NOT NULL,\n story_name TEXT NOT NULL,\n persona_id TEXT,\n task_id TEXT,\n completed INTEGER DEFAULT 0,\n actions_taken INTEGER,\n expected_actions INTEGER,\n efficiency REAL,\n findings_json TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_usability_sim_binding ON usability_simulation_results(binding_name);\nCREATE INDEX IF NOT EXISTS idx_usability_sim_story ON usability_simulation_results(story_name);\n";
19
+ export declare const MIGRATION_V11 = "\n-- PPA Triad Integration tables (RFC-0008)\n\n-- Compiled DID artifacts: scope lists, constraint rules, anti-pattern lists,\n-- BM25 corpus (SA-1), principle corpora (SA-2). Keyed by source_hash so the\n-- reconciler can detect DID changes cheaply.\nCREATE TABLE IF NOT EXISTS did_compiled_artifacts (\n id INTEGER PRIMARY KEY,\n did_name TEXT NOT NULL,\n namespace TEXT,\n source_hash TEXT NOT NULL,\n scope_lists_json TEXT,\n constraint_rules_json TEXT,\n anti_pattern_lists_json TEXT,\n measurable_signals_json TEXT,\n bm25_corpus_blob BLOB,\n principle_corpora_blob BLOB,\n compiled_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_did_compiled_did ON did_compiled_artifacts(did_name);\nCREATE INDEX IF NOT EXISTS idx_did_compiled_hash ON did_compiled_artifacts(source_hash);\n\n-- SA scoring events: layer 1/2/3 results per issue, phase weights, composite score.\nCREATE TABLE IF NOT EXISTS did_scoring_events (\n id INTEGER PRIMARY KEY,\n did_name TEXT NOT NULL,\n issue_number INTEGER NOT NULL,\n sa_dimension TEXT NOT NULL,\n phase TEXT NOT NULL,\n layer1_result_json TEXT,\n layer2_result_json TEXT,\n layer3_result_json TEXT,\n composite_score REAL,\n phase_weights_json TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_did_scoring_did ON did_scoring_events(did_name);\nCREATE INDEX IF NOT EXISTS idx_did_scoring_issue ON did_scoring_events(issue_number);\nCREATE INDEX IF NOT EXISTS idx_did_scoring_created ON did_scoring_events(created_at);\n\n-- SA feedback events: accept/dismiss/escalate/override signals from Product/Design leads.\n-- Used by C6 calibration (M6) and Phase 3 weight auto-calibration.\nCREATE TABLE IF NOT EXISTS did_feedback_events (\n id INTEGER PRIMARY KEY,\n did_name TEXT NOT NULL,\n issue_number INTEGER NOT NULL,\n dimension TEXT NOT NULL,\n signal TEXT NOT NULL CHECK (signal IN ('accept', 'dismiss', 'escalate', 'override')),\n principal TEXT,\n category TEXT,\n structural_score REAL,\n llm_score REAL,\n composite_score REAL,\n notes TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_did_feedback_did ON did_feedback_events(did_name);\nCREATE INDEX IF NOT EXISTS idx_did_feedback_issue ON did_feedback_events(issue_number);\nCREATE INDEX IF NOT EXISTS idx_did_feedback_signal ON did_feedback_events(signal);\nCREATE INDEX IF NOT EXISTS idx_did_feedback_created ON did_feedback_events(created_at);\n\n-- Design change events: emitted when DID.spec.plannedChanges[] adds an entry.\n-- Addendum A \u00A7A.9 Design\u2192Engineering lookahead.\nCREATE TABLE IF NOT EXISTS design_change_events (\n id INTEGER PRIMARY KEY,\n did_name TEXT NOT NULL,\n change_id TEXT NOT NULL,\n change_type TEXT NOT NULL,\n status TEXT NOT NULL,\n payload_json TEXT NOT NULL,\n emitted_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_design_change_did ON design_change_events(did_name);\nCREATE INDEX IF NOT EXISTS idx_design_change_change ON design_change_events(change_id);\n\n-- Code area metrics: used by enrichAdmissionInput (C3) for defect risk factor\n-- and by DesignQualityTrendDegrading monitor (A.8).\nCREATE TABLE IF NOT EXISTS code_area_metrics (\n id INTEGER PRIMARY KEY,\n code_area TEXT NOT NULL,\n defect_density REAL,\n churn_rate REAL,\n pr_rejection_rate REAL,\n code_acceptance_rate REAL,\n has_frontend_components INTEGER DEFAULT 0,\n design_metrics_json TEXT,\n data_point_count INTEGER DEFAULT 0,\n window_start TEXT,\n window_end TEXT,\n computed_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_code_area_metrics_area ON code_area_metrics(code_area);\nCREATE INDEX IF NOT EXISTS idx_code_area_metrics_computed ON code_area_metrics(computed_at);\n\n-- Design lookahead notification state: dedupe per issue with 7-day expiry.\n-- Used by C7 (\u00A711).\nCREATE TABLE IF NOT EXISTS design_lookahead_notifications (\n id INTEGER PRIMARY KEY,\n issue_number INTEGER NOT NULL,\n first_notified_at TEXT DEFAULT (datetime('now')),\n last_notified_at TEXT DEFAULT (datetime('now')),\n pillar_breakdown_json TEXT,\n UNIQUE(issue_number)\n);\nCREATE INDEX IF NOT EXISTS idx_lookahead_issue ON design_lookahead_notifications(issue_number);\n";
20
+ export declare const MIGRATION_V12 = "\n-- SA Phase-3 calibrated weights (RFC-0008 \u00A7B.8 \u2014 AISDLC-66).\n-- One row per dimension (SA-1, SA-2); upserted by the auto-calibrator\n-- nightly or on demand.\n-- CR-2 (RFC-0008 Addendum B \u00A7B.7): both weights MUST be \u2265 0.20 so\n-- neither layer can be dropped below a \"minimum influence\" floor by\n-- auto-calibration. The code-level clamp is the first gate; this\n-- CHECK is the last line of defense if the code clamp is bypassed.\nCREATE TABLE IF NOT EXISTS sa_phase_weights (\n id INTEGER PRIMARY KEY,\n dimension TEXT NOT NULL UNIQUE,\n w_structural REAL NOT NULL,\n w_llm REAL NOT NULL,\n calibrated_at TEXT DEFAULT (datetime('now')),\n CHECK (w_structural >= 0.20 AND w_structural <= 0.80),\n CHECK (w_llm >= 0.20 AND w_llm <= 0.80)\n);\nCREATE INDEX IF NOT EXISTS idx_sa_phase_weights_dim ON sa_phase_weights(dimension);\n";
21
+ export declare const MIGRATION_V13 = "\n-- RFC-0010 \u00A711.4 cost attribution: track the model alias used in pipeline YAML\n-- alongside the resolved physical model ID, plus an informational shadow cost\n-- (what subscription-harness work would have cost on pay-per-token).\nALTER TABLE cost_ledger ADD COLUMN model_alias TEXT;\nALTER TABLE cost_ledger ADD COLUMN shadow_cost_usd REAL;\nCREATE INDEX IF NOT EXISTS idx_cost_ledger_model_alias ON cost_ledger(model_alias);\n";
18
22
  export declare const MIGRATIONS: Migration[];
19
23
  //# sourceMappingURL=schema.d.ts.map