open-multi-agent-kit 0.78.2 → 0.78.3

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 (42) hide show
  1. package/CHANGELOG.md +27 -2
  2. package/dist/benchmark/contracts.d.ts +116 -0
  3. package/dist/benchmark/contracts.js +6 -0
  4. package/dist/benchmark/fixtures.d.ts +11 -0
  5. package/dist/benchmark/fixtures.js +121 -0
  6. package/dist/benchmark/harness.d.ts +13 -0
  7. package/dist/benchmark/harness.js +191 -0
  8. package/dist/benchmark/shadow-mode.d.ts +17 -0
  9. package/dist/benchmark/shadow-mode.js +96 -0
  10. package/dist/commands/merge.js +102 -56
  11. package/dist/contracts/provider-health.d.ts +37 -0
  12. package/dist/contracts/provider-health.js +49 -1
  13. package/dist/evidence/evidence-trust-score.d.ts +101 -0
  14. package/dist/evidence/evidence-trust-score.js +408 -0
  15. package/dist/evidence/index.d.ts +2 -0
  16. package/dist/evidence/index.js +1 -0
  17. package/dist/orchestration/merge-arbiter.d.ts +91 -0
  18. package/dist/orchestration/merge-arbiter.js +376 -0
  19. package/dist/providers/health.d.ts +3 -0
  20. package/dist/providers/health.js +46 -0
  21. package/dist/providers/index.d.ts +1 -0
  22. package/dist/providers/index.js +1 -0
  23. package/dist/providers/provider-health.d.ts +8 -1
  24. package/dist/providers/provider-health.js +39 -0
  25. package/dist/providers/provider-task-runner.js +31 -0
  26. package/dist/providers/provider.d.ts +2 -0
  27. package/dist/providers/router.js +87 -3
  28. package/dist/providers/types.d.ts +4 -0
  29. package/dist/runtime/provider-maturity-gate.d.ts +2 -0
  30. package/dist/runtime/provider-maturity-gate.js +28 -0
  31. package/dist/runtime/tool-dispatch-contracts.d.ts +24 -3
  32. package/dist/runtime/tool-dispatch-contracts.js +42 -2
  33. package/dist/runtime/weakness-remediation-index.d.ts +1 -1
  34. package/dist/runtime/weakness-remediation-index.js +1 -1
  35. package/dist/safety/enforcement-engine.d.ts +89 -0
  36. package/dist/safety/enforcement-engine.js +279 -0
  37. package/dist/safety/tool-authority-gate.d.ts +40 -0
  38. package/dist/safety/tool-authority-gate.js +92 -0
  39. package/dist/schema/evidence.schema.d.ts +2 -2
  40. package/dist/schema/proof-bundle.schema.d.ts +2 -2
  41. package/docs/benchmark-design.md +122 -0
  42. package/package.json +5 -2
@@ -1,3 +1,4 @@
1
+ import { PROVIDER_CAPABILITY_ORDINAL } from "../contracts/provider-health.js";
1
2
  import { DEFAULT_AUTHORITY_PROVIDER, resolveFallbackProvider } from "./types.js";
2
3
  const DEEPSEEK_READ_ONLY_ROLES = new Set([
3
4
  "explorer",
@@ -41,7 +42,17 @@ export function routeProvider(input) {
41
42
  const role = input.role.toLowerCase();
42
43
  const seed = `${input.nodeId ?? ""}:${role}:${input.taskType}`;
43
44
  const authorityProvider = resolveFallbackProvider(input.authorityProvider);
44
- const authorityDecision = (reason, confidence, deepseek, extra = {}) => authorityProviderDecision(authorityProvider, reason, confidence, deepseek, extra);
45
+ const authorityVector = input.providerHealthVectors?.[authorityProvider];
46
+ const authorityProviderAllowed = providerVectorAllowsAuthority(authorityVector);
47
+ const authorityProviderFallbackOnly = authorityVector
48
+ ? !providerVectorQuotaOk(authorityVector) && providerVectorAllowsDirect(authorityVector)
49
+ : false;
50
+ const authorityDecision = (reason, confidence, deepseek, extra = {}) => {
51
+ if (!authorityProviderAllowed || authorityProviderFallbackOnly) {
52
+ return authorityProviderDecision(authorityProvider, `${providerLabel(authorityProvider)} ${authorityProviderFallbackOnly ? "quota exhausted" : "auth insufficient"}; using fallback-only route`, Math.max(0.5, confidence - 0.15), deepseek, extra);
53
+ }
54
+ return authorityProviderDecision(authorityProvider, reason, confidence, deepseek, extra);
55
+ };
45
56
  const directDeepSeekAllowed = canUseDirectDeepSeek(role, input);
46
57
  const dedicatedDeepSeekAgent = isDedicatedDeepSeekAgent(input);
47
58
  const withRouteEnsemble = (decision, winner) => ({
@@ -60,6 +71,11 @@ export function routeProvider(input) {
60
71
  if (role === "orchestrator" || role === "merger" || role === "integrator") {
61
72
  return withRouteEnsemble(authorityDecision("Core orchestration and merge authority stay with the configured authority provider", 1), "safety-gate");
62
73
  }
74
+ // Hard constraint: if authority provider is blocked by vector, skip to safety gate
75
+ // unless an explicit, fully-available external provider is requested.
76
+ if (!authorityProviderAllowed && !requestedExternalProvider(input)) {
77
+ return withRouteEnsemble(authorityProviderDecision(authorityProvider, `${providerLabel(authorityProvider)} auth/quota insufficient for authority lanes; safety gate active`, 0.5), "safety-gate");
78
+ }
63
79
  const externalProvider = requestedExternalProvider(input);
64
80
  if (externalProvider) {
65
81
  if (!isProviderAvailable(input, externalProvider)) {
@@ -69,6 +85,12 @@ export function routeProvider(input) {
69
85
  }
70
86
  // If the external provider is the authority provider, route to it as authority
71
87
  if (externalProvider === authorityProvider) {
88
+ // Hard constraint: auth != ok → exclude authority lanes
89
+ if (!authorityProviderAllowed) {
90
+ return withRouteEnsemble(authorityDecision(`${providerLabel(externalProvider)} auth/quota insufficient for authority; using configured fallback`, 0.86, undefined, {
91
+ providerModel: genericProviderModelRef(input, externalProvider, "veto"),
92
+ }), "safety-gate");
93
+ }
72
94
  return withRouteEnsemble(authorityDecision(`${providerLabel(externalProvider)} is the configured authority provider`, 0.9, undefined, {
73
95
  providerModel: genericProviderModelRef(input, externalProvider, "authority"),
74
96
  }), "authority-provider");
@@ -178,8 +200,48 @@ function requestedExternalProvider(input) {
178
200
  function isGenericExternalProvider(value) {
179
201
  return typeof value === "string" && value !== "auto" && value !== "kimi" && value !== "deepseek";
180
202
  }
203
+ function providerVectorMeets(vector, minState) {
204
+ if (!vector)
205
+ return true;
206
+ const current = PROVIDER_CAPABILITY_ORDINAL[vector.auth];
207
+ const required = PROVIDER_CAPABILITY_ORDINAL[minState];
208
+ return current >= required;
209
+ }
210
+ function providerVectorQuotaOk(vector) {
211
+ if (!vector)
212
+ return true;
213
+ return PROVIDER_CAPABILITY_ORDINAL[vector.quota] >= PROVIDER_CAPABILITY_ORDINAL["quota_available"];
214
+ }
215
+ function providerVectorAllowsAuthority(vector) {
216
+ if (!vector)
217
+ return true;
218
+ return (PROVIDER_CAPABILITY_ORDINAL[vector.auth] >= PROVIDER_CAPABILITY_ORDINAL["auth_valid"] &&
219
+ PROVIDER_CAPABILITY_ORDINAL[vector.model] >= PROVIDER_CAPABILITY_ORDINAL["model_available"] &&
220
+ PROVIDER_CAPABILITY_ORDINAL[vector.quota] >= PROVIDER_CAPABILITY_ORDINAL["quota_available"]);
221
+ }
222
+ function providerVectorAllowsDirect(vector) {
223
+ if (!vector)
224
+ return true;
225
+ return (PROVIDER_CAPABILITY_ORDINAL[vector.auth] >= PROVIDER_CAPABILITY_ORDINAL["auth_valid"] &&
226
+ PROVIDER_CAPABILITY_ORDINAL[vector.model] >= PROVIDER_CAPABILITY_ORDINAL["model_available"] &&
227
+ PROVIDER_CAPABILITY_ORDINAL[vector.quota] >= PROVIDER_CAPABILITY_ORDINAL["quota_available"]);
228
+ }
229
+ function providerVectorAllowsAdvisory(vector) {
230
+ if (!vector)
231
+ return true;
232
+ return PROVIDER_CAPABILITY_ORDINAL[vector.auth] >= PROVIDER_CAPABILITY_ORDINAL["auth_present"];
233
+ }
181
234
  function isProviderAvailable(input, provider) {
182
235
  const explicit = input.providerAvailability?.[provider];
236
+ const vector = input.providerHealthVectors?.[provider];
237
+ if (vector) {
238
+ // Hard constraint: quota exhausted → fallback only (not fully available)
239
+ if (!providerVectorQuotaOk(vector))
240
+ return false;
241
+ // Hard constraint: auth not valid → not available for any lane
242
+ if (PROVIDER_CAPABILITY_ORDINAL[vector.auth] < PROVIDER_CAPABILITY_ORDINAL["auth_valid"])
243
+ return false;
244
+ }
183
245
  return explicit === undefined ? true : explicit;
184
246
  }
185
247
  function canUseGenericDirectProvider(role, input) {
@@ -187,7 +249,15 @@ function canUseGenericDirectProvider(role, input) {
187
249
  return false;
188
250
  if (input.needsMcp || input.needsToolCalling)
189
251
  return false;
190
- return input.readOnly === true || GENERIC_EXTERNAL_READ_ONLY_ROLES.has(role);
252
+ if (!input.readOnly && !GENERIC_EXTERNAL_READ_ONLY_ROLES.has(role))
253
+ return false;
254
+ const externalProvider = requestedExternalProvider(input);
255
+ if (externalProvider) {
256
+ const vector = input.providerHealthVectors?.[externalProvider];
257
+ if (vector && !providerVectorAllowsDirect(vector))
258
+ return false;
259
+ }
260
+ return true;
191
261
  }
192
262
  function canUseGenericAdvisoryProvider(role, input) {
193
263
  if (!GENERIC_EXTERNAL_ADVISORY_FILE_ROLES.has(role))
@@ -196,6 +266,12 @@ function canUseGenericAdvisoryProvider(role, input) {
196
266
  return false;
197
267
  if (input.needsMcp || input.needsToolCalling)
198
268
  return false;
269
+ const externalProvider = requestedExternalProvider(input);
270
+ if (externalProvider) {
271
+ const vector = input.providerHealthVectors?.[externalProvider];
272
+ if (vector && !providerVectorAllowsAdvisory(vector))
273
+ return false;
274
+ }
199
275
  return true;
200
276
  }
201
277
  function canUseDeepSeekProAdvisory(role, input) {
@@ -205,12 +281,20 @@ function canUseDeepSeekProAdvisory(role, input) {
205
281
  return false;
206
282
  if (input.needsMcp || input.needsToolCalling)
207
283
  return false;
284
+ const vector = input.providerHealthVectors?.["deepseek"];
285
+ if (vector && !providerVectorAllowsAdvisory(vector))
286
+ return false;
208
287
  return true;
209
288
  }
210
289
  function canUseDirectDeepSeek(role, input) {
211
290
  if (input.risk !== "read")
212
291
  return false;
213
- return input.readOnly === true || DEEPSEEK_READ_ONLY_ROLES.has(role);
292
+ if (!(input.readOnly === true || DEEPSEEK_READ_ONLY_ROLES.has(role)))
293
+ return false;
294
+ const vector = input.providerHealthVectors?.["deepseek"];
295
+ if (vector && !providerVectorAllowsDirect(vector))
296
+ return false;
297
+ return true;
214
298
  }
215
299
  function buildProviderRouteEnsemble(options) {
216
300
  const { input, role, decision, winner, directDeepSeekAllowed } = options;
@@ -71,6 +71,8 @@ export interface ProviderRouteInput {
71
71
  authorityProvider?: ProviderId;
72
72
  preferredModel?: string;
73
73
  preferredDeepSeekTier?: DeepSeekModelTier;
74
+ /** v2 capability vectors for hard-constraint filtering. */
75
+ providerHealthVectors?: Partial<Record<ProviderId, import("../contracts/provider-health.js").ProviderHealthVector>>;
74
76
  }
75
77
  export interface ProviderRouteDecision {
76
78
  provider: ProviderId;
@@ -90,6 +92,8 @@ export interface ProviderAvailability {
90
92
  checkedAt: number;
91
93
  reason?: string;
92
94
  disableForRun: boolean;
95
+ /** v2 capability vector (optional; present when profiler v2 is active). */
96
+ healthVector?: import("../contracts/provider-health.js").ProviderHealthVector;
93
97
  }
94
98
  export interface AgentProvider {
95
99
  id: ProviderId;
@@ -6,6 +6,7 @@
6
6
  * verdict.
7
7
  */
8
8
  import type { AdapterTestKind, AdapterTestResult, ProviderAuthorityClass } from "./contracts/evidence.js";
9
+ import type { ProviderHealthVector } from "../contracts/provider-health.js";
9
10
  /** Maturity evaluation result for a single provider. */
10
11
  export interface MaturityResult {
11
12
  /** Computed maturity score M_p ∈ [0, 1]. */
@@ -39,3 +40,4 @@ export interface ProviderMaturityTable {
39
40
  }
40
41
  export declare function createProviderMaturityTable(): ProviderMaturityTable;
41
42
  export declare function createProviderMaturityGate(): ProviderMaturityGate;
43
+ export declare function evaluateProviderFromVector(gate: ProviderMaturityGate, vector: ProviderHealthVector): MaturityResult;
@@ -5,6 +5,7 @@
5
5
  * produces a maturity score M_p, an authority class, and a pass/fail
6
6
  * verdict.
7
7
  */
8
+ import { PROVIDER_CAPABILITY_ORDINAL } from "../contracts/provider-health.js";
8
9
  // ── Constants ───────────────────────────────────────────────────
9
10
  const WEIGHT_AUTH = 0.10;
10
11
  const WEIGHT_READ = 0.10;
@@ -72,6 +73,30 @@ export function createProviderMaturityTable() {
72
73
  },
73
74
  };
74
75
  }
76
+ function vectorToAdapterResults(vector) {
77
+ const authOrdinal = PROVIDER_CAPABILITY_ORDINAL[vector.auth];
78
+ const binaryOrdinal = PROVIDER_CAPABILITY_ORDINAL[vector.binary];
79
+ const modelOrdinal = PROVIDER_CAPABILITY_ORDINAL[vector.model];
80
+ const quotaOrdinal = PROVIDER_CAPABILITY_ORDINAL[vector.quota];
81
+ const authScore = authOrdinal >= PROVIDER_CAPABILITY_ORDINAL["auth_valid"] ? 1.0 : authOrdinal / PROVIDER_CAPABILITY_ORDINAL["auth_valid"];
82
+ const readScore = vector.supportsRead ? 1.0 : 0.0;
83
+ const writeScore = vector.supportsWrite ? 1.0 : 0.0;
84
+ const shellScore = vector.supportsShell ? 1.0 : 0.0;
85
+ const mcpScore = binaryOrdinal >= PROVIDER_CAPABILITY_ORDINAL["tool_contract_verified"] ? 1.0 : binaryOrdinal / PROVIDER_CAPABILITY_ORDINAL["tool_contract_verified"];
86
+ const mergeScore = vector.evidencePassRate7d;
87
+ const evidenceScore = vector.evidencePassRate7d;
88
+ const fallbackScore = 1.0 - vector.failureEwma;
89
+ return [
90
+ { kind: "auth", passed: authScore >= 0.5, score: authScore },
91
+ { kind: "read", passed: readScore >= 0.5, score: readScore },
92
+ { kind: "write", passed: writeScore >= 0.5, score: writeScore },
93
+ { kind: "shell", passed: shellScore >= 0.5, score: shellScore },
94
+ { kind: "mcp", passed: mcpScore >= 0.5, score: mcpScore },
95
+ { kind: "merge", passed: mergeScore >= 0.5, score: mergeScore },
96
+ { kind: "evidence", passed: evidenceScore >= 0.5, score: evidenceScore },
97
+ { kind: "fallback", passed: fallbackScore >= 0.5, score: fallbackScore },
98
+ ];
99
+ }
75
100
  export function createProviderMaturityGate() {
76
101
  return {
77
102
  evaluate(results) {
@@ -99,3 +124,6 @@ export function createProviderMaturityGate() {
99
124
  },
100
125
  };
101
126
  }
127
+ export function evaluateProviderFromVector(gate, vector) {
128
+ return gate.evaluate(vectorToAdapterResults(vector));
129
+ }
@@ -1,6 +1,7 @@
1
1
  import type { OmkToolCall, OmkToolDefinition } from "./tool-registry-contract.js";
2
- import { type ToolAuthorityDecision, type ToolOp } from "../safety/tool-authority-gate.js";
2
+ import { type ToolAuthorityDecision, type ToolOp, type ToolOpV2 } from "../safety/tool-authority-gate.js";
3
3
  import type { ProviderAuthorityLevel } from "../contracts/provider-health.js";
4
+ import type { EnforcementProof } from "../safety/enforcement-engine.js";
4
5
  export interface ToolDispatchResult<R = unknown> {
5
6
  readonly call: OmkToolCall;
6
7
  readonly status: "fulfilled" | "rejected";
@@ -15,13 +16,15 @@ export type ToolAuthorityMode = "shadow" | "enforce";
15
16
  */
16
17
  export interface ToolAuthorityDecisionRecord {
17
18
  readonly toolName: string;
18
- readonly op: ToolOp;
19
+ readonly op: ToolOp | ToolOpV2;
19
20
  readonly decision: ToolAuthorityDecision;
20
21
  readonly mode: ToolAuthorityMode;
21
22
  /** True only when the verdict actually rejected the call (enforce + block). */
22
23
  readonly enforced: boolean;
23
24
  /** Redacted, human-readable reason. Never includes args or secret values. */
24
25
  readonly reason: string;
26
+ /** v2 enforcement proof hash when available. */
27
+ readonly policyHash?: string;
25
28
  }
26
29
  /**
27
30
  * Authority wiring for one dispatch turn. All inputs are non-secret enum/bool
@@ -42,6 +45,12 @@ export interface ToolAuthorityWiring {
42
45
  readonly enforce?: boolean;
43
46
  /** Optional sink for computed verdicts (invoked in both shadow and enforce). */
44
47
  readonly onDecision?: (record: ToolAuthorityDecisionRecord) => void;
48
+ /**
49
+ * v2 enforcement proof from the adapter / runtime.
50
+ * When present, the gate uses policy-dependent capability resolution.
51
+ * Runtimes without a valid proof cannot enter authority lanes.
52
+ */
53
+ readonly enforcementProof?: EnforcementProof;
45
54
  }
46
55
  /**
47
56
  * Resolve the global enforcement opt-in from the environment. Default OFF means
@@ -52,8 +61,9 @@ export declare function resolveToolAuthorityEnforcement(env?: Record<string, str
52
61
  /** Error used to reject a tool call rejected by the authority gate (enforce mode). */
53
62
  export declare class ToolAuthorityBlockedError extends Error {
54
63
  readonly toolName: string;
55
- readonly op: ToolOp;
64
+ readonly op: ToolOp | ToolOpV2;
56
65
  readonly decision: ToolAuthorityDecision;
66
+ readonly policyHash?: string;
57
67
  constructor(record: ToolAuthorityDecisionRecord);
58
68
  }
59
69
  /** Compute the gate verdict for a single call. Pure (no IO, no env reads). */
@@ -61,4 +71,15 @@ export declare function evaluateToolAuthority(toolName: string, wiring: ToolAuth
61
71
  readonly record: ToolAuthorityDecisionRecord;
62
72
  readonly blocked: boolean;
63
73
  };
74
+ /**
75
+ * Compute the gate verdict for a single call using v2 enforcement proof.
76
+ * Pure (no IO, no env reads).
77
+ *
78
+ * If `enforcementProof` is present, the gate uses policy-dependent capability
79
+ * resolution. Runtimes without a valid proof cannot enter authority lanes.
80
+ */
81
+ export declare function evaluateToolAuthorityV2(toolName: string, wiring: ToolAuthorityWiring): {
82
+ readonly record: ToolAuthorityDecisionRecord;
83
+ readonly blocked: boolean;
84
+ };
64
85
  export declare function dispatchToolCallsByContract<A, R>(calls: readonly OmkToolCall<A>[], registry: ReadonlyMap<string, OmkToolDefinition<A, R>>, dispatchOne: (call: OmkToolCall<A>) => Promise<R>, authority?: ToolAuthorityWiring): Promise<ToolDispatchResult<R>[]>;
@@ -1,5 +1,5 @@
1
1
  import { createToolExecutionBatches } from "./tool-registry-contract.js";
2
- import { decideToolAuthority, mapToolNameToOp, } from "../safety/tool-authority-gate.js";
2
+ import { decideToolAuthority, decideToolAuthorityV2, mapToolNameToOp, } from "../safety/tool-authority-gate.js";
3
3
  const ENFORCE_PATTERN = /^(1|true|yes|on)$/i;
4
4
  /**
5
5
  * Resolve the global enforcement opt-in from the environment. Default OFF means
@@ -20,12 +20,14 @@ export class ToolAuthorityBlockedError extends Error {
20
20
  toolName;
21
21
  op;
22
22
  decision;
23
+ policyHash;
23
24
  constructor(record) {
24
25
  super(record.reason);
25
26
  this.name = "ToolAuthorityBlockedError";
26
27
  this.toolName = record.toolName;
27
28
  this.op = record.op;
28
29
  this.decision = record.decision;
30
+ this.policyHash = record.policyHash;
29
31
  }
30
32
  }
31
33
  /** Compute the gate verdict for a single call. Pure (no IO, no env reads). */
@@ -57,6 +59,44 @@ export function evaluateToolAuthority(toolName, wiring) {
57
59
  blocked,
58
60
  };
59
61
  }
62
+ /**
63
+ * Compute the gate verdict for a single call using v2 enforcement proof.
64
+ * Pure (no IO, no env reads).
65
+ *
66
+ * If `enforcementProof` is present, the gate uses policy-dependent capability
67
+ * resolution. Runtimes without a valid proof cannot enter authority lanes.
68
+ */
69
+ export function evaluateToolAuthorityV2(toolName, wiring) {
70
+ const op = mapToolNameToOp(toolName);
71
+ if (wiring.enforcementProof) {
72
+ const decision = decideToolAuthorityV2({
73
+ op,
74
+ writeAuthority: wiring.writeAuthority,
75
+ shellAuthority: wiring.shellAuthority,
76
+ approvalPolicy: wiring.approvalPolicy,
77
+ sandboxMode: wiring.sandboxMode,
78
+ tty: wiring.tty,
79
+ enforcementProof: wiring.enforcementProof,
80
+ });
81
+ const enforce = wiring.enforce === true;
82
+ const wouldBlock = decision === "block" || (decision === "ask" && !wiring.tty);
83
+ const blocked = enforce && wouldBlock;
84
+ return {
85
+ record: {
86
+ toolName,
87
+ op,
88
+ decision,
89
+ mode: enforce ? "enforce" : "shadow",
90
+ enforced: blocked,
91
+ reason: redactedAuthorityReason(op, decision, wiring),
92
+ policyHash: wiring.enforcementProof.policyHash,
93
+ },
94
+ blocked,
95
+ };
96
+ }
97
+ // Fall back to legacy evaluation when no proof is present.
98
+ return evaluateToolAuthority(toolName, wiring);
99
+ }
60
100
  /**
61
101
  * Wrap a dispatch function with the authority checkpoint. In shadow mode the
62
102
  * wrapper records the verdict and always delegates to `dispatchOne`. In enforce
@@ -64,7 +104,7 @@ export function evaluateToolAuthority(toolName, wiring) {
64
104
  */
65
105
  function buildGatedDispatch(wiring, dispatchOne) {
66
106
  return async (call) => {
67
- const { record, blocked } = evaluateToolAuthority(call.toolName, wiring);
107
+ const { record, blocked } = evaluateToolAuthorityV2(call.toolName, wiring);
68
108
  wiring.onDecision?.(record);
69
109
  if (blocked) {
70
110
  throw new ToolAuthorityBlockedError(record);
@@ -5,7 +5,7 @@
5
5
  export { type IntegrationResultKind, type WeaknessRemediationState, type AdvancedControlLoopInput, type AdvancedControlLoopResult, type AdvancedControlLoop, type AdvancedControlLoopOptions, createAdvancedControlLoop, } from "./advanced-control-loop.js";
6
6
  export { type SurfaceItem, type ScoredSurfaceItem, type MandatoryAnchor, type CompressionResult, type PublicSurfaceCompressorOptions, computeSurfaceScore, enforceFlowInvariant, PublicSurfaceCompressor, } from "./public-surface.js";
7
7
  export { type ProofBundleScores, type TrustScoreResult, type ProofBundleTrustEngine, type DeriveScoresOptions, createProofBundleTrustEngine, } from "./proof-bundle-trust.js";
8
- export { type MaturityResult, type ProviderMaturityGate, createProviderMaturityGate, } from "./provider-maturity-gate.js";
8
+ export { type MaturityResult, type ProviderMaturityGate, createProviderMaturityGate, evaluateProviderFromVector, } from "./provider-maturity-gate.js";
9
9
  export { type RuntimeScoreV2, type RuntimeRouterDecisionV2, type RouterV2Options, type RouterV2ScoringEngine, type BlastRadiusParams, type EvidenceHistoryEntry, type NodeIntent, } from "./contracts/router-v2.js";
10
10
  export { createRouterV2ScoringEngine, } from "./router-v2-scoring.js";
11
11
  export { type ReleasePromotionInputs, type ReleasePromotionResult, type ReleaseVerdict, RELEASE_GATE_WEIGHTS, TAU_EVIDENCE, TAU_EVIDENCE_HIGH, TAU_PROOF, TAU_STABLE, BETA_PRIOR_ALPHA0, BETA_PRIOR_BETA0, SURFACE_BUDGET_K, } from "./contracts/weakness-remediation.js";
@@ -5,7 +5,7 @@
5
5
  export { createAdvancedControlLoop, } from "./advanced-control-loop.js";
6
6
  export { computeSurfaceScore, enforceFlowInvariant, PublicSurfaceCompressor, } from "./public-surface.js";
7
7
  export { createProofBundleTrustEngine, } from "./proof-bundle-trust.js";
8
- export { createProviderMaturityGate, } from "./provider-maturity-gate.js";
8
+ export { createProviderMaturityGate, evaluateProviderFromVector, } from "./provider-maturity-gate.js";
9
9
  export { createRouterV2ScoringEngine, } from "./router-v2-scoring.js";
10
10
  export { RELEASE_GATE_WEIGHTS, TAU_EVIDENCE, TAU_EVIDENCE_HIGH, TAU_PROOF, TAU_STABLE, BETA_PRIOR_ALPHA0, BETA_PRIOR_BETA0, SURFACE_BUDGET_K, } from "./contracts/weakness-remediation.js";
11
11
  export { createReleasePromotionGate, } from "../cli/release-promotion-gate.js";
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Policy / Sandbox Enforcement Engine v2
3
+ *
4
+ * Capability lattice with conservative policy combination.
5
+ * effectivePolicy = minByAuthority(userPolicy, repoPolicy, providerPolicy, adapterPolicy, riskPolicy)
6
+ *
7
+ * Conservative by default. Any ambiguity → block.
8
+ */
9
+ export type SandboxCapability = "read" | "write" | "shell" | "network" | "secret_read" | "secret_write" | "merge" | "publish";
10
+ export declare const ALL_CAPABILITIES: readonly SandboxCapability[];
11
+ export type CapabilityLevel = "none" | "advisory" | "direct" | "full";
12
+ export interface CapabilityLattice {
13
+ read: CapabilityLevel;
14
+ write: CapabilityLevel;
15
+ shell: CapabilityLevel;
16
+ network: CapabilityLevel;
17
+ secret_read: CapabilityLevel;
18
+ secret_write: CapabilityLevel;
19
+ merge: CapabilityLevel;
20
+ publish: CapabilityLevel;
21
+ }
22
+ export type SandboxMode = "read-only" | "workspace-write" | "network-isolated" | "unrestricted";
23
+ export type ApprovalPolicy = "interactive" | "auto" | "yolo" | "block";
24
+ export interface PolicyLayer {
25
+ readonly source: "user" | "repo" | "provider" | "adapter" | "risk";
26
+ /** Partial lattice — omitted capabilities mean "no opinion" (inherit from other layers). */
27
+ readonly lattice: Partial<CapabilityLattice>;
28
+ readonly sandboxMode?: SandboxMode;
29
+ readonly approvalPolicy?: ApprovalPolicy;
30
+ }
31
+ export interface CombinedPolicy {
32
+ readonly lattice: Readonly<CapabilityLattice>;
33
+ readonly sandboxMode: SandboxMode;
34
+ readonly approvalPolicy: ApprovalPolicy;
35
+ /** Ordered list of sources that contributed to the combination. */
36
+ readonly sources: readonly PolicyLayer["source"][];
37
+ }
38
+ export interface EnforcementProof {
39
+ readonly sandboxMode: SandboxMode;
40
+ /** Which policy layers were active in the final combination. */
41
+ readonly enforcedBy: readonly string[];
42
+ /** Capabilities fully blocked (level === "none" or sandbox hard floor). */
43
+ readonly blockedCapabilities: readonly SandboxCapability[];
44
+ /** Capabilities that require explicit approval (level === "advisory" or interactive policy). */
45
+ readonly approvalRequired: readonly SandboxCapability[];
46
+ /** Deterministic hash of the combined policy for audit / replay. */
47
+ readonly policyHash: string;
48
+ }
49
+ export declare function rankOf(level: CapabilityLevel): number;
50
+ export declare function defaultLattice(): CapabilityLattice;
51
+ /**
52
+ * Combine multiple policy layers by taking the **most restrictive**
53
+ * (minimum) authority level for each capability.
54
+ *
55
+ * If no layer expresses an opinion on a capability, it defaults to "full".
56
+ * If any layer expresses a sandbox mode, the most restrictive mode wins.
57
+ * If any layer expresses an approval policy, the most restrictive wins.
58
+ */
59
+ export declare function combinePoliciesByMinAuthority(layers: readonly PolicyLayer[]): CombinedPolicy;
60
+ /**
61
+ * Compute the enforcement proof from a combined policy.
62
+ *
63
+ * Rules:
64
+ * 1. read-only sandbox blocks write, shell, network, merge, publish.
65
+ * 2. network-isolated sandbox blocks network.
66
+ * 3. Any capability with level "none" is blocked.
67
+ * 4. Any capability with level "advisory" requires approval.
68
+ * 5. interactive policy requires approval for non-read capabilities.
69
+ * 6. block policy blocks everything except read.
70
+ */
71
+ export declare function computeEnforcementProof(combined: CombinedPolicy): EnforcementProof;
72
+ /**
73
+ * Returns true when the runtime/adapter has provided a valid enforcement proof.
74
+ * Runtimes without enforcement proof cannot enter authority lanes.
75
+ */
76
+ export declare function hasValidEnforcementProof(proof: unknown): proof is EnforcementProof;
77
+ export declare function policyLayerFromLegacyAuthorities(source: PolicyLayer["source"], options: {
78
+ writeAuthority?: "none" | "advisory" | "direct" | "full";
79
+ shellAuthority?: "none" | "advisory" | "direct" | "full";
80
+ sandboxMode?: SandboxMode;
81
+ approvalPolicy?: ApprovalPolicy;
82
+ }): PolicyLayer;
83
+ export type ToolOpV2 = "read" | "write" | "shell" | "merge" | "network" | "secret";
84
+ /**
85
+ * Map a capability-lattice capability to the coarse ToolOp used by the gate.
86
+ * This preserves backward compatibility with the existing 4-class gate while
87
+ * allowing the new lattice to express finer-grained restrictions.
88
+ */
89
+ export declare function capabilityToToolOp(cap: SandboxCapability): ToolOpV2;