Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

A-26013: JSON as Governance Config Format — Migration from YAML


title: JSON as Governance Config Format — Migration from YAML authors:


A-26013: JSON as Governance Config Format — Migration from YAML

Problem Statement

The .vadocs/ governance config (conf.yaml) was created as a YAML file by convention — YAML is common in documentation tooling (MyST uses myst.yml). As the config grew from a simple vocabulary registry toward a validation schema, YAML’s limitations emerged:

  1. No native schema validation. When the authors field needed format specification (list of {name, email} objects per MyST spec), we faced a choice: invent a custom value_format structure in YAML, or adopt a standard schema language. Custom invention means every new constraint type requires custom design and custom validation code.

  2. Parsing ambiguities. YAML’s implicit typing (Norway problem: NO → false), colon-space gotcha (already documented in CLAUDE.md as a project pitfall), and indentation sensitivity create failure modes that don’t exist in stricter formats.

  3. External dependency. Python’s yaml module requires PyYAML. The vadocs package (Phase 1.3) would carry this dependency solely for config parsing, while json is stdlib and tomllib (for pyproject.toml) is also stdlib since 3.11.

  4. Format invention pressure. The date_format regex at the bottom of conf.yaml was already a validation rule mixed into the vocabulary registry. Adding authors format would repeat the pattern. Each new complex field would require another custom structure — essentially building a bespoke schema language inside YAML.

The question: should governance configs remain YAML, move to JSON, or use another format?

Key Insights

Format comparison for machine-consumed governance configs

ConcernYAMLJSONTOML
Schema validationNone native; requires custom inventionJSON Schema — industry standard, jsonschema libraryNone native
Parsing ambiguityImplicit typing, : gotcha, multiple syntax formsUnambiguous grammarUnambiguous, typed
Python stdlib parserNo (PyYAML required)Yes (json module)Yes (tomllib, 3.11+)
Nested structuresGoodGoodWeak (verbose [section.sub.key])
CommentsNativeNot supportedNative
Human editing frequencyGovernance configs change rarelyRare edits are fine without commentsRare edits are fine
Agent consumptionParses structure, doesn’t benefit from commentsParses structure nativelyParses structure natively

Why not TOML?

TOML is already used in the ecosystem (pyproject.toml, ADR-26029). However, the governance configs have deeply nested structures — type registry with blocks, required/ optional fields, field registry entries with multiple properties. TOML’s flat section headers ([types.adr.blocks]) become verbose for this depth. JSON handles arbitrary nesting naturally.

The comments question

YAML’s only clear advantage over JSON is native comments. But for governance configs:

  1. Configs change rarely — they’re set-once governance decisions, not frequently-edited application configs. The lack of inline comments is acceptable for rare edits.

  2. JSON Schema replaces comments — every field, property, and constraint in JSON Schema has a description key. Documentation lives in the schema itself and is machine-readable, not just human-readable. This is strictly better than freeform YAML comments for a validation engine.

  3. Agents don’t benefit from comments — they parse structure, not prose. Field descriptions in JSON Schema are structured data that agents can reason about programmatically.

JSON Schema as the validation foundation

With JSON + JSON Schema, the authors format problem becomes standard:

{
  "authors": {
    "type": "array",
    "items": {
      "type": "object",
      "required": ["name", "email"],
      "properties": {
        "name": { "type": "string", "description": "Full name" },
        "email": { "type": "string", "format": "email" }
      }
    }
  }
}

This eliminates custom format invention entirely. The same schema can validate:

The jsonschema Python library provides validation with zero custom code for field formats. vadocs validators would call jsonschema.validate() instead of implementing custom checking logic for each field type.

Scope boundary: config format vs frontmatter format

Document frontmatter remains YAML — it’s embedded in markdown files and parsed by MyST. Only .vadocs/ governance config files migrate to JSON. The scripts continue to parse YAML frontmatter from documents; they switch from YAML to JSON only for loading their own config.

Migration path

  1. Convert .vadocs/conf.yaml → .vadocs/conf.json (mechanical translation)

  2. Create .vadocs/conf.schema.json (new: defines hub config structure and field formats)

  3. Convert spoke configs to JSON during directory restructuring

  4. Update scripts: yaml.safe_load(config_path) → json.load(config_path)

  5. Existing YAML config tests adapt to JSON fixtures

The migration is atomic — all configs switch in one commit as part of step 7.

Rejected Ideas

Stay YAML, add custom value_format keys

Attempted during brainstorming: added value_format: {type: list, items: {required: [name, email]}} to the authors field in conf.yaml. Immediately identified as schema language invention — if applied consistently to other fields (tags, date, version, status), it would become a bespoke schema format that requires custom validation code. JSON Schema already solves this.

YAML with companion JSON Schema

Keep YAML as human-editable source, generate JSON Schema alongside. Rejected because it requires maintaining synchronization between two files (or building a generator). If JSON Schema is the validation target, the source should also be JSON — one format, one source of truth.

References