agent-contracts 0.11.7 → 0.11.8
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 +26 -0
- package/dist/cli.js +65 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +65 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -229,6 +229,31 @@ Workflow steps support additional properties:
|
|
|
229
229
|
* `retry` (delegate steps) — defines a conditional retry loop with `condition`, `fix_task`, and optional `revalidate_task`
|
|
230
230
|
* `routing_key` (decision steps) — the field that determines branch selection. The legacy field `on` is still accepted but deprecated due to YAML 1.1 reserved word collision
|
|
231
231
|
|
|
232
|
+
### Validation
|
|
233
|
+
|
|
234
|
+
A **Validation** defines a verification step for an artifact:
|
|
235
|
+
|
|
236
|
+
* `target_artifact` — the artifact being verified
|
|
237
|
+
* `kind` — the type of verification (see below)
|
|
238
|
+
* `executor_type` — `tool` (automated) or `agent` (agent-driven)
|
|
239
|
+
* `executor` — the tool or agent that runs the validation
|
|
240
|
+
* `blocking` — whether the validation must pass before proceeding
|
|
241
|
+
* `produces_evidence` — optional artifact produced as evidence
|
|
242
|
+
|
|
243
|
+
#### Validation kinds
|
|
244
|
+
|
|
245
|
+
| Kind | Purpose | Example |
|
|
246
|
+
|------|---------|---------|
|
|
247
|
+
| `schema` | Structural schema check | JSON Schema validation, OpenAPI lint, SQL syntax |
|
|
248
|
+
| `mechanical` | Automated tool check | CLI linters, diff checks, coverage reports |
|
|
249
|
+
| `semantic` | Meaning-level review | Agent-based review of spec intent, plan coherence |
|
|
250
|
+
| `approval` | Human/agent sign-off gate | Architect approval before implementation |
|
|
251
|
+
| `provenance` | Source derivation verification | Confirm generated artifact derives from its canonical source (e.g., manifest from API contracts) |
|
|
252
|
+
| `traceability` | Cross-artifact link completeness | Verify every spec requirement reaches contracts, tests, and code |
|
|
253
|
+
| `fidelity` | Semantic faithfulness to source | Confirm tests actually verify spec intent, not just structural compliance |
|
|
254
|
+
|
|
255
|
+
`schema` and `mechanical` are best suited for automated checks via tools. `semantic`, `fidelity`, and `approval` are typically agent-driven. `provenance` and `traceability` can be either tool or agent-based depending on the verification complexity.
|
|
256
|
+
|
|
232
257
|
### Guardrail
|
|
233
258
|
|
|
234
259
|
A **Guardrail** declares a cross-cutting constraint:
|
|
@@ -1268,6 +1293,7 @@ Checks:
|
|
|
1268
1293
|
* prerequisite readability
|
|
1269
1294
|
* artifact ownership — `produces_artifact`/`reads_artifact` in execution steps vs. artifact producers/editors/consumers
|
|
1270
1295
|
* tool commands — `commands[].reads`/`commands[].writes` reference valid artifacts and align with `output_artifacts`
|
|
1296
|
+
* semantic validation phase coverage — warns when `semantic` or `fidelity` validations only appear in late workflow phases (e.g., audit) but not earlier phases (e.g., specify, plan)
|
|
1271
1297
|
* 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
|
|
1272
1298
|
* naming/style issues through Spectral rules
|
|
1273
1299
|
|
package/dist/cli.js
CHANGED
|
@@ -50676,7 +50676,7 @@ var ToolSchema = z9.object({
|
|
|
50676
50676
|
import { z as z10 } from "zod";
|
|
50677
50677
|
var ValidationSchema = z10.object({
|
|
50678
50678
|
target_artifact: z10.string(),
|
|
50679
|
-
kind: z10.enum(["schema", "mechanical", "semantic", "approval"]),
|
|
50679
|
+
kind: z10.enum(["schema", "mechanical", "semantic", "approval", "provenance", "traceability", "fidelity"]),
|
|
50680
50680
|
executor_type: z10.enum(["tool", "agent"]),
|
|
50681
50681
|
executor: z10.string(),
|
|
50682
50682
|
blocking: z10.boolean(),
|
|
@@ -52800,6 +52800,68 @@ var taskOutputValidationCompletenessRule = {
|
|
|
52800
52800
|
}
|
|
52801
52801
|
};
|
|
52802
52802
|
|
|
52803
|
+
// src/linter/rules/semantic-validation-phase-coverage.ts
|
|
52804
|
+
var SEMANTIC_KINDS = /* @__PURE__ */ new Set(["semantic", "fidelity"]);
|
|
52805
|
+
var semanticValidationPhaseCoverageRule = {
|
|
52806
|
+
id: "semantic-validation-phase-coverage",
|
|
52807
|
+
description: "Semantic and fidelity validations should appear in early workflow phases, not only in late phases.",
|
|
52808
|
+
run(dsl) {
|
|
52809
|
+
const diagnostics = [];
|
|
52810
|
+
const semanticValIds = /* @__PURE__ */ new Set();
|
|
52811
|
+
for (const [valId, val] of Object.entries(dsl.validations)) {
|
|
52812
|
+
if (SEMANTIC_KINDS.has(val.kind)) {
|
|
52813
|
+
semanticValIds.add(valId);
|
|
52814
|
+
}
|
|
52815
|
+
}
|
|
52816
|
+
if (semanticValIds.size === 0) {
|
|
52817
|
+
return diagnostics;
|
|
52818
|
+
}
|
|
52819
|
+
const phaseOrder = dsl.system.default_workflow_order;
|
|
52820
|
+
if (phaseOrder.length < 2) {
|
|
52821
|
+
return diagnostics;
|
|
52822
|
+
}
|
|
52823
|
+
const phaseValidations = /* @__PURE__ */ new Map();
|
|
52824
|
+
for (const phase of phaseOrder) {
|
|
52825
|
+
phaseValidations.set(phase, /* @__PURE__ */ new Set());
|
|
52826
|
+
}
|
|
52827
|
+
for (const [phase, wf] of Object.entries(dsl.workflow)) {
|
|
52828
|
+
if (!phaseValidations.has(phase)) continue;
|
|
52829
|
+
for (const step of wf.steps) {
|
|
52830
|
+
if (step.type === "validation" && semanticValIds.has(step.validation)) {
|
|
52831
|
+
phaseValidations.get(phase).add(step.validation);
|
|
52832
|
+
}
|
|
52833
|
+
}
|
|
52834
|
+
}
|
|
52835
|
+
for (const task of Object.values(dsl.tasks)) {
|
|
52836
|
+
const phase = task.workflow;
|
|
52837
|
+
if (!phaseValidations.has(phase)) continue;
|
|
52838
|
+
for (const valId of task.validations) {
|
|
52839
|
+
if (semanticValIds.has(valId)) {
|
|
52840
|
+
phaseValidations.get(phase).add(valId);
|
|
52841
|
+
}
|
|
52842
|
+
}
|
|
52843
|
+
}
|
|
52844
|
+
const earlyBoundary = Math.ceil(phaseOrder.length / 2);
|
|
52845
|
+
const earlyPhases = phaseOrder.slice(0, earlyBoundary);
|
|
52846
|
+
const latePhases = phaseOrder.slice(earlyBoundary);
|
|
52847
|
+
const earlyHasAny = earlyPhases.some(
|
|
52848
|
+
(p2) => (phaseValidations.get(p2)?.size ?? 0) > 0
|
|
52849
|
+
);
|
|
52850
|
+
const lateWithSemantic = latePhases.filter(
|
|
52851
|
+
(p2) => (phaseValidations.get(p2)?.size ?? 0) > 0
|
|
52852
|
+
);
|
|
52853
|
+
if (!earlyHasAny && lateWithSemantic.length > 0) {
|
|
52854
|
+
diagnostics.push({
|
|
52855
|
+
ruleId: "semantic-validation-phase-coverage",
|
|
52856
|
+
severity: "warning",
|
|
52857
|
+
path: "validations",
|
|
52858
|
+
message: `Semantic validations are only referenced in workflow phases [${lateWithSemantic.join(", ")}]. Consider adding semantic review to earlier phases [${earlyPhases.join(", ")}] to catch issues before implementation.`
|
|
52859
|
+
});
|
|
52860
|
+
}
|
|
52861
|
+
return diagnostics;
|
|
52862
|
+
}
|
|
52863
|
+
};
|
|
52864
|
+
|
|
52803
52865
|
// src/linter/linter.ts
|
|
52804
52866
|
var builtinRules = [
|
|
52805
52867
|
validationCoverageRule,
|
|
@@ -52811,7 +52873,8 @@ var builtinRules = [
|
|
|
52811
52873
|
guardrailPolicyCoverageRule,
|
|
52812
52874
|
yamlReservedKeySafetyRule,
|
|
52813
52875
|
artifactRequiredValidationWiringRule,
|
|
52814
|
-
taskOutputValidationCompletenessRule
|
|
52876
|
+
taskOutputValidationCompletenessRule,
|
|
52877
|
+
semanticValidationPhaseCoverageRule
|
|
52815
52878
|
];
|
|
52816
52879
|
function lint(dsl, rules = builtinRules) {
|
|
52817
52880
|
const diagnostics = [];
|