agent-contracts 0.30.4 → 0.31.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/README.md +10 -0
- package/dist/cli.js +75 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +99 -16
- package/dist/index.js +78 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -278,6 +278,8 @@ A **Guardrail Policy** defines enforcement strategy for guardrails:
|
|
|
278
278
|
|
|
279
279
|
* rules — array of enforcement rules mapping guardrails to actions
|
|
280
280
|
* Each rule specifies: severity (`critical`/`mandatory`/`warning`/`info`), action (`block`/`warn`/`shadow`/`info`), override permissions
|
|
281
|
+
* `action` supports a conditional form for state-dependent enforcement: `{ default: "block", when: { maintenance: "shadow" } }`
|
|
282
|
+
* Available states are declared system-wide via `system.states`
|
|
281
283
|
|
|
282
284
|
### Handoff Type
|
|
283
285
|
|
|
@@ -337,6 +339,7 @@ Design regressions become testable.
|
|
|
337
339
|
* **Inheritance with merge operators via `extends`**
|
|
338
340
|
* **Guardrail definitions** for cross-cutting process constraints
|
|
339
341
|
* **Guardrail policies** with configurable enforcement (block/warn/shadow/info)
|
|
342
|
+
* **State-dependent guardrail action** — `action` accepts a conditional form `{ default, when }` keyed by `system.states` for workspace-mode-aware enforcement
|
|
340
343
|
* **Software bindings** (DI) for tool-specific guardrail implementation (Cursor, Git, GitHub)
|
|
341
344
|
* **Guardrail generation** from DSL + policy + bindings via `generate guardrails`
|
|
342
345
|
* **Navigation index** — compile-time artifact-centric model mapping artifacts to operations, agent permissions, relations, and action routes
|
|
@@ -374,6 +377,7 @@ system:
|
|
|
374
377
|
- audit
|
|
375
378
|
- release
|
|
376
379
|
- reflect
|
|
380
|
+
states: [] # optional — named workspace states for conditional guardrail action
|
|
377
381
|
|
|
378
382
|
agents: {}
|
|
379
383
|
tasks: {}
|
|
@@ -1536,6 +1540,12 @@ guardrail_policies:
|
|
|
1536
1540
|
- guardrail: no-force-push
|
|
1537
1541
|
severity: critical
|
|
1538
1542
|
action: block
|
|
1543
|
+
- guardrail: branch-lock
|
|
1544
|
+
severity: critical
|
|
1545
|
+
action:
|
|
1546
|
+
default: block
|
|
1547
|
+
when:
|
|
1548
|
+
maintenance: shadow
|
|
1539
1549
|
- guardrail: english-only-code
|
|
1540
1550
|
severity: warning
|
|
1541
1551
|
action: warn
|
package/dist/cli.js
CHANGED
|
@@ -49099,10 +49099,16 @@ var GuardrailPolicyRuleEscalationSchema = z6.object({
|
|
|
49099
49099
|
target: z6.string(),
|
|
49100
49100
|
condition: z6.string().optional()
|
|
49101
49101
|
}).passthrough();
|
|
49102
|
+
var ActionEnum = z6.enum(["block", "warn", "shadow", "info"]);
|
|
49103
|
+
var ConditionalActionSchema = z6.object({
|
|
49104
|
+
default: ActionEnum,
|
|
49105
|
+
when: z6.record(z6.string(), ActionEnum)
|
|
49106
|
+
});
|
|
49107
|
+
var ActionSchema = z6.union([ActionEnum, ConditionalActionSchema]);
|
|
49102
49108
|
var GuardrailPolicyRuleSchema = z6.object({
|
|
49103
49109
|
guardrail: z6.string(),
|
|
49104
49110
|
severity: z6.enum(["critical", "mandatory", "warning", "info"]),
|
|
49105
|
-
action:
|
|
49111
|
+
action: ActionSchema,
|
|
49106
49112
|
allow_override: z6.boolean().default(false),
|
|
49107
49113
|
override_requires: z6.array(z6.string()).optional(),
|
|
49108
49114
|
escalation: GuardrailPolicyRuleEscalationSchema.optional()
|
|
@@ -49134,7 +49140,8 @@ var SystemSchema = z8.object({
|
|
|
49134
49140
|
name: z8.string(),
|
|
49135
49141
|
default_workflow_order: z8.array(z8.string()),
|
|
49136
49142
|
sections: z8.array(SectionSchema).optional(),
|
|
49137
|
-
context_loading: ContextLoadingSchema
|
|
49143
|
+
context_loading: ContextLoadingSchema,
|
|
49144
|
+
states: z8.array(z8.string()).default([])
|
|
49138
49145
|
}).passthrough();
|
|
49139
49146
|
|
|
49140
49147
|
// src/schema/task.ts
|
|
@@ -52246,6 +52253,70 @@ var guardrailPolicyCoverageRule = {
|
|
|
52246
52253
|
}
|
|
52247
52254
|
};
|
|
52248
52255
|
|
|
52256
|
+
// src/linter/rules/guardrail-policy-action-state.ts
|
|
52257
|
+
function isConditionalAction(action) {
|
|
52258
|
+
return typeof action === "object" && action !== null && "default" in action;
|
|
52259
|
+
}
|
|
52260
|
+
function collectReferencedWhenStates(dsl) {
|
|
52261
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
52262
|
+
for (const policy of Object.values(dsl.guardrail_policies)) {
|
|
52263
|
+
for (const rule of policy.rules) {
|
|
52264
|
+
if (isConditionalAction(rule.action)) {
|
|
52265
|
+
for (const state of Object.keys(rule.action.when)) {
|
|
52266
|
+
referenced.add(state);
|
|
52267
|
+
}
|
|
52268
|
+
}
|
|
52269
|
+
}
|
|
52270
|
+
}
|
|
52271
|
+
return referenced;
|
|
52272
|
+
}
|
|
52273
|
+
var guardrailPolicyActionStateUndefinedRule = {
|
|
52274
|
+
id: "guardrail-policy-action-state-undefined",
|
|
52275
|
+
description: "Policy rule action.when keys must reference states declared in system.states",
|
|
52276
|
+
run(dsl) {
|
|
52277
|
+
const diagnostics = [];
|
|
52278
|
+
const systemStates = new Set(dsl.system.states ?? []);
|
|
52279
|
+
for (const [policyId, policy] of Object.entries(dsl.guardrail_policies)) {
|
|
52280
|
+
for (let ruleIndex = 0; ruleIndex < policy.rules.length; ruleIndex++) {
|
|
52281
|
+
const rule = policy.rules[ruleIndex];
|
|
52282
|
+
if (!isConditionalAction(rule.action)) continue;
|
|
52283
|
+
for (const state of Object.keys(rule.action.when)) {
|
|
52284
|
+
if (!systemStates.has(state)) {
|
|
52285
|
+
diagnostics.push({
|
|
52286
|
+
ruleId: "guardrail-policy-action-state-undefined",
|
|
52287
|
+
severity: "error",
|
|
52288
|
+
path: `guardrail_policies.${policyId}.rules[${ruleIndex}].action.when.${state}`,
|
|
52289
|
+
message: `Policy rule references state "${state}" in action.when, but it is not declared in system.states`
|
|
52290
|
+
});
|
|
52291
|
+
}
|
|
52292
|
+
}
|
|
52293
|
+
}
|
|
52294
|
+
}
|
|
52295
|
+
return diagnostics;
|
|
52296
|
+
}
|
|
52297
|
+
};
|
|
52298
|
+
var systemStatesUnusedRule = {
|
|
52299
|
+
id: "system-states-unused",
|
|
52300
|
+
description: "Each state in system.states should be referenced by at least one policy rule action.when",
|
|
52301
|
+
run(dsl) {
|
|
52302
|
+
const diagnostics = [];
|
|
52303
|
+
const states = dsl.system.states ?? [];
|
|
52304
|
+
if (states.length === 0) return diagnostics;
|
|
52305
|
+
const referenced = collectReferencedWhenStates(dsl);
|
|
52306
|
+
for (const state of states) {
|
|
52307
|
+
if (!referenced.has(state)) {
|
|
52308
|
+
diagnostics.push({
|
|
52309
|
+
ruleId: "system-states-unused",
|
|
52310
|
+
severity: "info",
|
|
52311
|
+
path: `system.states`,
|
|
52312
|
+
message: `State "${state}" is declared in system.states but not referenced by any policy rule action.when`
|
|
52313
|
+
});
|
|
52314
|
+
}
|
|
52315
|
+
}
|
|
52316
|
+
return diagnostics;
|
|
52317
|
+
}
|
|
52318
|
+
};
|
|
52319
|
+
|
|
52249
52320
|
// src/linter/rules/yaml-reserved-key-safety.ts
|
|
52250
52321
|
var YAML_11_RESERVED_KEYS = /* @__PURE__ */ new Set([
|
|
52251
52322
|
"on",
|
|
@@ -53055,6 +53126,8 @@ var builtinRules = [
|
|
|
53055
53126
|
artifactOwnershipRule,
|
|
53056
53127
|
toolCommandsRule,
|
|
53057
53128
|
guardrailPolicyCoverageRule,
|
|
53129
|
+
guardrailPolicyActionStateUndefinedRule,
|
|
53130
|
+
systemStatesUnusedRule,
|
|
53058
53131
|
yamlReservedKeySafetyRule,
|
|
53059
53132
|
artifactRequiredValidationWiringRule,
|
|
53060
53133
|
taskOutputValidationCompletenessRule,
|