skills/skills-codex/paper-poster-html/SKILL.md
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.
npx skillsauth add wanshuiyin/Auto-claude-code-research-in-sleep paper-poster-htmlInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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 in the mainline
skill directory); ARIS adds style discipline gates, figure-provenance gates, the
fresh-agent review loop (same-family provisional in the base mirror), and the anti-patch-loop fix vocabulary.
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:
paper (.tex / PDF) ──► content plan + claim→evidence audit (fresh reviewer agent)
│
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
▼
executor visual review (≤3 issues × ≤3 rounds, fix-vocabulary only)
│ score ≥ 9
▼
final fresh-agent review (same-family provisional, full HTML+PDF)
│ pass
▼
verify-final → poster.pdf + GATE_REPORT.json
SKILL_SCRIPTS — helpers and templates are single-owner and ship inside the
mainline skill (Arch C) at skills/paper-poster-html/scripts/ and
skills/paper-poster-html/templates/. Resolve them in this order:
SKILL_HOME=""
[ -d ".agents/skills/paper-poster-html/scripts" ] && SKILL_HOME=".agents/skills/paper-poster-html"
if [ -z "$SKILL_HOME" ] && [ -z "${ARIS_REPO:-}" ] && [ -f .aris/installed-skills-codex.txt ]; then
ARIS_REPO=$(awk -F'\t' '$1=="repo_root"{print $2; exit}' .aris/installed-skills-codex.txt 2>/dev/null) || true
fi
[ -z "$SKILL_HOME" ] && [ -d "skills/paper-poster-html/scripts" ] && SKILL_HOME="skills/paper-poster-html"
[ -z "$SKILL_HOME" ] && [ -n "${ARIS_REPO:-}" ] && [ -d "$ARIS_REPO/skills/paper-poster-html/scripts" ] && SKILL_HOME="$ARIS_REPO/skills/paper-poster-html"
[ -z "$SKILL_HOME" ] && [ -d "$HOME/.codex/skills/paper-poster-html/scripts" ] && SKILL_HOME="$HOME/.codex/skills/paper-poster-html"
if [ -z "$SKILL_HOME" ]; then
echo "ERROR: paper-poster-html scripts not resolved. Re-run the ARIS Codex install." >&2
fi
SKILL_SCRIPTS="$SKILL_HOME/scripts"
If unresolved, the install is broken: abort and tell the user to re-install (Policy A — the gates ARE the skill; never improvise replacements).
REVIEWER_MODEL = gpt-5.6-sol, reasoning effort xhigh, fresh reviewer agent per
review call (a new spawn_agent: every time; never reuse a reviewer agent across
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 #2D5F8B accent
#C9A24A highlight + 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.AUTO_PROCEED = false — wait for explicit confirmation at every 🚦 checkpoint.
OUTPUT_DIR = poster_html/ in the working directory.
poster_html/POSTER_STATE.json exists with status: in_progress
(< 24 h), resume from the saved phase.python3 -m playwright install chromium → if install fails but system Chrome exists, scripts fall back to
channel="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.
If print rendering, PNG review, or PDF verification is impossible in the current
environment, stop and tell the user what to configure. Do not silently degrade
this skill into an unmeasured text-only poster draft.pdfinfo missing → PyMuPDF reads PDF dimensions. At least one of
pdftoppm / PyMuPDF must exist for PNG review renders.tex-svg.js once into poster_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.{spec, source_url, retrieved} into
POSTER_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.
Ask the user 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.
Read the paper source (.tex ideal; PDF otherwise). Extract: title/authors/affils,
the 3–5 headline numbers, core method (equations verbatim), main results
(tables/figures and what they show), takeaways. Build
poster_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".
Fresh-agent content audit (same-family provisional): give it the content plan path
poster_html/CLAIM_EVIDENCE.md.spawn_agent:
model: gpt-5.6-sol
reasoning_effort: xhigh
message: |
Audit a conference-poster content plan against its source paper.
Read these files yourself (no other context is provided):
- poster_html/POSTER_CONTENT_PLAN.md
- [paper source path(s)]
For EVERY claim, number, equation, and attribution in the plan, output one row:
| claim on poster | paper file:line | paper says (verbatim) | match? |
with match ∈ {OK, NUMERIC-MISMATCH, OVERCLAIM, MISSING-PRECONDITION,
NOT-IN-PAPER, SCOPE-NARROWED}. End with a count per category.
Fix every non-OK row or record it as a user-acknowledged tradeoff.
🚦 Checkpoint: content plan + audit summary. Wait.
Source preference chain:
figures/ (vector SVG/PDF → convert to SVG via
inkscape/pdf2svg if available, else rasterize ≥ 2× rendered px).extract_pdf_figures.py contact-sheet + auto to list candidate
regions → pick crops (🚦 human confirms crop choices) → crop at 300–450 DPI.page,x0,y0,x1,y1 bboxes.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.
cp "$SKILL_HOME/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.)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.
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 (per
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 always reads this
final capped SCORE, never the raw composite.
The visual review writes CALIBRATION: anchored|none, per-axis scores, and the
mandatory GAP paragraph. A fresh Codex review may drive another layout round but
its positive result is acceptance_status: provisional.
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.
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.
All hard gates PASS + polish warnings zero-or-waived + visual ≥ 9 first. Then a fresh reviewer agent reviews the final artifacts (not the content plan) — paths only, no executor framing:
spawn_agent:
model: gpt-5.6-sol
reasoning_effort: xhigh
message: |
Final print-readiness audit of a conference poster. Read these files yourself:
- poster_html/poster.html (final single-file poster)
- poster_html/poster_preview.png (rendered preview — view it)
- [paper source path(s)]
- poster_html/GATE_REPORT.json
- poster_html/CLAIM_EVIDENCE.md
Check: (1) fidelity & overclaims RE-CHECKED on the 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.
Verdict: PRINT-READY or NEEDS-FIX with a numbered, severity-ordered issue list.
The reviewer recommends; it does not edit. Any fix → back through Phase 4/5 gates — never straight to re-review.
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, reviewer verdict. Update POSTER_STATE.json → done.
poster_html/POSTER_STATE.json: {phase, venue, canvas{w,h,orientation,source_url, retrieved}, template, token_pack, design_decisions{...}, figures_selected[], visual_rounds, reviewer_verdicts{audit, final}, status, timestamp} — written after
every phase; enables compact-recovery resume.
run_gates.py output.design_decisions before "improving" anything.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.Save every reviewer call's trace per ../shared-references/review-tracing.md to
.aris/traces/paper-poster-html/<date>_run<NN>/ (audit + final agents, raw responses).
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 # reviewer claim→evidence audit
├── FIGURE_MANIFEST.json # figure provenance (sha256, page, bbox, dpi)
└── assets/{paper_figures,logos,qr,mathjax}/
/paper-talk / /slides-polish.development
Search GitHub Issues and Discussions for software errors, version compatibility problems, and exact error-string matches. Use for debugging and discovery only; results are not paper-citation evidence.
development
Search GitHub Issues and Discussions for software errors, version compatibility problems, and exact error-string matches. Use for debugging and discovery only; results are not paper-citation evidence.
testing
Run the Anti-Autoresearch integrity-forensics sweep (span-anchored evidence ledger → GPT auditors propose findings → deterministic rules-only adjudicator) against a paper via a SHA-pinned thin launcher — then convert the verdict into a typed policy gate (BLOCK/WARN/NO_NEW_BLOCKER) and an append-only obligations ledger. Use when user says "integrity forensics", "forensic audit this paper", "投稿前自查诚信", "审这篇论文的诚信", or says "anti-autoresearch" when the upstream repo's own skills are not installed. Also invoked by /paper-writing (submission self-forensics, default ON), /peer-review (forensic appendix), /resubmit-pipeline.
testing
Privileged applier that LANDS meta-optimize / corpus-audit patches the user approved — the ONLY skill permitted to mutate the skill corpus from a self-modification proposal, with cross-model jury and human approval at landing. Use when the user says "meta apply", "/meta-apply", "land the staged patches", "应用优化", after a /meta-optimize run.