DEFAULT poster pipeline
Paper Poster (HTML): measurement-gated poster generation

DEFAULT poster pipeline — build an academic conference poster (ICML/NeurIPS/ICLR/CVPR/...) as a single HTML/CSS file with measurement-driven hard gates, real paper figures, a two-hue design-token system, and print-ready PDF via headless…
---
name: paper-poster-html
description: "DEFAULT poster pipeline — build an academic conference poster (ICML/NeurIPS/ICLR/CVPR/...) as a single HTML/CSS file with measurement-driven hard gates, real paper figures, a two-hue design-token system, and print-ready PDF via headless Chromium. Use when the user says \"做海报\", \"poster\", \"conference poster\", \"paper poster\", or asks to design/redo a research poster. Supersedes the retired LaTeX /paper-poster."
argument-hint: "[paper-dir-or-pdf] [— venue: ICLR, canvas: 185x90cm landscape, venue-colors: true]"
allowed-tools: Bash(*), Read, Write, Edit, Grep, Glob, WebFetch, WebSearch, AskUserQuestion, mcp__codex__codex
---
# Paper Poster (HTML): measurement-gated poster generation
One HTML file styled for an exact print canvas (`@page { size: W H }`), rendered to PDF
via Playwright print emulation. **Iterate by measuring, not eyeballing** — the screen
preview lies; only print emulation at the correct viewport tells the truth. Core gate
machinery is adapted from [posterly](https://github.com/Chenruishuo/posterly) (MIT, ©
2026 Ruishuo Chen — see `NOTICE.md` and `LICENSES/posterly-MIT.txt`); ARIS adds style
discipline gates, figure-provenance gates, the cross-model review loop, and the
anti-patch-loop fix vocabulary.
## Why this skill exists (the failure it prevents)Overview
One HTML file styled for an exact print canvas (@page { size: W H }), rendered to PDF via Playwright print emulation. Iterate by measuring, not eyeballing — the screen preview lies; only print emulation at the correct viewport tells the truth. Core gate machinery is adapted from posterly (MIT, © 2026 Ruishuo Chen — see NOTICE.md and LICENSES/posterly-MIT.txt); ARIS adds style discipline gates, figure-provenance gates, the cross-model review loop, and the anti-patch-loop fix vocabulary.
Manual install (npx, ZIP)
npx skills add wanshuiyin/Auto-claude-code-research-in-sleep --skill paper-poster-html -g -a claude-codemkdir -p ~/.claude/skills && curl -sL https://codeload.github.com/wanshuiyin/Auto-claude-code-research-in-sleep/tar.gz/f1bd907b58f6 \
| tar -xz -C ~/.claude/skills --strip-components=2 Auto-claude-code-research-in-sleep-f1bd907b58f6/skills/paper-poster-htmlNew-Item -ItemType Directory -Force "$HOME\.claude\skills" | Out-Null; Invoke-WebRequest "https://m.agentalley.io/zip/f3fccde5145ff2879cd8/paper-poster-html.zip" -OutFile "$env:TEMP\paper-poster-html.zip"; Expand-Archive "$env:TEMP\paper-poster-html.zip" -DestinationPath "$HOME\.claude\skills" -ForceConnects with Agent Alley MCP · agentalley.io/mcp
Files included
SKILL.md18.0 KBDESIGN_FINAL.md9.7 KBIMPLEMENTATION_CONVENTIONS.md8.7 KBNOTICE.md3.2 KBLICENSES/1 file · 1.0 KBscripts/15 files · 246.9 KBtemplates/11 files · 167.2 KB
Read the files here
wanshuiyin/
- asset_check.py35.9 KB
- extract_pdf_figures.py25.4 KB
- poster_check.py9.9 KB
- preprocess_figures.py9.1 KB
- render_preview.py7.5 KB
- run_gates.py20.0 KB
- style_check.py51.9 KB
- __init__.py0 B
- canvas.py7.2 KB
- measure.py24.1 KB
- polish.py20.5 KB
- preflight.py21.1 KB
- render.py8.0 KB
- textutil.py616 B
- verify_final.py5.5 KB
Show the full text324 lines
Paper Poster (HTML): measurement-gated poster generation
One HTML file styled for an exact print canvas (@page { size: W H }), rendered to PDF
via Playwright print emulation. Iterate by measuring, not eyeballing — the screen
preview lies; only print emulation at the correct viewport tells the truth. Core gate
machinery is adapted from posterly (MIT, ©
2026 Ruishuo Chen — see NOTICE.md and LICENSES/posterly-MIT.txt); ARIS adds style
discipline gates, figure-provenance gates, the cross-model review loop, and the
anti-patch-loop fix vocabulary.
Why this skill exists (the failure it prevents)
A predecessor pipeline produced a poster with 30+ colors, zero real paper figures, a screen-pixel canvas, and tiny formulas floating in oversized boxes, then spent 12+ review rounds making it worse — each round added a new badge color or bespoke SVG patch. The cure is structural, not exhortative:
- Hard gates run before any aesthetic opinion (alignment, style, assets must PASS first — a reviewer never sees an unmeasured poster).
- A closed fix vocabulary — visual-review fixes can only touch design tokens, whole catalogued components, content rebalance, assets, or canvas choice. New inline styles / new hex values / bespoke decorations are structurally forbidden.
- Two-hue discipline as a machine check, not a style suggestion.
- Real paper figures with provenance manifest, or the gate fails.
Mental model
paper (.tex / PDF) ──► content plan + claim→evidence audit (codex, fresh)
│
figures extracted ─────────┤ FIGURE_MANIFEST.json (provenance, sha256)
(real paper figures ONLY) ▼
template scaffold ──► fill ──► run_gates.py ◄─── HARD, loop here
preflight → style → asset → measure → polish
│ all hard gates PASS
▼
Claude visual review (≤3 issues × ≤3 rounds, fix-vocabulary only)
│ score ≥ 9
▼
codex final cross-model review (fresh thread, full HTML+PDF)
│ pass
▼
verify-final → poster.pdf + GATE_REPORT.json
Constants
- SKILL_SCRIPTS =
${CLAUDE_SKILL_DIR}/scripts— all helpers are single-owner and ship inside this skill (Arch C). If the directory is missing the install is broken: abort and tell the user to re-install the skill (Policy A — the gates ARE the skill; never improvise replacements). - REVIEWER_MODEL =
gpt-6-astra, reasoningxhigh, fresh thread per review call (mcp__codex__codex, nevercodex-replyacross review boundaries). - CANVAS — from the venue's official spec, looked up live in Phase 0. Never assume. (Known anchor: ICLR 2026 main = 185×90 cm landscape per its official printing service; ICML/NeurIPS commonly 60×36 in landscape; workshop posters often 61×91 cm portrait. Specs change yearly — verify.)
- PALETTE — default =
templates/tokens/generic.json(slate-blue#2D5F8Baccent- gold
#C9A24Ahighlight + neutrals) for all venues. Venue packs are opt-in via— venue-colors: true. Purple-dominant accents (hue 250–285) are banned unless the user passes— allow-purple: true.
- gold
- AUTO_PROCEED = false — wait for explicit confirmation at every 🚦 checkpoint.
- OUTPUT_DIR =
poster_html/in the working directory.
Workflow
Phase 0 — Resume, dependencies, venue spec
- Resume: if
poster_html/POSTER_STATE.jsonexists withstatus: in_progress(< 24 h), resume from the saved phase. - Dependencies (degradation chain, in order):
- Playwright + bundled Chromium → if missing,
python3 -m playwright install chromium→ if install fails but system Chrome exists, scripts fall back tochannel="chrome"→ if all fail: you may produce the content plan and scaffold only, label everything "not print verified", and must NOT emit a final PDF. pdfinfomissing → PyMuPDF reads PDF dimensions. At least one of pdftoppm / PyMuPDF must exist for PNG review renders.- MathJax: download
tex-svg.jsonce intoposter_html/assets/mathjax/and reference it locally in the HTML. CDN is acceptable only for drafts; the measure gate hard-fails on unrendered MathJax either way.
- Playwright + bundled Chromium → if missing,
- Venue spec lookup (live): consult the venue's official poster-instructions page
(search + fetch). Extract dimensions, orientation, font floor, logo policy,
anonymity rules, file format. Record
{spec, source_url, retrieved}intoPOSTER_STATE.json— specs change yearly; never reuse a cached spec silently.
🚦 Checkpoint: echo the venue spec table (canvas, orientation, source URL) and the chosen template. Wait.
Phase 0.5 — Design discovery (one AskUserQuestion batch)
Ask once, ≤4 questions: layout template (from templates/README.md), palette
(default generic pack / venue pack / custom within constraints), logos + venue mark
(paths or "none" — never fabricate; check the venue's logo policy), QR target (paper /
code / project page / none — generate offline with qrencode or python-qrcode;
never a remote QR-service URL). Persist answers in POSTER_STATE.json as
design_decisions — re-read before any later "improvement" so deliberate choices are
never reverted.
Phase 1 — Paper ingest, content plan, claim audit
- Read the paper source (
.texideal; PDF otherwise). Extract: title/authors/affils, the 3–5 headline numbers, core method (equations verbatim), main results (tables/figures and what they show), takeaways. Buildposter_html/POSTER_CONTENT_PLAN.md— what goes in which column, word budget per card. Target density (excluding table cells, captions, author line, footer): standard poster 550–850 words; dense theory+empirical poster 750–1050 words, allowed only when ≥2 compact components are used (eqn-anatomy,flow-strip,derived-col,claim-pills,keybox--4). Warn yourself below 500 words on a 4-column landscape (it will read as sparse next to professionally dense posters) unless the template is hero/visual-first; warn above 1100 unless the user asked for dense mode. Bullets ≤ 8 words when possible — density comes from structure, not long prose. Prefer compact structure over prose: if the paper contains an explicit objective, algorithm, theorem mechanism, or baseline comparison, extract at least two of: (1) empirical objective / loss stack; (2) term-by-term equation anatomy; (3) a method-flow strip grounded in paper variables; (4) a derived-Δ column for method-vs-baseline rows; (5) a 4-up implementation/theory keybox; (6) a claim/evidence pill table for numeric-heavy posters. Do not invent an algorithm. If the paper has only an objective, label the component "objective flow" or "loss anatomy", never "algorithm". - Cross-model content audit (fresh codex thread,
xhigh): give it the content plan path + paper source path(s) — paths only, no summaries — and ask for a claim→evidence table:| claim on poster | paper file:line | paper says (verbatim) | match? |with match ∈ {OK, NUMERIC-MISMATCH, OVERCLAIM, MISSING-PRECONDITION, NOT-IN-PAPER, SCOPE-NARROWED}. Save toposter_html/CLAIM_EVIDENCE.md. - Fix every non-OK row or record it as a user-acknowledged tradeoff.
🚦 Checkpoint: content plan + audit summary. Wait.
Phase 2 — Real paper figures (provenance-gated)
Source preference chain:
- Paper source
figures/(vector SVG/PDF → convert to SVG viainkscape/pdf2svgif available, else rasterize ≥ 2× rendered px). - PDF-only:
extract_pdf_figures.py contact-sheet+autoto list candidate regions → pick crops (🚦 human confirms crop choices) →cropat 300–450 DPI. - Last resort: user supplies explicit
page,x0,y0,x1,y1bboxes.
Then preprocess_figures.py --autocrop every asset. Every paper-derived image gets a
FIGURE_MANIFEST.json entry (source hash, page, bbox, dpi, sha256, natural_px) and is
embedded as <img data-source="paper" data-asset-id="...">.
Hard rule: ≥ 2 paper-derived visuals or the asset gate fails. Theory-only papers
may waive the total-area rule (--waive-total-area) at a human checkpoint — never
silently. Never draw bespoke decorative SVG "figures" as substitutes.
Figure-area bands (asset gate, fractions of body): total target 14–22 % (warn < 12 % / > 24 %, hard < 10 % / > 28 %); per ordinary figure target 4–8 % (warn
10 %, hard > 13 %);
figure--duocombined 8–12 %. Hero templates pass--hero(centerpiece may take 30–40 %). The failure mode is symmetric: too small reads as decoration, too big crowds out content. Sibling figures that share axes or tell a before→after story belong in onefigure--duocard, not two cards.
Phase 3 — Scaffold + tokens
cp templates/<chosen>.html poster_html/poster.html; retarget @page + .poster
dims to the venue canvas (two edits, same values); apply the chosen token pack onto the
:root DESIGN TOKENS block; fill content per the plan; embed manifest figures.
Run preflight + style_check — both must PASS before any layout iteration. (A fresh
scaffold is expected to fail measure — that gate judges a filled poster.)
Phase 4 — Layout hard loop
After every layout change:
python3 "$SKILL_SCRIPTS/run_gates.py" poster_html/poster.html \
--tokens <pack.json> --manifest poster_html/FIGURE_MANIFEST.json \
--report poster_html/GATE_REPORT.json
Canonical order: preflight → style → asset → measure → polish. Targets: column-bottom
spread < 5 px (aim < 3), footer gap ∈ [30, 50] px, intercard gap ∈ [12, 50] px,
canvas-fill ∈ [95, 101] %, poster bbox aligned to page within ±2 px. Fix guidance for
each failure mode lives in the gate output and templates/COMPONENTS.md. Do not
proceed while any hard gate fails. Do not let a reviewer see an unmeasured poster.
Balance under-filled columns with content from the paper (Gate C), never with
whitespace, space-between, or stretched cards.
Phase 5 — Claude visual review (gated aesthetics)
Render and read the result yourself:
python3 "$SKILL_SCRIPTS/render_preview.py" poster_html/poster.html
pdftoppm -r 100 poster_html/poster_preview.pdf poster_html/review_full -png -f 1 -l 1
# plus 2-4 region crops at higher res (header / one column / equations) via PIL
Calibrate first (../shared-references/taste-calibration.md): if
human-curated references/good/ + references/bad/ exist under this skill
dir (or the project supplies its own pair), score those 3+3 reference posters
on the axes below BEFORE the target, anchoring the scale. Never select, search
for, or generate anchors yourself; if no reference sets exist, proceed
uncalibrated and mark CALIBRATION: none — never fabricate anchor scores.
Axes (weights sum 1.0): Design 0.35 · Craft 0.30 · Functionality 0.20 ·
Originality 0.15. Mapping: SCORE = min(round(1 + 9 × COMPOSITE), lowest triggered cap) — caps apply AFTER the mapping, and the loop's Score ≥ 9
threshold below always reads this final capped SCORE, never the raw
composite.
Score strictly 1–10. Critical caps (hard floors — a calibrated composite never overrides them): < 2 real paper figures → ≤ 3; broken canvas / clipped content / unreadable math → ≤ 4; ≥ 4 visible hue families or gradient-heavy header → ≤ 4; large blank cards or columns → ≤ 5; fabricated visual claim → ≤ 3. Checks: posterly-showcase gestalt (would this hang next to a professionally designed poster without looking like a patched dashboard?), single-accent discipline, real figures readable and central, print hierarchy (title → headline stats → figures → detail), column fill, equation prominence (no tiny math in oversized boxes), serif-body/sans-display pairing, no gradient kitsch, component consistency, 60-second narrative. Output format:
SCORE: N/10 (= min(round(1 + 9 × COMPOSITE), lowest cap); drives the loop)
COMPOSITE: 0.xx (weighted; list the four per-axis scores)
CALIBRATION: anchored | none
GAP: <which reference poster the target falls short of / exceeds, on which axis, and why — one paragraph; omit only when CALIBRATION: none>
CAPS_TRIGGERED: ...
TOP_ISSUES: (max 3)
ALLOWED_FIX_TYPE per issue: token | component | rebalance | asset | template/canvas
PATCH_LOOP_RISK: low | medium | high
Loop: fix (fix vocabulary below) → re-run Phase 4 gates → re-score. ≤ 3 issues per round, ≤ 3 rounds. Score ≥ 9 → Phase 6. Still < 9 after 3 rounds → STOP patching; escalate to template / canvas / content re-choice (back to Phase 3) or a human decision. Never enter round 4 of cosmetic patching.
Fix vocabulary (closed set — the anti-patch-loop core)
Allowed: (a) edit a :root token value; (b) swap/remove/add a whole component
instance from templates/COMPONENTS.md; (c) content rebalance (move a card across
columns, trim/grow text from the paper, resize a figure within its AR band);
(d) template/canvas re-choice; (e) global edits to an existing component's CSS
that reference only tokens; (f) switching predefined variants (.eqn--large,
.card--compact, .figure--wide, .nowrap, …); (g) asset fixes (re-crop, swap
for a clearer figure from the same paper, re-preprocess).
Forbidden: new inline styles, new hex values anywhere, bespoke decorative SVG,
per-element font-size overrides. A new component may not be born inside the visual
loop — stop, get a human checkpoint, add it to COMPONENTS.md, re-run from Phase 3.
Phase 6 — Codex final review (fresh thread, cross-model)
All hard gates PASS + polish warnings zero-or-waived + visual ≥ 9 first. Then a fresh
codex thread (xhigh) reviews the final artifacts (not the content plan):
poster.html, the rendered PDF/PNG, the paper source, GATE_REPORT.json,
CLAIM_EVIDENCE.md — paths only, no executor framing. It checks: (1) fidelity &
overclaims re-checked on final text (polish introduces new claims), (2) residue
(\ref{, TODO, raw < in math, missing images, remote URLs), (3) visual rhetoric
(headline numbers prominent, banner readable from 2 m), (4) gate-log coherence. The
reviewer recommends; it does not edit. Any fix → back through Phase 4/5 gates — never
straight to re-review.
Phase 7 — Final verification + report
python3 "$SKILL_SCRIPTS/poster_check.py" verify-final poster_html/poster_preview.pdf \
--from-html poster_html/poster.html --max-size-mb 20
Page count 1, dimensions match @page, size ≤ 20 MB, no TODO/residue, no remote
assets. Report: PDF path, final spread px, footer-gap range, gate summary table,
unresolved waivers, codex verdict. Update POSTER_STATE.json → done.
State persistence
poster_html/POSTER_STATE.json: {phase, venue, canvas{w,h,orientation,source_url, retrieved}, template, token_pack, design_decisions{...}, figures_selected[], visual_rounds, codex_threads{audit, final}, status, timestamp} — written after every
phase; enables compact-recovery resume.
Key rules
- Measure, don't eyeball. No layout claim without
run_gates.pyoutput. - Gates before aesthetics. Claude/codex review only ever sees a poster whose hard gates PASS. This ordering is what kills the patch-loop death spiral.
- Never invent paper numbers or figures. Numbers come from the paper source; visuals carry manifest provenance. Fabrication = critical cap ≤ 3.
- Two hues, one system. Accent + gold + neutrals. The style gate enforces it; don't negotiate with the gate.
- Real figures are the poster. A poster without the paper's own figures is a dashboard, not a poster.
- Fix vocabulary is closed. If a fix isn't expressible as token / component / rebalance / asset / canvas, it's the wrong fix.
- Cross-model verdicts. Claude drives the loop and scores visuals; acceptance of content fidelity comes from the fresh codex thread (a loop can drive, never acquit).
- Preserve user decisions. Re-read
design_decisionsbefore "improving" anything. - Vendor boundary.
poster_check.py,render_preview.py,_posterly/are vendored from posterly — keep diffs minimal; ARIS-side logic goes in the new scripts, not in vendored files.
Review tracing
Save every codex reviewer call's trace per shared-references/review-tracing.md to
.aris/traces/paper-poster-html/<date>_run<NN>/ (audit + final threads, raw responses).
Output contract
poster_html/
├── poster.html # single-file source of truth
├── poster_preview.pdf # print-emulated, verify-final-checked
├── poster_preview.png # thumbnail
├── POSTER_STATE.json # resume state
├── GATE_REPORT.json # canonical gate ledger (schema v1)
├── POSTER_CONTENT_PLAN.md # what-goes-where + word budgets
├── CLAIM_EVIDENCE.md # codex claim→evidence audit
├── FIGURE_MANIFEST.json # figure provenance (sha256, page, bbox, dpi)
└── assets/{paper_figures,logos,qr,mathjax}/
When NOT to use
- Slides, not a poster →
/paper-talk//slides-polish. - The paper's headline isn't stable yet — fix the paper first; a poster amplifies whatever story it's given.
| 1 | |
| 2 | name paper-poster-html |
| 3 | description "DEFAULT poster pipeline — build an academic conference poster (ICML/NeurIPS/ICLR/CVPR/...) as a single HTML/CSS file with measurement-driven hard gates, real paper figures, a two-hue design-token system, and print-ready PDF via headless Chromium. Use when the user says \"做海报\", \"poster\", \"conference poster\", \"paper poster\", or asks to design/redo a research poster. Supersedes the retired LaTeX /paper-poster." |
| 4 | argument-hint "[paper-dir-or-pdf] [— venue: ICLR, canvas: 185x90cm landscape, venue-colors: true]" |
| 5 | allowed-tools Bash(*), Read, Write, Edit, Grep, Glob, WebFetch, WebSearch, AskUserQuestion, mcp__codex__codex |
| 6 | |
| 7 | |
| 8 | # Paper Poster (HTML): measurement-gated poster generation |
| 9 | |
| 10 | One HTML file styled for an exact print canvas (`@page { size: W H }`), rendered to PDF |
| 11 | via Playwright print emulation. **Iterate by measuring, not eyeballing** — the screen |
| 12 | preview lies; only print emulation at the correct viewport tells the truth. Core gate |
| 13 | machinery is adapted from [posterly] (MIT, © |
| 14 | 2026 Ruishuo Chen — see `NOTICE.md` and `LICENSES/posterly-MIT.txt`); ARIS adds style |
| 15 | discipline gates, figure-provenance gates, the cross-model review loop, and the |
| 16 | anti-patch-loop fix vocabulary. |
| 17 | |
| 18 | ## Why this skill exists (the failure it prevents) |
| 19 | |
| 20 | A predecessor pipeline produced a poster with **30+ colors, zero real paper figures, a |
| 21 | screen-pixel canvas, and tiny formulas floating in oversized boxes**, then spent 12+ |
| 22 | review rounds making it *worse* — each round added a new badge color or bespoke SVG |
| 23 | patch. The cure is structural, not exhortative: |
| 24 | |
| 25 | **Hard gates run before any aesthetic opinion** (alignment, style, assets must PASS |
| 26 | first — a reviewer never sees an unmeasured poster). |
| 27 | **A closed fix vocabulary** — visual-review fixes can only touch design tokens, |
| 28 | whole catalogued components, content rebalance, assets, or canvas choice. New inline |
| 29 | styles / new hex values / bespoke decorations are structurally forbidden. |
| 30 | **Two-hue discipline as a machine check**, not a style suggestion. |
| 31 | **Real paper figures with provenance manifest**, or the gate fails. |
| 32 | |
| 33 | ## Mental model |
| 34 | |
| 35 | |
| 36 | paper (.tex / PDF) ──► content plan + claim→evidence audit (codex, fresh) |
| 37 | │ |
| 38 | figures extracted ─────────┤ FIGURE_MANIFEST.json (provenance, sha256) |
| 39 | (real paper figures ONLY) ▼ |
| 40 | template scaffold ──► fill ──► run_gates.py ◄─── HARD, loop here |
| 41 | preflight → style → asset → measure → polish |
| 42 | │ all hard gates PASS |
| 43 | ▼ |
| 44 | Claude visual review (≤3 issues × ≤3 rounds, fix-vocabulary only) |
| 45 | │ score ≥ 9 |
| 46 | ▼ |
| 47 | codex final cross-model review (fresh thread, full HTML+PDF) |
| 48 | │ pass |
| 49 | ▼ |
| 50 | verify-final → poster.pdf + GATE_REPORT.json |
| 51 | |
| 52 | |
| 53 | ## Constants |
| 54 | |
| 55 | **SKILL_SCRIPTS** = `${CLAUDE_SKILL_DIR}/scripts` — all helpers are single-owner and |
| 56 | ship inside this skill (Arch C). If the directory is missing the install is broken: |
| 57 | abort and tell the user to re-install the skill (Policy A — the gates ARE the skill; |
| 58 | never improvise replacements). |
| 59 | **REVIEWER_MODEL** = `gpt-6-astra`, reasoning `xhigh`, **fresh thread per review call** |
| 60 | (`mcp__codex__codex`, never `codex-reply` across review boundaries). |
| 61 | **CANVAS** — from the venue's official spec, looked up live in Phase 0. Never assume. |
| 62 | (Known anchor: ICLR 2026 main = 185×90 cm landscape per its official printing |
| 63 | service; ICML/NeurIPS commonly 60×36 in landscape; workshop posters often 61×91 cm |
| 64 | portrait. Specs change yearly — verify.) |
| 65 | **PALETTE** — default = `templates/tokens/generic.json` (slate-blue `#2D5F8B` accent |
| 66 | gold `#C9A24A` highlight + neutrals) for **all** venues. Venue packs are opt-in via |
| 67 | `— venue-colors: true`. Purple-dominant accents (hue 250–285) are banned unless the |
| 68 | user passes `— allow-purple: true`. |
| 69 | **AUTO_PROCEED = false** — wait for explicit confirmation at every 🚦 checkpoint. |
| 70 | **OUTPUT_DIR** = `poster_html/` in the working directory. |
| 71 | |
| 72 | ## Workflow |
| 73 | |
| 74 | ### Phase 0 — Resume, dependencies, venue spec |
| 75 | |
| 76 | **Resume**: if `poster_html/POSTER_STATE.json` exists with `status: in_progress` |
| 77 | (< 24 h), resume from the saved phase. |
| 78 | **Dependencies** (degradation chain, in order): |
| 79 | Playwright + bundled Chromium → if missing, `python3 -m playwright install |
| 80 | chromium` → if install fails but system Chrome exists, scripts fall back to |
| 81 | `channel="chrome"` → if all fail: you may produce the content plan and scaffold |
| 82 | only, label everything **"not print verified"**, and must NOT emit a final PDF. |
| 83 | `pdfinfo` missing → PyMuPDF reads PDF dimensions. At least one of |
| 84 | pdftoppm / PyMuPDF must exist for PNG review renders. |
| 85 | MathJax: download `tex-svg.js` once into `poster_html/assets/mathjax/` and |
| 86 | reference it locally in the HTML. CDN is acceptable only for drafts; the measure |
| 87 | gate hard-fails on unrendered MathJax either way. |
| 88 | **Venue spec lookup (live)**: consult the venue's official poster-instructions page |
| 89 | (search + fetch). Extract dimensions, orientation, font floor, logo policy, |
| 90 | anonymity rules, file format. Record `{spec, source_url, retrieved}` into |
| 91 | `POSTER_STATE.json` — specs change yearly; never reuse a cached spec silently. |
| 92 | |
| 93 | **🚦 Checkpoint**: echo the venue spec table (canvas, orientation, source URL) and the |
| 94 | chosen template. Wait. |
| 95 | |
| 96 | ### Phase 0.5 — Design discovery (one AskUserQuestion batch) |
| 97 | |
| 98 | Ask once, ≤4 questions: layout template (from `templates/README.md`), palette |
| 99 | (default generic pack / venue pack / custom within constraints), logos + venue mark |
| 100 | (paths or "none" — never fabricate; check the venue's logo policy), QR target (paper / |
| 101 | code / project page / none — generate **offline** with `qrencode` or python-`qrcode`; |
| 102 | never a remote QR-service URL). Persist answers in `POSTER_STATE.json` as |
| 103 | `design_decisions` — re-read before any later "improvement" so deliberate choices are |
| 104 | never reverted. |
| 105 | |
| 106 | ### Phase 1 — Paper ingest, content plan, claim audit |
| 107 | |
| 108 | Read the paper source (`.tex` ideal; PDF otherwise). Extract: title/authors/affils, |
| 109 | the 3–5 headline numbers, core method (equations verbatim), main results |
| 110 | (tables/figures and what they show), takeaways. Build |
| 111 | `poster_html/POSTER_CONTENT_PLAN.md` — what goes in which column, word budget per |
| 112 | card. **Target density** (excluding table cells, captions, author line, footer): |
| 113 | standard poster **550–850 words**; dense theory+empirical poster **750–1050 words**, |
| 114 | allowed only when ≥2 compact components are used (`eqn-anatomy`, `flow-strip`, |
| 115 | `derived-col`, `claim-pills`, `keybox--4`). Warn yourself below 500 words on a |
| 116 | 4-column landscape (it will read as sparse next to professionally dense posters) |
| 117 | unless the template is hero/visual-first; warn above 1100 unless the user asked for |
| 118 | dense mode. Bullets ≤ 8 words when possible — density comes from *structure*, not |
| 119 | long prose. **Prefer compact structure over prose**: if the paper contains an |
| 120 | explicit objective, algorithm, theorem mechanism, or baseline comparison, extract at |
| 121 | least two of: (1) empirical objective / loss stack; (2) term-by-term equation |
| 122 | anatomy; (3) a method-flow strip grounded in paper variables; (4) a derived-Δ column |
| 123 | for method-vs-baseline rows; (5) a 4-up implementation/theory keybox; (6) a |
| 124 | claim/evidence pill table for numeric-heavy posters. **Do not invent an algorithm.** |
| 125 | If the paper has only an objective, label the component "objective flow" or "loss |
| 126 | anatomy", never "algorithm". |
| 127 | **Cross-model content audit** (fresh codex thread, `xhigh`): give it the content |
| 128 | plan path + paper source path(s) — paths only, no summaries — and ask for a |
| 129 | claim→evidence table: `| claim on poster | paper file:line | paper says (verbatim) | |
| 130 | match? |` with match ∈ {OK, NUMERIC-MISMATCH, OVERCLAIM, MISSING-PRECONDITION, |
| 131 | NOT-IN-PAPER, SCOPE-NARROWED}. Save to `poster_html/CLAIM_EVIDENCE.md`. |
| 132 | Fix every non-OK row or record it as a user-acknowledged tradeoff. |
| 133 | |
| 134 | **🚦 Checkpoint**: content plan + audit summary. Wait. |
| 135 | |
| 136 | ### Phase 2 — Real paper figures (provenance-gated) |
| 137 | |
| 138 | Source preference chain: |
| 139 | Paper source `figures/` (vector SVG/PDF → convert to SVG via |
| 140 | `inkscape`/`pdf2svg` if available, else rasterize ≥ 2× rendered px). |
| 141 | PDF-only: `extract_pdf_figures.py contact-sheet` + `auto` to list candidate |
| 142 | regions → pick crops (**🚦 human confirms crop choices**) → `crop` at 300–450 DPI. |
| 143 | Last resort: user supplies explicit `page,x0,y0,x1,y1` bboxes. |
| 144 | |
| 145 | Then `preprocess_figures.py --autocrop` every asset. Every paper-derived image gets a |
| 146 | `FIGURE_MANIFEST.json` entry (source hash, page, bbox, dpi, sha256, natural_px) and is |
| 147 | embedded as `<img data-source="paper" data-asset-id="...">`. |
| 148 | |
| 149 | **Hard rule**: ≥ 2 paper-derived visuals or the asset gate fails. Theory-only papers |
| 150 | may waive the *total-area* rule (`--waive-total-area`) at a human checkpoint — never |
| 151 | silently. Never draw bespoke decorative SVG "figures" as substitutes. |
| 152 | |
| 153 | **Figure-area bands** (asset gate, fractions of *body*): total target **14–22 %** |
| 154 | (warn < 12 % / > 24 %, hard < 10 % / > 28 %); per ordinary figure target 4–8 % (warn |
| 155 | > 10 %, hard > 13 %); `figure--duo` combined 8–12 %. Hero templates pass `--hero` |
| 156 | (centerpiece may take 30–40 %). The failure mode is symmetric: too small reads as |
| 157 | decoration, too big crowds out content. Sibling figures that share axes or tell a |
| 158 | before→after story belong in one `figure--duo` card, not two cards. |
| 159 | |
| 160 | ### Phase 3 — Scaffold + tokens |
| 161 | |
| 162 | `cp templates/<chosen>.html poster_html/poster.html`; retarget `@page` + `.poster` |
| 163 | dims to the venue canvas (two edits, same values); apply the chosen token pack onto the |
| 164 | `:root` DESIGN TOKENS block; fill content per the plan; embed manifest figures. |
| 165 | Run `preflight` + `style_check` — both must PASS before any layout iteration. (A fresh |
| 166 | scaffold is *expected* to fail `measure` — that gate judges a filled poster.) |
| 167 | |
| 168 | ### Phase 4 — Layout hard loop |
| 169 | |
| 170 | After every layout change: |
| 171 | |
| 172 | |
| 173 | python3 "$SKILL_SCRIPTS/run_gates.py" poster_html/poster.html \ |
| 174 | --tokens <pack.json> --manifest poster_html/FIGURE_MANIFEST.json \ |
| 175 | --report poster_html/GATE_REPORT.json |
| 176 | |
| 177 | |
| 178 | Canonical order: preflight → style → asset → measure → polish. Targets: column-bottom |
| 179 | **spread < 5 px** (aim < 3), footer gap ∈ [30, 50] px, intercard gap ∈ [12, 50] px, |
| 180 | canvas-fill ∈ [95, 101] %, poster bbox aligned to page within ±2 px. Fix guidance for |
| 181 | each failure mode lives in the gate output and `templates/COMPONENTS.md`. **Do not |
| 182 | proceed while any hard gate fails. Do not let a reviewer see an unmeasured poster.** |
| 183 | Balance under-filled columns with *content from the paper* (Gate C), never with |
| 184 | whitespace, `space-between`, or stretched cards. |
| 185 | |
| 186 | ### Phase 5 — Claude visual review (gated aesthetics) |
| 187 | |
| 188 | Render and read the result yourself: |
| 189 | |
| 190 | |
| 191 | python3 "$SKILL_SCRIPTS/render_preview.py" poster_html/poster.html |
| 192 | pdftoppm -r 100 poster_html/poster_preview.pdf poster_html/review_full -png -f 1 -l 1 |
| 193 | # plus 2-4 region crops at higher res (header / one column / equations) via PIL |
| 194 | |
| 195 | |
| 196 | **Calibrate first** (`../shared-references/taste-calibration.md`): if |
| 197 | **human-curated** `references/good/` + `references/bad/` exist under this skill |
| 198 | dir (or the project supplies its own pair), score those 3+3 reference posters |
| 199 | on the axes below BEFORE the target, anchoring the scale. Never select, search |
| 200 | for, or generate anchors yourself; if no reference sets exist, proceed |
| 201 | uncalibrated and mark `CALIBRATION: none` — never fabricate anchor scores. |
| 202 | Axes (weights sum 1.0): Design 0.35 · Craft 0.30 · Functionality 0.20 · |
| 203 | Originality 0.15. Mapping: `SCORE = min(round(1 + 9 × COMPOSITE), lowest |
| 204 | triggered cap)` — caps apply AFTER the mapping, and the loop's `Score ≥ 9` |
| 205 | threshold below always reads this final capped `SCORE`, never the raw |
| 206 | composite. |
| 207 | |
| 208 | Score strictly 1–10. **Critical caps** (hard floors — a calibrated composite |
| 209 | never overrides them): < 2 real paper figures → ≤ 3; broken canvas / |
| 210 | clipped content / unreadable math → ≤ 4; ≥ 4 visible hue families or gradient-heavy |
| 211 | header → ≤ 4; large blank cards or columns → ≤ 5; fabricated visual claim → ≤ 3. |
| 212 | Checks: posterly-showcase gestalt (would this hang next to a professionally designed |
| 213 | poster without looking like a patched dashboard?), single-accent discipline, real |
| 214 | figures readable and central, print hierarchy (title → headline stats → figures → |
| 215 | detail), column fill, **equation prominence** (no tiny math in oversized boxes), |
| 216 | serif-body/sans-display pairing, no gradient kitsch, component consistency, 60-second |
| 217 | narrative. Output format: |
| 218 | |
| 219 | |
| 220 | SCORE: N/10 (= min(round(1 + 9 × COMPOSITE), lowest cap); drives the loop) |
| 221 | COMPOSITE: 0.xx (weighted; list the four per-axis scores) |
| 222 | CALIBRATION: anchored | none |
| 223 | GAP: <which reference poster the target falls short of / exceeds, on which axis, and why — one paragraph; omit only when CALIBRATION: none> |
| 224 | CAPS_TRIGGERED: ... |
| 225 | TOP_ISSUES: (max 3) |
| 226 | ALLOWED_FIX_TYPE per issue: token | component | rebalance | asset | template/canvas |
| 227 | PATCH_LOOP_RISK: low | medium | high |
| 228 | |
| 229 | |
| 230 | Loop: fix (fix vocabulary below) → re-run Phase 4 gates → re-score. **≤ 3 issues per |
| 231 | round, ≤ 3 rounds.** Score ≥ 9 → Phase 6. Still < 9 after 3 rounds → STOP patching; |
| 232 | escalate to template / canvas / content re-choice (back to Phase 3) or a human |
| 233 | decision. Never enter round 4 of cosmetic patching. |
| 234 | |
| 235 | #### Fix vocabulary (closed set — the anti-patch-loop core) |
| 236 | |
| 237 | Allowed: **(a)** edit a `:root` token value; **(b)** swap/remove/add a whole component |
| 238 | instance from `templates/COMPONENTS.md`; **(c)** content rebalance (move a card across |
| 239 | columns, trim/grow text *from the paper*, resize a figure within its AR band); |
| 240 | **(d)** template/canvas re-choice; **(e)** global edits to an existing component's CSS |
| 241 | that reference only tokens; **(f)** switching predefined variants (`.eqn--large`, |
| 242 | `.card--compact`, `.figure--wide`, `.nowrap`, …); **(g)** asset fixes (re-crop, swap |
| 243 | for a clearer figure from the same paper, re-preprocess). |
| 244 | |
| 245 | Forbidden: new inline styles, new hex values anywhere, bespoke decorative SVG, |
| 246 | per-element font-size overrides. **A new component may not be born inside the visual |
| 247 | loop** — stop, get a human checkpoint, add it to `COMPONENTS.md`, re-run from Phase 3. |
| 248 | |
| 249 | ### Phase 6 — Codex final review (fresh thread, cross-model) |
| 250 | |
| 251 | All hard gates PASS + polish warnings zero-or-waived + visual ≥ 9 first. Then a fresh |
| 252 | codex thread (`xhigh`) reviews the **final artifacts** (not the content plan): |
| 253 | `poster.html`, the rendered PDF/PNG, the paper source, `GATE_REPORT.json`, |
| 254 | `CLAIM_EVIDENCE.md` — paths only, no executor framing. It checks: (1) fidelity & |
| 255 | overclaims **re-checked on final text** (polish introduces new claims), (2) residue |
| 256 | (`\ref{`, `TODO`, raw `<` in math, missing images, remote URLs), (3) visual rhetoric |
| 257 | (headline numbers prominent, banner readable from 2 m), (4) gate-log coherence. The |
| 258 | reviewer recommends; it does not edit. Any fix → back through Phase 4/5 gates — never |
| 259 | straight to re-review. |
| 260 | |
| 261 | ### Phase 7 — Final verification + report |
| 262 | |
| 263 | |
| 264 | python3 "$SKILL_SCRIPTS/poster_check.py" verify-final poster_html/poster_preview.pdf \ |
| 265 | --from-html poster_html/poster.html --max-size-mb 20 |
| 266 | |
| 267 | |
| 268 | Page count 1, dimensions match `@page`, size ≤ 20 MB, no TODO/residue, no remote |
| 269 | assets. Report: PDF path, final spread px, footer-gap range, gate summary table, |
| 270 | unresolved waivers, codex verdict. Update `POSTER_STATE.json` → `done`. |
| 271 | |
| 272 | ## State persistence |
| 273 | |
| 274 | `poster_html/POSTER_STATE.json`: `{phase, venue, canvas{w,h,orientation,source_url, |
| 275 | retrieved}, template, token_pack, design_decisions{...}, figures_selected[], |
| 276 | visual_rounds, codex_threads{audit, final}, status, timestamp}` — written after every |
| 277 | phase; enables compact-recovery resume. |
| 278 | |
| 279 | ## Key rules |
| 280 | |
| 281 | **Measure, don't eyeball.** No layout claim without `run_gates.py` output. |
| 282 | **Gates before aesthetics.** Claude/codex review only ever sees a poster whose hard |
| 283 | gates PASS. This ordering is what kills the patch-loop death spiral. |
| 284 | **Never invent paper numbers or figures.** Numbers come from the paper source; |
| 285 | visuals carry manifest provenance. Fabrication = critical cap ≤ 3. |
| 286 | **Two hues, one system.** Accent + gold + neutrals. The style gate enforces it; |
| 287 | don't negotiate with the gate. |
| 288 | **Real figures are the poster.** A poster without the paper's own figures is a |
| 289 | dashboard, not a poster. |
| 290 | **Fix vocabulary is closed.** If a fix isn't expressible as token / component / |
| 291 | rebalance / asset / canvas, it's the wrong fix. |
| 292 | **Cross-model verdicts.** Claude drives the loop and scores visuals; acceptance of |
| 293 | content fidelity comes from the fresh codex thread (a loop can drive, never acquit). |
| 294 | **Preserve user decisions.** Re-read `design_decisions` before "improving" anything. |
| 295 | **Vendor boundary.** `poster_check.py`, `render_preview.py`, `_posterly/` are |
| 296 | vendored from posterly — keep diffs minimal; ARIS-side logic goes in the new |
| 297 | scripts, not in vendored files. |
| 298 | |
| 299 | ## Review tracing |
| 300 | |
| 301 | Save every codex reviewer call's trace per `shared-references/review-tracing.md` to |
| 302 | `.aris/traces/paper-poster-html/<date>_run<NN>/` (audit + final threads, raw responses). |
| 303 | |
| 304 | ## Output contract |
| 305 | |
| 306 | |
| 307 | poster_html/ |
| 308 | ├── poster.html # single-file source of truth |
| 309 | ├── poster_preview.pdf # print-emulated, verify-final-checked |
| 310 | ├── poster_preview.png # thumbnail |
| 311 | ├── POSTER_STATE.json # resume state |
| 312 | ├── GATE_REPORT.json # canonical gate ledger (schema v1) |
| 313 | ├── POSTER_CONTENT_PLAN.md # what-goes-where + word budgets |
| 314 | ├── CLAIM_EVIDENCE.md # codex claim→evidence audit |
| 315 | ├── FIGURE_MANIFEST.json # figure provenance (sha256, page, bbox, dpi) |
| 316 | └── assets/{paper_figures,logos,qr,mathjax}/ |
| 317 | |
| 318 | |
| 319 | ## When NOT to use |
| 320 | |
| 321 | Slides, not a poster → `/paper-talk` / `/slides-polish`. |
| 322 | The paper's headline isn't stable yet — fix the paper first; a poster amplifies |
| 323 | whatever story it's given. |
| 324 |
Details
- Updated
- Sep 18, 2026
- License
- MIT
- Stars on the repo
- ★ 16,473
- Checked
- Source
- wanshuiyin/Auto-claude-code-research-in-sleep ↗
- Creator
- wanshuiyin · 7 listings
Made with paper-poster-html



Similar skills
See all →
SkillTell us what your banner is for and what it should sayBanner Design - Multi-Format Creative Banner System
SkillGenerate or edit images with Codex's built-in imageQiaomu codex imagegen
SkillPromptfilm — turns one sentence into a researched 3D motion
SkillMake real, accurate maps as one self-contained HTMLMap design
Prompt${primarytext:Megane}{ category: STUDIORACECARSIDEPROFILECar poster
PromptDesigns an ultra-realistic cinematic movie poster featuringCreate a cultural superhero movie posterMore from wanshuiyin
SkillDescribe your invention in plain words and get backClaims Drafting: The Core Patent Skill
SkillDescribe your invention in everyday words and get backPatent Novelty and Non-Obviousness Check
SkillDescribe your invention in plain words and get backPatent Pipeline: From Invention to Filing
SkillGet a deep critical review of researchResearch Review via External Reviewer Backend (ultra reasoning)
SkillDescribe your invention in plain words and get back a formalStructure Your Invention For A Patent Filing
SkillPeriodically check WandB metrics during training to catchTraining check