diff --git a/papers/AESTHETIC-EYE.md b/papers/AESTHETIC-EYE.md index 3886ba28e..5a59b0bb9 100644 --- a/papers/AESTHETIC-EYE.md +++ b/papers/AESTHETIC-EYE.md @@ -2,7 +2,7 @@ `aesthetic-eye` is the render-first design gate for papers and their visual evidence. A successful TeX build is not visual approval. The final PDF must -receive a paper-wide brand verdict, and every evidence figure and diagram must +receive a paper-wide brand verdict, and every embedded evidence image and diagram must receive the literal verdict `design: pass` or `design: fail` in an `aesthetic-eye.json` beside the paper. @@ -66,9 +66,9 @@ it records the SHA-256 of the reviewed PDF. ## Evidence-figure checks -Every photographic, screenshot, plotted, or generated figure receives five -checks. The checker inventories figure environments containing -`\includegraphics` in the matching TeX source, so omitting their manifest +Every photographic, screenshot, plotted, or generated image receives five +checks. The checker inventories every `\includegraphics` item inside figure +environments in the matching TeX source, so omitting an image's manifest records is a failure. - `scale` — the evidence is large enough to inspect at normal PDF size; @@ -76,8 +76,10 @@ records is a failure. zooming beyond normal reading size; - `evidenceDominance` — the evidence, not its caption or surrounding prose, owns the figure's visual area; -- `crop` — empty margins and irrelevant interface chrome do not miniaturize the - useful content; +- `crop` — the complete evidentiary content is preserved. Use aspect-fit + letterboxing by default; crop only when the removed area is documented as + non-evidence, and do not let empty margins or irrelevant interface chrome + miniaturize the useful content; - `captionFit` — the caption identifies what is shown and what it proves without visually overpowering it. @@ -141,8 +143,9 @@ Place `aesthetic-eye.json` beside the paper source: ``` `crop` is `[x, y, width, height]` in normalized page coordinates, measured from -the upper-left. `expectedFigures` must match every TeX figure containing -`\includegraphics`; `expectedDiagrams` is the explicit diagram inventory, +the upper-left. `expectedFigures` must match every `\includegraphics` item inside +a TeX figure; multi-panel figures therefore require one verdict per embedded +image. `expectedDiagrams` is the explicit diagram inventory, including title illustrations that explain the system rather than merely decorate it. @@ -156,7 +159,7 @@ node papers/aesthetic-eye.mjs check papers/arxiv-example ``` The check fails when a visible brand name omits its period, the brand review is -absent, the dot-color check fails, a source evidence figure or diagram is +absent, the dot-color check fails, a source evidence image or diagram is missing from the manifest, a verdict is absent or failed, or the PDF changed after review. `.aesthetic-eye/` is disposable rendered evidence; the manifest is the durable review record. diff --git a/papers/FIGURE-TABLE-QA-CHECK.md b/papers/FIGURE-TABLE-QA-CHECK.md index 1dba37e83..65de878b8 100644 --- a/papers/FIGURE-TABLE-QA-CHECK.md +++ b/papers/FIGURE-TABLE-QA-CHECK.md @@ -28,7 +28,7 @@ use a LaTeX `figure` environment. 5. Reject and revise every visual failure. Rebuild and repeat the overview and detail checks until the entire paper passes. 6. Run `paper_aesthetic_eye_prepare`, inspect its all-page contact sheet and - every declared evidence-figure and diagram crop, and record the figure, + every declared evidence-image and diagram crop, and record the image, diagram, and brand verdicts in `aesthetic-eye.json` against the current PDF hash. 7. Run `paper_aesthetic_eye_check`. A missing, stale, malformed, or failing @@ -82,6 +82,9 @@ self-certifies a pass. ### Figures, diagrams, and embedded cards +- Preserve the complete evidentiary content by default. Aspect-fit the source + into its field and letterbox mismatched ratios; crop only documented + non-evidence, never content needed to interpret the artifact. - Flow direction and hierarchy are immediately unambiguous. - Repeated cards, logos, or nodes use equal widths, heights, row baselines, and gutters. Inspect the negative space between items, not only the items. diff --git a/papers/QUALITY-RUBRIC.md b/papers/QUALITY-RUBRIC.md index a1fe5dc86..610338c14 100644 --- a/papers/QUALITY-RUBRIC.md +++ b/papers/QUALITY-RUBRIC.md @@ -80,17 +80,18 @@ flagship paper is expected to show its argument, not just state it. - **D6** Screenshots are legitimate evidence: the coarse UI being criticized, the AC piece being praised, the user comment proving demand. Caption them like exhibits — say what the reader is looking at and why it is in the paper. -- **D7 [HARD] Aesthetic Eye.** Every evidence figure and diagram is inventoried +- **D7 [HARD] Aesthetic Eye.** Every embedded evidence image and diagram is inventoried in the paper's `aesthetic-eye.json` and receives an explicit visual-inference - verdict of `design: pass|fail`. Evidence figures must pass scale, legibility, - evidence dominance, crop, and caption-fit checks. Diagrams must pass clear + verdict of `design: pass|fail`. Each image in a multi-panel figure receives + its own verdict. Evidence images must pass scale, legibility, evidence + dominance, crop, and caption-fit checks. Diagrams must pass clear tangents, accessible type, balanced composition, intentional use of available space, legible hierarchy, and unambiguous edge routing. The paper-wide brand verdict also requires every visible wordmark to read `Aesthetic.Computer`, with its period in AC pink (`#B44887`). The manifest's PDF hash must match the built PDF. Run `node papers/aesthetic-eye.mjs prepare `, inspect the page contact - sheet and every evidence-figure and diagram crop, record the verdicts, then run + sheet and every evidence-image and diagram crop, record the verdicts, then run `node papers/aesthetic-eye.mjs check `. ## E — Cover (`bin/gen-cover.mjs`) diff --git a/papers/SCORE.md b/papers/SCORE.md index a7332ec58..2eda2fd2e 100644 --- a/papers/SCORE.md +++ b/papers/SCORE.md @@ -222,7 +222,7 @@ The mill's code lives at the top of `papers/` and in [`bin/`](bin/). All scripts | [`bin/crunch.mjs`](bin/crunch.mjs) | Build a paper on the **oven** instead of locally — for a machine with no TeX, or a document that must stay private. Tars the directory, POSTs it to `/paper-crunch`, streams the log, writes the PDF. Never commits and never publishes: the crunched PDF comes back to you and goes nowhere near `papers.aesthetic.computer` (that is `cli.mjs publish`, which builds from `main`). House `.sty` + webfonts resolve inside the oven's sandbox. | | [`bin/gen-cover.mjs`](bin/gen-cover.mjs) | Generate the colored-pencil vignette cover illustration for a dossier from `figures/cover-prompt.txt` via OpenAI gpt-image-2 (1024×1024 square, faded edges). | | [`bin/gen-qrs.mjs`](bin/gen-qrs.mjs) | Generate per-paper QR-code PNG pointing to the deployed permalink at `papers.aesthetic.computer/.pdf`. Uses `qrencode` CLI. | -| [`aesthetic-eye.mjs`](aesthetic-eye.mjs) | Render final-PDF page contacts plus evidence-figure and diagram crops; enforce useful evidence scale, the colored `Aesthetic.Computer` period, and current visual-inference verdicts. See [`AESTHETIC-EYE.md`](AESTHETIC-EYE.md). | +| [`aesthetic-eye.mjs`](aesthetic-eye.mjs) | Render final-PDF page contacts plus per-image evidence and diagram crops; enforce useful evidence scale, complete-content preservation, the colored `Aesthetic.Computer` period, and current visual-inference verdicts. See [`AESTHETIC-EYE.md`](AESTHETIC-EYE.md). | | [`bin/migrate-cover.mjs`](bin/migrate-cover.mjs) | One-shot migration: rewrite an old-style cover block (4em pals + 15em hero) into the new vignette layout (pals top-left + QR top-right + TikZ-overlaid title floating over faded illustration). Idempotent. | | [`bin/fix-people-tables.mjs`](bin/fix-people-tables.mjs) | One-shot: convert `tabularx{lXl}` people tables to `tabularx{lXX}` so the third column wraps and stops overflowing the column width. | diff --git a/papers/aesthetic-eye.mjs b/papers/aesthetic-eye.mjs index 31e9ce897..8de386388 100644 --- a/papers/aesthetic-eye.mjs +++ b/papers/aesthetic-eye.mjs @@ -3,7 +3,7 @@ // // A TeX build proves syntax, not design. This tool prepares evidence crops for // visual inference and enforces a current-PDF manifest whose verdict is the -// literal `design: pass|fail` for every evidence figure and diagram. +// literal `design: pass|fail` for every embedded evidence image and diagram. import { createHash } from "node:crypto"; import { execFile } from "node:child_process"; @@ -33,8 +33,11 @@ async function sha256(path) { export function countEvidenceFigures(sourceText) { return [...String(sourceText || "").matchAll(/\\begin\{figure\*?\}([\s\S]*?)\\end\{figure\*?\}/g)] - .filter((match) => /\\includegraphics(?:\[[^\]]*\])?\{/.test(match[1])) - .length; + .reduce( + (count, match) => count + + [...match[1].matchAll(/\\includegraphics(?:\[[^\]]*\])?\{/g)].length, + 0, + ); } function resolveInputs(input, manifestArg) { @@ -123,13 +126,13 @@ export function validateManifest(manifest, currentPdfSha256, sourceFigureCount = || figures.length > 0; if (figuresRequired) { if (!Number.isInteger(manifest?.expectedFigures) || manifest.expectedFigures < 0) { - errors.push("expectedFigures must be a non-negative integer when the source contains evidence figures"); + errors.push("expectedFigures must be a non-negative integer when the source contains evidence images"); } else { if (figures.length !== manifest.expectedFigures) { - errors.push(`expected ${manifest.expectedFigures} evidence figure(s), found ${figures.length}`); + errors.push(`expected ${manifest.expectedFigures} evidence image(s), found ${figures.length}`); } if (Number.isInteger(sourceFigureCount) && manifest.expectedFigures !== sourceFigureCount) { - errors.push(`source contains ${sourceFigureCount} evidence figure(s), manifest expects ${manifest.expectedFigures}`); + errors.push(`source contains ${sourceFigureCount} evidence image(s), manifest expects ${manifest.expectedFigures}`); } } const ids = new Set(); diff --git a/papers/test/aesthetic-eye.test.mjs b/papers/test/aesthetic-eye.test.mjs index ba406c401..a433595d0 100644 --- a/papers/test/aesthetic-eye.test.mjs +++ b/papers/test/aesthetic-eye.test.mjs @@ -34,11 +34,12 @@ const passingFigure = { }, }; -test("counts image-backed evidence figures but not a TikZ diagram", () => { +test("counts every embedded evidence image but not a TikZ diagram", () => { const source = String.raw` \begin{figure}\includegraphics{evidence}\end{figure} + \begin{figure}\includegraphics[width=.5\linewidth]{second}\includegraphics{third}\end{figure} \begin{figure*}\begin{tikzpicture}\end{tikzpicture}\end{figure*}`; - assert.equal(countEvidenceFigures(source), 1); + assert.equal(countEvidenceFigures(source), 3); }); test("fails when source evidence is absent from the Aesthetic Eye manifest", () => { @@ -47,7 +48,7 @@ test("fails when source evidence is absent from the Aesthetic Eye manifest", () assert.match(verdict.errors.join("\n"), /expectedFigures/); }); -test("passes a fully reviewed evidence figure", () => { +test("passes a fully reviewed evidence image", () => { const manifest = { ...baseManifest, expectedFigures: 1, figures: [passingFigure] }; assert.equal(validateManifest(manifest, "current-hash", 1).pass, true); }); diff --git a/slab/bin/paper-mcp.mjs b/slab/bin/paper-mcp.mjs index cd364f21b..5a378e5f0 100755 --- a/slab/bin/paper-mcp.mjs +++ b/slab/bin/paper-mcp.mjs @@ -670,7 +670,7 @@ const TOOLS = [ }, { name: "paper_aesthetic_eye_prepare", - description: "Prepare Aesthetic Eye review artifacts from an existing aesthetic-eye.json: an all-page contact sheet and one crop per declared evidence figure and diagram. Inspect every rendered artifact and update the manifest with the current PDF hash and literal visual verdicts. SIDE EFFECT: writes .aesthetic-eye/ raster files beside the paper.", + description: "Prepare Aesthetic Eye review artifacts from an existing aesthetic-eye.json: an all-page contact sheet and one crop per declared embedded evidence image and diagram. Inspect every rendered artifact and update the manifest with the current PDF hash and literal visual verdicts. SIDE EFFECT: writes .aesthetic-eye/ raster files beside the paper.", inputSchema: { type: "object", properties: { paper: { type: "string" } },