Skip to content

test: cross-validate scenario.schema.json with the Python validator#128

Merged
mertsatilmaz merged 1 commit into
mainfrom
test/scenario-schema-sync
May 17, 2026
Merged

test: cross-validate scenario.schema.json with the Python validator#128
mertsatilmaz merged 1 commit into
mainfrom
test/scenario-schema-sync

Conversation

@mertsatilmaz
Copy link
Copy Markdown
Collaborator

Summary

Adds `tests/test_scenario_schema_sync.py` with 45 tests that enforce three contracts between `schemas/scenario.schema.json` and `src/agent_harness/scenario.py::validate_scenario_data`:

  1. Every bundled scenario validates against both (20 parametrized cases — every `.yaml` under `scenarios/`).
  2. Generic structural errors are rejected by both (16 cases: missing required fields, bad enums, empty assertions, etc).
  3. Documented asymmetries are pinned, not silent:
    • 7 cases where Python rejects but the schema accepts (assertion-specific conditional rules: `memory_isolation` markers, `goal_integrity.expected_goal`, `allowed_tools`/`denied_tools` shapes).
    • 2 cases where the schema rejects but Python accepts (extra top-level fields, `target` without `adapter`).

Decision (per issue #88's "decide and document" requirement)

The schema stays intentionally permissive about assertion-specific conditional rules. JSON Schema can express "if/then" conditional shapes, but only verbosely, and every new assertion type would require a schema edit. Python is the source of truth for those rules at runtime. The schema does what JSON Schema does well: required fields, enums, top-level `additionalProperties: false`, required `target.adapter`.

Documented in `docs/scenario-spec.md` under a new "Validation: schema vs Python validator" section that names every asymmetry, so future contributors know what they're allowed to break on each side.

Test plan

  • `python -m pytest -q` — 295 passed (250 + 45 new)
  • `ruff check src tests` — clean
  • `mypy` — clean

Closes #88

Add tests/test_scenario_schema_sync.py with 45 tests that enforce three
contracts between the JSON Schema and the Python validator:

1. Every bundled scenario (20 files) validates against both.
2. Generic structural errors (missing required fields, bad enum values,
   empty assertions, etc.) are rejected by both — 16 cases.
3. Documented asymmetries are pinned, not silent: 7 assertion-specific
   conditional cases (memory_isolation markers, goal_integrity
   expected_goal, allowed_tools/denied_tools shapes) where Python is
   stricter than the schema, and 2 structural cases (extra top-level
   fields, target without adapter) where the schema is stricter than
   Python.

Per the issue's "decide and document" requirement: schema stays
intentionally permissive about assertion-specific conditional rules
because JSON Schema can't express them cheaply. Python is the source
of truth at runtime. The schema does as much structural enforcement as
JSON Schema does well: required fields, enums, top-level
additionalProperties: false, required target.adapter.

Document the decision in docs/scenario-spec.md under a new "Validation:
schema vs Python validator" section that names every documented
asymmetry, so future contributors changing either side know what
they're allowed to break.

Closes #88
@mertsatilmaz mertsatilmaz merged commit d4fe87e into main May 17, 2026
3 checks passed
@mertsatilmaz mertsatilmaz deleted the test/scenario-schema-sync branch May 17, 2026 18:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Keep Python scenario validation and scenario.schema.json in sync

1 participant