Road to 10 — Wave 2 · PR-T4

# Handoff bundle schema validator

7 fixture assertions · guards the #1400 agent schema rewrite

## What it locks

#1400 rewrote the orchestrator agent's expected schema from a speculative JSON manifest to the real gzipped-tarball layout observed during the #1399 dogfood. Nothing enforced that contract. PR-T4 adds a validator script + 7 fixture tests so a future refactor can't silently break bundle parsing.

## Observed schema (from #1400)

    <project-name>/
    ├── README.md           required
    ├── chats/
    │   └── chat*.md        required — ≥ 1
    └── project/
        └── *.html          optional — absent = incomplete bundle

## Fixture matrix

# | Fixture | Expected exit | Why
--- | --- | --- | ---
1 | complete (README + chats + project/*.html) | 0 | happy path
2 | incomplete (README + chats, no project/) | 0 | assistant waiting for clarification — still valid
3 | no README.md | 1 | structural violation
4 | no chats/ dir | 1 | transcript is load-bearing (per README)
5 | empty chats/ dir | 1 | no .md files = no transcript
6 | non-tarball input (plain text) | 1 or 2 | not a real bundle
7 | missing input path | 2 | tool/IO error, not a schema issue

## Local run output

    $ bash tests/unit/test-handoff-bundle-schema.sh

      ✓ complete bundle validates (exit 0)
      ✓ incomplete bundle validates (exit 0 — expected)
      ✓ missing README.md → exit 1
      ✓ missing chats/ → exit 1
      ✓ empty chats/ → exit 1
      ✓ non-tarball rejected (exit 1)
      ✓ missing input → exit 2 (tool/IO error)

    ════════════════════════════════════════════════════════════════
      Total: 7  |  Passed: 7  |  Failed: 0
    ════════════════════════════════════════════════════════════════

## Design choices

- Fixtures built on the fly (mkdir + touch + tar -czf). No committed binaries.
- Exit codes distinguish schema violation (1) from tool/IO error (2) so callers can handle each appropriately.
- Incomplete bundles are valid — they mean the assistant was waiting. The orchestrator's job is to surface that, not fail.
- Soft warning when README doesn't mention CODING AGENTS / handoff bundle / claude.ai/design — may not be a real Claude Design bundle.

## Wave 2 progress (4 of 5)

    PR-T1   formatStars unit test                ✓ merged (#1412)
    PR-T2   sync_versions round-trip             ✓ merged (#1414)
    PR-T3   Playwright E2E for landing           #1415 (open, CI running)
    PR-T4   handoff bundle schema validator      ← THIS PR
    PR-T5   stub-fallback integration test       last