Skip to content

Commit 20d9d61

Browse files
committed
Point 5: a deck's GENRE declares content it is not finished without
`design-by-purpose.md` carries nine purpose recipes — Type · Palette · Density · Layout · Icons · Signature, one per genre. Measured by grep, NOTHING consumed that file: a build could ignore it line by line and no gate would know, so every per-purpose rule in it was advisory by construction. And the four genres with the most rigid conventions were absent from the list entirely: grant aims · feasibility · risk committee progress · plan · ASK journal_club attribution · critique clinical_case presentation · investigations · management · outcome Three of those four are among the most common decks an academic makes, and one of them is the deck this session built by hand with no entry to follow. THE MECHANISM IS BORROWED, NOT INVENTED. `formats.py` + `check_surface.py` already do exactly this for SURFACES — a registry declares the sections a surface cannot be finished without — and that precedent exists because of a measured finding: "the billboard style that reads best is also the style that drops the two things a passer-by cannot reconstruct". The finding generalises. The shape of a genre is precisely what an author under time pressure drops: a committee deck loses the ask and silently becomes a status update. scripts/purposes.py (registry) + scripts/check_purpose.py (checker), on BOTH gate paths (parity: 21 sections, 0 problems), block-with-waiver like check_surface. EFFECTIVENESS — five purpose-built decks, both directions: * complete committee deck -> clean * same deck minus the ask -> reports exactly `ask` * grant deck with aims only -> reports exactly feasibility + risk * ask living only in SPEAKER NOTES -> clean (notes count; excluding them would fire on every deck that moved its sentences where this skill says to) * 中文 committee deck -> clean via the 中文 terms GENERALISATION: * multilingual term lists, with a test asserting EVERY section carries a non-Latin synonym — a monolingual list reports every CJK deck as missing every section * both record schemas (shared interview.picks, Codex design.purpose, and the audience brief when no purpose row was filled) — a floor read from one runtime stops applying to the other, which this repo has been through * a genre outside the registry binds to NOTHING and reports NOT CHECKED * a language the registry does not carry is cleared by EXTENDING the terms (design_plan.purpose_section_terms), which keeps the check alive, rather than by waiving it away — tested with a Dutch deck NEGATIVE BINDINGS, PINNED. The first draft bound on a bare "committee" and a bare "proposal". That would have pulled an INVESTMENT committee, an ETHICS committee, a steering committee and a business proposal into academic section lists — firing three or four times at the wrong deck, which is exactly how people learn to ignore a check. Worse, `recorded_purpose` also reads the AUDIENCE BRIEF, so a loose term reaches far more decks than a purpose row alone. Seven negative cases are now permanent assertions so a future loosening fails the suite. Honest about its limit, in the docstring and in design-by-purpose.md: it asks whether the deck NAMES the section, never whether it does it well — judging that stays the critic's — and the OTHER purposes in that file remain prose, reported as NOT CHECKED rather than implied to be covered. 58 assertions wired into CI · gate-batching 40/0 · gate-ergonomics 26/0 · surface-contract 40/0 · step1-artifacts 57/0 · critic-waiver 101/0 · timidity 21/0 · codex delivery gate and parity ok · all structural guards clean · SKILL.md lossless 2692/2692.
1 parent 5138698 commit 20d9d61

9 files changed

Lines changed: 785 additions & 1 deletion

File tree

.github/workflows/ci.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,17 @@ jobs:
679679
grep -qE "^[0-9]+ passed, 0 failed" /tmp/renderpar.log || {
680680
echo "::error::render-equivalence suite did not run to completion"; exit 1; }
681681
682+
# A deck's GENRE declares content it is not finished without — the formats.py/check_surface
683+
# mechanism generalised from SURFACES to GENRES. design-by-purpose.md carried nine purpose
684+
# recipes that NOTHING consumed, so every rule in it was advisory by construction.
685+
- name: Purpose sections (a genre's required content, both record schemas)
686+
run: |
687+
set -o pipefail
688+
python tests/test_purpose_sections.py | tee /tmp/purp.log
689+
grep -qE "^[0-9]+ passed, 0 failed" /tmp/purp.log || {
690+
echo "::error::purpose sections suite did not run to completion"; exit 1; }
691+
python scripts/check_purpose.py --selftest
692+
682693
# The clinical / evidence-synthesis forms. Each owns a rule that is wrong BY DEFAULT when
683694
# hand-rolled (a linear axis for ratios, a line instead of a step, a correlation instead of
684695
# limits of agreement) — and a wrong chart is a well-formed set of shapes, so no geometry

skills/slide-maker/SKILL.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ every **🔴 CHECKPOINT** is a hard stop.
274274
| Concern | Owner |
275275
|---|---|
276276
| The craft / the "why" (contrast · hierarchy · C.R.A.P. · layout safety) | `references/design-principles.md` |
277-
| Per-purpose look (defense vs exec vs lecture …) | `references/design-by-purpose.md` |
277+
| Per-purpose look (defense vs exec vs lecture …) | `references/design-by-purpose.md` — 🔴 four genres (grant · progress/guidance committee · journal club · clinical case) also DECLARE content they are not finished without, checked on both gate paths by `scripts/purposes.py` + `scripts/check_purpose.py` |
278278
| Per-TOPIC look (domain → apt presets → ANTI-PICK + cliché guard — the topic-adapted pick) | `references/design-by-topic.md` — 🔴 it adapts the LOOK only; a domain that needs its own FORM vocabulary is routed on the two rows below |
279279
| Bespoke registers invented from a subject's world (verified library to ADAPT + grow) | `references/bespoke-registers.md` |
280280
| Content — deep read + per-slide message (Step 1) | `agents/content-planner.md` |
@@ -516,6 +516,21 @@ source-material floor still gets asked);
516516
when in doubt, keep it. Never assume the **topic/content**, the **style**, or **which
517517
template** — confirm each.
518518

519+
🔴 **Four purposes DECLARE required content, and the deck is held to it at hand-off.** A grant
520+
proposal (aims · feasibility · risk), a progress/guidance committee (progress · plan · **ask**), a
521+
journal club (attribution · critique) and a clinical case (presentation · investigations ·
522+
management · outcome) each carry sections their audience is asked to judge against — so a deck
523+
missing one is not a lean deck, it is a deck missing something the room needs. `scripts/purposes.py`
524+
declares them and `scripts/check_purpose.py` looks for them in the built file (both gate paths, CJK
525+
terms included, extend with `design_plan.purpose_section_terms`, waive in writing). It binds ONLY
526+
when the recorded purpose matches a registry entry — anything else is NOT CHECKED, never a guessed
527+
genre. **This is the `formats.py`/`check_surface.py` mechanism generalised from SURFACES to GENRES**,
528+
and for the same measured reason: the shape of a genre is exactly what an author under time pressure
529+
drops. Each also carries one fidelity rule beyond never-invent — a pilot stated as a pilot, open work
530+
that reads as open, their claim separable from yours, and on a clinical case **de-identification,
531+
which is the one irreversible item on this page**. The other purposes in `design-by-purpose.md`
532+
remain prose, and a deck in one of those genres reports NOT CHECKED rather than clean.
533+
519534
**The `review:` question is NOT asked here — it moved to Step 5, after the first clean render.**
520535
It used to be a Step-0 axis, which forced the user to size a review of a deck nobody had seen;
521536
with the rendered deck in front of them the same choice is informed instead of blind, and that is

skills/slide-maker/references/design-by-purpose.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,74 @@ tabs. Like a conference talk but built for a *shared-screen* medium, not a proje
313313
`references/animation.md`); explicit "ask in the chat" prompts; a visible agenda so late
314314
joiners orient. If it's recorded, ensure every slide reads as a still frame.
315315

316+
## Grant proposal / funding pitch
317+
ERC · NWO · NIH · Horizon. The highest-stakes deck an academic makes, and the one with the most
318+
rigid conventions — reviewers score against *named* criteria, so a missing section is a lost point
319+
rather than a stylistic choice. Not a product pitch: the register is sober, and enthusiasm reads as
320+
a substitute for evidence.
321+
- **Type:** the academic default; equations only where the method genuinely turns on one.
322+
- **Palette:** institutional or sober; nothing that looks like a startup deck.
323+
- **Density:** high but structured — a reviewer is reading against a checklist, not being toured.
324+
- **Layout/chrome:** the scored sections visible as sections. Numbered aims.
325+
- **Signature:** the aims page is the deck. One sentence per aim, each falsifiable.
326+
- 🔴 **Declares (checked): aims · feasibility · risk.** Feasibility means *why this team, why now*
327+
pilot data, track record, access. Risk means named risks with named mitigations; "no significant
328+
risks" is read as not having thought about it.
329+
- 🔴 **Fidelity:** preliminary data is the section most often overstated. A pilot is a pilot — say n,
330+
say it is preliminary. A reviewer who catches one inflated claim discounts the rest.
331+
332+
## Progress / guidance committee meeting
333+
A PhD guidance committee, a thesis advisory board, a stage-gate review. It differs from a lab
334+
meeting in exactly one way, and it is the way that matters: **the room has to decide something**
335+
is this on track, does the thesis hold together, what should be scoped down. A committee deck with
336+
no ask has silently become a status update, and the meeting's most valuable output is lost.
337+
- **Type/palette:** the lab or institution's own template, unchanged. Nobody is being impressed.
338+
- **Density:** moderate-to-high; the deck is also the record of the year, read as well as presented.
339+
- **Layout/chrome:** status legible at a glance — what is done, what is out for review, what is
340+
still on your desk. Bind one hue to each state and keep it deck-wide.
341+
- **Signature:** the closing slide names the decisions you want them to weigh in on.
342+
- 🔴 **Declares (checked): progress · plan · ask.**
343+
- 🔴 **Fidelity:** what is not done must READ as not done. A committee exists to advise on open
344+
work, and a hypothesis promoted to a result removes the thing they are there to help with
345+
(`content.open_ledger` is the artifact).
346+
347+
## Journal club / presenting someone else's paper
348+
You are presenting work you did not do. Extremely common, and it carries a fidelity risk the
349+
universal never-invent rule does not reach: not fabrication but **misattribution** — stating their
350+
result more strongly than they did, or blurring their claims with your critique until the audience
351+
cannot tell which is which.
352+
- **Type/palette:** reuse the paper's own figures; let its visual language show through.
353+
- **Density:** moderate — the method matters, but the room has (in principle) read it.
354+
- **Layout/chrome:** a visible separation between *their claim* and *your reading*. A rail, a
355+
colour, a consistent slot — anything, as long as it is the same on every slide.
356+
- **Signature:** your assessment, owned as yours.
357+
- 🔴 **Declares (checked): attribution · critique.**
358+
- 🔴 **Fidelity:** attribute on the slide that carries the result, not only on the title slide. An
359+
audience that cannot tell which is which will remember your critique as the paper's conclusion.
360+
361+
## Clinical case presentation / tumour board / M&M
362+
A fixed clinical narrative. The structure is not a style choice: colleagues are being asked to judge
363+
a decision, and they cannot do that without the information that was available when it was made.
364+
- **Type/palette:** the institution's template; sober. Never playful — somber veto.
365+
- **Density:** high on the facts, minimal on chrome. Imaging large.
366+
- **Layout/chrome:** one section per stage, in order; imaging shown at a size a clinician can read.
367+
- **Signature:** the learning point, stated plainly.
368+
- 🔴 **Declares (checked): presentation · investigations · management · outcome.**
369+
- 🔴 **Fidelity — DE-IDENTIFICATION IS LOAD-BEARING.** This is the genre PRE-FLIGHT 5's burned-in
370+
identifier check exists for: name, MRN, accession, date of birth, study date, institution, read on
371+
all four edges and in every overlay strip. Get a de-identified export — never crop or blur and
372+
ship. Unlike everything else on this page, it is irreversible once the deck is sent.
373+
374+
> 🔴 **These four are CHECKED, not just described.** `scripts/purposes.py` declares the sections each
375+
> genre is not finished without and `scripts/check_purpose.py` looks for them in the built deck, on
376+
> both gate paths — the same mechanism `formats.py`/`check_surface.py` already applies to surfaces.
377+
> The check asks whether the deck NAMES the section, not whether it does it well; judging the latter
378+
> is the critic's job. Terms are multilingual; extend them with `design_plan.purpose_section_terms`
379+
> rather than waiving, and waive in writing when a deck genuinely has none.
380+
>
381+
> **The other purposes on this page are still prose.** That is a real gap and not a claim of
382+
> coverage: a genre with no registry entry binds to nothing and reports NOT CHECKED.
383+
316384
## Preset fit by purpose — a fast sanity map (fit is a default, avoid is a flag, both overridable with a stated reason)
317385
| Purpose | Natural fits | Flag before using |
318386
|---|---|---|

skills/slide-maker/references/file-inventory.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,24 @@ waiver once carried a whole deck through `all hand-off gates pass` with no indep
179179
the colour") stay prose and are REPORTED as unchecked. The register is resolved by
180180
`check_style_applied.declared_preset`, never a substring search: a bespoke deck whose pick read
181181
"beat blueprint-the-preset" was checked as `blueprint` on the first try.
182+
- `purposes.py` + `check_purpose.py` — a deck's GENRE declares content it is not finished without,
183+
checked against the built file on both gate paths. `references/design-by-purpose.md` carried nine
184+
purpose recipes and, measured by grep, NOTHING consumed it — so every per-purpose rule there was
185+
advisory by construction — and the four genres with the most rigid conventions were missing from
186+
the list entirely: grant proposal (aims · feasibility · risk), progress/guidance committee
187+
(progress · plan · ask), journal club (attribution · critique), clinical case
188+
(presentation · investigations · management · outcome). Three of those four are among the most
189+
common decks an academic makes. 🔴 This is the `formats.py` / `check_surface.py` mechanism
190+
generalised from SURFACES to GENRES, for the same measured reason — the shape of a genre is
191+
exactly what an author under time pressure drops (a poster loses methods and limitations; a
192+
committee deck loses the ask and becomes a status update). Binds by matching the RECORDED purpose
193+
(read from both record schemas, including the audience brief) against `binds_on` terms; no match
194+
is NOT CHECKED, never a guessed genre, because firing a clinical section list at a product pitch
195+
teaches the author to ignore the check. Section terms are multilingual (a 中文 deck names the same
196+
section in 中文 and a monolingual list would fire on every one), extendable with
197+
`design_plan.purpose_section_terms`, waivable with `{"purpose": {"waived": …}}`. It asks whether
198+
the deck NAMES the section, not whether it does it well — judging that stays the critic's. Each
199+
purpose also carries one fidelity rule beyond never-invent, printed every run.
182200
- `check_template_profile.py` — a registered template's `profile.md` must be OBEYED, not merely
183201
available. The registry is the one artefact in this skill with a MEMORY across decks — layout
184202
indices, decorative furniture that cannot be deleted from a layout and has to be covered by the

0 commit comments

Comments
 (0)