feat: add master notebook library scaffolding and review tooling

Add CLAUDE.md defining the Palladium master notebook conventions and
Red Panda Approval criteria, plus a review-notebook slash command for
LLM-driven notebook review.

Expand .gitignore to block client/engagement documents and generated
exports, keeping masters client-clean while allowing text/image sources.

Normalize slider widget numeric values from floats to integers in
notebook JSON.
This commit is contained in:
2026-07-31 16:16:07 +00:00
parent 53c069fddb
commit a967f73d09
61 changed files with 4881 additions and 4257 deletions

View File

@@ -0,0 +1,116 @@
# CX Exploration & Discovery Workshop
An **Assessment** — a reusable workshop master (see
[`docs/Assessment_Pattern_V1-00.md`](../../docs/Assessment_Pattern_V1-00.md))
— and a **live facilitation aid** for a CX discovery session, built on the
[Mercury Notebook Deliverable Pattern](../../docs/Mercury_Notebook_Pattern_V1-00.md).
Unlike the TEI business-case studies, this deliverable computes no dollars —
its "numbers" are **topic status and progress**. The Mercury stage is the
visual you share on a call or in a workshop while you work through the
questions; the question script and captured notes live backstage and export
as LLM input for the survey write-up or a downstream business case.
## What the client sees (the stage)
A calm **topic board**: each topic, its one-line scope, a status glyph, and —
for the topic under discussion — a **live sub-topic checklist**, above a
**progress bar** ("3/8 topics complete"). No wall of questions: you ask those.
![board preview](docs/board_preview.png)
You drive it from the sidebar — a **status** selector and a **notes** box per
topic, plus a **checkbox** per sub-topic. As the conversation moves you set a
topic *In progress*, tick sub-topics as you cover them, mark it *Complete* (or
*Skipped*), and jot answers. Every change re-renders the board and progress bar
(Mercury re-runs the cells below the widgets).
## What you work from (backstage)
JupyterLab and the exports carry the **facilitator question script** (all 95
prompts, grouped by topic → sub-topic) and the **captured-session appendix**
(status + notes as a markdown table and one JSON block). Neither shows on the
Mercury stage. The 8 topics / 26 sub-topics / ~110-minute agenda are the
structured form of the source survey.
## Where the content lives: in the notebook
Two tagged cells of
[`notebooks/cx_discovery.ipynb`](notebooks/cx_discovery.ipynb) carry
everything a consultant edits — **in Jupyter, never in a `.py` file**:
- **`topic-bank`** — the workshop content: every topic, sub-topic, and
facilitator prompt. It is the study's verbatim anchor: wording tracks the
source survey [`docs/cx_discovery_survey.md`](docs/cx_discovery_survey.md)
(the original `cxxm.md`), and the `key` slugs are stable identities the
sidebar widgets, captured notes, and JSON export all key off — never
renumber or rename them casually. The cell's own comment block carries the
full editing rules.
- **`engagement-data`** — the client facts (client, workshop date,
facilitator, attendees). **Placeholders in this master**; filled in the
engagement copy. The values flow to the stage board header, the export
preamble, and the JSON appendix `meta`.
`discoverylib/` holds **code only**: the `Topic`/`SubTopic` schema, the
status vocabulary, and the session engine — every engine function takes the
bank as its first argument. The ~42 sidebar widgets are built by a runtime
loop over `TOPICS`, so board, checklist, script, gate, and export all pick up
a content edit automatically. The test suite reads the tagged cells straight
out of the notebook (no kernel) and pins content shape, so `pytest` guards
the bank exactly as shipped.
## Layout
```
notebooks/cx_discovery.ipynb # THE deliverable — content + data + presentation
# tagged cells: topic-bank · engagement-data ·
# presentation ×4 · gate · data-appendix
# stage shows ONLY: title · progress line · board
discoverylib/ # the engine — code only, no content
session.py # Topic/SubTopic schema, status vocabulary, progress, export payload
staging.py # stage/backstage detection (+ backstage_md for the appendix)
scripts/export_report.py # execute once → exports/*.html + LLM-ready *.md
tests/ # content + engagement pins (read from the notebook), engine pins, staging
docs/cx_discovery_survey.md # source survey (the original cxxm.md)
exports/ # generated report sources (never committed)
```
## Run
```bash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
mercury --working-dir . # serve the stage (share this screen)
jupyter lab # analyst / facilitator view
pytest # content + engagement + engine + staging pins
jupyter nbconvert --to notebook --execute --inplace notebooks/cx_discovery.ipynb # gate
python scripts/export_report.py # exports/*.html + *.md for the LLM handoff
```
The `.md` export opens with a generated preamble (what the document is, the
engagement line, how to read it) and ends with the **Session state (JSON)**
block — the machine source of truth for the write-up. Presentation cells
(setup, the facilitator run-book, widgets, board) are stripped from it; the
HTML export keeps the full presentation for human review.
## Extending
New or reshaped discovery content is an edit to the notebook's `topic-bank`
cell in JupyterLab, then:
1. Re-run the notebook — the in-notebook **gate** recounts the bank
(topics / sub-topics / prompts / key order / agenda minutes); update its
pins if the change is deliberate.
2. `pytest``tests/test_topics.py` pins the same shape from outside the
kernel; re-pin the counts there too.
Add a topic and the sidebar controls, board, checklist, script, gate, and
export all pick it up — they're all derived from `TOPICS` at runtime. New
*logic* (not content) goes in `discoverylib/session.py` with pins in
`tests/test_session.py`.
**Running this for a client?** Don't fill client data into this master —
follow the copy-out checklist in
[`docs/Assessment_Pattern_V1-00.md`](../../docs/Assessment_Pattern_V1-00.md):
copy the directory out of Palladium, stamp it `YYYYMM_Client_CX_Discovery`,
fill the `engagement-data` cell there, and treat the copy as confidential.