@suluk/agents 0.1.1 → 0.1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suluk/agents",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Suluk Agent composition (C027): lint + project an `x-suluk-agents` map (skills + deterministic routes + by-name sub-agents) to a Claude plugin AND an OpenRouter/OpenAI-compatible manifest — one contract, two artifacts, zero network at generate time. Determinism is DECLARED not enforced; the matcher never reads an agent field. CANDIDATE tooling — NOT official OAS.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -18,7 +18,7 @@ import { policiesFor } from "./policy";
18
18
  */
19
19
  export type ResolvedTarget =
20
20
  | { kind: "pinned"; model: string }
21
- | { kind: "router"; model: "openrouter/auto"; allowedModels: string[]; costQualityTradeoff: number }
21
+ | { kind: "router"; model: "openrouter/auto"; allowedModels: string[]; costQualityTradeoff: number; provider?: { zdr: true } }
22
22
  | { kind: "latest"; model: string; note: string };
23
23
 
24
24
  export interface SkillModelResolution {
@@ -92,13 +92,23 @@ export function skillModels(doc: OpenAPIv4Document, agentName: string, skillName
92
92
  const snapshotHash = declared ? null : catalog.snapshotHash;
93
93
 
94
94
  const mode = skill?.modelResolve ?? "pinned";
95
+ const governed = isGoverned(doc, agentName);
96
+ // ZDR (C030, verified 2026-06-13 — `provider:{zdr:true}` combines with `model:"openrouter/auto"`, 200 live): we have no
97
+ // per-model ZDR FACT to pin against, so ZDR is enforceable ONLY at runtime via the router → a `zdr` skill resolves to the
98
+ // ROUTER regardless of `modelResolve`. Authors who pinned get it: the pin can't honor ZDR, the router can.
99
+ const wantsZdr = !!skill?.modelRequire?.zdr;
95
100
  // GOVERNANCE GATE (mechanical): a governed skill MUST pin — router/latest are non-reproducible + cannot bind an endpoint.
96
- if (isGoverned(doc, agentName) && mode !== "pinned")
101
+ if (governed && mode !== "pinned")
97
102
  throw new Error(`@suluk/agents: skill "${skillName}" of agent "${agentName}" is GOVERNED by an operator policy — modelResolve:"${mode}" is inadmissible (a governed skill must be "pinned" for reproducible, auditable, endpoint-bindable selection). Remove the policy or use "pinned".`);
103
+ // ZDR-under-governance is unsatisfiable via OpenRouter: ZDR needs the router (`provider.zdr`), governance forces a pin, and
104
+ // region/license have NO endpoint knob — fail loud rather than silently dropping the ZDR constraint or the governance pin.
105
+ if (governed && wantsZdr)
106
+ throw new Error(`@suluk/agents: skill "${skillName}" of agent "${agentName}" requires ZDR (modelRequire.zdr) AND is GOVERNED by an operator policy — unsatisfiable: ZDR is enforced only via the router's provider.zdr, but a governed skill must pin (region/license have no OpenRouter endpoint knob). Drop one.`);
98
107
 
99
108
  let target: ResolvedTarget;
100
109
  let pickPinned: boolean;
101
- if (mode === "router") { target = { kind: "router", model: "openrouter/auto", allowedModels: ids, costQualityTradeoff: deriveCQT(skill) }; pickPinned = false; }
110
+ if (wantsZdr) { target = { kind: "router", model: "openrouter/auto", allowedModels: ids, costQualityTradeoff: deriveCQT(skill), provider: { zdr: true } }; pickPinned = false; }
111
+ else if (mode === "router") { target = { kind: "router", model: "openrouter/auto", allowedModels: ids, costQualityTradeoff: deriveCQT(skill) }; pickPinned = false; }
102
112
  else if (mode === "latest") { target = { kind: "latest", model: toLatestAlias(ids[0] ?? ""), note: "~-latest defers the concrete version to request time — NOT reproducible (recorded in the why-explainer)" }; pickPinned = false; }
103
113
  else { target = { kind: "pinned", model: ids[0] ?? "" }; pickPinned = true; }
104
114
 
@@ -96,3 +96,24 @@ describe("C030 resolution target — pin (default) / router (delegate) / latest,
96
96
  expect(deriveCQT({ modelProfile: "max-reasoning" })).toBe(0);
97
97
  });
98
98
  });
99
+
100
+ describe("C030 ZDR — verified 2026-06-13 (provider.zdr + openrouter/auto combine, 200 live)", () => {
101
+ test("a modelRequire.zdr skill resolves to the ROUTER with provider:{zdr:true} EVEN at the default (pinned) mode — no per-model ZDR fact to pin against", () => {
102
+ const d = doc();
103
+ d["x-suluk-agents"]!.conin.skills!.operate = { modelProfile: "balanced", modelRequire: { zdr: true } }; // no modelResolve ⇒ default pinned
104
+ const r = skillModels(d, "conin", "operate", SEED_CATALOG);
105
+ expect(r.target.kind).toBe("router");
106
+ if (r.target.kind === "router") {
107
+ expect(r.target.provider).toEqual({ zdr: true });
108
+ expect(r.target.allowedModels).toEqual(r.ids); // ZDR is enforced at the endpoint; the fence still enumerates survivors
109
+ }
110
+ expect(r.pickPinned).toBe(false); // the served id is logged-not-pinned (ZDR endpoint chosen at runtime)
111
+ });
112
+
113
+ test("ZDR + an operator policy is UNSATISFIABLE via OpenRouter — fails loud (ZDR needs the router, governance forces a pin)", () => {
114
+ const d = doc();
115
+ d["x-suluk-policy"] = { fleet: { appliesTo: ["#/x-suluk-agents/conin"], modelAllowlist: ["google/gemini-2.5-flash"] } };
116
+ d["x-suluk-agents"]!.conin.skills!.operate = { modelProfile: "balanced", modelRequire: { zdr: true } };
117
+ expect(() => skillModels(d, "conin", "operate", SEED_CATALOG)).toThrow(/ZDR|unsatisfiable/i);
118
+ });
119
+ });