@aid-framework/ir 0.0.0 → 0.1.48

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 +199 -0
  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 +44 -14
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Gate 4 — cost.
3
+ *
4
+ * Cost profiles are resolved from the offline catalog in `src/catalog/models.json`, so
5
+ * an estimate is deterministic and reproducible on a machine with no network. The gate
6
+ * fails *closed* on an unpriced model that someone declared a budget for: an unpriced
7
+ * model cannot be shown to fit a budget, and silently assuming it does is the failure
8
+ * mode this gate exists to prevent.
9
+ *
10
+ * A retrieval path is not free by omission: the candidate chunks a retriever materialises
11
+ * are charged to the model that embeds them, so a retriever with a wide `topK` over large
12
+ * chunks shows up in the estimate and can exceed a declared budget on its own.
13
+ */
14
+ import { catalogCostProfile } from '../catalog/index.js';
15
+ import { IR_DIAGNOSTIC_CODES } from '../diagnostics.js';
16
+ import { reporter } from './contract.js';
17
+ const SUPPRESSED = [];
18
+ /** Rough tokens-per-character for a natural-language prompt. Fixed, so estimates compare. */
19
+ const CHARS_PER_TOKEN = 4;
20
+ /** Output tokens assumed when neither the params nor the catalog bound them. */
21
+ const DEFAULT_OUTPUT_TOKENS = 512;
22
+ export function costGate(ir, options) {
23
+ const diagnostics = [];
24
+ const report = reporter(options);
25
+ for (const evalShape of ir.evals) {
26
+ const estimate = estimateEvalCost(ir, evalShape);
27
+ if (estimate.models.length === 0)
28
+ continue;
29
+ if (estimate.cost === undefined) {
30
+ const unpriced = estimate.models.filter((model) => model.cost === undefined);
31
+ const named = unpriced.map((model) => model.model).join(', ');
32
+ if (estimate.budget !== undefined) {
33
+ diagnostics.push(report.error({
34
+ code: IR_DIAGNOSTIC_CODES.costProfileUnknown,
35
+ message: `the cost gate rejected this eval: "${evalShape.id}" declares a budget of ${estimate.budget}, but the costProfile of ${named} is unknown, so the budget cannot be enforced`,
36
+ path: ['evals', evalShape.id, 'metrics'],
37
+ hint: 'add the model to src/catalog/models.json, set models.<alias>.costProfile, or drop the budget',
38
+ }));
39
+ }
40
+ else {
41
+ diagnostics.push(report.warn({
42
+ code: IR_DIAGNOSTIC_CODES.costProfileUnknown,
43
+ message: `the cost gate could not price this eval: the costProfile of ${named} is unknown, so "${evalShape.id}" has no cost estimate`,
44
+ path: ['evals', evalShape.id, 'target'],
45
+ hint: 'add the model to src/catalog/models.json, or set models.<alias>.costProfile',
46
+ }));
47
+ }
48
+ continue;
49
+ }
50
+ if (estimate.budget === undefined || estimate.cost <= estimate.budget)
51
+ continue;
52
+ diagnostics.push(report.warn({
53
+ code: IR_DIAGNOSTIC_CODES.costBudgetExceeded,
54
+ message: `the cost gate flagged this eval: "${evalShape.id}" is estimated at ${estimate.cost.toFixed(6)} per run, above its declared budget of ${estimate.budget}`,
55
+ path: ['evals', evalShape.id, 'metrics'],
56
+ hint: 'raise the budget, shorten the prompt, or cap maxTokens',
57
+ }));
58
+ }
59
+ return { diagnostics, suppressed: SUPPRESSED };
60
+ }
61
+ /**
62
+ * The estimated per-run cost of one eval target: the sum over the models on the
63
+ * target's path of its prompt tokens and its bounded output tokens, plus the work the
64
+ * target's retrievers do.
65
+ */
66
+ export function estimateEvalCost(ir, evalShape) {
67
+ const prompts = new Map(ir.prompts.map((prompt) => [prompt.id, prompt]));
68
+ const models = new Map(ir.models.map((model) => [model.id, model]));
69
+ const used = promptsForTarget(ir, evalShape, prompts);
70
+ const budget = evalShape.costBudget;
71
+ const estimates = new Map();
72
+ for (const prompt of used) {
73
+ const model = models.get(prompt.model);
74
+ if (model === undefined)
75
+ continue;
76
+ addEstimate(estimates, model, Math.ceil(prompt.template.length / CHARS_PER_TOKEN), model.params?.maxTokens ?? model.limits?.maxOutputTokens ?? DEFAULT_OUTPUT_TOKENS);
77
+ }
78
+ for (const part of retrievalParts(ir, evalShape, models)) {
79
+ addEstimate(estimates, part.model, part.inputTokens, 0);
80
+ }
81
+ const parts = [...estimates.values()].sort((left, right) => left.model < right.model ? -1 : left.model > right.model ? 1 : 0);
82
+ const inputTokens = parts.reduce((total, part) => total + part.inputTokens, 0);
83
+ const outputTokens = parts.reduce((total, part) => total + part.outputTokens, 0);
84
+ const priced = parts.every((part) => part.cost !== undefined);
85
+ const result = { inputTokens, outputTokens, models: parts };
86
+ if (priced) {
87
+ result.cost = parts.reduce((total, part) => total + (part.cost ?? 0), 0);
88
+ }
89
+ if (budget !== undefined)
90
+ result.budget = budget;
91
+ return result;
92
+ }
93
+ function addEstimate(estimates, model, inputTokens, outputTokens) {
94
+ const existing = estimates.get(model.id);
95
+ if (existing === undefined) {
96
+ estimates.set(model.id, {
97
+ model: model.id,
98
+ inputTokens,
99
+ outputTokens,
100
+ cost: priceRun(model, inputTokens, outputTokens),
101
+ });
102
+ return;
103
+ }
104
+ existing.inputTokens += inputTokens;
105
+ existing.outputTokens += outputTokens;
106
+ existing.cost = priceRun(model, existing.inputTokens, existing.outputTokens);
107
+ }
108
+ function priceRun(model, inputTokens, outputTokens) {
109
+ const profile = modelProfile(model);
110
+ if (profile === undefined)
111
+ return undefined;
112
+ return ((inputTokens / 1_000_000) * profile.inputPerMTok +
113
+ (outputTokens / 1_000_000) * profile.outputPerMTok);
114
+ }
115
+ function modelProfile(model) {
116
+ return model.costProfile ?? catalogCostProfile(model.modelId, model.costProfileId)?.profile;
117
+ }
118
+ /**
119
+ * The per-run work a target's retrievers do: a retriever materialises `topK` candidate
120
+ * chunks, and each chunk is `chunking.size` characters, so the candidate set is
121
+ * `topK * ceil(size / CHARS_PER_TOKEN)` tokens. Those tokens are charged to the
122
+ * retriever's embedding model -- the model that produces them -- and not again to the
123
+ * generation model, whose estimate prices its prompt template.
124
+ *
125
+ * A reranker is charged only when its model is *modelled*: a model the catalog prices,
126
+ * or one the spec gives a costProfile. Phase 1 ships a deterministic lexical reranker
127
+ * that costs nothing to run, so charging an unpriced reranker would fail a declared
128
+ * budget closed on a model that has no rate to exceed it.
129
+ */
130
+ function retrievalParts(ir, evalShape, models) {
131
+ const parts = [];
132
+ for (const step of stepsForTarget(ir, evalShape)) {
133
+ if (step.kind !== 'retrieve')
134
+ continue;
135
+ const retriever = ir.retrievers.find((entry) => entry.id === step.retriever);
136
+ if (retriever === undefined)
137
+ continue;
138
+ const inputTokens = retriever.topK * Math.ceil(retriever.chunking.size / CHARS_PER_TOKEN);
139
+ const embedModel = models.get(retriever.embedModel);
140
+ if (embedModel !== undefined)
141
+ parts.push({ model: embedModel, inputTokens });
142
+ const rerankModel = retriever.rerank === undefined ? undefined : models.get(retriever.rerank.model);
143
+ if (rerankModel !== undefined && modelProfile(rerankModel) !== undefined) {
144
+ parts.push({ model: rerankModel, inputTokens });
145
+ }
146
+ }
147
+ return parts;
148
+ }
149
+ /** The steps of the pipeline an eval target names, or none for a prompt target. */
150
+ function stepsForTarget(ir, evalShape) {
151
+ if (evalShape.target.kind === 'prompt')
152
+ return [];
153
+ const pipeline = ir.pipelines.find((entry) => entry.id === evalShape.target.id);
154
+ return pipeline === undefined ? [] : pipeline.steps;
155
+ }
156
+ function promptsForTarget(ir, evalShape, prompts) {
157
+ const found = [];
158
+ for (const step of stepsForTarget(ir, evalShape)) {
159
+ if (step.kind !== 'generate')
160
+ continue;
161
+ const prompt = prompts.get(step.prompt);
162
+ if (prompt !== undefined)
163
+ found.push(prompt);
164
+ }
165
+ return found;
166
+ }
167
+ //# sourceMappingURL=cost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost.js","sourceRoot":"","sources":["../../src/gates/cost.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Deployment — one gate, `deploy/streaming`.
3
+ *
4
+ * A deployment that asks for streaming asks for something a target can only honour if
5
+ * it declares the capability. The Python `ModelGateway.stream()` produces SSE bytes
6
+ * (Phase 2 L5) and the py-fastapi generator now emits a `text/event-stream` branch on
7
+ * the pipeline route (P7a), so py-fastapi declares `streaming` and this gate passes for
8
+ * it. The TypeScript gateway still raises `FeatureDeferredError` (ratified L6), so the
9
+ * TypeScript target still declares nothing and still fails closed here.
10
+ *
11
+ * The decision is read from the injected declarations rather than hard-coded, which is
12
+ * what keeps the gate honest in both directions: it fails while a target has no
13
+ * streaming route, and it passes only once that target actually declares the capability
14
+ * -- declaring it is what removes the false declaration this layer exists to catch
15
+ * (defect D-1).
16
+ *
17
+ * The check covers every configured target: a project that generates for two targets
18
+ * and asks for streaming must not ship a deployment one of them silently cannot serve.
19
+ */
20
+ import type { IR } from '../shapes.js';
21
+ import { type GateOptions, type GateResult } from './contract.js';
22
+ export declare function deployStreamingGate(ir: IR, options: GateOptions): GateResult;
23
+ //# sourceMappingURL=deploy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/gates/deploy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAA6B,MAAM,eAAe,CAAC;AAE7F,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,UAAU,CAuB5E"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Deployment — one gate, `deploy/streaming`.
3
+ *
4
+ * A deployment that asks for streaming asks for something a target can only honour if
5
+ * it declares the capability. The Python `ModelGateway.stream()` produces SSE bytes
6
+ * (Phase 2 L5) and the py-fastapi generator now emits a `text/event-stream` branch on
7
+ * the pipeline route (P7a), so py-fastapi declares `streaming` and this gate passes for
8
+ * it. The TypeScript gateway still raises `FeatureDeferredError` (ratified L6), so the
9
+ * TypeScript target still declares nothing and still fails closed here.
10
+ *
11
+ * The decision is read from the injected declarations rather than hard-coded, which is
12
+ * what keeps the gate honest in both directions: it fails while a target has no
13
+ * streaming route, and it passes only once that target actually declares the capability
14
+ * -- declaring it is what removes the false declaration this layer exists to catch
15
+ * (defect D-1).
16
+ *
17
+ * The check covers every configured target: a project that generates for two targets
18
+ * and asks for streaming must not ship a deployment one of them silently cannot serve.
19
+ */
20
+ import { resolveRequiredCapability } from '../capabilities.js';
21
+ import { IR_DIAGNOSTIC_CODES } from '../diagnostics.js';
22
+ import { NO_SUPPRESSIONS, reporter } from './contract.js';
23
+ export function deployStreamingGate(ir, options) {
24
+ const diagnostics = [];
25
+ const report = reporter(options);
26
+ for (const deployment of ir.deployments) {
27
+ if (!deployment.streaming)
28
+ continue;
29
+ const unable = ir.project.targets.filter((target) => {
30
+ const declared = options.targetCapabilities[target] ?? [];
31
+ return !declared.some((entry) => resolveRequiredCapability(entry) === 'streaming');
32
+ });
33
+ if (unable.length === 0)
34
+ continue;
35
+ diagnostics.push(report.error({
36
+ code: IR_DIAGNOSTIC_CODES.deployStreaming,
37
+ message: `the deploy gate rejected "${deployment.id}": it requests streaming, but ${unable.map((target) => `"${target}"`).join(', ')} ${unable.length === 1 ? 'does' : 'do'} not declare the "streaming" capability`,
38
+ path: ['deployments', deployment.id, 'streaming'],
39
+ hint: 'set streaming: false until a target implements it, or generate for a target that declares it',
40
+ }));
41
+ }
42
+ return { diagnostics, suppressed: NO_SUPPRESSIONS };
43
+ }
44
+ //# sourceMappingURL=deploy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/gates/deploy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAqB,MAAM,mBAAmB,CAAC;AAE3E,OAAO,EAAqC,eAAe,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE7F,MAAM,UAAU,mBAAmB,CAAC,EAAM,EAAE,OAAoB;IAC9D,MAAM,WAAW,GAAmB,EAAE,CAAC;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEjC,KAAK,MAAM,UAAU,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACxC,IAAI,CAAC,UAAU,CAAC,SAAS;YAAE,SAAS;QACpC,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE;YAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC1D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,yBAAyB,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,CAAC;QACrF,CAAC,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAElC,WAAW,CAAC,IAAI,CACd,MAAM,CAAC,KAAK,CAAC;YACX,IAAI,EAAE,mBAAmB,CAAC,eAAe;YACzC,OAAO,EAAE,6BAA6B,UAAU,CAAC,EAAE,iCAAiC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,yCAAyC;YACpN,IAAI,EAAE,CAAC,aAAa,EAAE,UAAU,CAAC,EAAE,EAAE,WAAW,CAAC;YACjD,IAAI,EAAE,8FAA8F;SACrG,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC;AACtD,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Gate 6 — eval coverage.
3
+ *
4
+ * A pipeline Phase 0 actually serves and that no CI-gating eval covers is a warning,
5
+ * not an error: a partially evaluated app is legitimate, a *silently* uncovered
6
+ * endpoint is not.
7
+ */
8
+ import type { IR } from '../shapes.js';
9
+ import { type GateOptions, type GateResult } from './contract.js';
10
+ export declare function evalCoverageGate(ir: IR, options: GateOptions): GateResult;
11
+ //# sourceMappingURL=eval-coverage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-coverage.d.ts","sourceRoot":"","sources":["../../src/gates/eval-coverage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAkC,MAAM,eAAe,CAAC;AAMlG,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,UAAU,CAyBzE"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Gate 6 — eval coverage.
3
+ *
4
+ * A pipeline Phase 0 actually serves and that no CI-gating eval covers is a warning,
5
+ * not an error: a partially evaluated app is legitimate, a *silently* uncovered
6
+ * endpoint is not.
7
+ */
8
+ import { IR_DIAGNOSTIC_CODES } from '../diagnostics.js';
9
+ import { reporter } from './contract.js';
10
+ const SUPPRESSED = [];
11
+ export function evalCoverageGate(ir, options) {
12
+ const diagnostics = [];
13
+ const report = reporter(options);
14
+ const covered = new Set(ir.evals
15
+ .filter((evalShape) => evalShape.gate.ci && evalShape.target.kind === 'pipeline')
16
+ .map((evalShape) => evalShape.target.id));
17
+ for (const pipeline of ir.pipelines) {
18
+ if (pipeline.trigger.kind !== 'http' || covered.has(pipeline.id))
19
+ continue;
20
+ diagnostics.push(report.warn({
21
+ code: IR_DIAGNOSTIC_CODES.evalUncovered,
22
+ message: `the eval-coverage gate flagged this pipeline: "${pipeline.id}" is served over HTTP but no eval with gate.ci: true targets it`,
23
+ path: ['pipelines', pipeline.id],
24
+ hint: `add an eval targeting "pipeline:${pipeline.id}" and set gate.ci: true`,
25
+ }));
26
+ }
27
+ checkRetrievalCoverage(ir, diagnostics, report);
28
+ return { diagnostics, suppressed: SUPPRESSED };
29
+ }
30
+ /**
31
+ * A retrieval surface with no retrieval metric is unmeasured: an `exact-match` eval says
32
+ * nothing about whether the right chunks were retrieved, because it only sees the answer
33
+ * that retrieval fed into. The rule is spec-wide rather than per-retriever because a
34
+ * `retrieval` metric names no retriever -- it asserts what a query should bring back.
35
+ */
36
+ function checkRetrievalCoverage(ir, diagnostics, report) {
37
+ if (ir.retrievers.length === 0)
38
+ return;
39
+ const measured = ir.evals.some((evalShape) => evalShape.metrics.some((metric) => metric.kind === 'retrieval'));
40
+ if (measured)
41
+ return;
42
+ const names = ir.retrievers.map((retriever) => retriever.id).join(', ');
43
+ diagnostics.push(report.warn({
44
+ code: IR_DIAGNOSTIC_CODES.evalUncovered,
45
+ message: `the eval-coverage gate flagged this retrieval surface: the IR declares the retriever(s) ${names} but no eval carries a "retrieval" metric, so nothing measures what they retrieve`,
46
+ path: ['retrievers'],
47
+ hint: 'add an eval with a metric of kind "retrieval", and gate it in CI so the measurement runs',
48
+ }));
49
+ }
50
+ //# sourceMappingURL=eval-coverage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-coverage.js","sourceRoot":"","sources":["../../src/gates/eval-coverage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,mBAAmB,EAAqB,MAAM,mBAAmB,CAAC;AAE3E,OAAO,EAAqC,QAAQ,EAAwB,MAAM,eAAe,CAAC;AAElG,MAAM,UAAU,GAAsB,EAAE,CAAC;AAIzC,MAAM,UAAU,gBAAgB,CAAC,EAAM,EAAE,OAAoB;IAC3D,MAAM,WAAW,GAAmB,EAAE,CAAC;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEjC,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,EAAE,CAAC,KAAK;SACL,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,SAAS,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC;SAChF,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAC3C,CAAC;IAEF,KAAK,MAAM,QAAQ,IAAI,EAAE,CAAC,SAAS,EAAE,CAAC;QACpC,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAAE,SAAS;QAC3E,WAAW,CAAC,IAAI,CACd,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,mBAAmB,CAAC,aAAa;YACvC,OAAO,EAAE,kDAAkD,QAAQ,CAAC,EAAE,iEAAiE;YACvI,IAAI,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,CAAC;YAChC,IAAI,EAAE,mCAAmC,QAAQ,CAAC,EAAE,yBAAyB;SAC9E,CAAC,CACH,CAAC;IACJ,CAAC;IAED,sBAAsB,CAAC,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IAEhD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC;AACjD,CAAC;AAED;;;;;GAKG;AACH,SAAS,sBAAsB,CAAC,EAAM,EAAE,WAA2B,EAAE,MAAgB;IACnF,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACvC,MAAM,QAAQ,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAC3C,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,WAAW,CAAC,CAChE,CAAC;IACF,IAAI,QAAQ;QAAE,OAAO;IACrB,MAAM,KAAK,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxE,WAAW,CAAC,IAAI,CACd,MAAM,CAAC,IAAI,CAAC;QACV,IAAI,EAAE,mBAAmB,CAAC,aAAa;QACvC,OAAO,EAAE,2FAA2F,KAAK,mFAAmF;QAC5L,IAAI,EAAE,CAAC,YAAY,CAAC;QACpB,IAAI,EAAE,0FAA0F;KACjG,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Guardrails — two gates.
3
+ *
4
+ * `guardrails/coverage`: a tool that writes or destroys must reach a guardrail stage
5
+ * that can inspect the call before it happens. The check is conditional on the IR
6
+ * declaring at least one guardrail, and that condition is reported as a suppressed
7
+ * check rather than left implicit. The suppression covers two different populations,
8
+ * and since v0.2 exists it is no longer accurate to describe them as one: a 0.1 spec
9
+ * predates the section and cannot opt in at all, while a 0.2 spec that declares none
10
+ * has made a choice. Neither can be enforced here, because no Phase 2 L1 runtime
11
+ * evaluates a policy — demanding the declaration would be unbuildable rather than
12
+ * fail-closed, and calling that "enforced" would be the same false assurance as
13
+ * suppressing it silently.
14
+ *
15
+ * `guardrails/policies`: the closed policy vocabulary is re-checked here because the IR
16
+ * is a published contract a non-TypeScript producer can write directly, plus the two
17
+ * rules the schema deliberately leaves to this layer — a `redact` action must name what
18
+ * it redacts, and a guardrail may only cover tools that exist.
19
+ */
20
+ import { type IR } from '../shapes.js';
21
+ import { type GateOptions, type GateResult } from './contract.js';
22
+ export declare function guardrailCoverageGate(ir: IR, options: GateOptions): GateResult;
23
+ export declare function guardrailPolicyGate(ir: IR, options: GateOptions): GateResult;
24
+ //# sourceMappingURL=guardrails.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardrails.d.ts","sourceRoot":"","sources":["../../src/gates/guardrails.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAA0B,KAAK,EAAE,EAAyB,MAAM,cAAc,CAAC;AACtF,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,UAAU,EAIhB,MAAM,eAAe,CAAC;AAUvB,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,UAAU,CAwB9E;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,UAAU,CAyE5E"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Guardrails — two gates.
3
+ *
4
+ * `guardrails/coverage`: a tool that writes or destroys must reach a guardrail stage
5
+ * that can inspect the call before it happens. The check is conditional on the IR
6
+ * declaring at least one guardrail, and that condition is reported as a suppressed
7
+ * check rather than left implicit. The suppression covers two different populations,
8
+ * and since v0.2 exists it is no longer accurate to describe them as one: a 0.1 spec
9
+ * predates the section and cannot opt in at all, while a 0.2 spec that declares none
10
+ * has made a choice. Neither can be enforced here, because no Phase 2 L1 runtime
11
+ * evaluates a policy — demanding the declaration would be unbuildable rather than
12
+ * fail-closed, and calling that "enforced" would be the same false assurance as
13
+ * suppressing it silently.
14
+ *
15
+ * `guardrails/policies`: the closed policy vocabulary is re-checked here because the IR
16
+ * is a published contract a non-TypeScript producer can write directly, plus the two
17
+ * rules the schema deliberately leaves to this layer — a `redact` action must name what
18
+ * it redacts, and a guardrail may only cover tools that exist.
19
+ */
20
+ import { IR_DIAGNOSTIC_CODES } from '../diagnostics.js';
21
+ import { GUARDRAIL_POLICY_KINDS, isGuardrailPolicyKind } from '../shapes.js';
22
+ import { NO_SUPPRESSIONS, reporter, } from './contract.js';
23
+ const SUPPRESSED = [
24
+ {
25
+ check: 'guardrails/coverage-without-declaration',
26
+ reason: 'Whether a spec that declares no guardrail at all should still be required to add one is a decision for the guardrails engine layer (design §7.4): no Phase 2 L1 runtime evaluates a policy, so requiring a declaration here would protect nothing. It would also fail two different populations for different reasons — a 0.1 spec predates the section and cannot opt in at all, while a 0.2 spec that declares none has made a choice this layer cannot yet enforce. What this layer can decide — that a declared guardrail actually covers the side-effecting tools it exists for — is enforced below.',
27
+ },
28
+ ];
29
+ export function guardrailCoverageGate(ir, options) {
30
+ const diagnostics = [];
31
+ const report = reporter(options);
32
+ if (ir.guardrails.length === 0)
33
+ return { diagnostics, suppressed: SUPPRESSED };
34
+ for (const tool of ir.tools) {
35
+ if (tool.sideEffects !== 'write' && tool.sideEffects !== 'destructive')
36
+ continue;
37
+ const covered = ir.guardrails.some((guardrail) => guardrail.stages.includes('tool-call') &&
38
+ (guardrail.tools.length === 0 || guardrail.tools.includes(tool.id)));
39
+ if (covered)
40
+ continue;
41
+ diagnostics.push(report.error({
42
+ code: IR_DIAGNOSTIC_CODES.guardrailCoverage,
43
+ message: `the guardrails gate rejected "${tool.id}": the tool has sideEffects "${tool.sideEffects}" but no declared guardrail covers it at the "tool-call" stage`,
44
+ path: ['tools', tool.id, 'sideEffects'],
45
+ hint: `add a guardrail with stages: [tool-call] whose tools list is empty or names "${tool.id}"`,
46
+ }));
47
+ }
48
+ return { diagnostics, suppressed: SUPPRESSED };
49
+ }
50
+ export function guardrailPolicyGate(ir, options) {
51
+ const diagnostics = [];
52
+ const report = reporter(options);
53
+ const tools = new Set(ir.tools.map((tool) => tool.id));
54
+ const prompts = new Set(ir.prompts.map((prompt) => prompt.id));
55
+ for (const guardrail of ir.guardrails) {
56
+ if (guardrail.stages.length === 0) {
57
+ diagnostics.push(report.error({
58
+ code: IR_DIAGNOSTIC_CODES.guardrailPolicy,
59
+ message: `the guardrails gate rejected "${guardrail.id}": it declares no stage, so no runtime could ever invoke it`,
60
+ path: ['guardrails', guardrail.id, 'stages'],
61
+ hint: 'name at least one of input, output, retrieval, tool-call',
62
+ }));
63
+ }
64
+ if (guardrail.policies.length === 0) {
65
+ diagnostics.push(report.error({
66
+ code: IR_DIAGNOSTIC_CODES.policyEmpty,
67
+ message: `the guardrails gate rejected "${guardrail.id}": it declares no policy, so there is nothing for the stage to evaluate`,
68
+ path: ['guardrails', guardrail.id, 'policies'],
69
+ hint: `name one of ${GUARDRAIL_POLICY_KINDS.join(', ')}`,
70
+ }));
71
+ }
72
+ guardrail.policies.forEach((policy, index) => {
73
+ if (isGuardrailPolicyKind(policy))
74
+ return;
75
+ diagnostics.push(report.error({
76
+ code: IR_DIAGNOSTIC_CODES.guardrailPolicy,
77
+ message: `the guardrails gate rejected "${guardrail.id}": policy "${policy}" is not in the closed vocabulary (${GUARDRAIL_POLICY_KINDS.join(', ')})`,
78
+ path: ['guardrails', guardrail.id, 'policies', index],
79
+ hint: 'name a policy the guardrails engine implements, or extend the vocabulary deliberately',
80
+ }));
81
+ });
82
+ if (guardrail.action === 'redact' && guardrail.redact.length === 0) {
83
+ diagnostics.push(report.error({
84
+ code: IR_DIAGNOSTIC_CODES.guardrailPolicy,
85
+ message: `the guardrails gate rejected "${guardrail.id}": action is "redact" but it names no field to redact, so the action cannot be executed or tested`,
86
+ path: ['guardrails', guardrail.id, 'redact'],
87
+ hint: 'list the field names the redaction removes',
88
+ }));
89
+ }
90
+ guardrail.tools.forEach((tool, index) => {
91
+ if (tools.has(tool))
92
+ return;
93
+ diagnostics.push(report.error({
94
+ code: IR_DIAGNOSTIC_CODES.guardrailPolicy,
95
+ message: `the guardrails gate rejected "${guardrail.id}": tools names "${tool}", which is not a declared tool`,
96
+ path: ['guardrails', guardrail.id, 'tools', index],
97
+ hint: `declared tools: ${[...tools].sort().join(', ') || 'none'}`,
98
+ }));
99
+ });
100
+ const fallback = guardrail.onFail.fallbackPrompt;
101
+ if (fallback !== undefined && !prompts.has(fallback)) {
102
+ diagnostics.push(report.error({
103
+ code: IR_DIAGNOSTIC_CODES.guardrailPolicy,
104
+ message: `the guardrails gate rejected "${guardrail.id}": onFail.fallbackPrompt names "${fallback}", which is not a declared prompt`,
105
+ path: ['guardrails', guardrail.id, 'onFail', 'fallbackPrompt'],
106
+ hint: `declared prompts: ${[...prompts].sort().join(', ') || 'none'}`,
107
+ }));
108
+ }
109
+ }
110
+ return { diagnostics, suppressed: NO_SUPPRESSIONS };
111
+ }
112
+ //# sourceMappingURL=guardrails.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardrails.js","sourceRoot":"","sources":["../../src/gates/guardrails.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Human-in-the-loop — one gate.
3
+ *
4
+ * An agent that can reach a tool which writes or destroys has two acceptable states:
5
+ * it declares a HITL policy (so the run stops for a human), or every such tool
6
+ * declares `requiresConfirmation: true` (so the approval is attached to the tool
7
+ * itself, where it cannot be forgotten when a new agent is added). Anything else is a
8
+ * side effect reachable with nobody in the loop, which fails closed.
9
+ *
10
+ * The gate deliberately does not evaluate the HITL policy expression: that is the
11
+ * parser's job at build time and the runtime's job at run time. It checks presence,
12
+ * because absence is the failure this layer can decide.
13
+ */
14
+ import type { IR } from '../shapes.js';
15
+ import { type GateOptions, type GateResult } from './contract.js';
16
+ export declare function hitlSideEffectGate(ir: IR, options: GateOptions): GateResult;
17
+ //# sourceMappingURL=hitl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hitl.d.ts","sourceRoot":"","sources":["../../src/gates/hitl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,EAAE,EAAa,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAA6B,MAAM,eAAe,CAAC;AAE7F,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,UAAU,CA0B3E"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Human-in-the-loop — one gate.
3
+ *
4
+ * An agent that can reach a tool which writes or destroys has two acceptable states:
5
+ * it declares a HITL policy (so the run stops for a human), or every such tool
6
+ * declares `requiresConfirmation: true` (so the approval is attached to the tool
7
+ * itself, where it cannot be forgotten when a new agent is added). Anything else is a
8
+ * side effect reachable with nobody in the loop, which fails closed.
9
+ *
10
+ * The gate deliberately does not evaluate the HITL policy expression: that is the
11
+ * parser's job at build time and the runtime's job at run time. It checks presence,
12
+ * because absence is the failure this layer can decide.
13
+ */
14
+ import { IR_DIAGNOSTIC_CODES } from '../diagnostics.js';
15
+ import { NO_SUPPRESSIONS, reporter } from './contract.js';
16
+ export function hitlSideEffectGate(ir, options) {
17
+ const diagnostics = [];
18
+ const report = reporter(options);
19
+ const tools = new Map(ir.tools.map((tool) => [tool.id, tool]));
20
+ for (const agent of ir.agents) {
21
+ if (agent.humanInTheLoop !== undefined)
22
+ continue;
23
+ const ungranted = agent.tools
24
+ .map((id) => tools.get(id))
25
+ .filter((tool) => tool !== undefined)
26
+ .filter((tool) => tool.sideEffects === 'write' || tool.sideEffects === 'destructive')
27
+ .filter((tool) => !tool.requiresConfirmation);
28
+ if (ungranted.length === 0)
29
+ continue;
30
+ const names = ungranted.map((tool) => `"${tool.id}" (${tool.sideEffects})`).join(', ');
31
+ diagnostics.push(report.error({
32
+ code: IR_DIAGNOSTIC_CODES.hitlSideEffect,
33
+ message: `the HITL gate rejected "${agent.id}": it can call ${names}, which ${ungranted.length === 1 ? 'has' : 'have'} side effects, but it declares no humanInTheLoop policy and the tool does not require confirmation`,
34
+ path: ['agents', agent.id, 'humanInTheLoop'],
35
+ hint: 'declare humanInTheLoop, or set requiresConfirmation: true on the tool',
36
+ }));
37
+ }
38
+ return { diagnostics, suppressed: NO_SUPPRESSIONS };
39
+ }
40
+ //# sourceMappingURL=hitl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hitl.js","sourceRoot":"","sources":["../../src/gates/hitl.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,kBAAkB,CAAC,EAAM,EAAE,OAAoB;IAC7D,MAAM,WAAW,GAAmB,EAAE,CAAC;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAE/D,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,cAAc,KAAK,SAAS;YAAE,SAAS;QACjD,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK;aAC1B,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;aAC1B,MAAM,CAAC,CAAC,IAAI,EAAqB,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC;aACvD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,KAAK,OAAO,IAAI,IAAI,CAAC,WAAW,KAAK,aAAa,CAAC;aACpF,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAChD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAErC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvF,WAAW,CAAC,IAAI,CACd,MAAM,CAAC,KAAK,CAAC;YACX,IAAI,EAAE,mBAAmB,CAAC,cAAc;YACxC,OAAO,EAAE,2BAA2B,KAAK,CAAC,EAAE,kBAAkB,KAAK,WAAW,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,oGAAoG;YACzN,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,gBAAgB,CAAC;YAC5C,IAAI,EAAE,uEAAuE;SAC9E,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC;AACtD,CAAC"}
@@ -0,0 +1,66 @@
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 type { IrDiagnostic } from '../diagnostics.js';
13
+ import type { IR } from '../shapes.js';
14
+ import { agentsBudgetDegradeGate, agentsBudgetGate, agentsHandoffGate, agentsRefsGate } from './agents.js';
15
+ import { capabilityGate } from './capability.js';
16
+ import type { Gate, GateOptions, GateReporter, GateResult, SuppressedCheck } from './contract.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 declare const GATES: {
28
+ readonly referential: typeof referentialGate;
29
+ readonly normalize: typeof normalizeGate;
30
+ readonly capability: typeof capabilityGate;
31
+ readonly cost: typeof costGate;
32
+ readonly security: typeof securityGate;
33
+ readonly 'eval-coverage': typeof evalCoverageGate;
34
+ readonly 'agents/refs-resolve': typeof agentsRefsGate;
35
+ readonly 'agents/handoff-cycles': typeof agentsHandoffGate;
36
+ readonly 'agents/budgets': typeof agentsBudgetGate;
37
+ readonly 'agents/budget-degrade': typeof agentsBudgetDegradeGate;
38
+ readonly 'guardrails/coverage': typeof guardrailCoverageGate;
39
+ readonly 'guardrails/policies': typeof guardrailPolicyGate;
40
+ readonly 'hitl/side-effects': typeof hitlSideEffectGate;
41
+ readonly 'memory/refs': typeof memoryRefsGate;
42
+ readonly 'deploy/streaming': typeof deployStreamingGate;
43
+ readonly 'orchestration/deepagents': typeof orchestrationDeepagentsGate;
44
+ };
45
+ export type GateName = keyof typeof GATES;
46
+ export interface GateRunResult {
47
+ /** False when any gate emitted an error-severity diagnostic. */
48
+ ok: boolean;
49
+ diagnostics: IrDiagnostic[];
50
+ suppressed: SuppressedCheck[];
51
+ byGate: Record<GateName, GateResult>;
52
+ }
53
+ /**
54
+ * Runs every gate against the IR. The capability set the gates check is derived here
55
+ * from the IR's own content, so the value a generator consumes is the value that was
56
+ * checked rather than whatever the caller happened to pass in.
57
+ */
58
+ export declare function runGates(ir: IR, options?: Partial<GateOptions>): GateRunResult;
59
+ export { reporter } from './contract.js';
60
+ export type { EvalCostEstimate, ModelCostEstimate } from './cost.js';
61
+ export { estimateEvalCost } from './cost.js';
62
+ export { diffPaths, isNormalized, normalize } from './normalize.js';
63
+ export { policyAuthenticates } from './security.js';
64
+ export type { Gate, GateName as GateId, GateOptions, GateReporter, GateResult, SuppressedCheck };
65
+ export { agentsBudgetDegradeGate, agentsBudgetGate, agentsHandoffGate, agentsRefsGate, capabilityGate, costGate, deployStreamingGate, evalCoverageGate, GATES as GATE_REGISTRY, guardrailCoverageGate, guardrailPolicyGate, hitlSideEffectGate, memoryRefsGate, normalizeGate, orchestrationDeepagentsGate, referentialGate, securityGate, };
66
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gates/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAClG,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;CAiBuB,CAAC;AAE1C,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,KAAK,CAAC;AAE1C,MAAM,WAAW,aAAa;IAC5B,gEAAgE;IAChE,EAAE,EAAE,OAAO,CAAC;IACZ,WAAW,EAAE,YAAY,EAAE,CAAC;IAC5B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;CACtC;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,aAAa,CAwBlF;AAED,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,YAAY,EAAE,IAAI,EAAE,QAAQ,IAAI,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC;AACjG,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,QAAQ,EACR,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,IAAI,aAAa,EACtB,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,2BAA2B,EAC3B,eAAe,EACf,YAAY,GACb,CAAC"}