This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
# 28 — Conditions and policy DSL
|
||||
|
||||
## Goal
|
||||
|
||||
Conditional inputs, guardrails, workflow steps, checks and incompatibilities use a declarative data structure. Implementations must never execute condition text through JavaScript, a shell, template helpers or another general-purpose expression evaluator.
|
||||
|
||||
## Condition forms
|
||||
|
||||
A condition is exactly one of:
|
||||
|
||||
```yaml
|
||||
fact:
|
||||
path: inputs.migrationRequired
|
||||
operator: eq
|
||||
value: true
|
||||
```
|
||||
|
||||
```yaml
|
||||
all:
|
||||
- fact: { path: repository.stack.languages, operator: contains, value: TypeScript }
|
||||
- fact: { path: repository.capabilities, operator: contains, value: build-command }
|
||||
```
|
||||
|
||||
```yaml
|
||||
any:
|
||||
- fact: { path: composition.workMode, operator: eq, value: execute }
|
||||
- fact: { path: composition.workMode, operator: eq, value: recovery }
|
||||
```
|
||||
|
||||
```yaml
|
||||
not:
|
||||
fact: { path: inputs.preserveCompatibility, operator: truthy }
|
||||
```
|
||||
|
||||
## Allowed roots
|
||||
|
||||
- `inputs` — normalized declared playbook inputs;
|
||||
- `repository` — allowlisted normalized Repository Profile facts;
|
||||
- `composition` — work mode, autonomy, output format and resolved scope facts;
|
||||
- `platform` — safe platform capabilities and non-secret policy facts.
|
||||
|
||||
No path may reference environment variables, integration secrets, raw repository files, database queries or arbitrary object prototypes.
|
||||
|
||||
## Operators
|
||||
|
||||
- `exists`
|
||||
- `truthy`
|
||||
- `falsy`
|
||||
- `eq`
|
||||
- `neq`
|
||||
- `in`
|
||||
- `not-in`
|
||||
- `contains`
|
||||
- `gt`
|
||||
- `gte`
|
||||
- `lt`
|
||||
- `lte`
|
||||
|
||||
Operator compatibility is type-checked. Numeric comparison does not coerce strings. `contains` supports arrays and strings. `in` tests whether the fact value is present in the supplied array.
|
||||
|
||||
## Three-valued evaluation
|
||||
|
||||
Evaluation returns `true`, `false` or `unknown`.
|
||||
|
||||
Unknown occurs when:
|
||||
|
||||
- a path does not exist;
|
||||
- the value has the wrong type;
|
||||
- a required repository profile is absent;
|
||||
- an adapter cannot provide a declared capability.
|
||||
|
||||
Handling:
|
||||
|
||||
| Context | Unknown behavior |
|
||||
|---|---|
|
||||
| Blocking guardrail | Include the guardrail and add a warning; fail closed |
|
||||
| Incompatible condition | Treat as not proven incompatible and show compatibility unknown |
|
||||
| Required workflow/check | Include and warn |
|
||||
| Optional workflow/check | Exclude and warn |
|
||||
| Input visibility | Show the field so required context is not hidden |
|
||||
| Export readiness | Block only when the unresolved condition affects a required input or safety decision |
|
||||
|
||||
## Policy precedence
|
||||
|
||||
Conditions decide whether a rule applies; they do not change precedence. Final policy order remains:
|
||||
|
||||
1. platform non-overridable policy;
|
||||
2. workspace policy;
|
||||
3. repository policy;
|
||||
4. playbook guardrail;
|
||||
5. user-selectable option.
|
||||
|
||||
A false lower-priority condition cannot disable a higher-priority rule.
|
||||
|
||||
## Capability vocabulary
|
||||
|
||||
Playbooks may require only the governed capabilities in `schemas/playbook.schema.json`.
|
||||
|
||||
`test-command` is satisfied by at least one confirmed unit, integration or end-to-end test command. More specific capabilities require the corresponding command role.
|
||||
|
||||
A command marked `safeForAgentSuggestion: false` may satisfy compatibility but must not be rendered as an instruction to execute without explicit user confirmation.
|
||||
|
||||
## Determinism
|
||||
|
||||
- Object key order does not affect the result.
|
||||
- Array order for `all` and `any` does not affect the boolean result, but stored source order is preserved for provenance.
|
||||
- No current time, network call or mutable external state is available to the evaluator.
|
||||
- Every fact access is recorded in the provenance result.
|
||||
|
||||
## Validation failures
|
||||
|
||||
The package importer rejects:
|
||||
|
||||
- unknown roots or operators;
|
||||
- paths to undeclared inputs;
|
||||
- `eq` or comparison conditions with an incompatible literal type when the input type is known;
|
||||
- empty `all` or `any` groups;
|
||||
- nesting deeper than 12 levels;
|
||||
- more than 100 total condition nodes per package;
|
||||
- conditions that would require secret values.
|
||||
Reference in New Issue
Block a user