@kindgi/api 0.1.4-rc.0 → 0.1.4-rc.2

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 (262) hide show
  1. package/dist/agent-binding.d.ts +20 -2
  2. package/dist/agent-binding.d.ts.map +1 -1
  3. package/dist/agent-pins.d.ts.map +1 -1
  4. package/dist/agent-pins.js +4 -1
  5. package/dist/agent-pins.js.map +1 -1
  6. package/dist/app.d.ts +8 -0
  7. package/dist/app.d.ts.map +1 -1
  8. package/dist/app.js +30 -5
  9. package/dist/app.js.map +1 -1
  10. package/dist/deploy-versions.d.ts +10 -5
  11. package/dist/deploy-versions.d.ts.map +1 -1
  12. package/dist/deploy-versions.js +4 -10
  13. package/dist/deploy-versions.js.map +1 -1
  14. package/dist/derive-agent-version.d.ts +9 -1
  15. package/dist/derive-agent-version.d.ts.map +1 -1
  16. package/dist/derive-agent-version.js +11 -1
  17. package/dist/derive-agent-version.js.map +1 -1
  18. package/dist/errors.d.ts.map +1 -1
  19. package/dist/errors.js +26 -0
  20. package/dist/errors.js.map +1 -1
  21. package/dist/eval-case-binding.d.ts +10 -0
  22. package/dist/eval-case-binding.d.ts.map +1 -1
  23. package/dist/eval-run-binding.d.ts +21 -3
  24. package/dist/eval-run-binding.d.ts.map +1 -1
  25. package/dist/eval-run-binding.js.map +1 -1
  26. package/dist/eval-run-dispatcher.d.ts +3 -0
  27. package/dist/eval-run-dispatcher.d.ts.map +1 -1
  28. package/dist/eval-run-dispatcher.js.map +1 -1
  29. package/dist/flow-binding.d.ts +8 -0
  30. package/dist/flow-binding.d.ts.map +1 -1
  31. package/dist/flow-pins.d.ts +20 -7
  32. package/dist/flow-pins.d.ts.map +1 -1
  33. package/dist/flow-pins.js +36 -11
  34. package/dist/flow-pins.js.map +1 -1
  35. package/dist/gate-policy-binding.d.ts +164 -0
  36. package/dist/gate-policy-binding.d.ts.map +1 -0
  37. package/dist/gate-policy-binding.js +12 -0
  38. package/dist/gate-policy-binding.js.map +1 -0
  39. package/dist/gate.d.ts +56 -0
  40. package/dist/gate.d.ts.map +1 -0
  41. package/dist/gate.js +359 -0
  42. package/dist/gate.js.map +1 -0
  43. package/dist/guardrail-binding.d.ts +8 -0
  44. package/dist/guardrail-binding.d.ts.map +1 -1
  45. package/dist/handler-binding.d.ts +17 -2
  46. package/dist/handler-binding.d.ts.map +1 -1
  47. package/dist/index.d.ts +11 -4
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +3 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/judged-dispatcher.d.ts +20 -1
  52. package/dist/judged-dispatcher.d.ts.map +1 -1
  53. package/dist/judged-dispatcher.js +57 -7
  54. package/dist/judged-dispatcher.js.map +1 -1
  55. package/dist/judgment-binding.d.ts +38 -0
  56. package/dist/judgment-binding.d.ts.map +1 -1
  57. package/dist/judgment-binding.js +19 -0
  58. package/dist/judgment-binding.js.map +1 -1
  59. package/dist/live-version-binding.d.ts +206 -0
  60. package/dist/live-version-binding.d.ts.map +1 -0
  61. package/dist/live-version-binding.js +4 -0
  62. package/dist/live-version-binding.js.map +1 -0
  63. package/dist/middleware/authorize.d.ts.map +1 -1
  64. package/dist/middleware/authorize.js +13 -2
  65. package/dist/middleware/authorize.js.map +1 -1
  66. package/dist/middleware/project-ref.d.ts +25 -0
  67. package/dist/middleware/project-ref.d.ts.map +1 -0
  68. package/dist/middleware/project-ref.js +72 -0
  69. package/dist/middleware/project-ref.js.map +1 -0
  70. package/dist/openapi/generate.d.ts.map +1 -1
  71. package/dist/openapi/generate.js +4 -0
  72. package/dist/openapi/generate.js.map +1 -1
  73. package/dist/openapi/operations.d.ts +6 -0
  74. package/dist/openapi/operations.d.ts.map +1 -1
  75. package/dist/openapi/operations.js +524 -27
  76. package/dist/openapi/operations.js.map +1 -1
  77. package/dist/openapi/schemas.d.ts +43 -0
  78. package/dist/openapi/schemas.d.ts.map +1 -1
  79. package/dist/openapi/schemas.js +1050 -7
  80. package/dist/openapi/schemas.js.map +1 -1
  81. package/dist/publish-refused.d.ts +18 -0
  82. package/dist/publish-refused.d.ts.map +1 -0
  83. package/dist/publish-refused.js +22 -0
  84. package/dist/publish-refused.js.map +1 -0
  85. package/dist/registry-read-only.d.ts +32 -0
  86. package/dist/registry-read-only.d.ts.map +1 -0
  87. package/dist/registry-read-only.js +22 -0
  88. package/dist/registry-read-only.js.map +1 -0
  89. package/dist/retention-binding.d.ts +29 -0
  90. package/dist/retention-binding.d.ts.map +1 -1
  91. package/dist/routes/agent-releases.d.ts +40 -0
  92. package/dist/routes/agent-releases.d.ts.map +1 -0
  93. package/dist/routes/agent-releases.js +462 -0
  94. package/dist/routes/agent-releases.js.map +1 -0
  95. package/dist/routes/agents.d.ts +7 -1
  96. package/dist/routes/agents.d.ts.map +1 -1
  97. package/dist/routes/agents.js +38 -4
  98. package/dist/routes/agents.js.map +1 -1
  99. package/dist/routes/approvals.d.ts.map +1 -1
  100. package/dist/routes/approvals.js +27 -9
  101. package/dist/routes/approvals.js.map +1 -1
  102. package/dist/routes/audit.d.ts.map +1 -1
  103. package/dist/routes/audit.js +7 -0
  104. package/dist/routes/audit.js.map +1 -1
  105. package/dist/routes/auth.js +1 -1
  106. package/dist/routes/auth.js.map +1 -1
  107. package/dist/routes/blocks.d.ts.map +1 -1
  108. package/dist/routes/blocks.js +37 -12
  109. package/dist/routes/blocks.js.map +1 -1
  110. package/dist/routes/conversations.d.ts +0 -7
  111. package/dist/routes/conversations.d.ts.map +1 -1
  112. package/dist/routes/conversations.js +19 -3
  113. package/dist/routes/conversations.js.map +1 -1
  114. package/dist/routes/deployments.d.ts +6 -0
  115. package/dist/routes/deployments.d.ts.map +1 -1
  116. package/dist/routes/deployments.js +49 -5
  117. package/dist/routes/deployments.js.map +1 -1
  118. package/dist/routes/env.d.ts.map +1 -1
  119. package/dist/routes/env.js +1 -0
  120. package/dist/routes/env.js.map +1 -1
  121. package/dist/routes/eval-comparison.d.ts +4 -2
  122. package/dist/routes/eval-comparison.d.ts.map +1 -1
  123. package/dist/routes/eval-comparison.js +59 -10
  124. package/dist/routes/eval-comparison.js.map +1 -1
  125. package/dist/routes/eval-runs.d.ts +7 -1
  126. package/dist/routes/eval-runs.d.ts.map +1 -1
  127. package/dist/routes/eval-runs.js +34 -3
  128. package/dist/routes/eval-runs.js.map +1 -1
  129. package/dist/routes/eval-versions.d.ts +25 -0
  130. package/dist/routes/eval-versions.d.ts.map +1 -0
  131. package/dist/routes/eval-versions.js +66 -0
  132. package/dist/routes/eval-versions.js.map +1 -0
  133. package/dist/routes/flows.d.ts +14 -7
  134. package/dist/routes/flows.d.ts.map +1 -1
  135. package/dist/routes/flows.js +14 -8
  136. package/dist/routes/flows.js.map +1 -1
  137. package/dist/routes/gate-policies.d.ts +19 -0
  138. package/dist/routes/gate-policies.d.ts.map +1 -0
  139. package/dist/routes/gate-policies.js +191 -0
  140. package/dist/routes/gate-policies.js.map +1 -0
  141. package/dist/routes/gate-policy-spec.d.ts +17 -0
  142. package/dist/routes/gate-policy-spec.d.ts.map +1 -0
  143. package/dist/routes/gate-policy-spec.js +192 -0
  144. package/dist/routes/gate-policy-spec.js.map +1 -0
  145. package/dist/routes/gate-policy-wire.d.ts +3 -0
  146. package/dist/routes/gate-policy-wire.d.ts.map +1 -0
  147. package/dist/routes/gate-policy-wire.js +18 -0
  148. package/dist/routes/gate-policy-wire.js.map +1 -0
  149. package/dist/routes/guardrails.d.ts.map +1 -1
  150. package/dist/routes/guardrails.js +4 -0
  151. package/dist/routes/guardrails.js.map +1 -1
  152. package/dist/routes/hierarchy-errors.d.ts +21 -0
  153. package/dist/routes/hierarchy-errors.d.ts.map +1 -1
  154. package/dist/routes/hierarchy-errors.js +21 -0
  155. package/dist/routes/hierarchy-errors.js.map +1 -1
  156. package/dist/routes/judged-suites.js +7 -0
  157. package/dist/routes/judged-suites.js.map +1 -1
  158. package/dist/routes/judgments.d.ts +4 -1
  159. package/dist/routes/judgments.d.ts.map +1 -1
  160. package/dist/routes/judgments.js +92 -19
  161. package/dist/routes/judgments.js.map +1 -1
  162. package/dist/routes/live-scope-wire.d.ts +32 -0
  163. package/dist/routes/live-scope-wire.d.ts.map +1 -0
  164. package/dist/routes/live-scope-wire.js +71 -0
  165. package/dist/routes/live-scope-wire.js.map +1 -0
  166. package/dist/routes/policies.d.ts +6 -3
  167. package/dist/routes/policies.d.ts.map +1 -1
  168. package/dist/routes/policies.js +55 -3
  169. package/dist/routes/policies.js.map +1 -1
  170. package/dist/routes/projects.d.ts.map +1 -1
  171. package/dist/routes/projects.js +59 -9
  172. package/dist/routes/projects.js.map +1 -1
  173. package/dist/routes/retention.d.ts.map +1 -1
  174. package/dist/routes/retention.js +18 -2
  175. package/dist/routes/retention.js.map +1 -1
  176. package/dist/routes/reviewers.d.ts +8 -1
  177. package/dist/routes/reviewers.d.ts.map +1 -1
  178. package/dist/routes/reviewers.js +20 -3
  179. package/dist/routes/reviewers.js.map +1 -1
  180. package/dist/routes/runs.d.ts.map +1 -1
  181. package/dist/routes/runs.js +23 -13
  182. package/dist/routes/runs.js.map +1 -1
  183. package/dist/routes/secrets.d.ts.map +1 -1
  184. package/dist/routes/secrets.js +2 -0
  185. package/dist/routes/secrets.js.map +1 -1
  186. package/dist/routes/segments.d.ts +17 -0
  187. package/dist/routes/segments.d.ts.map +1 -0
  188. package/dist/routes/segments.js +68 -0
  189. package/dist/routes/segments.js.map +1 -0
  190. package/dist/routes/teams.d.ts.map +1 -1
  191. package/dist/routes/teams.js +53 -8
  192. package/dist/routes/teams.js.map +1 -1
  193. package/dist/routes/tools.d.ts.map +1 -1
  194. package/dist/routes/tools.js +4 -0
  195. package/dist/routes/tools.js.map +1 -1
  196. package/dist/routes/uuid-param.d.ts +11 -0
  197. package/dist/routes/uuid-param.d.ts.map +1 -0
  198. package/dist/routes/uuid-param.js +19 -0
  199. package/dist/routes/uuid-param.js.map +1 -0
  200. package/dist/tool-binding.d.ts +8 -0
  201. package/dist/tool-binding.d.ts.map +1 -1
  202. package/openapi.json +6484 -2402
  203. package/package.json +21 -21
  204. package/src/agent-binding.ts +21 -2
  205. package/src/agent-pins.ts +3 -1
  206. package/src/app.ts +47 -4
  207. package/src/deploy-versions.ts +12 -15
  208. package/src/derive-agent-version.ts +12 -1
  209. package/src/errors.ts +26 -0
  210. package/src/eval-case-binding.ts +7 -0
  211. package/src/eval-run-binding.ts +31 -3
  212. package/src/eval-run-dispatcher.ts +3 -0
  213. package/src/flow-binding.ts +9 -0
  214. package/src/flow-pins.ts +49 -9
  215. package/src/gate-policy-binding.ts +171 -0
  216. package/src/gate.ts +467 -0
  217. package/src/guardrail-binding.ts +9 -0
  218. package/src/handler-binding.ts +17 -2
  219. package/src/index.ts +47 -1
  220. package/src/judged-dispatcher.ts +100 -9
  221. package/src/judgment-binding.ts +62 -0
  222. package/src/live-version-binding.ts +237 -0
  223. package/src/middleware/authorize.ts +18 -2
  224. package/src/middleware/project-ref.ts +88 -0
  225. package/src/openapi/generate.ts +5 -0
  226. package/src/openapi/operations.ts +664 -27
  227. package/src/openapi/schemas.ts +1175 -33
  228. package/src/publish-refused.ts +31 -0
  229. package/src/registry-read-only.ts +43 -0
  230. package/src/retention-binding.ts +30 -0
  231. package/src/routes/agent-releases.ts +581 -0
  232. package/src/routes/agents.ts +53 -3
  233. package/src/routes/approvals.ts +36 -8
  234. package/src/routes/audit.ts +10 -0
  235. package/src/routes/auth.ts +1 -1
  236. package/src/routes/blocks.ts +39 -14
  237. package/src/routes/conversations.ts +31 -3
  238. package/src/routes/deployments.ts +75 -5
  239. package/src/routes/env.ts +1 -0
  240. package/src/routes/eval-comparison.ts +59 -11
  241. package/src/routes/eval-runs.ts +46 -3
  242. package/src/routes/eval-versions.ts +110 -0
  243. package/src/routes/flows.ts +34 -11
  244. package/src/routes/gate-policies.ts +226 -0
  245. package/src/routes/gate-policy-spec.ts +229 -0
  246. package/src/routes/gate-policy-wire.ts +20 -0
  247. package/src/routes/guardrails.ts +7 -0
  248. package/src/routes/hierarchy-errors.ts +23 -0
  249. package/src/routes/judged-suites.ts +5 -0
  250. package/src/routes/judgments.ts +107 -23
  251. package/src/routes/live-scope-wire.ts +90 -0
  252. package/src/routes/policies.ts +61 -3
  253. package/src/routes/projects.ts +72 -9
  254. package/src/routes/retention.ts +21 -2
  255. package/src/routes/reviewers.ts +23 -4
  256. package/src/routes/runs.ts +34 -20
  257. package/src/routes/secrets.ts +2 -0
  258. package/src/routes/segments.ts +75 -0
  259. package/src/routes/teams.ts +66 -8
  260. package/src/routes/tools.ts +7 -0
  261. package/src/routes/uuid-param.ts +28 -0
  262. package/src/tool-binding.ts +9 -0
@@ -0,0 +1,164 @@
1
+ import type { ReviewerRole } from '@kindgi/authz';
2
+ import type { Cursor, LiveScope, Result, TenantId, Timestamp } from '@kindgi/types';
3
+ /**
4
+ * Gate policies (evals step 4b): what a promotion of an agent must show
5
+ * before a version goes live for a scope. One policy per agent and scope;
6
+ * the most specific one covering a promotion's scope applies, at its
7
+ * latest active version. The same registry shape as retention policies:
8
+ * the caller names the policy and its semver versions.
9
+ */
10
+ /** The metrics a policy can gate, from a comparison's summary. */
11
+ export declare const GATE_METRICS: readonly ["weightedYesShare", "judgedCoverage", "weightedPrecisionAtK"];
12
+ export type GateMetricName = (typeof GATE_METRICS)[number];
13
+ export interface GateMetricSpec {
14
+ readonly name: GateMetricName;
15
+ /** `weightedPrecisionAtK` only: the summary's `k` must be this. */
16
+ readonly k?: number;
17
+ /** The candidate must reach this. */
18
+ readonly minCandidate?: number;
19
+ /** The candidate may fall at most this far below the baseline (`0`: no drop at all). */
20
+ readonly maxDrop?: number;
21
+ }
22
+ /**
23
+ * What a policy asks of a promotion. Every part is optional; an empty
24
+ * spec checks nothing (the promotion is still recorded with the policy).
25
+ * A promotion must name a comparison (`evalRunId`) exactly when the spec
26
+ * checks anything one shows: `comparison`, `evidence`, `metrics`,
27
+ * `replay` or `onlyRestrictedClasses`.
28
+ */
29
+ export interface GatePolicySpec {
30
+ readonly comparison?: {
31
+ /** The comparison must have finished within this many hours. */
32
+ readonly maxAgeHours?: number;
33
+ /** The comparison must have run this test set (and version). */
34
+ readonly suite?: {
35
+ readonly id: string;
36
+ readonly version?: string;
37
+ };
38
+ };
39
+ /** The judged evidence behind each gated metric (`n` cases, total weight). */
40
+ readonly evidence?: {
41
+ readonly minCases?: number;
42
+ readonly minWeight?: number;
43
+ };
44
+ readonly metrics?: readonly GateMetricSpec[];
45
+ /** Replay counts; each knob left out of the block is 0. No block: no replay checks. */
46
+ readonly replay?: {
47
+ readonly maxDiverged?: number;
48
+ readonly maxErrors?: number;
49
+ readonly maxRefusedWrites?: number;
50
+ readonly maxStopped?: number;
51
+ };
52
+ /** A passing promotion waits for a reviewer's approval. */
53
+ readonly approvals?: {
54
+ /** The reviewer role it needs (default `senior`). */
55
+ readonly role?: ReviewerRole;
56
+ /** Whoever asked can't approve it (default `true`). */
57
+ readonly separateApprover?: boolean;
58
+ };
59
+ /**
60
+ * Only judgments recorded under a restricted judge class count (T200):
61
+ * the comparison must be weighted `restricted-only`, so a class anyone
62
+ * may assert can't move the gate.
63
+ */
64
+ readonly onlyRestrictedClasses?: boolean;
65
+ }
66
+ export interface GatePolicy {
67
+ readonly id: string;
68
+ readonly version: string;
69
+ readonly tenantId: TenantId;
70
+ readonly agentId: string;
71
+ readonly scope: LiveScope;
72
+ readonly spec: GatePolicySpec;
73
+ readonly description?: string;
74
+ readonly createdAt: Timestamp;
75
+ /** Set when this version was unregistered. */
76
+ readonly unregisteredAt?: Timestamp;
77
+ }
78
+ /** A policy version, as a promotion records which one gated it. */
79
+ export interface GatePolicyRef {
80
+ readonly id: string;
81
+ readonly version: string;
82
+ }
83
+ export interface GatePolicyPublishInput {
84
+ readonly tenantId: TenantId;
85
+ readonly id: string;
86
+ readonly version: string;
87
+ readonly agentId: string;
88
+ readonly scope: LiveScope;
89
+ readonly spec: GatePolicySpec;
90
+ readonly description?: string;
91
+ }
92
+ export type GatePolicyErrorCode =
93
+ /** This id and version are registered already. */
94
+ 'gate-policy-already-registered'
95
+ /** Another policy already gates this agent and scope. */
96
+ | 'gate-policy-scope-taken'
97
+ /** A new version names another agent or scope than the policy's. */
98
+ | 'gate-policy-scope-changed'
99
+ /**
100
+ * The scope resolves to the agent's latest version (no pin covers it),
101
+ * so publishing a version would make it live there ungated: pin a
102
+ * version for the scope, or one above it, first.
103
+ */
104
+ | 'gate-policy-scope-unpinned' | 'gate-policy-not-found'
105
+ /** The scope names an org or project the tenant doesn't have. */
106
+ | 'scope-invalid' | 'persistence-error';
107
+ export interface GatePolicyError {
108
+ readonly code: GatePolicyErrorCode;
109
+ readonly message: string;
110
+ /** `gate-policy-scope-taken`: the policy that holds the scope. */
111
+ readonly heldBy?: string;
112
+ }
113
+ export interface GatePolicyListInput {
114
+ readonly tenantId: TenantId;
115
+ readonly agentId?: string;
116
+ /** Only the policy of exactly this scope. */
117
+ readonly scope?: LiveScope;
118
+ readonly limit: number;
119
+ readonly cursor?: Cursor;
120
+ }
121
+ export interface GatePolicyVersionInput {
122
+ readonly tenantId: TenantId;
123
+ readonly id: string;
124
+ readonly version: string;
125
+ }
126
+ export interface GatePolicyBinding {
127
+ /**
128
+ * Register `id` at `version`: a new policy, or a new version of one
129
+ * (same agent and scope). A gated scope always resolves to a pin:
130
+ * `gate-policy-scope-unpinned` when nothing covering the scope is pinned.
131
+ */
132
+ publish(input: GatePolicyPublishInput): Promise<Result<GatePolicy, GatePolicyError>>;
133
+ /** The policy's latest active version, or `null`. */
134
+ get(input: {
135
+ readonly tenantId: TenantId;
136
+ readonly id: string;
137
+ }): Promise<GatePolicy | null>;
138
+ /** One version, unregistered ones too, or `null`. */
139
+ getVersion(input: GatePolicyVersionInput): Promise<GatePolicy | null>;
140
+ /** Every version of a policy, oldest first. */
141
+ listVersions(input: {
142
+ readonly tenantId: TenantId;
143
+ readonly id: string;
144
+ }): Promise<readonly GatePolicy[]>;
145
+ /** Each policy's latest active version. */
146
+ list(input: GatePolicyListInput): Promise<{
147
+ readonly data: readonly GatePolicy[];
148
+ readonly nextCursor?: Cursor;
149
+ }>;
150
+ unregister(input: GatePolicyVersionInput): Promise<Result<GatePolicy, GatePolicyError>>;
151
+ reinstate(input: GatePolicyVersionInput): Promise<Result<GatePolicy, GatePolicyError>>;
152
+ /**
153
+ * The policy that gates a promotion of `agentId` for `scope`: the most
154
+ * specific scope with an active policy (a segment path's longer
155
+ * prefixes first, then its project, the project's org, the tenant), at
156
+ * its latest active version. `null`: no policy, so no gate.
157
+ */
158
+ resolve(input: {
159
+ readonly tenantId: TenantId;
160
+ readonly agentId: string;
161
+ readonly scope: LiveScope;
162
+ }): Promise<GatePolicy | null>;
163
+ }
164
+ //# sourceMappingURL=gate-policy-binding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-policy-binding.d.ts","sourceRoot":"","sources":["../src/gate-policy-binding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ /**
4
+ * Gate policies (evals step 4b): what a promotion of an agent must show
5
+ * before a version goes live for a scope. One policy per agent and scope;
6
+ * the most specific one covering a promotion's scope applies, at its
7
+ * latest active version. The same registry shape as retention policies:
8
+ * the caller names the policy and its semver versions.
9
+ */
10
+ /** The metrics a policy can gate, from a comparison's summary. */
11
+ export const GATE_METRICS = ['weightedYesShare', 'judgedCoverage', 'weightedPrecisionAtK'];
12
+ //# sourceMappingURL=gate-policy-binding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-policy-binding.js","sourceRoot":"","sources":["../src/gate-policy-binding.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAKjC;;;;;;GAMG;AAEH,kEAAkE;AAClE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,kBAAkB,EAAE,gBAAgB,EAAE,sBAAsB,CAAU,CAAC"}
package/dist/gate.d.ts ADDED
@@ -0,0 +1,56 @@
1
+ import type { ReviewerRole } from '@kindgi/authz';
2
+ import type { LiveScope } from '@kindgi/types';
3
+ import type { GatePolicySpec } from './gate-policy-binding.js';
4
+ import type { JudgedComparisonSummary } from './judged-dispatcher.js';
5
+ /**
6
+ * The promotion gate (evals step 4b): a policy's checks against a
7
+ * comparison's summary. Pure; the promotion route and `…/check` both
8
+ * call it, so a check answers exactly what a promotion would.
9
+ */
10
+ /** One check, as the promotion records it and every client shows it. */
11
+ export interface GateCheck {
12
+ /** Stable: `metric.weightedPrecisionAtK.minCandidate`, `replay.maxDiverged`, … */
13
+ readonly name: string;
14
+ readonly passed: boolean;
15
+ /** A plain sentence saying what was found against what the policy asks. */
16
+ readonly message: string;
17
+ readonly value?: number | string;
18
+ readonly threshold?: number | string;
19
+ }
20
+ /** What a passing promotion still needs: a reviewer's approval. */
21
+ export interface GateApproval {
22
+ readonly role: ReviewerRole;
23
+ /** How many reviewers decide (one, today). */
24
+ readonly count: number;
25
+ readonly separateApprover: boolean;
26
+ }
27
+ export interface GateInput {
28
+ readonly spec: GatePolicySpec;
29
+ /** What's being promoted. */
30
+ readonly promotion: {
31
+ readonly agentId: string;
32
+ readonly version: string;
33
+ /** The promoted version's `pinsDigest`; `null` for a version published before pins. */
34
+ readonly pinsDigest: string | null;
35
+ readonly scope: LiveScope;
36
+ };
37
+ /** The comparison named by `evalRunId`; `null` when none was. */
38
+ readonly summary: JudgedComparisonSummary | null;
39
+ /** The version serving the promotion's scope now: what "no regression" is measured against. */
40
+ readonly servingVersion: string;
41
+ /**
42
+ * The org of the project the comparison's judgments came from (for an
43
+ * org promotion). Absent: that project has no org, or none was looked up.
44
+ */
45
+ readonly summaryProjectOrgId?: string;
46
+ readonly now: Date;
47
+ }
48
+ export interface GateResult {
49
+ readonly checks: readonly GateCheck[];
50
+ readonly passed: boolean;
51
+ /** Set when the policy asks for an approval. */
52
+ readonly approval?: GateApproval;
53
+ }
54
+ export declare function gateApproval(spec: GatePolicySpec): GateApproval | undefined;
55
+ export declare function evaluateGate(input: GateInput): GateResult;
56
+ //# sourceMappingURL=gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../src/gate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,KAAK,EAAkC,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/F,OAAO,KAAK,EAAoB,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAExF;;;;GAIG;AAEH,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACxB,kFAAkF;IAClF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACtC;AAED,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACpC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,6BAA6B;IAC7B,QAAQ,CAAC,SAAS,EAAE;QAClB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,uFAAuF;QACvF,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;KAC3B,CAAC;IACF,iEAAiE;IACjE,QAAQ,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACjD,+FAA+F;IAC/F,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;CAClC;AAgBD,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,YAAY,GAAG,SAAS,CAO3E;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,CAiDzD"}
package/dist/gate.js ADDED
@@ -0,0 +1,359 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ /** Room for float rounding in the metric comparisons. */
4
+ const EPSILON = 1e-9;
5
+ /** Whether the spec checks anything only a comparison shows. */
6
+ function needsComparison(spec) {
7
+ return (spec.comparison !== undefined ||
8
+ spec.evidence !== undefined ||
9
+ (spec.metrics?.length ?? 0) > 0 ||
10
+ spec.replay !== undefined ||
11
+ spec.onlyRestrictedClasses === true);
12
+ }
13
+ export function gateApproval(spec) {
14
+ if (spec.approvals === undefined)
15
+ return undefined;
16
+ return {
17
+ role: spec.approvals.role ?? 'senior',
18
+ count: 1,
19
+ separateApprover: spec.approvals.separateApprover ?? true,
20
+ };
21
+ }
22
+ export function evaluateGate(input) {
23
+ const { spec, summary } = input;
24
+ const checks = [];
25
+ const approval = gateApproval(spec);
26
+ const required = needsComparison(spec);
27
+ if (summary === null) {
28
+ if (required) {
29
+ checks.push({
30
+ name: 'comparison.required',
31
+ passed: false,
32
+ message: 'This policy needs a comparison: name one with `evalRunId` (a finished comparison eval run of this version).',
33
+ });
34
+ }
35
+ return result(checks, approval);
36
+ }
37
+ if (required) {
38
+ checks.push({
39
+ name: 'comparison.required',
40
+ passed: true,
41
+ message: `Comparison ${summary.evalRunId} is named.`,
42
+ });
43
+ }
44
+ checks.push(statusCheck(spec, summary));
45
+ if (spec.comparison?.maxAgeHours !== undefined) {
46
+ checks.push(freshnessCheck(spec.comparison.maxAgeHours, summary, input.now));
47
+ }
48
+ if (spec.comparison?.suite !== undefined)
49
+ checks.push(suiteCheck(spec.comparison.suite, summary));
50
+ checks.push(sameContentsCheck(input));
51
+ checks.push(baselineCheck(summary, input));
52
+ checks.push(scopeCheck(summary, input));
53
+ if (spec.onlyRestrictedClasses === true) {
54
+ const counted = summary.classWeights ?? 'as-recorded';
55
+ checks.push({
56
+ name: 'classWeights.restrictedOnly',
57
+ passed: counted === 'restricted-only',
58
+ message: counted === 'restricted-only'
59
+ ? 'The comparison counted only restricted judge classes.'
60
+ : "The policy counts only restricted judge classes; the comparison counted every class. Re-run it with `classWeights: 'restricted-only'`.",
61
+ value: counted,
62
+ threshold: 'restricted-only',
63
+ });
64
+ }
65
+ if (spec.replay !== undefined)
66
+ checks.push(...replayChecks(spec.replay, summary));
67
+ for (const metric of spec.metrics ?? [])
68
+ checks.push(...metricChecks(metric, spec, summary));
69
+ return result(checks, approval);
70
+ }
71
+ function result(checks, approval) {
72
+ return {
73
+ checks,
74
+ passed: checks.every((c) => c.passed),
75
+ ...(approval !== undefined && { approval }),
76
+ };
77
+ }
78
+ function statusCheck(spec, summary) {
79
+ const maxErrors = spec.replay?.maxErrors ?? 0;
80
+ const base = { name: 'comparison.status', value: summary.status };
81
+ if (summary.status === 'completed') {
82
+ return { ...base, passed: true, message: 'The comparison completed.' };
83
+ }
84
+ if (summary.status === 'partial' && summary.errors <= maxErrors) {
85
+ return {
86
+ ...base,
87
+ passed: true,
88
+ message: `The comparison finished with ${count(summary.errors, 'case')} in error; the policy allows ${maxErrors}.`,
89
+ threshold: maxErrors,
90
+ };
91
+ }
92
+ return {
93
+ ...base,
94
+ passed: false,
95
+ message: summary.status === 'failed'
96
+ ? 'The comparison failed.'
97
+ : `The comparison finished with ${count(summary.errors, 'case')} in error; the policy allows ${maxErrors}.`,
98
+ ...(summary.status === 'partial' && { threshold: maxErrors }),
99
+ };
100
+ }
101
+ function freshnessCheck(maxAgeHours, summary, now) {
102
+ const ageHours = (now.getTime() - new Date(summary.completedAt).getTime()) / 3_600_000;
103
+ const passed = ageHours <= maxAgeHours;
104
+ return {
105
+ name: 'comparison.freshness',
106
+ passed,
107
+ message: `The comparison finished ${round(ageHours)} hours ago; the policy accepts up to ${maxAgeHours}.`,
108
+ value: round(ageHours),
109
+ threshold: maxAgeHours,
110
+ };
111
+ }
112
+ function suiteCheck(suite, summary) {
113
+ const ran = `${summary.suite.id} ${summary.suite.version}`;
114
+ const wanted = suite.version === undefined ? suite.id : `${suite.id} ${suite.version}`;
115
+ const passed = summary.suite.id === suite.id &&
116
+ (suite.version === undefined || summary.suite.version === suite.version);
117
+ return {
118
+ name: 'comparison.suite',
119
+ passed,
120
+ message: passed
121
+ ? `The comparison ran test set ${ran}.`
122
+ : `The comparison ran test set ${ran}; the policy needs ${wanted}.`,
123
+ value: ran,
124
+ threshold: wanted,
125
+ };
126
+ }
127
+ function sameContentsCheck(input) {
128
+ const { promotion, summary } = input;
129
+ const candidate = summary?.candidate;
130
+ const name = 'sameContents';
131
+ const promoted = `${promotion.agentId} ${promotion.version}`;
132
+ if (candidate === undefined || candidate.kind !== 'agent') {
133
+ return {
134
+ name,
135
+ passed: false,
136
+ message: `The comparison ran a flow; compare the agent itself (${promoted}).`,
137
+ };
138
+ }
139
+ const compared = `${candidate.agentId} ${candidate.version}`;
140
+ if (candidate.agentId !== promotion.agentId || candidate.version !== promotion.version) {
141
+ return {
142
+ name,
143
+ passed: false,
144
+ message: `The comparison ran ${compared}, not ${promoted}.`,
145
+ value: compared,
146
+ threshold: promoted,
147
+ };
148
+ }
149
+ if (promotion.pinsDigest === null) {
150
+ return {
151
+ name,
152
+ passed: false,
153
+ message: `${promoted} was published before versions recorded their pins: republish it to pin it, then compare that version.`,
154
+ };
155
+ }
156
+ if (candidate.pinsDigest === undefined) {
157
+ return {
158
+ name,
159
+ passed: false,
160
+ message: 'The comparison predates recording what the candidate ran (its pinsDigest): re-run the comparison.',
161
+ };
162
+ }
163
+ const passed = candidate.pinsDigest === promotion.pinsDigest;
164
+ return {
165
+ name,
166
+ passed,
167
+ message: passed
168
+ ? `The comparison ran ${promoted} with the same pins.`
169
+ : `The comparison ran ${promoted} with other pins than it has now: re-run the comparison.`,
170
+ value: candidate.pinsDigest,
171
+ threshold: promotion.pinsDigest,
172
+ };
173
+ }
174
+ function baselineCheck(summary, input) {
175
+ const name = 'baselineIsLive';
176
+ const serving = `${input.promotion.agentId} ${input.servingVersion}`;
177
+ const versions = summary.baseline.kind === 'recorded'
178
+ ? summary.baseline.versions.map((v) => 'agentId' in v ? `${v.agentId} ${v.version}` : `flow ${v.flowId} ${v.version}`)
179
+ : [`${summary.baseline.agentId} ${summary.baseline.version}`];
180
+ if (versions.length !== 1) {
181
+ return {
182
+ name,
183
+ passed: false,
184
+ message: `The comparison's baseline mixes ${versions.length} versions (${versions.join(', ')}); it must be the one live for the scope, ${serving}.`,
185
+ value: versions.join(', '),
186
+ threshold: serving,
187
+ };
188
+ }
189
+ const passed = versions[0] === serving;
190
+ return {
191
+ name,
192
+ passed,
193
+ message: passed
194
+ ? `The baseline is ${serving}, the version live for the scope.`
195
+ : `The baseline is ${versions[0]}; the version live for the scope is ${serving}. Re-run the comparison against it.`,
196
+ value: versions[0] ?? '',
197
+ threshold: serving,
198
+ };
199
+ }
200
+ function scopeCheck(summary, input) {
201
+ const name = 'scopeCovered';
202
+ const from = summary.scope.projectId;
203
+ const scope = input.promotion.scope;
204
+ const judgedIn = from === undefined ? 'the whole tenant' : `project ${from}`;
205
+ switch (scope.kind) {
206
+ case 'tenant':
207
+ return { name, passed: true, message: `The judgments came from ${judgedIn}.` };
208
+ case 'org': {
209
+ const passed = from === undefined || input.summaryProjectOrgId === scope.orgId;
210
+ return {
211
+ name,
212
+ passed,
213
+ message: passed
214
+ ? `The judgments came from ${judgedIn}, within org ${scope.orgId}.`
215
+ : `The judgments came from ${judgedIn}, outside org ${scope.orgId}.`,
216
+ };
217
+ }
218
+ case 'project':
219
+ case 'segment': {
220
+ const passed = from === scope.projectId;
221
+ return {
222
+ name,
223
+ passed,
224
+ message: passed
225
+ ? `The judgments came from project ${scope.projectId}, the one promoted in.`
226
+ : `The judgments came from ${judgedIn}; this promotion is for project ${scope.projectId}, so it needs that project's judgments.`,
227
+ };
228
+ }
229
+ }
230
+ }
231
+ const REPLAY_KNOBS = [
232
+ [
233
+ 'maxDiverged',
234
+ 'diverged',
235
+ 'case diverged from its recorded reads',
236
+ 'cases diverged from their recorded reads',
237
+ ],
238
+ ['maxErrors', 'errors', 'case errored', 'cases errored'],
239
+ ['maxRefusedWrites', 'refusedWrites', 'write was refused', 'writes were refused'],
240
+ ['maxStopped', 'stopped', 'case stopped at a refused write', 'cases stopped at a refused write'],
241
+ ];
242
+ function replayChecks(replay, summary) {
243
+ return REPLAY_KNOBS.map(([knob, field, one, many]) => {
244
+ const max = replay[knob] ?? 0;
245
+ const value = summary[field];
246
+ return {
247
+ name: `replay.${knob}`,
248
+ passed: value <= max,
249
+ message: `${value} ${value === 1 ? one : many}; the policy allows ${max}.`,
250
+ value,
251
+ threshold: max,
252
+ };
253
+ });
254
+ }
255
+ function metricLabel(name, metric) {
256
+ switch (name) {
257
+ case 'weightedYesShare':
258
+ return 'The weighted yes share';
259
+ case 'judgedCoverage':
260
+ return 'Judged coverage';
261
+ case 'weightedPrecisionAtK':
262
+ return `Precision at ${metric.k ?? 'k'}`;
263
+ }
264
+ }
265
+ function metricChecks(spec, policy, summary) {
266
+ const metric = summary.metrics[spec.name];
267
+ const label = metricLabel(spec.name, metric);
268
+ const at = `metric.${spec.name}`;
269
+ const checks = [];
270
+ if (spec.name === 'weightedPrecisionAtK' && spec.k !== undefined) {
271
+ checks.push({
272
+ name: `${at}.k`,
273
+ passed: metric.k === spec.k,
274
+ message: metric.k === spec.k
275
+ ? `The comparison ranked the top ${spec.k}, as the policy asks.`
276
+ : `The comparison ranked the top ${metric.k ?? '?'}; the policy gates the top ${spec.k}. Re-run it with \`k: ${spec.k}\`.`,
277
+ ...(metric.k !== undefined && { value: metric.k }),
278
+ threshold: spec.k,
279
+ });
280
+ }
281
+ checks.push(...evidenceChecks(spec, policy, metric, label));
282
+ if (spec.minCandidate !== undefined) {
283
+ const value = metric.candidate;
284
+ checks.push({
285
+ name: `${at}.minCandidate`,
286
+ passed: value !== null && value + EPSILON >= spec.minCandidate,
287
+ message: value === null
288
+ ? `${label} has no judged evidence for the candidate; the policy needs at least ${fmt(spec.minCandidate)}.`
289
+ : `${label} is ${fmt(value)}; the policy needs at least ${fmt(spec.minCandidate)}.`,
290
+ ...(value !== null && { value: round(value) }),
291
+ threshold: spec.minCandidate,
292
+ });
293
+ }
294
+ if (spec.maxDrop !== undefined) {
295
+ const { candidate, baseline } = metric;
296
+ const floor = baseline === null ? null : baseline - spec.maxDrop;
297
+ checks.push({
298
+ name: `${at}.maxDrop`,
299
+ passed: candidate !== null && floor !== null && candidate + EPSILON >= floor,
300
+ message: candidate === null || baseline === null
301
+ ? `${label} can't be compared: the ${candidate === null ? 'candidate' : 'baseline'} has no judged evidence.`
302
+ : `${label} is ${fmt(candidate)} against the live version's ${fmt(baseline)}; the policy allows a drop of at most ${fmt(spec.maxDrop)}.`,
303
+ ...(candidate !== null && baseline !== null && { value: round(candidate - baseline) }),
304
+ threshold: -spec.maxDrop,
305
+ });
306
+ }
307
+ return checks;
308
+ }
309
+ function evidenceChecks(spec, policy, metric, label) {
310
+ const evidence = policy.evidence;
311
+ if (evidence === undefined)
312
+ return [];
313
+ const at = `evidence.${spec.name}`;
314
+ const sides = [
315
+ { prefix: '', whose: 'the candidate', n: metric.n, weight: metric.weight },
316
+ ];
317
+ // "No regression" means nothing on a baseline with two judgments.
318
+ if (spec.maxDrop !== undefined) {
319
+ sides.push({
320
+ prefix: 'baseline',
321
+ whose: 'the baseline',
322
+ n: metric.baselineN,
323
+ weight: metric.baselineWeight,
324
+ });
325
+ }
326
+ const checks = [];
327
+ for (const side of sides) {
328
+ const key = (k) => side.prefix === '' ? `${at}.${k[0]?.toLowerCase()}${k.slice(1)}` : `${at}.${side.prefix}${k}`;
329
+ if (evidence.minCases !== undefined) {
330
+ checks.push({
331
+ name: key('MinCases'),
332
+ passed: side.n >= evidence.minCases,
333
+ message: `${label} rests on ${count(side.n, 'judged case')} for ${side.whose}; the policy needs at least ${evidence.minCases}.`,
334
+ value: side.n,
335
+ threshold: evidence.minCases,
336
+ });
337
+ }
338
+ if (evidence.minWeight !== undefined) {
339
+ checks.push({
340
+ name: key('MinWeight'),
341
+ passed: side.weight + EPSILON >= evidence.minWeight,
342
+ message: `${label} rests on judgments weighing ${fmt(side.weight)} for ${side.whose}; the policy needs at least ${fmt(evidence.minWeight)}.`,
343
+ value: round(side.weight),
344
+ threshold: evidence.minWeight,
345
+ });
346
+ }
347
+ }
348
+ return checks;
349
+ }
350
+ function round(n) {
351
+ return Math.round(n * 1000) / 1000;
352
+ }
353
+ function fmt(n) {
354
+ return String(round(n));
355
+ }
356
+ function count(n, noun) {
357
+ return `${n} ${noun}${n === 1 ? '' : 's'}`;
358
+ }
359
+ //# sourceMappingURL=gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate.js","sourceRoot":"","sources":["../src/gate.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import type { TupleEnqueueHook } from '@kindgi/authz';
2
2
  import type { Guardrail } from '@kindgi/guardrails';
3
3
  import type { Scope } from '@kindgi/platform';
4
4
  import type { Cursor, GuardrailId, ProjectId, TenantId } from '@kindgi/types';
5
+ import type { RegistryReadOnly } from './registry-read-only.js';
5
6
  /**
6
7
  * Caller-plugged surface for the guardrail catalog. Same shape as
7
8
  * `AgentRegistryBinding` / `ToolRegistryBinding`: the API package does
@@ -23,6 +24,13 @@ import type { Cursor, GuardrailId, ProjectId, TenantId } from '@kindgi/types';
23
24
  * inspects the payload.
24
25
  */
25
26
  export interface GuardrailRegistryBinding {
27
+ /**
28
+ * Set when this registry takes no writes (under `kindgi dev`, the
29
+ * pack's files are the source of its guardrails): every write is refused
30
+ * with `409 registry-read-only` and this reason, before the binding is
31
+ * called. See `RegistryReadOnly`.
32
+ */
33
+ readonly readOnly?: RegistryReadOnly;
26
34
  /**
27
35
  * Cursor-paginated list of guardrails sorted by id ascending.
28
36
  * Optional `nameFilter` is a prefix match on the guardrail id —