# Visual Trajectory Viewer V0.4

V0.4 is a static, read-only trajectory manager for visual coding experiments.
It turns the previous single-case long page into four linked workspaces:

1. **Overview** — Gallery and case × run Matrix over a lightweight catalog.
2. **Run dossier** — one immutable case/run result with independent lifecycle,
   artifact, verdict and trace axes.
3. **Compare** — one fixed target with two or three ordered run outputs.
4. **Replay** — every stored raw event remains a canonical, addressable step;
   visual frames change only when a real artifact changes.

The viewer does not start, stop, retry, upload or delete experiments. It does
not modify v-harness. Source adapters build one normalized static package under
`public/data/`, and Cloudflare Pages serves the result without a database or
dynamic backend.

## Current package

The generated package contains:

- 25 immutable run/dataset records across five experiment groups;
- 235 case-run results, deduplicated into stable case identities by target
  SHA-256 when the target exists;
- full, sanitized/partial and aggregate-only trace availability levels;
- `vharness_visual_trace_case_v0.7` traces and a deterministic
  `event-narrator-zh-v1` replay index;
- the V3 ablation `case-h1` full trace with 770 raw events, 288 tool calls, six
  epochs and seven distinct real frame checksums.

The Run dossier includes an explicit `图片聚焦 / Image focus` control. It
temporarily hides the data navigator, run facts and lower dossier sections,
expands the comparator to the full content width and grows the visual stage to
the remaining viewport height. `Target`, `Final`, side-by-side, Overlay,
Fit width/height and BBox controls remain available inside focus mode; Escape
restores the complete dossier and keyboard focus to the toggle.

The package keeps older V2, V3, VeriHarness and historical dataset adapters.
Old trace packages remain readable; current repository data is rebuilt to the
V0.7 public contract.

## Deployed viewer

- Stable: `https://multimodal-verification-board.pages.dev/0-Project/20260704-vdiff-vharness-visual-trajectory-viewer/public/`
- Validated production deployment: `https://932e8bb9.multimodal-verification-board.pages.dev/0-Project/20260704-vdiff-vharness-visual-trajectory-viewer/public/`
- Legacy V2 comparison viewer remains published as a fallback; the V2 and V3
  board pages now make V0.4 the primary trajectory/comparison entry.

The stable and immutable deployment URLs were both browser-checked against the
Overview, Run, Compare and Replay routes on 2026-07-14. The production package
also passed the 390 px and 800 px responsive flows, keyboard evidence-panel
flow, legacy-link normalization, partial replay and aggregate-only replay
checks recorded in `docs/qa/v04/README.md`.

## Identity and truth boundaries

For a visual reproduction case with a target:

```text
case_uid    = sha256:<full target SHA-256>
run_uid     = <dataset_id>
case_run_id = <run_uid>::<case_uid>
epoch_id    = <case_run_id>::epoch:<ordinal>
event_id    = <case_run_id>::event:<raw_event_index>
```

When a target is missing, the builder emits a `legacy:<project>:<case>`
identity. That fallback may open a dossier but is not automatically eligible
for cross-run comparison.

`events[]` and their ordering are raw truth. `replay_index.steps[]` is a
derived navigation index and never replaces or merges raw events.
`derived_turns[]` remains a separate repair layer for known historical recorder
binding anomalies.

Frame provenance is explicit:

- `explicit_event_frame` — the event has a verifiable stored frame;
- `epoch_snapshot` — a real persisted epoch image is associated with the step;
- `held_previous` — the step has no new image and reuses the last real frame;
- `unavailable` — no truthful frame can be shown.

## Source and generated layout

```text
20260704-vdiff-vharness-visual-trajectory-viewer/
  GOAL_SPEC.md
  docs/
    trace-schema.md
    trace-integrity-goal-spec.md
    qa/v04/
  scripts/
    build_trace_package.py
    trace_integrity.py
  tests/
  viewer/                    # source; edit here
    index.html
    viewer.css
    viewer.js
    modules/
  public/                    # generated; do not hand-edit
    data/catalog.json
    data/datasets.json
```

The builder replaces `public/` and copies `viewer/` into it. Do not make the
same edit manually in both locations.

## Build and test

From this subproject:

```bash
python scripts/build_trace_package.py
python -m unittest discover -s tests -v
for file in viewer/*.js viewer/modules/*.js; do node --check "$file"; done
python scripts/qa_viewer_v04.py \
  --base-url http://127.0.0.1:8127/0-Project/20260704-vdiff-vharness-visual-trajectory-viewer/public/ \
  --output docs/qa/v04
```

The default builder reads the repository's frozen V2, V3 and VeriHarness run
artifacts. It also performs a final text-artifact sanitization pass so the
public package does not depend on a later deployment copy to remove workstation
paths.

## Browse locally

Some safe artifact URLs are site-root paths into sibling public project data.
Serve the repository root, not only this `public/` directory:

```bash
cd /path/to/3-multimodal-verification-for-coding-loop
python -m http.server 8127 --bind 127.0.0.1
```

Then open:

```text
http://127.0.0.1:8127/0-Project/20260704-vdiff-vharness-visual-trajectory-viewer/public/?view=overview
```

Representative deep links:

```text
?view=run&dataset=v3-ablation-l3-full-v-harness-r1&case=case-h1&section=epochs&epoch=2
?view=compare&case_uid=sha256:<full-sha>&runs=<run-a>,<run-b>,<run-c>
?view=replay&dataset=v3-ablation-l3-full-v-harness-r1&case=case-h1&event=157
```

Legacy links remain valid:

```text
?dataset=<dataset_id>&case=<source_case_id>
```

## Decoupling contract

- Do not edit upstream v-harness prompt, gate, tools, recorder or model policy
  for this viewer.
- Add a source adapter/profile for a new artifact family; do not hide a latest
  run lookup in client code.
- Add immutable run ids instead of overwriting historical results.
- Never infer case equivalence without exact target identity.
- Never generate missing events, frames, epochs, gate evidence or construction
  strategy in the browser.
- Keep all published evidence inside the static public allowlist and run the
  path/secret scan before deployment.
