{
  "run_id": "lucasrosati--claude-code-memory-setup-claude-haiku-5-5-1792883077068027634",
  "checker": {
    "claims": [
      {
        "claim": "Graphify AST-only mode builds a structural code graph without an LLM key",
        "command": "<guest-path> extract . --out ./graphify-out-checker-2f5bbf9a7f7443a8a1a3a0f0a8e51f70 --no-cluster --code-only",
        "evidence": "no LLM extraction\n[graphify extract] found 13 code, 0 docs, 0 papers, 0 images\n[graphify extract] 4 file(s) not classified (no supported extension or shebang), skipped: .gitignore, .lycheeignore, LICENSE, example.synthetic.jsonl\n[graphify extract] AST extraction on 13 code files...\n[graphify extract] wrote <guest-path> \u2014 103 nodes, 150 edges (no clustering)\n",
        "expected": "indexes the 7 code files locally and skips LLM extraction",
        "input": "graphify extract . --out ./graphify-out --no-cluster --code-only on this repo",
        "kind": "claim",
        "outcome": "Real input produced the expected result: no LLM extraction",
        "returncode": 0,
        "source": "This generates a structural graph without semantic edges.",
        "source_checked": true,
        "source_file": "README.md",
        "verdict": "yes"
      },
      {
        "claim": "Chat import adds automatic tags and frontmatter to vault notes",
        "command": "/usr/bin/python3 scripts/claude_to_obsidian.py --export-dir <guest-path> --vault-dir <guest-path> --dry-run",
        "evidence": "Tags: automation, docker, pipeline\n  \u2192 <guest-path>\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nSUMMARY\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nTotal processed: 1\n  Code: 1\n  Web:  0\nUnique tags found: 3\n  automation, docker, pipeline\n\n\u26a0 Dry run \u2014 no files were modified.\n",
        "expected": "dry run reports tags automation, docker, pipeline for the note",
        "input": "one exported code chat mentioning docker and pipeline",
        "kind": "claim",
        "outcome": "Real input produced the expected result: Tags: automation, docker, pipeline",
        "returncode": 0,
        "source": "with frontmatter, automatic tags, and wikilinks to existing notes.",
        "source_checked": true,
        "source_file": "README.md",
        "verdict": "yes"
      }
    ],
    "cycle_checks": [
      {
        "claim": "The sync wrapper is meant to run on a daily schedule and import chats into the vault",
        "command": "/bin/bash <guest-path>",
        "evidence": "\ud83d\udcc1 Saving logs to: <guest-path>\n\n\ud83d\udce4 Extracting all 0 sessions as MARKDOWN...\n\n\u2705 Successfully extracted 0/0 sessions\nVault notes found: 1\nNo .md files found in export directory.; product invocation failed: {\"argv\": [\"/bin/bash\", \"<guest-path>\"], \"returncode\": 0, \"stdout\": \"\\ud83d\\udcc1 Saving logs to: <guest-path>\\n\\n\\ud83d\\udce4 Extracting all 0 sessions as MARKDOWN...\\n\\n\\u2705 Successfully extracted 0/0 sessions\\nVault notes found: 1\\nNo .md files found in export directory.\\n\", \"stderr\": \"\", \"needs_credentials\": false, \"needs_browser\": false}",
        "expected": "the chat is moved into the vault as a web note and the log records Sync completed",
        "input": "one exported web chat in fakehome/claude-exports/web (session-docker.md)",
        "kind": "cycle",
        "method": "run-once by hand: the real sync script, HOME redirected to a fake home holding copied scripts, venv on PATH; no source edits",
        "outcome": "Triggered one cycle by hand (run-once by hand: the real sync script, HOME redirected to a fake home holding copied scripts, venv on PATH; no source edits; normal trigger: daily cron at 22:00 (documented in the script header)): \ud83d\udcc1 Saving logs to: <guest-path>\n\n\ud83d\udce4 Extracting all 0 sessions as MARKDOWN...\n\n\u2705 Successfully extracted 0/0 sessions\nVault notes found: 1\nNo .md files found in export directory.; product invocation failed: {\"argv\": [\"/bin/bash\", \"<guest-path>\"], \"returncode\": 0, \"stdout\": \"\\ud83d\\udcc1 Saving logs to: <guest-path>\\n\\n\\ud83d\\udce4 Extracting all 0 sessions as MARKDOWN...\\n\\n\\u2705 Successfully extracted 0/0 sessions\\nVault notes found: 1\\nNo .md files found in export directory.\\n\", \"stderr\": \"\", \"needs_credentials\": false, \"needs_browser\": false}",
        "returncode": 0,
        "schedule": "daily cron at 22:00 (documented in the script header)",
        "source": "scripts/sync_claude_obsidian.sh",
        "verdict": "no"
      }
    ],
    "details": {
      "argv": [
        "<guest-path>",
        "extract",
        ".",
        "--out",
        "./graphify-out-checker-e187888e5de1435e8a9cb9eefe5e2f0e",
        "--no-cluster",
        "--code-only"
      ],
      "expected_file": "./graphify-out-checker-e187888e5de1435e8a9cb9eefe5e2f0e",
      "file_checked": true,
      "file_excerpt": "check_json_blocks.py\", \"file_type\": \"code\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L1\"}, {\"id\": \"$graphify-root$_github_scripts_check_json_blocks_partial\", \"label\": \"partial()\", \"file_type\": \"code\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L25\", \"_callable\": true}, {\"id\": \"$graphify-root$_github_scripts_check_json_blocks_blocks_in\", \"label\": \"blocks_in()\", \"file_type\": \"code\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L31\", \"_callable\": true}, {\"id\": \"path\", \"label\": \"Path\", \"file_type\": \"code\", \"source_file\": \"\", \"source_location\": \"\", \"origin_file\": \"$graphify-root$/.github/scripts/check_json_blocks.py\"}, {\"id\": \"$graphify-root$_github_scripts_check_json_blocks_main\", \"label\": \"main()\", \"file_type\": \"code\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L47\", \"_callable\": true}, {\"id\": \"$graphify-root$_github_scripts_check_json_blocks_rationale_2\", \"label\": \"Validate every ```json fenced block in the given markdown files. The guide\\u2026\", \"file_type\": \"rationale\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L2\"}, {\"id\": \"$graphify-root$_github_scripts_check_json_blocks_rationale_32\", \"label\": \"Yield (start_line, text) for each ```json block.\", \"file_type\": \"rationale\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L32\"}], \"edges\": [{\"source\": \"$graphify-root$_github_scripts_check_json_blocks_py\", \"target\": \"json\", \"relation\": \"imports\", \"context\": \"import\", \"confidence\": \"EXTRACTED\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L15\", \"weight\": 1.0, \"_python_import_module\": \"json\", \"_python_import_bindings\": [[\"json\", \"json\"]], \"_python_import_module_binding\": true}, {\"source\": \"$graphify-root$_github_scripts_check_json_blocks_py\", \"target\": \"re\", \"relation\": \"imports\", \"context\": \"import\", \"confidence\": \"EXTRACTED\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L16\", \"weight\": 1.0, \"_python_import_module\": \"re\", \"_python_import_bindings\": [[\"re\", \"re\"]], \"_python_import_module_binding\": true}, {\"source\": \"$graphify-root$_github_scripts_check_json_blocks_py\", \"target\": \"sys\", \"relation\": \"imports\", \"context\": \"import\", \"confidence\": \"EXTRACTED\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L17\", \"weight\": 1.0, \"_python_import_module\": \"sys\", \"_python_import_bindings\": [[\"sys\", \"sys\"]], \"_python_import_module_binding\": true}, {\"source\": \"$graphify-root$_github_scripts_check_json_blocks_py\", \"target\": \"pathlib\", \"relation\": \"imports_from\", \"context\": \"import\", \"confidence\": \"EXTRACTED\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L18\", \"weight\": 1.0, \"_python_import_module\": \"pathlib\", \"_python_import_bindings\": [[\"Path\", \"Path\"]]}, {\"source\": \"$graphify-root$_github_scripts_check_json_blocks_py\", \"target\": \"$graphify-root$_github_scripts_check_json_blocks_partial\", \"relation\": \"contains\", \"confidence\": \"EXTRACTED\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L25\", \"weight\": 1.0}, {\"source\": \"$graphify-root$_github_scripts_check_json_blocks_py\", \"target\": \"$graphify-root$_github_scripts_check_json_blocks_blocks_in\", \"relation\": \"contains\", \"confidence\": \"EXTRACTED\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L31\", \"weight\": 1.0}, {\"source\": \"$graphify-root$_github_scripts_check_json_blocks_blocks_in\", \"target\": \"path\", \"relation\": \"references\", \"context\": \"parameter_type\", \"confidence\": \"EXTRACTED\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L31\", \"weight\": 1.0}, {\"source\": \"$graphify-root$_github_scripts_check_json_blocks_py\", \"target\": \"$graphify-root$_github_scripts_check_json_blocks_main\", \"relation\": \"contains\", \"confidence\": \"EXTRACTED\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L47\", \"weight\": 1.0}, {\"source\": \"$graphify-root$_github_scripts_check_json_blocks_main\", \"target\": \"$graphify-root$_github_scripts_check_json_blocks_blocks_in\", \"relation\": \"calls\", \"context\": \"call\", \"confidence\": \"EXTRACTED\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L54\", \"weight\": 1.0}, {\"source\": \"$graphify-root$_github_scripts_check_json_blocks_main\", \"target\": \"$graphify-root$_github_scripts_check_json_blocks_partial\", \"relation\": \"calls\", \"context\": \"call\", \"confidence\": \"EXTRACTED\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L55\", \"weight\": 1.0}, {\"source\": \"$graphify-root$_github_scripts_check_json_blocks_rationale_2\", \"target\": \"$graphify-root$_github_scripts_check_json_blocks_py\", \"relation\": \"rationale_for\", \"confidence\": \"EXTRACTED\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L2\", \"weight\": 1.0}, {\"source\": \"$graphify-root$_github_scripts_check_json_blocks_rationale_32\", \"target\": \"$graphify-root$_github_scripts_check_json_blocks_blocks_in\", \"relation\": \"rationale_for\", \"confidence\": \"EXTRACTED\", \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L32\", \"weight\": 1.0}], \"raw_calls\": [{\"caller_nid\": \"$graphify-root$_github_scripts_check_json_blocks_partial\", \"callee\": \"match\", \"is_member_call\": true, \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L28\", \"receiver\": \"COMMENT_RE\", \"_python_receiver_shadowed\": true}, {\"caller_nid\": \"$graphify-root$_github_scripts_check_json_blocks_partial\", \"callee\": \"splitlines\", \"is_member_call\": true, \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L28\", \"receiver\": \"block\", \"_python_receiver_shadowed\": true}, {\"caller_nid\": \"$graphify-root$_github_scripts_check_json_blocks_blocks_in\", \"callee\": \"splitlines\", \"is_member_call\": true, \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L33\", \"receiver\": null, \"_python_receiver_shadowed\": true}, {\"caller_nid\": \"$graphify-root$_github_scripts_check_json_blocks_blocks_in\", \"callee\": \"read_text\", \"is_member_call\": true, \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L33\", \"receiver\": \"path\", \"_python_receiver_shadowed\": true, \"receiver_type\": \"Path\"}, {\"caller_nid\": \"$graphify-root$_github_scripts_check_json_blocks_blocks_in\", \"callee\": \"match\", \"is_member_call\": true, \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L36\", \"receiver\": \"OPEN_RE\", \"_python_receiver_shadowed\": true}, {\"caller_nid\": \"$graphify-root$_github_scripts_check_json_blocks_blocks_in\", \"callee\": \"match\", \"is_member_call\": true, \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L40\", \"receiver\": \"CLOSE_RE\", \"_python_receiver_shadowed\": true}, {\"caller_nid\": \"$graphify-root$_github_scripts_check_json_blocks_blocks_in\", \"callee\": \"append\", \"is_member_call\": true, \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L41\", \"receiver\": \"body\", \"_python_receiver_shadowed\": true}, {\"caller_nid\": \"$graphify-root$_github_scripts_check_json_blocks_blocks_in\", \"callee\": \"join\", \"is_member_call\": true, \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L43\", \"receiver\": null, \"_python_receiver_shadowed\": true}, {\"caller_nid\": \"$graphify-root$_github_scripts_check_json_blocks_main\", \"callee\": \"Path\", \"is_member_call\": false, \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L48\", \"receiver\": null, \"via_stub\": true}, {\"caller_nid\": \"$graphify-root$_github_scripts_check_json_blocks_main\", \"callee\": \"Path\", \"is_member_call\": false, \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L48\", \"receiver\": null, \"via_stub\": true}, {\"caller_nid\": \"$graphify-root$_github_scripts_check_json_blocks_main\", \"callee\": \"is_file\", \"is_member_call\": true, \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L51\", \"receiver\": \"path\", \"_python_receiver_shadowed\": true}, {\"caller_nid\": \"$graphify-root$_github_scripts_check_json_blocks_main\", \"callee\": \"loads\", \"is_member_call\": true, \"source_file\": \".github/scripts/check_json_blocks.py\", \"source_location\": \"L60\", \"receiver\": \"json\", \"_python_receiver_shadowed\": false}]}\n{\"nodes\": [{\"id\": \"$graphify-root$_benchmarks_summarize_py\", \"label\": \"summarize.py\", \"file_type\": \"code\", \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L1\"}, {\"id\": \"$graphify-root$_benchmarks_summarize_summarize\", \"label\": \"summarize()\", \"file_type\": \"code\", \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L10\", \"_callable\": true}, {\"id\": \"$graphify-root$_benchmarks_summarize_main\", \"label\": \"main()\", \"file_type\": \"code\", \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L47\", \"_callable\": true}, {\"id\": \"$graphify-root$_benchmarks_summarize_rationale_2\", \"label\": \"Summarize paired, normalized usage ledgers; never invoke a model.\", \"file_type\": \"rationale\", \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L2\"}], \"edges\": [{\"source\": \"$graphify-root$_benchmarks_summarize_py\", \"target\": \"argparse\", \"relation\": \"imports\", \"context\": \"import\", \"confidence\": \"EXTRACTED\", \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L3\", \"weight\": 1.0, \"_python_import_module\": \"argparse\", \"_python_import_bindings\": [[\"argparse\", \"argparse\"]], \"_python_import_module_binding\": true}, {\"source\": \"$graphify-root$_benchmarks_summarize_py\", \"target\": \"json\", \"relation\": \"imports\", \"context\": \"import\", \"confidence\": \"EXTRACTED\", \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L4\", \"weight\": 1.0, \"_python_import_module\": \"json\", \"_python_import_bindings\": [[\"json\", \"json\"]], \"_python_import_module_binding\": true}, {\"source\": \"$graphify-root$_benchmarks_summarize_py\", \"target\": \"pathlib\", \"relation\": \"imports_from\", \"context\": \"import\", \"confidence\": \"EXTRACTED\", \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L5\", \"weight\": 1.0, \"_python_import_module\": \"pathlib\", \"_python_import_bindings\": [[\"Path\", \"Path\"]]}, {\"source\": \"$graphify-root$_benchmarks_summarize_py\", \"target\": \"$graphify-root$_benchmarks_summarize_summarize\", \"relation\": \"contains\", \"confidence\": \"EXTRACTED\", \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L10\", \"weight\": 1.0}, {\"source\": \"$graphify-root$_benchmarks_summarize_py\", \"target\": \"$graphify-root$_benchmarks_summarize_main\", \"relation\": \"contains\", \"confidence\": \"EXTRACTED\", \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L47\", \"weight\": 1.0}, {\"source\": \"$graphify-root$_benchmarks_summarize_main\", \"target\": \"$graphify-root$_benchmarks_summarize_summarize\", \"relation\": \"calls\", \"context\": \"call\", \"confidence\": \"EXTRACTED\", \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L53\", \"weight\": 1.0}, {\"source\": \"$graphify-root$_benchmarks_summarize_rationale_2\", \"target\": \"$graphify-root$_benchmarks_summarize_py\", \"relation\": \"rationale_for\", \"confidence\": \"EXTRACTED\", \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L2\", \"weight\": 1.0}], \"raw_calls\": [{\"caller_nid\": \"$graphify-root$_benchmarks_summarize_summarize\", \"callee\": \"ValueError\", \"is_member_call\": false, \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L16\", \"receiver\": null}, {\"caller_nid\": \"$graphify-root$_benchmarks_summarize_summarize\", \"callee\": \"ValueError\", \"is_member_call\": false, \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L19\", \"receiver\": null}, {\"caller_nid\": \"$graphify-root$_benchmarks_summarize_summarize\", \"callee\": \"add\", \"is_member_call\": true, \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L20\", \"receiver\": \"seen\", \"_python_receiver_shadowed\": true}, {\"caller_nid\": \"$graphify-root$_benchmarks_summarize_summarize\", \"callee\": \"FIELDS\", \"is_member_call\": false, \"indirect\": true, \"context\": \"argument\", \"source_file\": \"benchmarks/summarize.py\", \"source_location\": \"L22\"}, {\"caller",
      "kind": "cli",
      "needs_browser": false,
      "needs_credentials": false,
      "returncode": 0,
      "scope": "product operation",
      "stderr": "",
      "stdout": "[graphify extract] scanning <guest-path>\n[graphify extract] --code-only: skipping 12 non-code file(s) (12 docs, 0 papers, 0 images) \u2014 no LLM extraction\n[graphify extract] found 13 code, 0 docs, 0 papers, 0 images\n[graphify extract] 4 file(s) not classified (no supported extension or shebang), skipped: .gitignore, .lycheeignore, LICENSE, example.synthetic.jsonl\n[graphify extract] AST extraction on 13 code files...\n[graphify extract] wrote <guest-path> \u2014 103 nodes, 150 edges (no clustering)",
      "working": true
    },
    "evidence_strength": "readme_checked",
    "example_checks": [
      {
        "claim": "Benchmark usage summarizer runs on the synthetic fixture",
        "command": "/usr/bin/python3 benchmarks/summarize.py benchmarks/example.synthetic.jsonl",
        "deferred": false,
        "evidence": "[\n  {\n    \"scope\": \"query\",\n    \"pair\": \"synthetic-only\",\n    \"usage\": {\n      \"baseline\": {\n        \"input_uncached\": 100,\n        \"input_cache_read\": 20,\n        \"input_cache_write\": 10,\n        \"output\": 10\n      },\n      \"memory\": {\n        \"input_uncached\": 40,\n        \"input_cache_read\": 10,\n        \"input_cache_write\": 10,\n        \"output\": 10\n      }\n    },\n    \"total_tokens\": {\n      \"baseline\": 140,\n      \"memory\": 70\n    },\n    \"baseline_over_memory\": 2.0,\n    \"reduction_percent\": 50.0\n  }\n]",
        "expected": "prints a JSON summary with a 50 percent reduction for the synthetic fixture",
        "input": "benchmarks/example.synthetic.jsonl",
        "kind": "example",
        "outcome": "command completed successfully",
        "returncode": 0,
        "source": "benchmarks/README.md",
        "verdict": "yes"
      },
      {
        "claim": "Graph query returns matching code nodes from the extracted graph",
        "command": "<guest-path> query claude_to_obsidian --graph <guest-path>",
        "deferred": false,
        "evidence": "otes() at=scripts/claude_to_obsidian.py:L336\nEDGE process_file() --calls [EXTRACTED context=call]--> detect_origin() at=scripts/claude_to_obsidian.py:L257\nEDGE process_file() --calls [EXTRACTED context=call]--> extract_tags() at=scripts/claude_to_obsidian.py:L258\nEDGE process_file() --calls [EXTRACTED context=call]--> insert_wikilinks() at=scripts/claude_to_obsidian.py:L267\nEDGE main() --calls [EXTRACTED context=call]--> process_file() at=scripts/claude_to_obsidian.py:L353\nEDGE process_file() --calls [EXTRACTED context=call]--> strip_existing_frontmatter() at=scripts/claude_to_obsidian.py:L255",
        "expected": "lists NODE extract_tags() from scripts/claude_to_obsidian.py",
        "input": "query claude_to_obsidian against a graph extracted by the AST-only run",
        "kind": "example",
        "outcome": "command completed successfully",
        "returncode": 0,
        "source": "README.md Part 3 Useful Commands: graphify query \"question\"",
        "verdict": "yes"
      },
      {
        "claim": "CI JSON-block check validates README examples",
        "command": "/usr/bin/python3 .github/scripts/check_json_blocks.py README.md README.pt-BR.md CHANGELOG.md scripts/README.md",
        "deferred": false,
        "evidence": "ok    README.md:618\nok    README.pt-BR.md:622\n\n2 valid, 0 skipped (partial), 0 invalid",
        "expected": "all JSON blocks valid",
        "input": "README.md README.pt-BR.md CHANGELOG.md scripts/README.md",
        "kind": "example",
        "outcome": "command completed successfully",
        "returncode": 0,
        "source": ".github/workflows/ci.yml validate-hook-json job",
        "verdict": "yes"
      },
      {
        "claim": "CI README parity check passes for English and Portuguese guides",
        "command": "/usr/bin/python3 .github/scripts/check_parity.py",
        "deferred": false,
        "evidence": "README.md: 12 sections, 39 code blocks\nREADME.pt-BR.md: 12 sections, 39 code blocks\nOK: section count matches\nOK: code block counts within tolerance (delta 0)",
        "expected": "section counts match",
        "input": "README.md and README.pt-BR.md",
        "kind": "example",
        "outcome": "command completed successfully",
        "returncode": 0,
        "source": ".github/workflows/ci.yml README parity job",
        "verdict": "yes"
      }
    ],
    "status": "PASS"
  },
  "diagnosis": null
}
