agent-contracts 0.24.0 → 0.25.0

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/dist/cli.js CHANGED
@@ -49690,6 +49690,7 @@ var PrerequisiteSchema = z.object({
49690
49690
  var AgentSchema = z.object({
49691
49691
  role_name: z.string(),
49692
49692
  purpose: z.string(),
49693
+ own_artifacts: z.array(z.string()).default([]),
49693
49694
  can_read_artifacts: z.array(z.string()).default([]),
49694
49695
  can_write_artifacts: z.array(z.string()).default([]),
49695
49696
  can_execute_tools: z.array(z.string()).default([]),
@@ -49923,6 +49924,8 @@ var ExecutionStepSchema = z9.object({
49923
49924
  uses_tool: z9.string().optional(),
49924
49925
  produces_artifact: z9.string().optional(),
49925
49926
  reads_artifact: z9.string().optional(),
49927
+ validates_artifact: z9.string().optional(),
49928
+ validation_kind: z9.enum(["schema", "mechanical", "semantic", "approval", "provenance", "traceability", "fidelity"]).optional(),
49926
49929
  depends_on: z9.array(z9.string()).optional(),
49927
49930
  skip_condition: z9.string().optional(),
49928
49931
  wait_for_approval: z9.boolean().optional()
@@ -49990,6 +49993,8 @@ var ToolSchema = z12.object({
49990
49993
  input_artifacts: z12.array(z12.string()).default([]),
49991
49994
  output_artifacts: z12.array(z12.string()).default([]),
49992
49995
  invokable_by: z12.array(z12.string()).default([]),
49996
+ cli_contract: z12.string().optional(),
49997
+ artifact_bindings: z12.record(z12.string(), z12.string()).default({}),
49993
49998
  side_effects: z12.array(z12.string()).default([]),
49994
49999
  commands: z12.array(CommandSchema).default([]),
49995
50000
  guardrails: z12.array(z12.string()).optional()
@@ -50000,8 +50005,8 @@ import { z as z13 } from "zod";
50000
50005
  var ValidationSchema = z13.object({
50001
50006
  target_artifact: z13.string(),
50002
50007
  kind: z13.enum(["schema", "mechanical", "semantic", "approval", "provenance", "traceability", "fidelity"]),
50003
- executor_type: z13.enum(["tool", "agent"]),
50004
- executor: z13.string(),
50008
+ executor_type: z13.enum(["tool", "agent"]).optional(),
50009
+ executor: z13.string().optional(),
50005
50010
  blocking: z13.boolean(),
50006
50011
  produces_evidence: z13.string().optional(),
50007
50012
  description: z13.string().optional()
@@ -52103,6 +52108,9 @@ function checkReferences(dsl) {
52103
52108
  }
52104
52109
  }
52105
52110
  for (const [id, agent] of Object.entries(dsl.agents)) {
52111
+ for (const ref of agent.own_artifacts) {
52112
+ checkExists(ref, artifactIds, "artifacts", `agents.${id}.own_artifacts`);
52113
+ }
52106
52114
  for (const ref of agent.can_read_artifacts) {
52107
52115
  checkExists(ref, artifactIds, "artifacts", `agents.${id}.can_read_artifacts`);
52108
52116
  }
@@ -52158,7 +52166,7 @@ function checkReferences(dsl) {
52158
52166
  }
52159
52167
  for (const valId of art.required_validations) {
52160
52168
  const validation = dsl.validations[valId];
52161
- if (validation?.executor_type === "tool") {
52169
+ if (validation?.executor_type === "tool" && validation.executor) {
52162
52170
  const tool = dsl.tools[validation.executor];
52163
52171
  if (tool && tool.invokable_by.length === 0) {
52164
52172
  diagnostics.push({
@@ -52176,12 +52184,15 @@ function checkReferences(dsl) {
52176
52184
  checkExists(ref, agentIds, "agents", `tools.${id}.invokable_by`);
52177
52185
  }
52178
52186
  }
52187
+ for (const ref of Object.values(tool.artifact_bindings)) {
52188
+ checkExists(ref, artifactIds, "artifacts", `tools.${id}.artifact_bindings`);
52189
+ }
52179
52190
  }
52180
52191
  for (const [id, val] of Object.entries(dsl.validations)) {
52181
52192
  checkExists(val.target_artifact, artifactIds, "artifacts", `validations.${id}.target_artifact`);
52182
- if (val.executor_type === "tool") {
52193
+ if (val.executor_type === "tool" && val.executor) {
52183
52194
  checkExists(val.executor, toolIds, "tools", `validations.${id}.executor`);
52184
- } else if (val.executor_type === "agent") {
52195
+ } else if (val.executor_type === "agent" && val.executor) {
52185
52196
  checkExists(val.executor, agentIds, "agents", `validations.${id}.executor`);
52186
52197
  }
52187
52198
  }
@@ -52565,10 +52576,10 @@ var toolExecutionRule = {
52565
52576
  for (const [agentId, agent] of Object.entries(dsl.agents)) {
52566
52577
  for (const toolId of agent.can_execute_tools) {
52567
52578
  const invokableBy = toolInvokableBy.get(toolId);
52568
- if (invokableBy && !invokableBy.has(agentId)) {
52579
+ if (invokableBy && invokableBy.size > 0 && !invokableBy.has(agentId)) {
52569
52580
  diagnostics.push({
52570
52581
  ruleId: "tool-execution",
52571
- severity: "error",
52582
+ severity: "warning",
52572
52583
  path: `agents.${agentId}.can_execute_tools`,
52573
52584
  message: `Agent "${agentId}" has can_execute_tools "${toolId}" but tool's invokable_by does not include "${agentId}"`
52574
52585
  });
@@ -52576,12 +52587,13 @@ var toolExecutionRule = {
52576
52587
  }
52577
52588
  }
52578
52589
  for (const [toolId, tool] of Object.entries(dsl.tools)) {
52590
+ if (tool.invokable_by.length === 0) continue;
52579
52591
  for (const agentId of tool.invokable_by) {
52580
52592
  const agent = dsl.agents[agentId];
52581
52593
  if (agent && !agent.can_execute_tools.includes(toolId)) {
52582
52594
  diagnostics.push({
52583
52595
  ruleId: "tool-execution",
52584
- severity: "error",
52596
+ severity: "warning",
52585
52597
  path: `tools.${toolId}.invokable_by`,
52586
52598
  message: `Tool "${toolId}" has invokable_by "${agentId}" but agent's can_execute_tools does not include "${toolId}"`
52587
52599
  });
@@ -52604,7 +52616,7 @@ var toolExecutionRule = {
52604
52616
  }
52605
52617
  }
52606
52618
  for (const [valId, val] of Object.entries(dsl.validations)) {
52607
- if (val.executor_type !== "tool") continue;
52619
+ if (val.executor_type !== "tool" || !val.executor) continue;
52608
52620
  const hasExecutor = Object.values(dsl.agents).some(
52609
52621
  (a3) => a3.can_execute_tools.includes(val.executor)
52610
52622
  );
@@ -52697,10 +52709,10 @@ var taskAgentBindingRule = {
52697
52709
  });
52698
52710
  }
52699
52711
  const tool = dsl.tools[step.uses_tool];
52700
- if (tool && !tool.invokable_by.includes(task.target_agent)) {
52712
+ if (tool && tool.invokable_by.length > 0 && !tool.invokable_by.includes(task.target_agent)) {
52701
52713
  diagnostics.push({
52702
52714
  ruleId: "task-agent-binding",
52703
- severity: "error",
52715
+ severity: "warning",
52704
52716
  path: `tasks.${taskId}.execution_steps`,
52705
52717
  message: `Task "${taskId}" step uses_tool "${step.uses_tool}" but tool's invokable_by does not include "${task.target_agent}"`
52706
52718
  });
@@ -53184,6 +53196,7 @@ var validationExecutorNoContextRule = {
53184
53196
  run(dsl) {
53185
53197
  const diagnostics = [];
53186
53198
  for (const [validationId, val] of Object.entries(dsl.validations)) {
53199
+ if (!val.executor) continue;
53187
53200
  if (val.executor_type === "agent") {
53188
53201
  const agent = dsl.agents[val.executor];
53189
53202
  if (!agent) continue;
@@ -53211,6 +53224,40 @@ var validationExecutorNoContextRule = {
53211
53224
  }
53212
53225
  };
53213
53226
 
53227
+ // src/linter/rules/artifact-ownership-consistency.ts
53228
+ var artifactOwnershipConsistencyRule = {
53229
+ id: "artifact-ownership-consistency",
53230
+ description: "Ensure own_artifacts entries are included in can_read_artifacts and check deprecated owner field consistency",
53231
+ run(dsl) {
53232
+ const diagnostics = [];
53233
+ for (const [agentId, agent] of Object.entries(dsl.agents)) {
53234
+ for (const artId of agent.own_artifacts) {
53235
+ if (!agent.can_read_artifacts.includes(artId)) {
53236
+ diagnostics.push({
53237
+ ruleId: "artifact-ownership-consistency",
53238
+ severity: "warning",
53239
+ path: `agents.${agentId}.own_artifacts`,
53240
+ message: `Agent "${agentId}" owns artifact "${artId}" but does not include it in can_read_artifacts`
53241
+ });
53242
+ }
53243
+ }
53244
+ }
53245
+ for (const [artId, art] of Object.entries(dsl.artifacts)) {
53246
+ if (!art.owner) continue;
53247
+ const ownerAgent = dsl.agents[art.owner];
53248
+ if (ownerAgent && !ownerAgent.own_artifacts.includes(artId)) {
53249
+ diagnostics.push({
53250
+ ruleId: "artifact-ownership-consistency",
53251
+ severity: "warning",
53252
+ path: `artifacts.${artId}.owner`,
53253
+ message: `Artifact "${artId}" has deprecated owner "${art.owner}" but agent does not list it in own_artifacts`
53254
+ });
53255
+ }
53256
+ }
53257
+ return diagnostics;
53258
+ }
53259
+ };
53260
+
53214
53261
  // src/linter/rules/extension-consumption.ts
53215
53262
  function isRecord4(v2) {
53216
53263
  return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
@@ -53398,6 +53445,7 @@ var builtinRules = [
53398
53445
  entityNoGuardrailsRule,
53399
53446
  guardrailOrphanedRule,
53400
53447
  validationExecutorNoContextRule,
53448
+ artifactOwnershipConsistencyRule,
53401
53449
  extensionDeclaredButUnusedRule,
53402
53450
  extensionScopeMismatchRule,
53403
53451
  extensionUndeclaredUsageRule
@@ -53867,9 +53915,9 @@ var ruleset = {
53867
53915
  }
53868
53916
  },
53869
53917
  "tool-invokable-by-ref": {
53870
- description: "Tool invokable_by must reference existing agents",
53918
+ description: "(deprecated) Tool invokable_by must reference existing agents",
53871
53919
  message: "{{error}}",
53872
- severity: "error",
53920
+ severity: "warn",
53873
53921
  given: "$.tools.*",
53874
53922
  then: {
53875
53923
  field: "invokable_by",
@@ -53888,8 +53936,8 @@ var ruleset = {
53888
53936
  }
53889
53937
  },
53890
53938
  "artifact-owner-exists": {
53891
- description: "Every artifact must have an owner",
53892
- severity: "error",
53939
+ description: "(deprecated) Every artifact must have an owner",
53940
+ severity: "warn",
53893
53941
  given: "$.artifacts.*",
53894
53942
  then: {
53895
53943
  field: "owner",
@@ -54593,8 +54641,8 @@ function collectReferencedIds(workflow, dsl, relatedTasks) {
54593
54641
  } else if (step.type === "validation") {
54594
54642
  const val = dsl.validations[step.validation];
54595
54643
  if (val) {
54596
- if (val.executor_type === "agent") addAgent(val.executor);
54597
- else tools.add(val.executor);
54644
+ if (val.executor && val.executor_type === "agent") addAgent(val.executor);
54645
+ else if (val.executor) tools.add(val.executor);
54598
54646
  artifacts.add(val.target_artifact);
54599
54647
  }
54600
54648
  }
@@ -54970,9 +55018,9 @@ function collectPhaseOps(dsl, wfId) {
54970
55018
  } else if (step.type === "validation") {
54971
55019
  const val = dsl.validations[step.validation];
54972
55020
  if (val) {
54973
- if (val.executor_type === "agent") {
55021
+ if (val.executor_type === "agent" && val.executor) {
54974
55022
  addOp(agentOps, val.executor, "validate");
54975
- } else {
55023
+ } else if (val.executor) {
54976
55024
  addOp(toolOps, val.executor, "verification");
54977
55025
  }
54978
55026
  addOp(artifactOps, val.target_artifact, "V");