# CLAUDE.md β€” Palladium (library of master notebooks) 🐾 Palladium is a **library of master notebooks** for consulting delivery: Mercury-served Jupyter deliverables a client watches on a live call. "Library" means the copies in this repo are **masters** β€” client-clean, reusable, maintained β€” it does **not** mean drafts. A master becomes a client deliverable only as an **engagement copy made outside this repo**, where it acquires client data and becomes confidential. The notebook a client can open and trust is the whole product. ## 🐾 Red Panda Approvalβ„’ β€” for a consulting master library Don't satisfy a checklist β€” satisfy the red pandas. Ask of each change: *does this earn approval?* 1. **Rebuildable From Nothing** β€” inside any master: `python -m venv .venv` β†’ `pip install -e ".[dev]"` β†’ `pytest` β†’ headless gate β†’ `mercury --working-dir .` brings up the deliverable with no manual step. And a master **copied out of the repo runs standalone** β€” self-contained engine, own `staging.py`, no import back into Palladium. The ability to stand a workshop up on short notice is the product. 2. **Elegant Simplicity** β€” these are workshop tools, not enterprise platforms; the obvious solution, done well. A content cell should read like the survey it came from, not like a framework. 3. **Observable & Debuggable** β€” a failing gate names the number that drifted; diagnostics flow through `backstage()`, never onto the client-facing stage; the exports show the whole session state so a failure is diagnosable after the call. 4. **Consistent Patterns** β€” the three-layer contract, widget-pairs, tagged cells, per-master engine packages. Match the pattern docs, not personal taste. 5. **Actually Works** β€” "pytest was green" is not "the board renders on the stage with the engine's numbers." The gate under headless `nbconvert --execute` plus an actual Mercury render are the proof. Criteria 1 and 5 are **externally verifiable** β€” the rebuild works or it doesn't; the stage renders or it doesn't. Verify them, don't assert them. Criteria 2–4 are judgement calls: when in doubt, match what the repo already does rather than grading your own elegance. > If a paw print isn't leading the response, the rest of this file probably isn't > being honoured either. Lead with one. 🐾 --- ## The three-layer contract Every master separates three concerns; the split IS the architecture: | Layer | Audience | Holds | Never holds | |---|---|---|---| | **Mercury** (the stage) | the client | the polished board/case, sidebar controls | diagnostics, question scripts, internals | | **Notebook cells** (backstage) | the consultant | **content** (topic banks, prompts) and **client data** (engagement facts, spend, headcount) in **tagged cells**; presentation code | math | | **Python modules** (the engine) | tests + the notebook | reusable logic, schema, calculations β€” typed, `mypy --strict`, pinned | **content β€” NEVER** | The rule that has teeth: **content never lives in `.py`** β€” not as constants, not as a notebook generator's string blocks. The notebook is the document the consultant edits; hiding its content in importable modules defeats the point of a notebook. Mechanics: [docs/Mercury_Notebook_Pattern_V1-00.md](docs/Mercury_Notebook_Pattern_V1-00.md); per-type contracts: [docs/Assessment_Pattern_V1-00.md](docs/Assessment_Pattern_V1-00.md) and [docs/Study_Pattern_V1-00.md](docs/Study_Pattern_V1-00.md). ## Taxonomy - **Study** (`studies/YYYYMM_…`, dated) β€” reproduction of a dated base document (Forrester TEI or similar); verbatim anchor + client overlay; the date is the publication's, so it stays. - **Assessment** (`assessments/Instrument_Name`, undated) β€” reusable workshop instrument; a living master. Reference implementation: `assessments/CX_Discovery_Workshop/`. - **Engagement copy** (`YYYYMM_Client_Instrument`, stamped at copy-time) β€” a master copied OUT of this repo for a client; confidential; never merges back. - **`template/MercuryNotebook/`** β€” copy-me scaffold for new studies (py-engine model only β€” see Known liabilities). - **`core/`** β€” the shared Athena toolkit; masters do NOT import it. ## Before working in a master: check where you are **Look at the path.** Which master's root are you under? Each master has its **own venv** β€” `.venv` inside the master directory, provisioned by `pip install -e ".[dev]"` there; the repo-root `.venv` (from `make setup`) serves only `core/` and the notebook structural suite. Running a master's pytest from the wrong venv is the classic "missing module" ghost. - Stage detection is **per view, not per server**: the primary signal is `__mercury__` in `JPY_SESSION_NAME` (the app's shadow-copy session); `MERCURY_CONFIG_DIR` is only a fallback and is set **only** by `mercury --working-dir`. Never set either manually except to simulate the stage in a test (Mercury pattern Β§6 has the mechanism). - Only masters live here. **If a notebook in this repo contains a real client's name, something is wrong** β€” stop and flag it (see Confidentiality). ## Risk tier: CONSULTING MASTERS β€” what you may run **Free** β€” run without asking: `pytest`, `mypy`, `ruff`, `make test`, `make check-notebooks`, `jupyter nbconvert --execute` on a master, `mercury --working-dir .` locally, `python scripts/export_report.py`, and any read-only git. **Show first** β€” produce the diff/output, present it, wait for a human "go": content edits to `topic-bank`/`engagement-data` cells or anchor-adjacent wording; re-pinning a gate or test after a content/engine change (show the pin diff and the KPI moves honestly); moving or renaming a master; `.gitignore` changes; `git commit`. **Forbidden without explicit go-ahead:** `git push`; editing `*_VERBATIM` anchors; committing any client document (SOW, quote, NDA'd vendor deck); putting a client's name or data into a master; history rewrites; deleting a study or assessment. > The one clause that always applies: *"the user asked me to update the workshop" is > not explicit go-ahead for a Show-first change.* Explicit go-ahead is the user seeing > the specific diff and saying yes to **that**. --- ## Conventions (always-on) ### Done means the stage shows the engine's numbers, not that the file saved The cell is a wish; the executed notebook is the fact. An edit that is syntactically perfect has changed **nothing** until the notebook re-runs β€” and the committed outputs now lie about the deliverable. 1. **Pin it** β€” `pytest` + `mypy` in the master's venv. 2. **Execute it** β€” `jupyter nbconvert --to notebook --execute --inplace notebooks/*.ipynb`; the gate passing headless is the study's smoke test. 3. **Export it** β€” `python scripts/export_report.py`; the `.md` must carry the appendix and its final JSON block. 4. **Read it back from the real system** β€” serve with Mercury (or open the exported HTML) and look at the board; then check what depends on the change: test pins, gate pins, README counts, pattern docs, the export JSON. A master is a *chain* β€” a renamed content key breaks widgets, notes, and the export two hops downstream. ### Confidentiality β€” masters stay client-clean There is no Palladium without this rule; it is what makes the library shareable. - Masters carry **placeholder** engagement data, published or synthetic numbers, and no client statements. Client personalization happens in an **engagement copy** made outside the repo (copy β†’ rename `YYYYMM_Client_…` β†’ fresh venv β†’ fill `engagement-data` β†’ verify; canonical checklist in the Assessment Pattern) β€” **before** any client data is entered, and the copy never merges back. - **Never commit a client document** β€” SOWs, quotes, pricing decks, NDA'd vendor material. `.gitignore` blocks binary documents under every master's `docs/` and anything matching `*SOW*`; that is a guardrail, not permission β€” the rule is the rule even where the pattern has a hole. The ONE exception: a Study's **published, public** source PDF, added deliberately with `git add -f` and named in the commit message. - Improvements discovered on an engagement come back to the master as **clean edits** (content/logic only, client facts stripped). ### Notebooks - Widget-pair rule, gate cell, stage/backstage, data appendix, packaging: the [Mercury pattern](docs/Mercury_Notebook_Pattern_V1-00.md) is the contract β€” read it before editing any notebook. - Tagged cells are the consultant's surface: `topic-bank` (content), `engagement-data` (client facts; placeholders in masters), `presentation`, `gate`, `data-appendix`. Tags are load-bearing β€” tests, the structural suite, and the export pipeline all find cells by tag. - Content-cell keys are **stable identities** (widgets, notes, exports key off them); a title edit renames its sidebar widget label, which resets that widget's state mid-session. - `assessments/CX_AI_Diagnostic/notebooks/diagnostic.ipynb` is **generated** by its `scripts/build_notebook.py` β€” never hand-edit it (and don't "fix" it to notebook-first casually; that's a recorded redesign). ### Python - One venv per master; `pip install -e ".[dev]"` provisions everything (whole toolchain as core deps β€” never a `requirements.txt` in a master). - Engines are `mypy --strict` clean; new logic lands as engine code + pins **before** the notebook section that renders it. - `staging.py` is copied per master (self-containment beats DRY here β€” an engagement copy must run alone). The mypy-strict variant in `assessments/CX_Discovery_Workshop/discoverylib/staging.py` (with `backstage_md`) is the canonical form for new masters. ## Always-on anti-patterns - **Content:** never move workshop content into `.py` β€” including generators that hold cell sources as strings. - **Client data:** never in a master; never in a commit; a client name in `assessments/` or `template/` means the copy-out step was skipped. - **Anchors:** never edit `*_VERBATIM` β€” overlay corrections, don't rewrite the record. - **Widgets:** never read `.value` in the defining cell; widget cells emit no output. - **Surfaces:** never build a parallel UI (Streamlit twin, second app) β€” the notebook is the surface. - **Exports:** never commit generated exports; `exports/` is gitignored on purpose. - **Emptiness pins:** never assert that engagement placeholders are empty β€” the filled engagement copy must stay green. --- ## Environment - Repo root: `/home/robert/notebook/git/palladium` Β· remote: `ssh://git@git.helu.ca:22022/r/palladium.git` (Robert's Gitea) Β· branch `main`. - Root venv: `make setup` (core/Athena layer + the notebook structural suite; `make test`, `make check-notebooks`). One venv **per master** besides it. - Python β‰₯3.10 per master (`CX_AI_Diagnostic` pins β‰₯3.11; root core is β‰₯3.11); Mercury 3.2.x; per-master mypy is strict; repo-wide lint is ruff (root `pyproject.toml`). - Athena onboarding: `00_setup.ipynb` (writes `.env`; sandbox `https://athena.ouranos.helu.ca`). ## Known liabilities (flag, don't silently fix) If you find a known non-compliant choice, raise it rather than quietly fixing it or quietly leaving it. Live ones worth knowing: - **`studies/202607_CTM_GenesysCX/` is a real-client engagement study inside the library** β€” committed confidential vendor/client PDFs in `docs/` (also in git history), plus a signed SOW PDF sitting on disk untracked-and-ignored (the `*SOW*` ignore hides it from `git status` β€” it is still there). Grandfathered: do not add more material, do not use it as precedent; extraction to an engagement archive is a recorded follow-up. Two of its notebooks are dirty in the working tree β€” pre-existing, leave them. - **`assessments/CX_AI_Diagnostic/` pre-dates the notebook-first model** β€” generated notebook, content in YAML configs. Redesign pending; until then its shape is intentional. Its `mypy` is also not clean in a fresh venv (11 pre-existing errors: missing pandas/PyYAML/plotly stubs, unannotated functions) even though its `pyproject.toml` declares strict mode β€” pytest and the headless execute are green; fix the typing with the redesign, not piecemeal. - **TEI twins + CTM pre-date the tagged-cell taxonomy** β€” the structural suite grandfathers them by name in `tests/nbcheck.py`, each with its reason. - **Every master except CX Discovery still carries the env-var-only `staging.py`** (TEI twins, CTM, AI Diagnostic, template) β€” their `on_stage()` misses the Mercury app unless the server was launched with `--working-dir`, so **their stages leak backstage content** on a plain `mercury` launch (found live 2026-07-31; fixed in the Discovery reference). The retrofit is a recorded opportunity β€” until it lands, serve those masters only via `mercury --working-dir .`. - **`template/MercuryNotebook/` encodes only the py-engine model** (and its `staging.py` lacks the mypy-strict `backstage_md` variant); rework is a recorded follow-up. Its `exports/*.{html,md}` are tracked β€” predates the exports rule. - **`docs/brand.md` references a `brand_dark.md` that does not exist.** - **`core.bootstrap.init(study=…)` imports `studies..config`** β€” vestigial (no study ships a `config.py`; `studies/__init__.py` exists to serve it). Don't remove the `__init__.py` without retiring that path. ## Identified opportunities (recorded, not built) - A private installable Palladium package on the Gitea (CI exists there) β€” would replace per-master `staging.py` copies; revisit when the duplication bites. - A copy-out helper script (`scripts/new_engagement.py`) β€” after the manual checklist has been exercised a few times. - CTM extraction to a confidential engagement archive. - TEI + AI Diagnostic redesigns to the notebook-first model (each moves its notebook from GRANDFATHERED to NOTEBOOK_FIRST in `tests/nbcheck.py`). - Template rework: an Assessment template derived from the Discovery reference; staging.py retrofit across masters (now urgent-ish: brings the corrected shadow-session stage detection, plus mypy-strict + `backstage_md`, to the TEI twins, CTM, AI Diagnostic, and the template). ## Reference **Read the pattern for your master type before working in it β€” they hold the detail this file summarises:** - [docs/Assessment_Pattern_V1-00.md](docs/Assessment_Pattern_V1-00.md) β€” assessments: notebook-first content, engagement-data cell, copy-out checklist - [docs/Study_Pattern_V1-00.md](docs/Study_Pattern_V1-00.md) β€” studies: verbatim anchor + overlay, reproduction gate, published-PDF exception Everything else: - [docs/Mercury_Notebook_Pattern_V1-00.md](docs/Mercury_Notebook_Pattern_V1-00.md) β€” the shared mechanics (reactivity, gate, staging, appendix, packaging) - [docs/Notebook_Review_Prompt_V1-00.md](docs/Notebook_Review_Prompt_V1-00.md) β€” the LLM review; run as `/review-notebook ` - [docs/brand.md](docs/brand.md) β€” NTT DATA palette for stages and exports - [docs/Athena_TEI.md](docs/Athena_TEI.md) + `docs/Athena API.yaml` β€” the core/Athena layer - [README.md](README.md) β€” taxonomy, quick start, engagement workflow