agent-contracts 0.11.5 → 0.11.6
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/README.md +7 -1
- package/dist/cli.js +110 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.js +110 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1234,7 +1234,9 @@ Checks:
|
|
|
1234
1234
|
Checks:
|
|
1235
1235
|
|
|
1236
1236
|
* bidirectional consistency
|
|
1237
|
-
* validation coverage
|
|
1237
|
+
* validation coverage — warns when artifacts lack validations or have empty `required_validations` (fails under `--strict`)
|
|
1238
|
+
* artifact-required-validation wiring — verifies every entry in `artifact.required_validations` exists, targets the correct artifact, and is referenced in a workflow step or task
|
|
1239
|
+
* task-output-validation completeness — checks that tasks producing artifacts (via `execution_steps.produces_artifact` or agent `can_write_artifacts`) cover those artifacts' `required_validations`
|
|
1238
1240
|
* workflow graph completeness
|
|
1239
1241
|
* merge integrity
|
|
1240
1242
|
* read-only write violations
|
|
@@ -1244,6 +1246,10 @@ Checks:
|
|
|
1244
1246
|
* YAML safety — warns when YAML 1.1 reserved words (`on`, `yes`, `no`, `true`, `false`, etc.) are used in positions where they may be misinterpreted by non-1.2 parsers
|
|
1245
1247
|
* naming/style issues through Spectral rules
|
|
1246
1248
|
|
|
1249
|
+
#### `--strict` mode
|
|
1250
|
+
|
|
1251
|
+
When `--strict` is passed to `lint` or `check`, warnings are treated as failures (exit code 1). This is particularly relevant for artifact-centric validation rules — empty `required_validations`, orphaned validation wiring, and incomplete task coverage are all warnings that become blocking under `--strict`.
|
|
1252
|
+
|
|
1247
1253
|
---
|
|
1248
1254
|
|
|
1249
1255
|
## Best used with runtime frameworks
|
package/dist/cli.js
CHANGED
|
@@ -52288,6 +52288,7 @@ var validationCoverageRule = {
|
|
|
52288
52288
|
}
|
|
52289
52289
|
validationsByArtifact.get(val.target_artifact).add(val.kind);
|
|
52290
52290
|
}
|
|
52291
|
+
const strictArtifactTypes = ["code", "config", "schema"];
|
|
52291
52292
|
for (const [artId, art] of Object.entries(dsl.artifacts)) {
|
|
52292
52293
|
const kinds = validationsByArtifact.get(artId);
|
|
52293
52294
|
if (!kinds || kinds.size === 0) {
|
|
@@ -52299,8 +52300,7 @@ var validationCoverageRule = {
|
|
|
52299
52300
|
});
|
|
52300
52301
|
continue;
|
|
52301
52302
|
}
|
|
52302
|
-
|
|
52303
|
-
if (mechanicalTypes.includes(art.type) && !kinds.has("mechanical") && !kinds.has("schema")) {
|
|
52303
|
+
if (strictArtifactTypes.includes(art.type) && !kinds.has("mechanical") && !kinds.has("schema")) {
|
|
52304
52304
|
diagnostics.push({
|
|
52305
52305
|
ruleId: "validation-coverage",
|
|
52306
52306
|
severity: "warning",
|
|
@@ -52309,6 +52309,16 @@ var validationCoverageRule = {
|
|
|
52309
52309
|
});
|
|
52310
52310
|
}
|
|
52311
52311
|
}
|
|
52312
|
+
for (const [artId, art] of Object.entries(dsl.artifacts)) {
|
|
52313
|
+
if (art.required_validations.length === 0) {
|
|
52314
|
+
diagnostics.push({
|
|
52315
|
+
ruleId: "validation-coverage",
|
|
52316
|
+
severity: "warning",
|
|
52317
|
+
path: `artifacts.${artId}`,
|
|
52318
|
+
message: `Artifact "${artId}" has empty required_validations`
|
|
52319
|
+
});
|
|
52320
|
+
}
|
|
52321
|
+
}
|
|
52312
52322
|
const referencedValidations = /* @__PURE__ */ new Set();
|
|
52313
52323
|
for (const wf of Object.values(dsl.workflow)) {
|
|
52314
52324
|
for (const step of wf.steps) {
|
|
@@ -52695,6 +52705,101 @@ var yamlReservedKeySafetyRule = {
|
|
|
52695
52705
|
}
|
|
52696
52706
|
};
|
|
52697
52707
|
|
|
52708
|
+
// src/linter/rules/artifact-required-validation-wiring.ts
|
|
52709
|
+
var artifactRequiredValidationWiringRule = {
|
|
52710
|
+
id: "artifact-required-validation-wiring",
|
|
52711
|
+
description: "Every validation listed in artifact.required_validations must exist, target the artifact, and be referenced in a workflow step or task.",
|
|
52712
|
+
run(dsl) {
|
|
52713
|
+
const diagnostics = [];
|
|
52714
|
+
const referencedValidations = /* @__PURE__ */ new Set();
|
|
52715
|
+
for (const wf of Object.values(dsl.workflow)) {
|
|
52716
|
+
for (const step of wf.steps) {
|
|
52717
|
+
if (step.type === "validation") {
|
|
52718
|
+
referencedValidations.add(step.validation);
|
|
52719
|
+
}
|
|
52720
|
+
}
|
|
52721
|
+
}
|
|
52722
|
+
for (const task of Object.values(dsl.tasks)) {
|
|
52723
|
+
for (const valId of task.validations) {
|
|
52724
|
+
referencedValidations.add(valId);
|
|
52725
|
+
}
|
|
52726
|
+
}
|
|
52727
|
+
for (const [artId, art] of Object.entries(dsl.artifacts)) {
|
|
52728
|
+
for (const reqValId of art.required_validations) {
|
|
52729
|
+
const val = dsl.validations[reqValId];
|
|
52730
|
+
if (!val) {
|
|
52731
|
+
diagnostics.push({
|
|
52732
|
+
ruleId: "artifact-required-validation-wiring",
|
|
52733
|
+
severity: "error",
|
|
52734
|
+
path: `artifacts.${artId}`,
|
|
52735
|
+
message: `required_validation "${reqValId}" does not exist in validations`
|
|
52736
|
+
});
|
|
52737
|
+
continue;
|
|
52738
|
+
}
|
|
52739
|
+
if (val.target_artifact !== artId) {
|
|
52740
|
+
diagnostics.push({
|
|
52741
|
+
ruleId: "artifact-required-validation-wiring",
|
|
52742
|
+
severity: "error",
|
|
52743
|
+
path: `artifacts.${artId}`,
|
|
52744
|
+
message: `required_validation "${reqValId}" has target_artifact "${val.target_artifact}" instead of "${artId}"`
|
|
52745
|
+
});
|
|
52746
|
+
}
|
|
52747
|
+
if (!referencedValidations.has(reqValId)) {
|
|
52748
|
+
diagnostics.push({
|
|
52749
|
+
ruleId: "artifact-required-validation-wiring",
|
|
52750
|
+
severity: "warning",
|
|
52751
|
+
path: `artifacts.${artId}`,
|
|
52752
|
+
message: `required_validation "${reqValId}" is defined but not referenced in any workflow step or task`
|
|
52753
|
+
});
|
|
52754
|
+
}
|
|
52755
|
+
}
|
|
52756
|
+
}
|
|
52757
|
+
return diagnostics;
|
|
52758
|
+
}
|
|
52759
|
+
};
|
|
52760
|
+
|
|
52761
|
+
// src/linter/rules/task-output-validation-completeness.ts
|
|
52762
|
+
var taskOutputValidationCompletenessRule = {
|
|
52763
|
+
id: "task-output-validation-completeness",
|
|
52764
|
+
description: "Tasks producing artifacts should cover those artifacts' required_validations in their validations list.",
|
|
52765
|
+
run(dsl) {
|
|
52766
|
+
const diagnostics = [];
|
|
52767
|
+
for (const [taskId, task] of Object.entries(dsl.tasks)) {
|
|
52768
|
+
const producedArtifacts = /* @__PURE__ */ new Set();
|
|
52769
|
+
if (task.execution_steps) {
|
|
52770
|
+
for (const step of task.execution_steps) {
|
|
52771
|
+
if (step.produces_artifact) {
|
|
52772
|
+
producedArtifacts.add(step.produces_artifact);
|
|
52773
|
+
}
|
|
52774
|
+
}
|
|
52775
|
+
}
|
|
52776
|
+
const agent = dsl.agents[task.target_agent];
|
|
52777
|
+
if (agent) {
|
|
52778
|
+
for (const artId of agent.can_write_artifacts) {
|
|
52779
|
+
producedArtifacts.add(artId);
|
|
52780
|
+
}
|
|
52781
|
+
}
|
|
52782
|
+
const taskValidations = new Set(task.validations);
|
|
52783
|
+
for (const artId of producedArtifacts) {
|
|
52784
|
+
const art = dsl.artifacts[artId];
|
|
52785
|
+
if (!art || art.required_validations.length === 0) continue;
|
|
52786
|
+
const missing = art.required_validations.filter(
|
|
52787
|
+
(v2) => !taskValidations.has(v2)
|
|
52788
|
+
);
|
|
52789
|
+
if (missing.length > 0) {
|
|
52790
|
+
diagnostics.push({
|
|
52791
|
+
ruleId: "task-output-validation-completeness",
|
|
52792
|
+
severity: "warning",
|
|
52793
|
+
path: `tasks.${taskId}`,
|
|
52794
|
+
message: `Task produces artifact "${artId}" which requires validations [${missing.join(", ")}] but task.validations does not include them`
|
|
52795
|
+
});
|
|
52796
|
+
}
|
|
52797
|
+
}
|
|
52798
|
+
}
|
|
52799
|
+
return diagnostics;
|
|
52800
|
+
}
|
|
52801
|
+
};
|
|
52802
|
+
|
|
52698
52803
|
// src/linter/linter.ts
|
|
52699
52804
|
var builtinRules = [
|
|
52700
52805
|
validationCoverageRule,
|
|
@@ -52704,7 +52809,9 @@ var builtinRules = [
|
|
|
52704
52809
|
artifactOwnershipRule,
|
|
52705
52810
|
toolCommandsRule,
|
|
52706
52811
|
guardrailPolicyCoverageRule,
|
|
52707
|
-
yamlReservedKeySafetyRule
|
|
52812
|
+
yamlReservedKeySafetyRule,
|
|
52813
|
+
artifactRequiredValidationWiringRule,
|
|
52814
|
+
taskOutputValidationCompletenessRule
|
|
52708
52815
|
];
|
|
52709
52816
|
function lint(dsl, rules = builtinRules) {
|
|
52710
52817
|
const diagnostics = [];
|