{
"contracts": [
{
"id": "step-confirmation",
"mode": "BLOCK",
"triggers": [{"type": "tool", "pattern": "*", "count": 3}]
}
]
}
ADR-003: YAML Config instead of JSON/AsciiDoc
Status
Accepted
Context
The plugin needs a configuration format for steering rules. The config is written by the user and read by the ConfigLoader component. Requirements:
-
Readability: Must be easy for humans to write (no expert knowledge required)
-
Diff-friendliness: One changed rule = one line diff
-
Validatability: Must be checkable against a schema (Zod)
-
Comments: Users must be able to comment out / deactivate rules
-
Ecosystem Alignment: Should be compatible with existing standards
Alternatives Considered
Option A: JSON
Advantages: - Natively supported by Zod (JSON.parse) - Widely used, every language can read JSON - Strict format (no interpreted values)
Disadvantages: - No comments — Users cannot comment out rules - Poor diff readability — especially with nested objects - Trailing commas not allowed (source of errors) - Users must quote keys (unnecessary typing effort) - More syntactic "noise" than YAML for comparable structures
Option B: YAML (chosen)
contracts:
- id: step-confirmation
mode: BLOCK
# Temporary disabled:
# - id: source-anchor
triggers:
- type: tool
pattern: "*"
count: 3
Advantages:
- Comments with # — rules can be deactivated without being deleted
- Excellent diff readability — one line change = one line diff
- Easier to write (no quotes around keys, fewer brackets)
- Already established for comparable agent-steering formats:
- agentcontract/spec uses .contract.yaml
- Kiros /steering uses YAML
- Natively parsed by js-yaml library
- Can be validated with Zod (after YAML→JS object transformation)
Disadvantages:
- Significant whitespace — indentation errors cause parse failures
- Not type-safe by default (Zod schema validation catches this)
- Less strict than JSON (empty values become null)
- js-yaml as an additional runtime dependency
Option C: AsciiDoc (.adoc)
Format of the Semantic-Anchors repository. Could serve as a native config format.
Disadvantages: - Not a structured data format — AsciiDoc is for documentation, not configuration - No standardised schema validation - Would need to be parsed with regex/ADoc parser (no Zod support) - Far less common for config purposes - Would make contribution to the Semantic-Anchors repo easier, but worsen user experience
Option D: opencode.jsonc (JSON with Comments)
opencode itself uses opencode.jsonc as its config format.
Disadvantages:
- Positioning: Plugin config should be separate from opencode config (own file)
- .jsonc (JSON with Comments) has no native parser — would need stripping before JSON.parse
- Less common than YAML for steering rules
- agentcontract/spec and Kiros also use YAML — alignment more important than opencode convention
Evaluation Criteria
| Criterion | Weight | Description |
|---|---|---|
Readability |
High |
Easy for humans to write and read |
Diff-friendliness |
High |
Small diff size for individual changes |
Comments |
High |
Users must be able to deactivate rules |
Schema-validatability |
High |
Must be checkable with Zod |
Ecosystem alignment |
Medium |
Should harmonise with agentcontract/spec etc. |
Type safety |
Medium |
Wrong types should be detected early |
Decision
Option B: YAML was chosen.
Rationale:
- Only option with comments + diff-friendliness + schema validation
- Alignment with agentcontract/spec (YAML) and Kiros (YAML) is strategically more important than alignment with opencode (JSONC)
- js-yaml + Zod provide sufficient type safety
- Indentation problems are detected early through Zod schema errors
Consequences
-
Positive: Users can comment out rules (feature JSON does not offer)
-
Positive: Small diff size for config changes
-
Positive: Alignment with
agentcontract/specand Kiros -
Negative: Additional dependency (
js-yaml) -
Negative: Indentation errors are a common source of mistakes for YAML beginners
-
Negative: No 1:1 mapping to opencode config format (two different formats in the setup)
-
Trade-off: YAML + Zod schema = slightly more complexity when loading, but better UX when writing
Related
-
Decision 3 in 04-solution-strategy.md
-
config/loader.tsin 05-building-block-view.md -
config/schema.tsin 05-building-block-view.md
Sources
-
AgentContract Specification — YAML Format: https://github.com/agentcontract/spec/blob/main/SPEC.md
-
js-yaml library: https://github.com/nodeca/js-yaml
-
Zod library: https://zod.dev/
-
KIROS /steering: Reference concept for runtime steering files
-
opencode Config (JSONC): https://opencode.ai/docs/config
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.