---
paths:
  - backend/thesis_seed.py
  - backend/thesis_review.py
  - backend/mcp/architect_agent.py
  - backend/mcp/architect_tools.py
  - backend/mcp/architect_grounding.py
---

# Thesis Workshop & canonical gate

Read this before editing thesis nodes, versions, the review flow, or the Architect copilot.

## The two layers

- **Working tree** — thesis nodes with status `draft | candidate | approved | retired`. Code and seeds may move nodes around this ladder freely.
- **Canonical** — a frozen `thesis_version`, the read source for the live agent prompt. A version becomes canonical **only** by human **dual** sign-off through `backend/thesis_review.py` (currently Grant + Jonathan).

## Hard rules

- **Never set a `thesis_version` canonical from code or seeds.** That is human dual sign-off, full stop. `ensure_*` seeders may promote a *working* spine to `approved` (node-level, reversible) but must not freeze a canonical version.
- **Soft-delete subtlety — this trips people up:** `_node_tree` and `create_thesis_version` filter on `deleted_at IS NULL` and **ignore status**. So to drop a node from *both* the live agent prompt and version snapshots you must set `deleted_at` — setting `status='retired'` alone leaves it in the tree.

## Boot behavior

- On boot, `ensure_thesis_v2_promoted` makes the v2.0 reserve-asset spine the working *approved* spine (node-level, reversible) — it does **not** freeze a canonical version. Promotion to canonical still waits on dual sign-off in the Workshop.
- **The core `positioning` variant group has 7 members, not 2.** The seed plants Option A/B, then `ensure_positioning_framings` (2026-06-05 Architect pass) additively inserts 5 competing framings (titles `Option C–G … (Architect, NN/60)`) into the same group. So `choose_variant` on any member retires the other 6. Tests (`test_thesis_seed.py`, `test_thesis_actions.py`) assert this 2+5=7 shape — keep them in sync if the framing set changes.

See also `docs/thesis-handoff.md` for the current thesis content state.
