Skip to content

Fix validate_json.py: parse all fields.yaml schemas; stop vacuous pass#8

Open
xwang4-svg wants to merge 1 commit into
Weizhena:masterfrom
xwang4-svg:fix/validate-json-schema-coverage
Open

Fix validate_json.py: parse all fields.yaml schemas; stop vacuous pass#8
xwang4-svg wants to merge 1 commit into
Weizhena:masterfrom
xwang4-svg:fix/validate-json-schema-coverage

Conversation

@xwang4-svg

Copy link
Copy Markdown

Problem

validate_json.py is meant to enforce that each /research-deep result JSON covers every field defined in fields.yaml ("Task is complete only after validation passes"). In practice it passed everything, due to two issues:

1. Only the field_categories: schema was parsed. But /research (per its own SKILL.md Step 4) emits fields.yaml as:

fields:
  <category>:
    - {name: ..., description: ..., detail_level: ...}
uncertain: []

load_fields_yaml read data.get("field_categories", [])[]0 fields. With an empty field set, coverage_rate defaults to 100% and missing_required is empty, so every JSON "passes" vacuously. (field_categories does not appear in any SKILL.md — only inside this script.)

2. required defaulted to False. Even when fields were parsed, valid (len(missing_required) == 0) stayed True with missing fields unless each was explicitly required: true — which the emitted schema never sets.

Repro (before), with a fields.yaml in the fields:{cat:[...]} shape /research produces:

$ python validate_json.py -f fields.yaml -d results
Total fields: 0 (required: 0, optional: 0)
[PASS] foo.json   Coverage: 100.0% (0/0)

Fix

  • load_fields_yaml now accepts field_categories: [...], fields: {<cat>: [...]}, flat fields: [...], and a generic fallback that walks for {name: ...} dicts. When no field carries an explicit required: key, all fields are treated as required (the script's stated purpose is complete coverage); files that do mark required: keep their opt-in semantics unchanged.
  • extract_json_fields also descends into JSON keys named after declared categories, so nested output isn't falsely reported as missing.
  • Applied to all four copies: research-en, research-zh, research-codex-en, research-codex-zh.
  • Added tests/test_validate_json_schemas.py — runs against every copy; asserts both schemas parse and that a JSON missing a defined field now fails.

Repro (after):

Total fields: 4 (required: 4, optional: 0)
[PASS] foo.json   Coverage: 100.0% (4/4)
# a JSON missing a defined field now -> [FAIL] ... Missing required fields

Note / tradeoff

The "all fields required when none are explicitly marked" rule makes validation stricter than before (previously, unmarked = optional = always pass). This matches what the validator is documented to do, but if you'd prefer keeping required opt-in and gating strictness behind a --strict flag instead, I'm happy to adjust.

$ python tests/test_validate_json_schemas.py
...
RESULT: ALL PASS

🤖 Generated with Claude Code

The validator only parsed the `field_categories:` schema, but /research emits
fields.yaml as `fields: {<category>: [{name, description, detail_level}]}`. That
shape was read as ZERO fields, so coverage defaulted to 100% and every result
JSON "passed" -- the validation step was effectively a no-op. `required` also
defaulted to False, so `valid` stayed True even when fields were missing.

- load_fields_yaml: accept field_categories / fields:{cat:[...]} / flat fields:[...]
  plus a generic fallback; treat all fields as required when no `required:` marker
  exists (explicit `required:` markers keep their opt-in semantics, unchanged).
- extract_json_fields: also descend into JSON keys named after declared categories.
- Apply to all 4 skill copies (research-en/zh, research-codex-en/zh).
- Add tests/test_validate_json_schemas.py regression test (guards all copies).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

1 participant