Files
imbad0202__academic-researc…/examples/figure_table_trace_example.md
T
Edward Cheng-I Wu 4464abe04c feat(#261): Figure/Table Fidelity Gate — caption-claim trace + Stage 4.5 check (#372)
Closes #261

## What

Adds the **Figure/Table Fidelity Gate** — the visual analog of the §F.3.2 partial-evidence trap addressed for prose citations in #213 and review synthesis in #214 (Kong et al. 2026 §3.4, arXiv:2605.18661). The existing VLM Figure Verification Protocol checks *"does the rendered figure match the source data?"*; it cannot check *"does the caption's interpretation follow from the data, and does the manuscript cite this artifact for a claim it actually supports?"* This PR closes that gap.

## Approach — prose-layer only (mirrors #214, not #213)

The `figure_table_trace[]` producer (`visualization_agent`) and consumer (`integrity_verification_agent`) are both LLM agents reading a markdown Figure Package — there is **no deterministic downstream parser**, so this ships as a prose contract with **no JSON Schema, no lint invariant, no gold fixture**. Machine-validating the YAML shape would be false rigor (it proves field presence, not visual claim fidelity) and an unrequested maintenance surface. This is the same scope decision #214 made; #213 got schema+lint only because it has a machine consumer.

## Changes (5 files, +244 / -1, prose/protocol + doc example only)

- **`academic-paper/references/vlm_figure_verification.md`** — new Figure/Table Trace section: the `figure_table_trace[]` block (six required keys: `artifact_id`, `source_data`, `transformation`, `caption_claim`, `supported_manuscript_claims`, `limitations`) + field rules.
- **`academic-paper/agents/visualization_agent.md`** — emits the trace in the Figure Package (new Step 6.6); claims identified by text + locator (not a bare id — the agent can run before the draft's claim manifest exists).
- **`academic-pipeline/agents/integrity_verification_agent.md`** — Phase **C3. Figure/Table Caption Fidelity** at Stage 4.5: entry well-formedness (malformed → short-circuit FAIL) + four fidelity checks (trace completeness / caption-claim support with compound-caption sub-claim decomposition / bidirectional manuscript-claim linkage / limitation visibility), with an explicit FAIL-vs-advisory severity table and per-entry precedence.
- **`examples/figure_table_trace_example.md`** — 3-figure + 1-table ML ablation walkthrough (normal trace, decomposed compound caption, empty-limitations advisory, reverse-linkage omission).
- **`CHANGELOG.md`** — `[Unreleased]` entry.

## Key design points

- **Severity is split, not blanket-advisory.** A caption that contradicts *or is unsupported/overstated by* the data, an untraceable claim-bearing artifact, a missing/overstated/omitted manuscript link, or a dropped known limitation → **FAIL (block)**. Only uncertainty signals are advisory: empty `limitations: []` → `[FIGURE-LIMITATIONS-EMPTY]` (never a silent pass), VLM skipped with reason, legacy figure with no package.
- **Anti-skip:** an updated Figure Package missing the trace is a FAIL, not the legacy advisory case.
- **Bidirectional linkage:** every *substantive* manuscript use of an artifact must be listed (incidental/structural mentions exempt) — catches one-sided traces that declare only flattering support.
- **Inherits, doesn't duplicate:** C3 reuses the C1 data-cross-referencing layer; it does not re-render figures (VLM) or re-verify raw data (C1). Its new coverage is interpretation + linkage.

## Verification

- Regression green: **2291 passed / 3 skipped / 1 xfailed**.
- Reviewed across multiple independent passes to convergence; severity table verified exhaustive and mutually exclusive.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-06-08 13:17:45 +08:00

6.8 KiB
Raw Blame History

Example: figure_table_trace[] for an ML ablation paper (#261)

A documentation example (not an executable fixture) showing how the visualization_agent emits a figure_table_trace[] block and how the integrity_verification_agent's Phase C3 (Figure/Table Caption Fidelity) reads it. The paper is a fictional ablation study, "Scaling depth in sparse retrievers", with three figures and one table.

Reference: academic-paper/references/vlm_figure_verification.md (Figure/Table Trace section). The trace is a prose contract — there is no JSON Schema or lint behind it (mirroring the #214 prose-layer decision, not the #213 schema-layer one).


The trace block (in the Figure Package)

figure_table_trace:
  # Case 1 — normal traced figure, single caption claim, limitation surfaced
  - artifact_id: "fig-1"
    source_data: {dataset_id: "depth-sweep", file: "results/depth_sweep.csv"}
    transformation: {script: "scripts/plot_depth.py", hash: "9f2a4c1"}
    caption_claim: "Retrieval recall@10 increases with encoder depth from 4 to 12 layers."
    supported_manuscript_claims:
      - {claim: "Recall improves with encoder depth over the tested range.", locator: "Results §4.1, ¶2"}
    limitations:
      - "Only depths {4, 8, 12} were run; intermediate depths are not measured."

  # Case 2 — compound caption claim (decomposed by the integrity gate before judging)
  - artifact_id: "fig-2"
    source_data: {dataset_id: "depth-sweep", file: "results/depth_sweep.csv"}
    transformation: {script: "scripts/plot_depth.py", hash: "9f2a4c1"}
    caption_claim: "Deeper encoders improve recall AND reduce variance across the three seeds."
    supported_manuscript_claims:
      - {claim: "Depth improves recall.", locator: "Results §4.1, ¶2"}
      - {claim: "Depth reduces cross-seed variance.", locator: "Results §4.1, ¶3"}
    limitations:
      - "Variance is computed over 3 seeds only; the variance-reduction claim is low-powered."

  # Case 3 — empty limitations → advisory, not silent pass
  - artifact_id: "fig-3"
    source_data: {dataset_id: "latency-bench", file: "results/latency_bench.csv"}
    transformation: "manual derivation: §5.3 paragraph 1 (median over 1000 queries, warm cache)"
    caption_claim: "Inference latency is flat from depth 4 to 12."
    supported_manuscript_claims:
      - {claim: "Depth does not increase inference latency.", locator: "Results §5.3, ¶1"}
    limitations: []

  # Table with a trace entry — same checks apply
  - artifact_id: "table-2"
    source_data: {dataset_id: "depth-sweep", file: "results/depth_sweep.csv"}
    transformation: {script: "scripts/make_table2.py", hash: "9f2a4c1"}
    caption_claim: "Per-depth recall@10 and recall@100 with 95% CIs."
    supported_manuscript_claims:
      - {claim: "Recall improves with encoder depth over the tested range.", locator: "Results §4.1, ¶2"}
      - {claim: "Depth improves recall.", locator: "Results §4.1, ¶2"}
    limitations:
      - "CIs are bootstrap (n=1000); not corrected for multiple comparisons across depths."

How Phase C3 reads each case

Case 1 — fig-1 (normal, single claim)

  • (1) Trace completeness — PASS. {script, hash} present; data file pointed to.
  • (2) Caption-claim support — the single claim "recall increases with depth 4→12" follows from depth_sweep.csv if the plotted recall is monotone across the three measured depths. Judge against the data, not the rendering.
  • (3) Manuscript-claim linkage (both directions)Forward: the listed claim ("Recall improves with encoder depth over the tested range", Results §4.1 ¶2) must actually cite Figure 1 and must not say more than the data shows (asserting monotonicity at unmeasured depths would be an overstatement → FAIL). The claim is identified by text + locator, not by an id, because the figure can be produced before the draft's claim manifest exists. Reverse: the gate also scans the manuscript for every place it leans on Figure 1 — if §6 Discussion says "Figure 1 shows latency is unaffected" but that use is not in supported_manuscript_claims, the one-sided trace is an omission → FAIL (the author cannot quietly drop an unflattering use from the trace).
  • (4) Limitation visibility — the "{4,8,12} only" limitation must appear in caption Note / Discussion / Limitations. If it does → PASS; if the scholar listed it but the manuscript dropped it → FAIL (blocking).

Case 2 — fig-2 (compound claim, decomposed)

The caption_claim is compound, so Phase C3 decomposes it (borrowing #213 as prose guidance only):

  • sub-claim A: "deeper encoders improve recall"
  • sub-claim B: "deeper encoders reduce variance across the three seeds"

Each is judged independently. A common failure: A holds in the data but B is asserted on 3 seeds with overlapping ranges — the caption claims B as established when the data only weakly supports it. A caption supported on A but not B is not fully supported: the entry takes the verdict of its weakest sub-claim, so the unsupported B routes the whole entry to FAIL caption-claim support (not PASS WITH NOTES — partial support is not a clean pass). The two manuscript claims ("Depth improves recall" §4.1 ¶2; "Depth reduces cross-seed variance" §4.1 ¶3) are checked separately for linkage and overstatement.

Case 3 — fig-3 (empty limitations)

  • (1)(3) judged as above; note the transformation here is a precise manual-derivation pointer (§5.3 ¶1, median over 1000 queries, warm cache) — acceptable. A vague "computed manually" would be UNTRACEABLE → FAIL for a claim-bearing artifact.
  • (4) Limitation visibilitylimitations: []. The gate does not invent a limitation; it emits [FIGURE-LIMITATIONS-EMPTY] as a named advisory (PASS WITH NOTES). A latency-flat claim with no stated caveats (cache state? hardware? batch size?) is exactly the kind of omission the advisory makes visible without pretending the agent can enumerate every missing caveat.

table-2 (table with trace)

Same four checks as a figure. The table is not a figure, but because it has a figure_table_trace[] entry the fidelity check applies in full. A standalone table with no trace entry would instead surface a trace-unavailable finding.


Cross-reference

  • #213 — sub-claim decomposition before citation judgment (citation-layer half of the §F.3.2 partial-evidence trap). The decomposition idea in Case 2 is borrowed from here as prose guidance only.
  • #214 — sub-claim inventory before consensus in editorial synthesis (synthesis-layer half). #261 mirrors #214's prose-layer scope decision (no schema/lint/fixture).
  • Kong et al. (2026) §3.4 (arXiv:2605.18661) — the originating finding: an AI-generated figure can look professional while its caption/claims do not follow from the data.