# Symposium-2026 Design Loop — Operator Guide

**Location:** `docs/design/symposium-2026/`
**Event:** TR Advisory Symposium, Huntington Beach — June 2–4, 2026
**Branch:** `design/symposium-2026` (never work on `main`)

This guide covers how to run the design loop infrastructure, build and verify individual
surfaces, manage brand packs, and commit work correctly. Read it before touching any
surface HTML.

---

## Wave 0 — Infrastructure Gate

Wave 0 must pass before any surface HTML work begins. It validates that brand packs are
in the expected state, that font URLs are reachable (required before `tr_partner` can be
activated), and that the verifier tool is registered.

Run all four commands in order:

```bash
node scripts/design/preflight.mjs
node scripts/design/build-brand-css.mjs
node scripts/design/build-manifest.mjs
node --test tests/design/*.test.mjs
```

What each command does:

| Command | Output | Blocks if… |
|---------|--------|------------|
| `preflight.mjs` | `.preflight.json` | `proposalforge` pack is not approved, or `tr_partner` is approved but Clario font URL is missing |
| `build-brand-css.mjs` | `_brand.css` | Any required palette, typography, or button key is missing from either brand pack |
| `build-manifest.mjs` | `manifest.yaml` | Evidence YAML and audit markdown are out of sync |
| `node --test tests/design/*.test.mjs` | Console pass/fail | Any design-loop test fails |

If any step exits with a non-zero code, stop. Do not proceed to surface work until all
four pass cleanly. Wave 0 failures are infrastructure problems, not design problems —
fix the underlying cause before continuing.

---

## Surface-Wave Workflow

Follow these steps for every surface. Do not skip steps or reorder them.

### Step 1 — Run Wave 0

Confirm Wave 0 is passing before touching the surface. If you have made any changes to
brand pack YAML files since your last Wave 0 run, re-run all four commands now.

### Step 2 — Scaffold the surface

```bash
node scripts/design/scaffold-surface.mjs {slug}
```

Replace `{slug}` with the surface slug from the wave table below (e.g. `p5-proposal-generation`).

The scaffolder creates three files under `docs/design/symposium-2026/{slug}/`:

- `index.html` — a brand-aware HTML placeholder with the brand toggle bar and draft banner
  logic already wired in
- `notes.md` — a structured notes template with Audit Row, CTAs, Intended Routes, and
  Verifier Transcript sections
- `screenshots/.gitkeep` — ensures the screenshots directory is tracked by git

The scaffolder will not overwrite files that have been hand-edited. Once you remove the
`<!-- PLACEHOLDER: scaffold-generated -->` marker from `index.html` or `notes.md`, the
scaffolder treats that file as yours and skips it on future runs.

### Step 3 — Edit the surface

Edit `{slug}/index.html` to build the surface prototype. Edit `{slug}/notes.md` to
complete the Audit Row table, list every CTA, and record the intended Laravel route for
each CTA. Both files must be complete before running the verifier.

Design constraints:
- All colors and fonts must come from `_brand.css` custom properties — no raw hex codes,
  no inline font-family strings
- No Laravel/Blade template syntax (`{{ }}`, `@route()`, `url()`, etc.)
- If this is `p3-ingestion` or `p8-new-client-lane`, follow the specific overclaim guards
  documented in Verifier Rules 6 and 7
- The brand toggle bar and draft banner are already in the scaffolded `index.html`;
  do not remove them

### Step 4 — Run the verifier loop

The verifier is `mcp__codex-cli__review` running GPT-5.5, deferred to Opus to invoke.
Opus runs the tool against the surface HTML and notes, checks all 9 verifier rules in
`_verifier-rules.md`, and appends the transcript to `notes.md`.

The loop runs up to 3 cycles per surface per brand. After each cycle, the manifest is
updated with the new `verifier_status`. Possible outcomes:

| Status | Meaning |
|--------|---------|
| `pass` | All 9 rules satisfied for this brand render |
| `fail` | One or more rules failed; transcript explains what to fix |
| `escalated` | 3 cycles exhausted without a pass; human review required |
| `escalated_no_verifier` | Tool unavailable; surface is held pending verifier registration |

Fix any failures reported in the transcript, then re-run the verifier cycle. A surface
is complete only when both brand renders (`proposalforge` and `tr_partner`) show `pass`
or an approved escalation disposition in `manifest.yaml`.

Opus is not permitted to serve as its own verifier. If Opus is the session model, it
must invoke `mcp__codex-cli__review` for verification rather than self-reviewing.

### Step 5 — Capture screenshots

```bash
node scripts/design/screenshot.mjs {slug} proposalforge
node scripts/design/screenshot.mjs {slug} tr_partner
```

This runs Playwright Chromium at 1440×900 and writes PNGs to
`{slug}/screenshots/proposalforge.png` and `{slug}/screenshots/tr_partner.png`.

Screenshots must be captured after the surface passes the verifier for each brand.
Do not capture screenshots of placeholder content.

### Step 6 — Update the manifest

```bash
node scripts/design/build-manifest.mjs
```

Re-run the manifest builder after a surface reaches verifier pass. This is an idempotent
operation — it preserves existing `verifier_status` values and updates timestamps.

### Step 7 — Rebuild the index

```bash
node scripts/design/build-index.mjs
```

This regenerates `index.html` (the clickable surface directory) from the current
`manifest.yaml`. Run this after every manifest update so the index reflects the
latest verifier and screenshot status.

### Step 8 — Commit the surface

Commit one surface at a time. See Commit Discipline below.

---

## Wave Order

Build surfaces in wave order. Each wave has a different quality bar.

| Wave | Surfaces | Polish Target | David Approval Gate? |
|------|----------|---------------|----------------------|
| 0 | Infrastructure (CSS, manifest, tests) | Must pass — no HTML work without it | No |
| 1 | p5-proposal-generation, p9-existing-client-lane, p10-acceptance-handoff | Demo-Flawless Closing Arc — highest fidelity, both brands fully verified | Yes |
| 2 | p2-intake, p7-deck-renderer | Demo-Tight Bookends — screenshot + verifier pass required | Yes |
| 3 | p1-firm-setup, p4-client-intelligence, p6-pricing, p11-client-portal | Breadth / Supporting Context — full verifier pass | Yes |
| 4 | p3-ingestion, p8-new-client-lane | Honest Stub Surfaces — overclaim guards enforced, verification-pending badges visible | No |

Wave 1 surfaces are the most important. They are the closing arc of the demo. Work on
these first and give them the most attention. Wave 4 surfaces exist to set honest
expectations — they should look intentional, not broken.

---

## tr_partner Draft Restrictions

### What "draft" means

The `tr_partner` brand pack is currently in `draft` status. This means the Clario font
license and Thomson Reuters co-brand approval are both pending. Until the pack moves to
`approved` status:

- No `tr_partner` rendered surface may be shared with anyone outside the internal team
- No screenshot taken under the `tr_partner` brand may be included in external materials
- No link to a `tr_partner` render may be sent in email, Slack, or any other channel
  that reaches Thomson Reuters contacts or prospects

### The BLOCKED badge

On the `index.html` surface directory page, every `tr_partner` link appears with a red
`BLOCKED` badge and the link is visually grayed out and non-clickable. This is generated
automatically by `build-index.mjs` based on the `external_use_approved: false` field in
`manifest.yaml`, which is itself derived from `brand-packs/tr_partner.yaml`. You do not
need to set this manually.

### The draft banner

Every surface rendered in the `tr_partner` brand (i.e. when `body.brand-tr-partner` is
active or when `?brand=tr_partner` is in the URL) shows a yellow banner at the top of
the page reading:

```
[INTERNAL DRAFT — Not for external distribution]
```

This banner is wired into the scaffolded `index.html` template. It fires from a
`<script>` block that reads the active brand and shows or hides the banner element
accordingly. Do not remove or hide this logic when editing a surface.

### How to activate tr_partner

When the Clario font license and Thomson Reuters co-brand approval have been secured,
update `brand-packs/tr_partner.yaml`:

1. Set `provenance.approval_status` to `approved`
2. Set `provenance.approved_by` to the approver's name
3. Set `provenance.approved_at` to the approval date (ISO 8601)
4. Set `typography.font_url` to the licensed Clario font URL
5. Set `restrictions.external_use_approved` to `true`
6. Set `restrictions.public_render_allowed` to `true`

Then re-run the full Wave 0 sequence. The `BLOCKED` badges will clear automatically
once `build-manifest.mjs` detects the updated approval state.

---

## GPT Image 2 Review-Board Policy

GPT Image 2 mockups are internal planning aids that help evaluate layout and visual
direction before committing to hand-coded HTML. They are never shipped to any external
audience.

### Where to put mockups

Store all review-board mockups in the `_review-board/` subdirectory of the surface:

```
docs/design/symposium-2026/
  _review-board/
    proposalforge-mockup.png
    tr-partner-mockup.png
```

Naming convention: `_review-board/{brand}-mockup.png`

The `_review-board/` directory at the root of the design loop may also contain cross-surface
planning mockups. Always prefix the filename with the brand name so the origin is clear at a glance.

### What review-board mockups are for

- Exploring layout options before writing HTML
- Communicating visual direction to advisors in internal review sessions
- Validating that the planned design direction is achievable within the brand token constraints

### What review-board mockups are not for

- External audiences of any kind
- Thomson Reuters contacts or partners
- Any public-facing material, presentation, or proposal

Review-board files are gitignored from the repository's public surfaces but tracked
locally for internal reference. If a mockup file somehow appears in a PR destined for
an external-facing branch, remove it before merging.

---

## Commit Discipline

### One surface per commit

Each commit should contain the files for exactly one surface:

```
docs/design/symposium-2026/{slug}/index.html
docs/design/symposium-2026/{slug}/notes.md
docs/design/symposium-2026/{slug}/screenshots/proposalforge.png
docs/design/symposium-2026/{slug}/screenshots/tr_partner.png
docs/design/symposium-2026/{slug}/screenshots/.gitkeep
docs/design/symposium-2026/manifest.yaml          (updated)
docs/design/symposium-2026/index.html             (regenerated)
```

Do not combine two surface completions into one commit. It makes wave attribution
and rollback harder.

### Wave 0 infrastructure in its own commit

All Wave 0 infrastructure files — `_brand.css`, `manifest.yaml` (initial build),
`index.html` (initial build), `.preflight.json` — belong in a single infrastructure
commit separate from any surface work. Suggested message:

```
build(design): Wave 0 infrastructure — brand CSS, manifest, index
```

### Suggested surface commit message format

```
design(symposium): p5-proposal-generation — Wave 1 verifier pass (both brands)
```

---

## Quick Reference

| Task | Command |
|------|---------|
| Run full Wave 0 gate | `node scripts/design/preflight.mjs && node scripts/design/build-brand-css.mjs && node scripts/design/build-manifest.mjs && node --test tests/design/*.test.mjs` |
| Scaffold a surface | `node scripts/design/scaffold-surface.mjs {slug}` |
| Capture screenshots | `node scripts/design/screenshot.mjs {slug} proposalforge` / `tr_partner` |
| Update manifest | `node scripts/design/build-manifest.mjs` |
| Rebuild index | `node scripts/design/build-index.mjs` |
| Check verifier rules | See `docs/design/symposium-2026/_verifier-rules.md` |

---

## File Map

```
docs/design/symposium-2026/
  _brand.css              Generated — do not edit by hand
  _verifier-rules.md      9 canonical verifier rules (this loop's truth surface)
  .preflight.json         Generated — Wave 0 audit result (gitignored)
  manifest.yaml           11 × 2 audit matrix (generated, verifier progress preserved)
  index.html              Clickable surface directory (generated from manifest)
  README.md               This file
  p{n}-{slug}/
    index.html            Static surface prototype (hand-edited after scaffold)
    notes.md              Audit row, CTAs, intended routes, verifier transcript
    screenshots/
      proposalforge.png
      tr_partner.png
      .gitkeep
  _review-board/          Internal GPT Image 2 mockups — never external
```
