@aid-framework/ir 0.0.0-stage → 0.1.39

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 (122) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +134 -2
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/build.d.ts +74 -0
  5. package/dist/build.d.ts.map +1 -0
  6. package/dist/build.js +1079 -0
  7. package/dist/build.js.map +1 -0
  8. package/dist/capabilities.d.ts +65 -0
  9. package/dist/capabilities.d.ts.map +1 -0
  10. package/dist/capabilities.js +176 -0
  11. package/dist/capabilities.js.map +1 -0
  12. package/dist/catalog/index.d.ts +36 -0
  13. package/dist/catalog/index.d.ts.map +1 -0
  14. package/dist/catalog/index.js +43 -0
  15. package/dist/catalog/index.js.map +1 -0
  16. package/dist/catalog/models.json +52 -0
  17. package/dist/diagnostics.d.ts +90 -0
  18. package/dist/diagnostics.d.ts.map +1 -0
  19. package/dist/diagnostics.js +103 -0
  20. package/dist/diagnostics.js.map +1 -0
  21. package/dist/gates/agents.d.ts +34 -0
  22. package/dist/gates/agents.d.ts.map +1 -0
  23. package/dist/gates/agents.js +233 -0
  24. package/dist/gates/agents.js.map +1 -0
  25. package/dist/gates/capability.d.ts +15 -0
  26. package/dist/gates/capability.d.ts.map +1 -0
  27. package/dist/gates/capability.js +81 -0
  28. package/dist/gates/capability.js.map +1 -0
  29. package/dist/gates/contract.d.ts +35 -0
  30. package/dist/gates/contract.d.ts.map +1 -0
  31. package/dist/gates/contract.js +19 -0
  32. package/dist/gates/contract.js.map +1 -0
  33. package/dist/gates/cost.d.ts +40 -0
  34. package/dist/gates/cost.d.ts.map +1 -0
  35. package/dist/gates/cost.js +167 -0
  36. package/dist/gates/cost.js.map +1 -0
  37. package/dist/gates/deploy.d.ts +23 -0
  38. package/dist/gates/deploy.d.ts.map +1 -0
  39. package/dist/gates/deploy.js +44 -0
  40. package/dist/gates/deploy.js.map +1 -0
  41. package/dist/gates/eval-coverage.d.ts +11 -0
  42. package/dist/gates/eval-coverage.d.ts.map +1 -0
  43. package/dist/gates/eval-coverage.js +50 -0
  44. package/dist/gates/eval-coverage.js.map +1 -0
  45. package/dist/gates/guardrails.d.ts +24 -0
  46. package/dist/gates/guardrails.d.ts.map +1 -0
  47. package/dist/gates/guardrails.js +112 -0
  48. package/dist/gates/guardrails.js.map +1 -0
  49. package/dist/gates/hitl.d.ts +17 -0
  50. package/dist/gates/hitl.d.ts.map +1 -0
  51. package/dist/gates/hitl.js +40 -0
  52. package/dist/gates/hitl.js.map +1 -0
  53. package/dist/gates/index.d.ts +66 -0
  54. package/dist/gates/index.d.ts.map +1 -0
  55. package/dist/gates/index.js +77 -0
  56. package/dist/gates/index.js.map +1 -0
  57. package/dist/gates/memory.d.ts +13 -0
  58. package/dist/gates/memory.d.ts.map +1 -0
  59. package/dist/gates/memory.js +67 -0
  60. package/dist/gates/memory.js.map +1 -0
  61. package/dist/gates/normalize.d.ts +26 -0
  62. package/dist/gates/normalize.d.ts.map +1 -0
  63. package/dist/gates/normalize.js +228 -0
  64. package/dist/gates/normalize.js.map +1 -0
  65. package/dist/gates/orchestration.d.ts +17 -0
  66. package/dist/gates/orchestration.d.ts.map +1 -0
  67. package/dist/gates/orchestration.js +46 -0
  68. package/dist/gates/orchestration.js.map +1 -0
  69. package/dist/gates/referential.d.ts +12 -0
  70. package/dist/gates/referential.d.ts.map +1 -0
  71. package/dist/gates/referential.js +554 -0
  72. package/dist/gates/referential.js.map +1 -0
  73. package/dist/gates/security.d.ts +22 -0
  74. package/dist/gates/security.d.ts.map +1 -0
  75. package/dist/gates/security.js +225 -0
  76. package/dist/gates/security.js.map +1 -0
  77. package/dist/index.d.ts +27 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +19 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/policy/ast.d.ts +61 -0
  82. package/dist/policy/ast.d.ts.map +1 -0
  83. package/dist/policy/ast.js +48 -0
  84. package/dist/policy/ast.js.map +1 -0
  85. package/dist/policy/index.d.ts +7 -0
  86. package/dist/policy/index.d.ts.map +1 -0
  87. package/dist/policy/index.js +4 -0
  88. package/dist/policy/index.js.map +1 -0
  89. package/dist/policy/lexer.d.ts +27 -0
  90. package/dist/policy/lexer.d.ts.map +1 -0
  91. package/dist/policy/lexer.js +147 -0
  92. package/dist/policy/lexer.js.map +1 -0
  93. package/dist/policy/parser.d.ts +15 -0
  94. package/dist/policy/parser.d.ts.map +1 -0
  95. package/dist/policy/parser.js +202 -0
  96. package/dist/policy/parser.js.map +1 -0
  97. package/dist/predicate/ast.d.ts +125 -0
  98. package/dist/predicate/ast.d.ts.map +1 -0
  99. package/dist/predicate/ast.js +111 -0
  100. package/dist/predicate/ast.js.map +1 -0
  101. package/dist/predicate/index.d.ts +7 -0
  102. package/dist/predicate/index.d.ts.map +1 -0
  103. package/dist/predicate/index.js +4 -0
  104. package/dist/predicate/index.js.map +1 -0
  105. package/dist/predicate/lexer.d.ts +30 -0
  106. package/dist/predicate/lexer.d.ts.map +1 -0
  107. package/dist/predicate/lexer.js +176 -0
  108. package/dist/predicate/lexer.js.map +1 -0
  109. package/dist/predicate/parser.d.ts +16 -0
  110. package/dist/predicate/parser.d.ts.map +1 -0
  111. package/dist/predicate/parser.js +317 -0
  112. package/dist/predicate/parser.js.map +1 -0
  113. package/dist/schema/ir.schema.json +1144 -0
  114. package/dist/serialize.d.ts +15 -0
  115. package/dist/serialize.d.ts.map +1 -0
  116. package/dist/serialize.js +53 -0
  117. package/dist/serialize.js.map +1 -0
  118. package/dist/shapes.d.ts +671 -0
  119. package/dist/shapes.d.ts.map +1 -0
  120. package/dist/shapes.js +159 -0
  121. package/dist/shapes.js.map +1 -0
  122. package/package.json +41 -3
@@ -0,0 +1,77 @@
1
+ /**
2
+ * The build-time gates, run as one report.
3
+ *
4
+ * Error-severity diagnostics fail the build; warnings do not. Suppressed checks are
5
+ * merged alongside the diagnostics so a caller can always see what was *not* enforced.
6
+ *
7
+ * The nine gates Phase 2 L1 adds are named by the id the plan's P5 table gives them,
8
+ * because that id is what appears in mutation evidence and in a reviewer's search for
9
+ * "which gate stopped this". A gate whose name drifts from the plan is a gate nobody
10
+ * can find.
11
+ */
12
+ import { hasErrors, sortDiagnostics } from '@aid-framework/spec';
13
+ import { deriveRequiredCapabilities } from '../capabilities.js';
14
+ import { phase0TargetCapabilities } from '../catalog/index.js';
15
+ import { agentsBudgetDegradeGate, agentsBudgetGate, agentsHandoffGate, agentsRefsGate, } from './agents.js';
16
+ import { capabilityGate } from './capability.js';
17
+ import { costGate } from './cost.js';
18
+ import { deployStreamingGate } from './deploy.js';
19
+ import { evalCoverageGate } from './eval-coverage.js';
20
+ import { guardrailCoverageGate, guardrailPolicyGate } from './guardrails.js';
21
+ import { hitlSideEffectGate } from './hitl.js';
22
+ import { memoryRefsGate } from './memory.js';
23
+ import { normalizeGate } from './normalize.js';
24
+ import { orchestrationDeepagentsGate } from './orchestration.js';
25
+ import { referentialGate } from './referential.js';
26
+ import { securityGate } from './security.js';
27
+ export const GATES = {
28
+ referential: referentialGate,
29
+ normalize: normalizeGate,
30
+ capability: capabilityGate,
31
+ cost: costGate,
32
+ security: securityGate,
33
+ 'eval-coverage': evalCoverageGate,
34
+ 'agents/refs-resolve': agentsRefsGate,
35
+ 'agents/handoff-cycles': agentsHandoffGate,
36
+ 'agents/budgets': agentsBudgetGate,
37
+ 'agents/budget-degrade': agentsBudgetDegradeGate,
38
+ 'guardrails/coverage': guardrailCoverageGate,
39
+ 'guardrails/policies': guardrailPolicyGate,
40
+ 'hitl/side-effects': hitlSideEffectGate,
41
+ 'memory/refs': memoryRefsGate,
42
+ 'deploy/streaming': deployStreamingGate,
43
+ 'orchestration/deepagents': orchestrationDeepagentsGate,
44
+ };
45
+ /**
46
+ * Runs every gate against the IR. The capability set the gates check is derived here
47
+ * from the IR's own content, so the value a generator consumes is the value that was
48
+ * checked rather than whatever the caller happened to pass in.
49
+ */
50
+ export function runGates(ir, options = {}) {
51
+ const checked = { ...ir, requiredCapabilities: deriveRequiredCapabilities(ir) };
52
+ const resolved = {
53
+ targetCapabilities: options.targetCapabilities ?? phase0TargetCapabilities(),
54
+ file: options.file,
55
+ };
56
+ const byGate = {};
57
+ const diagnostics = [];
58
+ const suppressed = [];
59
+ for (const name of Object.keys(GATES)) {
60
+ const result = GATES[name](checked, resolved);
61
+ byGate[name] = result;
62
+ diagnostics.push(...result.diagnostics);
63
+ suppressed.push(...result.suppressed);
64
+ }
65
+ return {
66
+ ok: !hasErrors(diagnostics),
67
+ diagnostics: sortDiagnostics(diagnostics),
68
+ suppressed,
69
+ byGate,
70
+ };
71
+ }
72
+ export { reporter } from './contract.js';
73
+ export { estimateEvalCost } from './cost.js';
74
+ export { diffPaths, isNormalized, normalize } from './normalize.js';
75
+ export { policyAuthenticates } from './security.js';
76
+ export { agentsBudgetDegradeGate, agentsBudgetGate, agentsHandoffGate, agentsRefsGate, capabilityGate, costGate, deployStreamingGate, evalCoverageGate, GATES as GATE_REGISTRY, guardrailCoverageGate, guardrailPolicyGate, hitlSideEffectGate, memoryRefsGate, normalizeGate, orchestrationDeepagentsGate, referentialGate, securityGate, };
77
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gates/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Memory — one gate.
3
+ *
4
+ * Every reference a memory tier makes must resolve, and each tier kind must name the
5
+ * thing that makes it work: a `summary` tier with no model has nothing to summarize
6
+ * with, and a `semantic`/`episodic`/`vector` tier with no store has nowhere to persist.
7
+ * Reporting that at build time is the difference between "declared" and "declared and
8
+ * possible"; the runtime is not asked to discover it on the first request.
9
+ */
10
+ import type { IR } from '../shapes.js';
11
+ import { type GateOptions, type GateResult } from './contract.js';
12
+ export declare function memoryRefsGate(ir: IR, options: GateOptions): GateResult;
13
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/gates/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,EAAE,EAAe,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAA6B,MAAM,eAAe,CAAC;AAK7F,wBAAgB,cAAc,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,UAAU,CAoEvE"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Memory — one gate.
3
+ *
4
+ * Every reference a memory tier makes must resolve, and each tier kind must name the
5
+ * thing that makes it work: a `summary` tier with no model has nothing to summarize
6
+ * with, and a `semantic`/`episodic`/`vector` tier with no store has nowhere to persist.
7
+ * Reporting that at build time is the difference between "declared" and "declared and
8
+ * possible"; the runtime is not asked to discover it on the first request.
9
+ */
10
+ import { IR_DIAGNOSTIC_CODES } from '../diagnostics.js';
11
+ import { NO_SUPPRESSIONS, reporter } from './contract.js';
12
+ /** The tier kinds that need somewhere to persist, as opposed to staying in the run. */
13
+ const PERSISTENT_KINDS = ['semantic', 'episodic', 'vector'];
14
+ export function memoryRefsGate(ir, options) {
15
+ const diagnostics = [];
16
+ const report = reporter(options);
17
+ const stores = new Set(ir.stores.map((store) => store.id));
18
+ const models = new Set(ir.models.map((model) => model.id));
19
+ for (const memory of ir.memory) {
20
+ if (memory.store !== undefined && !stores.has(memory.store)) {
21
+ diagnostics.push(report.error({
22
+ code: IR_DIAGNOSTIC_CODES.memoryRef,
23
+ message: `the memory gate rejected "${memory.id}": store names "${memory.store}", which is not a declared store`,
24
+ path: ['memory', memory.id, 'store'],
25
+ hint: `declared stores: ${[...stores].sort().join(', ') || 'none'}`,
26
+ }));
27
+ }
28
+ if (memory.backend !== undefined &&
29
+ memory.backend !== 'in-process' &&
30
+ !stores.has(memory.backend)) {
31
+ diagnostics.push(report.error({
32
+ code: IR_DIAGNOSTIC_CODES.memoryRef,
33
+ message: `the memory gate rejected "${memory.id}": backend names "${memory.backend}", which is neither a declared store nor "in-process"`,
34
+ path: ['memory', memory.id, 'backend'],
35
+ hint: `use "in-process" or one of: ${[...stores].sort().join(', ') || 'no stores declared'}`,
36
+ }));
37
+ }
38
+ if (memory.summarizeModel !== undefined && !models.has(memory.summarizeModel)) {
39
+ diagnostics.push(report.error({
40
+ code: IR_DIAGNOSTIC_CODES.memoryRef,
41
+ message: `the memory gate rejected "${memory.id}": summarizeModel names "${memory.summarizeModel}", which is not a declared model`,
42
+ path: ['memory', memory.id, 'summarizeModel'],
43
+ hint: `declared models: ${[...models].sort().join(', ') || 'none'}`,
44
+ }));
45
+ }
46
+ if (memory.kind === 'summary' && memory.summarizeModel === undefined) {
47
+ diagnostics.push(report.error({
48
+ code: IR_DIAGNOSTIC_CODES.memoryRef,
49
+ message: `the memory gate rejected "${memory.id}": kind is "summary" but no summarizeModel is declared, so nothing can produce the summary`,
50
+ path: ['memory', memory.id, 'summarizeModel'],
51
+ hint: 'name the model that summarizes, or use a window tier',
52
+ }));
53
+ }
54
+ if (PERSISTENT_KINDS.includes(memory.kind) &&
55
+ memory.store === undefined &&
56
+ (memory.backend === undefined || memory.backend === 'in-process')) {
57
+ diagnostics.push(report.error({
58
+ code: IR_DIAGNOSTIC_CODES.memoryRef,
59
+ message: `the memory gate rejected "${memory.id}": kind "${memory.kind}" outlives the run but names neither a store nor an external backend`,
60
+ path: ['memory', memory.id, 'store'],
61
+ hint: 'declare store or backend, or use a buffer/window tier',
62
+ }));
63
+ }
64
+ }
65
+ return { diagnostics, suppressed: NO_SUPPRESSIONS };
66
+ }
67
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/gates/memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Gate 2 — normalization.
3
+ *
4
+ * `normalize` is a total, pure, idempotent function that materializes every default
5
+ * into the IR, resolved from the top-level `observability` downwards. Its existence
6
+ * is what lets generated code never supply a default of its own: the gate re-runs it
7
+ * and reports anything the builder left implicit, so "the IR is normalized" is a
8
+ * checked property rather than a hope.
9
+ */
10
+ import { type IR } from '../shapes.js';
11
+ import { type GateOptions, type GateResult } from './contract.js';
12
+ /**
13
+ * Materializes every default the builder may have left implicit. Applying it twice is
14
+ * a no-op: each rule only ever fills an absent value, and no rule depends on the order
15
+ * another ran in, so normalization is idempotent and order-independent.
16
+ */
17
+ export declare function normalize(ir: IR): IR;
18
+ /**
19
+ * The dot-paths at which two IR values disagree, so the gate can say *which* default
20
+ * is missing rather than only that the IR differs from its normalization. Keys present
21
+ * on one side only are reported, which is how an unmaterialized default is caught.
22
+ */
23
+ export declare function diffPaths(before: unknown, after: unknown, path?: (string | number)[]): string[];
24
+ export declare function normalizeGate(ir: IR, options: GateOptions): GateResult;
25
+ export declare function isNormalized(ir: IR): boolean;
26
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/gates/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,EAML,KAAK,EAAE,EAaR,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAkC,MAAM,eAAe,CAAC;AAMlG;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CA0BpC;AA8FD;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,OAAO,EACd,IAAI,GAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAO,GAC7B,MAAM,EAAE,CAkBV;AAMD,wBAAgB,aAAa,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,UAAU,CA0BtE;AAqED,wBAAgB,YAAY,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAE5C"}
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Gate 2 — normalization.
3
+ *
4
+ * `normalize` is a total, pure, idempotent function that materializes every default
5
+ * into the IR, resolved from the top-level `observability` downwards. Its existence
6
+ * is what lets generated code never supply a default of its own: the gate re-runs it
7
+ * and reports anything the builder left implicit, so "the IR is normalized" is a
8
+ * checked property rather than a hope.
9
+ */
10
+ import { DEFAULT_EVAL_MAX_REGRESSION, DEFAULT_EVAL_SAMPLES, sensitiveNames } from '../build.js';
11
+ import { catalogModel } from '../catalog/index.js';
12
+ import { IR_DIAGNOSTIC_CODES } from '../diagnostics.js';
13
+ import { canonicalJson } from '../serialize.js';
14
+ import { DEFAULT_MAX_CONTEXT_TOKENS, DEFAULT_OBSERVABILITY, DEFAULT_RUNTIME, INDEX_METRICS, isIndexMetric, modelIdentity, PHASE_0_PROVIDERS, pipelineIdentity, promptIdentity, toolIdentity, } from '../shapes.js';
15
+ import { reporter } from './contract.js';
16
+ const SUPPRESSED = [];
17
+ /**
18
+ * Materializes every default the builder may have left implicit. Applying it twice is
19
+ * a no-op: each rule only ever fills an absent value, and no rule depends on the order
20
+ * another ran in, so normalization is idempotent and order-independent.
21
+ */
22
+ export function normalize(ir) {
23
+ const normalized = structuredClone(ir);
24
+ const observability = normalizeObservability(normalized.observability, sensitiveNames(normalized));
25
+ normalized.observability = observability;
26
+ normalized.runtime = { ...DEFAULT_RUNTIME, ...normalized.runtime };
27
+ normalized.models = normalized.models.map(normalizeModel);
28
+ normalized.prompts = normalized.prompts.map((prompt) => ({
29
+ ...prompt,
30
+ identity: promptIdentity(prompt.id, prompt.version),
31
+ params: prompt.params ?? {},
32
+ examples: prompt.examples ?? [],
33
+ guardrails: prompt.guardrails ?? [],
34
+ evals: prompt.evals ?? [],
35
+ traits: prompt.traits ?? [],
36
+ }));
37
+ normalized.tools = normalized.tools.map(normalizeTool);
38
+ normalized.pipelines = normalized.pipelines.map((pipeline) => normalizePipeline(pipeline, observability));
39
+ normalized.evals = normalized.evals.map(normalizeEval);
40
+ return normalized;
41
+ }
42
+ function normalizeObservability(raw, inherited) {
43
+ return {
44
+ trace: raw?.trace ?? DEFAULT_OBSERVABILITY.trace,
45
+ redact: [...(raw?.redact ?? inherited)],
46
+ };
47
+ }
48
+ function normalizeModel(model) {
49
+ return {
50
+ ...model,
51
+ identity: modelIdentity(model.id),
52
+ capabilities: [...model.capabilities],
53
+ params: model.params ?? {},
54
+ limits: {
55
+ ...model.limits,
56
+ contextTokens: model.limits?.contextTokens ?? DEFAULT_MAX_CONTEXT_TOKENS,
57
+ },
58
+ fallbacks: [...(model.fallbacks ?? [])],
59
+ traits: model.traits ?? [],
60
+ };
61
+ }
62
+ function normalizeTool(tool) {
63
+ return {
64
+ ...tool,
65
+ identity: toolIdentity(tool.id),
66
+ requiresConfirmation: tool.requiresConfirmation || tool.sideEffects === 'destructive',
67
+ traits: tool.traits ?? [],
68
+ };
69
+ }
70
+ function normalizePipeline(pipeline, inherited) {
71
+ return {
72
+ ...pipeline,
73
+ identity: pipelineIdentity(pipeline.id),
74
+ steps: pipeline.steps.map(normalizeStep),
75
+ errorPolicy: {
76
+ retries: pipeline.errorPolicy?.retries ?? 0,
77
+ fallback: pipeline.errorPolicy?.fallback,
78
+ deadLetter: pipeline.errorPolicy?.deadLetter,
79
+ },
80
+ observability: normalizeObservability(pipeline.observability, inherited.redact),
81
+ };
82
+ }
83
+ function normalizeStep(step) {
84
+ // The kinds that carry no `input` map: `rerank`, `guard` and `agent` are leaves with a
85
+ // scalar operand each, so materializing an empty `input` on them would emit a field the
86
+ // IR schema forbids.
87
+ if (step.kind === 'emit' ||
88
+ step.kind === 'retrieve' ||
89
+ step.kind === 'reduce' ||
90
+ step.kind === 'rerank' ||
91
+ step.kind === 'guard' ||
92
+ step.kind === 'agent') {
93
+ return step;
94
+ }
95
+ if (step.kind === 'branch') {
96
+ return {
97
+ ...step,
98
+ // biome-ignore lint/suspicious/noThenProperty: the branch shape names its taken arm `then`.
99
+ then: step.then.map(normalizeStep),
100
+ ...(step.else === undefined ? {} : { else: step.else.map(normalizeStep) }),
101
+ };
102
+ }
103
+ if (step.kind === 'parallel') {
104
+ return { ...step, branches: step.branches.map((arm) => arm.map(normalizeStep)) };
105
+ }
106
+ if (step.kind === 'map')
107
+ return { ...step, step: normalizeStep(step.step) };
108
+ return { ...step, input: step.input ?? {} };
109
+ }
110
+ function normalizeEval(evalShape) {
111
+ return {
112
+ ...evalShape,
113
+ dataset: { ...evalShape.dataset },
114
+ metrics: [...evalShape.metrics],
115
+ gate: {
116
+ ci: evalShape.gate.ci,
117
+ maxRegression: evalShape.gate.maxRegression ?? DEFAULT_EVAL_MAX_REGRESSION,
118
+ samples: evalShape.gate.samples ?? DEFAULT_EVAL_SAMPLES,
119
+ ...(evalShape.gate.minMean === undefined ? {} : { minMean: evalShape.gate.minMean }),
120
+ },
121
+ traits: evalShape.traits ?? [],
122
+ };
123
+ }
124
+ /**
125
+ * The dot-paths at which two IR values disagree, so the gate can say *which* default
126
+ * is missing rather than only that the IR differs from its normalization. Keys present
127
+ * on one side only are reported, which is how an unmaterialized default is caught.
128
+ */
129
+ export function diffPaths(before, after, path = []) {
130
+ if (before === after)
131
+ return [];
132
+ if (Array.isArray(before) && Array.isArray(after)) {
133
+ const length = Math.max(before.length, after.length);
134
+ const found = [];
135
+ for (let index = 0; index < length; index += 1) {
136
+ found.push(...diffPaths(before[index], after[index], [...path, index]));
137
+ }
138
+ return found;
139
+ }
140
+ if (isRecord(before) && isRecord(after)) {
141
+ const found = [];
142
+ for (const key of new Set([...Object.keys(before), ...Object.keys(after)])) {
143
+ found.push(...diffPaths(before[key], after[key], [...path, key]));
144
+ }
145
+ return found;
146
+ }
147
+ return path.length === 0 ? [] : [path.join('.')];
148
+ }
149
+ function isRecord(value) {
150
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
151
+ }
152
+ export function normalizeGate(ir, options) {
153
+ const diagnostics = [];
154
+ const report = reporter(options);
155
+ const normalized = normalize(ir);
156
+ const missing = diffPaths(ir, normalized);
157
+ if (missing.length > 0) {
158
+ diagnostics.push(report.error({
159
+ code: IR_DIAGNOSTIC_CODES.normalizationIncomplete,
160
+ message: `the normalize gate rejected this IR: ${missing.length} value(s) were left implicit for the generator to invent, at ${missing.join(', ')}`,
161
+ path: [],
162
+ hint: 'every default is materialized during the build, so a generator never supplies one',
163
+ }));
164
+ }
165
+ for (const model of normalized.models) {
166
+ checkModel(model, diagnostics, report);
167
+ }
168
+ for (const retriever of normalized.retrievers) {
169
+ checkRetriever(retriever, normalized, diagnostics, report);
170
+ }
171
+ return { diagnostics, suppressed: SUPPRESSED };
172
+ }
173
+ function checkModel(model, diagnostics, report) {
174
+ if (!PHASE_0_PROVIDERS.includes(model.provider)) {
175
+ diagnostics.push(report.error({
176
+ code: IR_DIAGNOSTIC_CODES.providerUnsupported,
177
+ message: `the normalize gate rejected this model: provider "${model.provider}" is not one of the providers Phase 0 serves (${PHASE_0_PROVIDERS.join(', ')})`,
178
+ path: ['models', model.id, 'provider'],
179
+ }));
180
+ }
181
+ const limit = model.limits?.maxOutputTokens ?? catalogModel(model.modelId)?.limits?.maxOutputTokens;
182
+ const requested = model.params?.maxTokens;
183
+ if (limit === undefined || requested === undefined || requested <= limit)
184
+ return;
185
+ diagnostics.push(report.error({
186
+ code: IR_DIAGNOSTIC_CODES.paramExceedsLimit,
187
+ message: `the normalize gate rejected these params: model "${model.id}" requests maxTokens ${requested}, above the catalog limit of ${limit}`,
188
+ path: ['models', model.id, 'params', 'maxTokens'],
189
+ hint: 'lower the request, or pin a model whose limits allow it',
190
+ }));
191
+ }
192
+ /**
193
+ * A retriever's declarations have to agree with the model that embeds for it, and with
194
+ * the metric vocabulary. Neither is a value a generator could resolve on its own: a
195
+ * store whose width differs from the embedder's holds vectors a runtime cannot index,
196
+ * and a metric outside the vocabulary names a distance no adapter computes.
197
+ *
198
+ * The dimension rule compares only when the embedding model's width is *known* -- which
199
+ * it is when the model appears in the offline catalog. With one side undeclared there is
200
+ * nothing to be inconsistent with, so the store's own declaration stands as the only
201
+ * claim in the IR.
202
+ */
203
+ function checkRetriever(retriever, ir, diagnostics, report) {
204
+ if (!isIndexMetric(retriever.index.metric)) {
205
+ diagnostics.push(report.error({
206
+ code: IR_DIAGNOSTIC_CODES.indexMetricUnknown,
207
+ message: `the normalize gate rejected this index: metric "${retriever.index.metric}" is not one of ${INDEX_METRICS.join(', ')}`,
208
+ path: ['retrievers', retriever.id, 'index', 'metric'],
209
+ hint: 'declare a metric from the vocabulary, or extend it deliberately',
210
+ }));
211
+ }
212
+ const embedding = ir.embeddings.find((entry) => entry.id === retriever.embedModel);
213
+ const store = ir.stores.find((entry) => entry.id === retriever.store);
214
+ if (embedding?.dimensions === undefined || store?.dimensions === undefined)
215
+ return;
216
+ if (embedding.dimensions === store.dimensions)
217
+ return;
218
+ diagnostics.push(report.error({
219
+ code: IR_DIAGNOSTIC_CODES.dimensionMismatch,
220
+ message: `the normalize gate rejected this store: "${store.id}" declares ${store.dimensions} dimensions, but embedding model "${embedding.id}" produces ${embedding.dimensions}`,
221
+ path: ['stores', store.id, 'dimensions'],
222
+ hint: "declare the store at the embedding model's width, or embed with a model that matches it",
223
+ }));
224
+ }
225
+ export function isNormalized(ir) {
226
+ return canonicalJson(ir) === canonicalJson(normalize(ir));
227
+ }
228
+ //# sourceMappingURL=normalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/gates/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAqB,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,eAAe,EAEf,aAAa,EAEb,aAAa,EAEb,aAAa,EAEb,iBAAiB,EAEjB,gBAAgB,EAChB,cAAc,EAId,YAAY,GACb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAqC,QAAQ,EAAwB,MAAM,eAAe,CAAC;AAElG,MAAM,UAAU,GAAsB,EAAE,CAAC;AAIzC;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,EAAM;IAC9B,MAAM,UAAU,GAAG,eAAe,CAAC,EAAE,CAAO,CAAC;IAC7C,MAAM,aAAa,GAAG,sBAAsB,CAC1C,UAAU,CAAC,aAAa,EACxB,cAAc,CAAC,UAAU,CAAC,CAC3B,CAAC;IAEF,UAAU,CAAC,aAAa,GAAG,aAAa,CAAC;IACzC,UAAU,CAAC,OAAO,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC;IACnE,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC1D,UAAU,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACvD,GAAG,MAAM;QACT,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC;QACnD,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;QAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;QAC/B,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,EAAE;QACnC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;QACzB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;KAC5B,CAAC,CAAC,CAAC;IACJ,UAAU,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACvD,UAAU,CAAC,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC3D,iBAAiB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAC3C,CAAC;IACF,UAAU,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAEvD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,sBAAsB,CAC7B,GAAmC,EACnC,SAA4B;IAE5B,OAAO;QACL,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,qBAAqB,CAAC,KAAK;QAChD,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,IAAI,SAAS,CAAC,CAAC;KACxC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,KAAiB;IACvC,OAAO;QACL,GAAG,KAAK;QACR,QAAQ,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,YAAY,EAAE,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC;QACrC,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE;QAC1B,MAAM,EAAE;YACN,GAAG,KAAK,CAAC,MAAM;YACf,aAAa,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa,IAAI,0BAA0B;SACzE;QACD,SAAS,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QACvC,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE;KAC3B,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,IAAe;IACpC,OAAO;QACL,GAAG,IAAI;QACP,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,oBAAoB,EAAE,IAAI,CAAC,oBAAoB,IAAI,IAAI,CAAC,WAAW,KAAK,aAAa;QACrF,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;KAC1B,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAuB,EAAE,SAA6B;IAC/E,OAAO;QACL,GAAG,QAAQ;QACX,QAAQ,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC;QACxC,WAAW,EAAE;YACX,OAAO,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,IAAI,CAAC;YAC3C,QAAQ,EAAE,QAAQ,CAAC,WAAW,EAAE,QAAQ;YACxC,UAAU,EAAE,QAAQ,CAAC,WAAW,EAAE,UAAU;SAC7C;QACD,aAAa,EAAE,sBAAsB,CAAC,QAAQ,CAAC,aAAa,EAAE,SAAS,CAAC,MAAM,CAAC;KAChF,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,IAAe;IACpC,uFAAuF;IACvF,wFAAwF;IACxF,qBAAqB;IACrB,IACE,IAAI,CAAC,IAAI,KAAK,MAAM;QACpB,IAAI,CAAC,IAAI,KAAK,UAAU;QACxB,IAAI,CAAC,IAAI,KAAK,QAAQ;QACtB,IAAI,CAAC,IAAI,KAAK,QAAQ;QACtB,IAAI,CAAC,IAAI,KAAK,OAAO;QACrB,IAAI,CAAC,IAAI,KAAK,OAAO,EACrB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO;YACL,GAAG,IAAI;YACP,4FAA4F;YAC5F,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC;YAClC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;SAC3E,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC7B,OAAO,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;IACnF,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC5E,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;AAC9C,CAAC;AAED,SAAS,aAAa,CAAC,SAAoB;IACzC,OAAO;QACL,GAAG,SAAS;QACZ,OAAO,EAAE,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE;QACjC,OAAO,EAAE,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC;QAC/B,IAAI,EAAE;YACJ,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE;YACrB,aAAa,EAAE,SAAS,CAAC,IAAI,CAAC,aAAa,IAAI,2BAA2B;YAC1E,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,IAAI,oBAAoB;YACvD,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;SACrF;QACD,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,EAAE;KAC/B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CACvB,MAAe,EACf,KAAc,EACd,IAAI,GAAwB,EAAE;IAE9B,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,EAAE,CAAC;IAChC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACxC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,GAAG,IAAI,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3E,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAM,EAAE,OAAoB;IACxD,MAAM,WAAW,GAAmB,EAAE,CAAC;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEjC,MAAM,UAAU,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,SAAS,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IAC1C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,WAAW,CAAC,IAAI,CACd,MAAM,CAAC,KAAK,CAAC;YACX,IAAI,EAAE,mBAAmB,CAAC,uBAAuB;YACjD,OAAO,EAAE,wCAAwC,OAAO,CAAC,MAAM,gEAAgE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACnJ,IAAI,EAAE,EAAE;YACR,IAAI,EAAE,mFAAmF;SAC1F,CAAC,CACH,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACtC,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QAC9C,cAAc,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC;AACjD,CAAC;AAED,SAAS,UAAU,CAAC,KAAiB,EAAE,WAA2B,EAAE,MAAgB;IAClF,IAAI,CAAE,iBAAuC,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvE,WAAW,CAAC,IAAI,CACd,MAAM,CAAC,KAAK,CAAC;YACX,IAAI,EAAE,mBAAmB,CAAC,mBAAmB;YAC7C,OAAO,EAAE,qDAAqD,KAAK,CAAC,QAAQ,iDAAiD,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YAC5J,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,UAAU,CAAC;SACvC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GACT,KAAK,CAAC,MAAM,EAAE,eAAe,IAAI,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC;IACxF,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC;IAC1C,IAAI,KAAK,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,IAAI,KAAK;QAAE,OAAO;IACjF,WAAW,CAAC,IAAI,CACd,MAAM,CAAC,KAAK,CAAC;QACX,IAAI,EAAE,mBAAmB,CAAC,iBAAiB;QAC3C,OAAO,EAAE,oDAAoD,KAAK,CAAC,EAAE,wBAAwB,SAAS,gCAAgC,KAAK,EAAE;QAC7I,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC;QACjD,IAAI,EAAE,yDAAyD;KAChE,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,cAAc,CACrB,SAAyB,EACzB,EAAM,EACN,WAA2B,EAC3B,MAAgB;IAEhB,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3C,WAAW,CAAC,IAAI,CACd,MAAM,CAAC,KAAK,CAAC;YACX,IAAI,EAAE,mBAAmB,CAAC,kBAAkB;YAC5C,OAAO,EAAE,mDAAmD,SAAS,CAAC,KAAK,CAAC,MAAM,mBAAmB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC/H,IAAI,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC;YACrD,IAAI,EAAE,iEAAiE;SACxE,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,SAAS,CAAC,UAAU,CAAC,CAAC;IACnF,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC;IACtE,IAAI,SAAS,EAAE,UAAU,KAAK,SAAS,IAAI,KAAK,EAAE,UAAU,KAAK,SAAS;QAAE,OAAO;IACnF,IAAI,SAAS,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU;QAAE,OAAO;IACtD,WAAW,CAAC,IAAI,CACd,MAAM,CAAC,KAAK,CAAC;QACX,IAAI,EAAE,mBAAmB,CAAC,iBAAiB;QAC3C,OAAO,EAAE,4CAA4C,KAAK,CAAC,EAAE,cAAc,KAAK,CAAC,UAAU,qCAAqC,SAAS,CAAC,EAAE,cAAc,SAAS,CAAC,UAAU,EAAE;QAChL,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,YAAY,CAAC;QACxC,IAAI,EAAE,yFAAyF;KAChG,CAAC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAAM;IACjC,OAAO,aAAa,CAAC,EAAE,CAAC,KAAK,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Orchestration — one gate, `orchestration/deepagents`.
3
+ *
4
+ * An agent that delegates its loop to a framework is a different kind of dependency
5
+ * from one AID runs itself: the framework's behaviour is no longer described by the
6
+ * IR, so the version has to be pinned in the spec or the build is not reproducible, and
7
+ * the loop has to be able to call tools or the framework has nothing to drive. Both
8
+ * failures are cheap to state and expensive to discover, so neither is a warning.
9
+ *
10
+ * The gate reads the model's declared capability rather than a catalog: a model whose
11
+ * capability set lives in the IR is what the capability gate negotiates with, and the
12
+ * two must not disagree.
13
+ */
14
+ import type { IR } from '../shapes.js';
15
+ import { type GateOptions, type GateResult } from './contract.js';
16
+ export declare function orchestrationDeepagentsGate(ir: IR, options: GateOptions): GateResult;
17
+ //# sourceMappingURL=orchestration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestration.d.ts","sourceRoot":"","sources":["../../src/gates/orchestration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAA6B,MAAM,eAAe,CAAC;AAE7F,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,UAAU,CAkCpF"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Orchestration — one gate, `orchestration/deepagents`.
3
+ *
4
+ * An agent that delegates its loop to a framework is a different kind of dependency
5
+ * from one AID runs itself: the framework's behaviour is no longer described by the
6
+ * IR, so the version has to be pinned in the spec or the build is not reproducible, and
7
+ * the loop has to be able to call tools or the framework has nothing to drive. Both
8
+ * failures are cheap to state and expensive to discover, so neither is a warning.
9
+ *
10
+ * The gate reads the model's declared capability rather than a catalog: a model whose
11
+ * capability set lives in the IR is what the capability gate negotiates with, and the
12
+ * two must not disagree.
13
+ */
14
+ import { IR_DIAGNOSTIC_CODES } from '../diagnostics.js';
15
+ import { NO_SUPPRESSIONS, reporter } from './contract.js';
16
+ export function orchestrationDeepagentsGate(ir, options) {
17
+ const diagnostics = [];
18
+ const report = reporter(options);
19
+ const models = new Map(ir.models.map((model) => [model.id, model]));
20
+ for (const agent of ir.agents) {
21
+ if (agent.engine !== 'deepagents')
22
+ continue;
23
+ if (agent.engineVersion === undefined || agent.engineVersion.trim() === '') {
24
+ diagnostics.push(report.error({
25
+ code: IR_DIAGNOSTIC_CODES.orchestrationDeepagents,
26
+ message: `the orchestration gate rejected "${agent.id}": engine is "deepagents" but no engineVersion is pinned, so the generated app would depend on whatever the framework resolves to`,
27
+ path: ['agents', agent.id, 'engineVersion'],
28
+ hint: 'pin the framework version in engineVersion',
29
+ }));
30
+ }
31
+ const model = models.get(agent.model);
32
+ // An unresolved model is `agents/refs-resolve`'s diagnostic; do not double-report.
33
+ if (model === undefined)
34
+ continue;
35
+ if (model.capabilities.includes('tool-calling'))
36
+ continue;
37
+ diagnostics.push(report.error({
38
+ code: IR_DIAGNOSTIC_CODES.orchestrationDeepagents,
39
+ message: `the orchestration gate rejected "${agent.id}": engine "deepagents" drives a tool-calling loop, but its model "${model.id}" does not declare the "tool-calling" capability`,
40
+ path: ['agents', agent.id, 'model'],
41
+ hint: 'bind a model that declares tool-calling, or use engine: native',
42
+ }));
43
+ }
44
+ return { diagnostics, suppressed: NO_SUPPRESSIONS };
45
+ }
46
+ //# sourceMappingURL=orchestration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestration.js","sourceRoot":"","sources":["../../src/gates/orchestration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,mBAAmB,EAAqB,MAAM,mBAAmB,CAAC;AAE3E,OAAO,EAAqC,eAAe,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE7F,MAAM,UAAU,2BAA2B,CAAC,EAAM,EAAE,OAAoB;IACtE,MAAM,WAAW,GAAmB,EAAE,CAAC;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAEpE,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY;YAAE,SAAS;QAE5C,IAAI,KAAK,CAAC,aAAa,KAAK,SAAS,IAAI,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3E,WAAW,CAAC,IAAI,CACd,MAAM,CAAC,KAAK,CAAC;gBACX,IAAI,EAAE,mBAAmB,CAAC,uBAAuB;gBACjD,OAAO,EAAE,oCAAoC,KAAK,CAAC,EAAE,mIAAmI;gBACxL,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,eAAe,CAAC;gBAC3C,IAAI,EAAE,4CAA4C;aACnD,CAAC,CACH,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtC,mFAAmF;QACnF,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,IAAI,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,cAAc,CAAC;YAAE,SAAS;QAC1D,WAAW,CAAC,IAAI,CACd,MAAM,CAAC,KAAK,CAAC;YACX,IAAI,EAAE,mBAAmB,CAAC,uBAAuB;YACjD,OAAO,EAAE,oCAAoC,KAAK,CAAC,EAAE,qEAAqE,KAAK,CAAC,EAAE,kDAAkD;YACpL,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC;YACnC,IAAI,EAAE,gEAAgE;SACvE,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC;AACtD,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Gate 1 — referential integrity (§7.1).
3
+ *
4
+ * Every reference resolves, and resolves to the right *kind*: a `tool` step naming
5
+ * a prompt is an error, not a lookup miss. Bindings are defined before use and
6
+ * unique within one pipeline scope, prompt placeholders and variables agree, and
7
+ * a model's fallback chain terminates.
8
+ */
9
+ import type { IR } from '../shapes.js';
10
+ import { type GateOptions, type GateResult } from './contract.js';
11
+ export declare function referentialGate(ir: IR, options: GateOptions): GateResult;
12
+ //# sourceMappingURL=referential.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"referential.d.ts","sourceRoot":"","sources":["../../src/gates/referential.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,EAAE,EAAqD,MAAM,cAAc,CAAC;AAC1F,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAkC,MAAM,eAAe,CAAC;AAkClG,wBAAgB,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,UAAU,CA0BxE"}