Skill Tracer
Skills › Scientific Agent Skills › pptx-posters › manifest_spec.md

manifest_spec.md

300 lines · skills/pptx-posters/references/manifest_spec.md at 5f2bc03

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# Poster manifest 2.0
2

Poster manifest 2.0

Raw lines 1 to 2
3## Purpose
4
5The manifest is the only content input to the generator. It binds:
6
7- approved text and images;
8- exact source IDs;
9- local asset hashes and licenses;
10- PowerPoint canvas and physical output geometry;
11- conference and printer rules;
12- accessibility/quality thresholds and their basis;
13- reading order;
14- author approval to a canonical content hash.
16Unknown keys, duplicate JSON keys, non-finite numbers, remote asset paths, path escape,
17unapproved fields, unresolved sources, unused records, and common placeholders are
18rejected.

Purpose

The manifest is the only content input to the generator. It binds:

  • approved text and images;
  • exact source IDs;
  • local asset hashes and licenses;
  • PowerPoint canvas and physical output geometry;
  • conference and printer rules;
  • accessibility/quality thresholds and their basis;
  • reading order;
  • author approval to a canonical content hash.

Unknown keys, duplicate JSON keys, non-finite numbers, remote asset paths, path escape, unapproved fields, unresolved sources, unused records, and common placeholders are rejected.

Raw lines 3 to 19
20## Template
22`assets/poster_manifest_template.json` is intentionally invalid. It contains
23replacement tokens, false confirmations, and draft approval so it cannot produce a
24poster accidentally.
26Copy it into a project directory, then replace every field with reviewed values.
27Asset paths are relative to that manifest's directory.

Template

assets/poster_manifest_template.json is intentionally invalid. It contains replacement tokens, false confirmations, and draft approval so it cannot produce a poster accidentally.

Copy it into a project directory, then replace every field with reviewed values. Asset paths are relative to that manifest's directory.

Raw lines 20 to 28
29## Top-level object
31Manifest version 2.0 requires exactly these keys:
33- `schema_version`
34- `document`
35- `canvas`
36- `physical_output`
37- `requirements`
38- `quality`
39- `palette`
40- `sources`
41- `assets`
42- `elements`
43- `approval`
45The validator rejects extensions to the schema rather than silently ignoring them.

Top-level object

Manifest version 2.0 requires exactly these keys:

  • schema_version
  • document
  • canvas
  • physical_output
  • requirements
  • quality
  • palette
  • sources
  • assets
  • elements
  • approval

The validator rejects extensions to the schema rather than silently ignoring them.

Raw lines 29 to 46
47## `document`
49- `id`: stable identifier beginning with a letter.
50- `title`: exact approved title, at most 255 characters.
51- `subject`: exact approved description for core document metadata, at most 255 characters.
52- `language`: BCP 47-style language tag.
53- `authors`: exact ordered author names; joined by `; ` they must fit the 255-character
54 core-property limit. No author is silently dropped or shortened.
55- `source_ids`: exact records supporting title, subject, language, and author metadata.
57Exactly one text element with role `title` must match `document.title` verbatim.
58It must have `reading_order: 1`; generation uses it as the native PowerPoint slide
59title placeholder rather than as an undifferentiated text box.

document

  • id: stable identifier beginning with a letter.
  • title: exact approved title, at most 255 characters.
  • subject: exact approved description for core document metadata, at most 255 characters.
  • language: BCP 47-style language tag.
  • authors: exact ordered author names; joined by ; they must fit the 255-character core-property limit. No author is silently dropped or shortened.
  • source_ids: exact records supporting title, subject, language, and author metadata.

Exactly one text element with role title must match document.title verbatim. It must have reading_order: 1; generation uses it as the native PowerPoint slide title placeholder rather than as an undifferentiated text box.

Raw lines 47 to 60
61## `canvas`
63- `width_in`, `height_in`: PowerPoint slide dimensions, each 1–56 inches.
64- `background_color`: opaque six-digit sRGB hex.
66These are design dimensions, not automatically the physical trim size.

canvas

  • width_in, height_in: PowerPoint slide dimensions, each 1–56 inches.
  • background_color: opaque six-digit sRGB hex.

These are design dimensions, not automatically the physical trim size.

Raw lines 61 to 67
68## `physical_output`
70- `trim_width_in`, `trim_height_in`: finished physical dimensions.
71- `bleed_in`: physical bleed on each edge.
72- `safe_margin_in`: inset inside the trim edge for non-bleed content.
73- `orientation`: `portrait`, `landscape`, or `square`, matching trim dimensions.
75The physical artboard is trim plus twice the bleed. It must share the canvas aspect
76ratio.

physical_output

  • trim_width_in, trim_height_in: finished physical dimensions.
  • bleed_in: physical bleed on each edge.
  • safe_margin_in: inset inside the trim edge for non-bleed content.
  • orientation: portrait, landscape, or square, matching trim dimensions.

The physical artboard is trim plus twice the bleed. It must share the canvas aspect ratio.

Raw lines 68 to 77
78## `requirements`

requirements

Raw lines 78 to 79
80### `conference`
82The organizer record must be confirmed and provide:
84- exact `source_id`;
85- maximum width and height;
86- orientation (`portrait`, `landscape`, `square`, or `either`);
87- required delivery format (`PDF`, `PPTX`, `PDF_AND_PPTX`, or `OTHER`);
88- notes copied or summarized from the verified rule.
90The physical trim dimensions must fit.
91The referenced source record must have kind `conference_rule`.

conference

The organizer record must be confirmed and provide:

  • exact source_id;
  • maximum width and height;
  • orientation (portrait, landscape, square, or either);
  • required delivery format (PDF, PPTX, PDF_AND_PPTX, or OTHER);
  • notes copied or summarized from the verified rule.

The physical trim dimensions must fit. The referenced source record must have kind conference_rule.

Raw lines 80 to 92
93### `printer`
95The printer record must be confirmed and provide:
97- exact `source_id`;
98- trim width/height, bleed, and safe margin matching `physical_output`;
99- accepted color mode (`RGB`, `CMYK`, or `PRINTER_MANAGED`);
100- whether uniform scaling is allowed;
101- notes describing the confirmed workflow.
103If scaling is forbidden, canvas and physical artboard must be 1:1. A CMYK requirement
104does not prevent creation of an editable RGB PPTX, but the export plan blocks a claim
105of print readiness pending printer-approved conversion/proof.
106The referenced source record must have kind `printer_rule`.

printer

The printer record must be confirmed and provide:

  • exact source_id;
  • trim width/height, bleed, and safe margin matching physical_output;
  • accepted color mode (RGB, CMYK, or PRINTER_MANAGED);
  • whether uniform scaling is allowed;
  • notes describing the confirmed workflow.

If scaling is forbidden, canvas and physical artboard must be 1:1. A CMYK requirement does not prevent creation of an editable RGB PPTX, but the export plan blocks a claim of print readiness pending printer-approved conversion/proof. The referenced source record must have kind printer_rule.

Raw lines 93 to 107
108## `quality`
110- `minimum_font_pt_final`
111- `font_guidance_basis`
112- `font_guidance_source_id`
113- `minimum_raster_dpi_final`
114- `raster_dpi_basis`
115- `raster_dpi_source_id`
117Basis values are:
119- `heuristic`
120- `source_specific`
121- `conference_requirement`
122- `printer_requirement`
124A heuristic must have a null source ID. Every other basis requires an exact source
125ID. Values apply at final physical output, after uniform scaling.

quality

  • minimum_font_pt_final
  • font_guidance_basis
  • font_guidance_source_id
  • minimum_raster_dpi_final
  • raster_dpi_basis
  • raster_dpi_source_id

Basis values are:

  • heuristic
  • source_specific
  • conference_requirement
  • printer_requirement

A heuristic must have a null source ID. Every other basis requires an exact source ID. Values apply at final physical output, after uniform scaling.

Raw lines 108 to 126
127## `palette`
129`colors` maps stable IDs to opaque `#RRGGBB` sRGB values.
131Each `contrast_pairs` record contains:
133- `id`
134- `foreground_color_id`
135- `background_color_id`
136- `usage`: `normal_text`, `large_text`, or `non_text`
138The validator applies 4.5:1 to normal text and 3:1 to large text/non-text. A text
139element using `large_text` must be at least 18 pt final, or at least 14 pt final and
140bold.
142`data_series_redundant_encoding` must be true. This is an author confirmation that
143color is supplemented by labels, shapes, markers, patterns, or line styles. It is not
144an automated certification.

palette

colors maps stable IDs to opaque #RRGGBB sRGB values.

Each contrast_pairs record contains:

  • id
  • foreground_color_id
  • background_color_id
  • usage: normal_text, large_text, or non_text

The validator applies 4.5:1 to normal text and 3:1 to large text/non-text. A text element using large_text must be at least 18 pt final, or at least 14 pt final and bold.

data_series_redundant_encoding must be true. This is an author confirmation that color is supplemented by labels, shapes, markers, patterns, or line styles. It is not an automated certification.

Raw lines 127 to 145
146## `sources`
148Each source has:
150- `id`
151- `kind`
152- `citation`
153- `locator`
154- `author_verified: true`
156Kinds include author content, publication, dataset, asset license, conference rule,
157printer rule, institutional rule, and other.
159Every source must be used, and every referenced ID must exist. The scripts do not
160resolve URLs, DOIs, or local records.

sources

Each source has:

  • id
  • kind
  • citation
  • locator
  • author_verified: true

Kinds include author content, publication, dataset, asset license, conference rule, printer rule, institutional rule, and other.

Every source must be used, and every referenced ID must exist. The scripts do not resolve URLs, DOIs, or local records.

Raw lines 146 to 161
162## `assets`
164The array may be empty: figures, logos, and QR codes are optional. Only local
165PNG/JPEG assets are accepted when an asset is present. Each record has:
167- `id`
168- manifest-relative `path`
169- `role`: `figure`, `logo`, or `qr_code`
170- lowercase SHA-256
171- exact `source_id`
172- `license`: exact license or permission statement
173- `provenance`: exact author-verified origin or generation record
174- concise `alt_text`
175- `author_approved: true`
176- `qr_target`
178`qr_target` is null except for QR assets, where it is an exact `https://` URL. Files
179are bounded, final symlinks are rejected, paths cannot escape the manifest directory,
180and hashes must match.
182All asset records must be placed in the poster.
183Use one asset record for repeated placement of the same file; duplicate asset paths
184are rejected.
186The image inventory rejects EXIF, XMP, comments, and embedded text/application
187metadata to avoid publishing hidden or location-identifying information. Flatten and
188strip such metadata in an author-reviewed offline workflow, then hash and approve the
189resulting pixels as a new asset. ICC profiles and basic technical image fields are
190reported but not silently removed.

assets

The array may be empty: figures, logos, and QR codes are optional. Only local PNG/JPEG assets are accepted when an asset is present. Each record has:

  • id
  • manifest-relative path
  • role: figure, logo, or qr_code
  • lowercase SHA-256
  • exact source_id
  • license: exact license or permission statement
  • provenance: exact author-verified origin or generation record
  • concise alt_text
  • author_approved: true
  • qr_target

qr_target is null except for QR assets, where it is an exact https:// URL. Files are bounded, final symlinks are rejected, paths cannot escape the manifest directory, and hashes must match.

All asset records must be placed in the poster. Use one asset record for repeated placement of the same file; duplicate asset paths are rejected.

The image inventory rejects EXIF, XMP, comments, and embedded text/application metadata to avoid publishing hidden or location-identifying information. Flatten and strip such metadata in an author-reviewed offline workflow, then hash and approve the resulting pixels as a new asset. ICC profiles and basic technical image fields are reported but not silently removed.

Raw lines 162 to 191
192## `elements`
194Elements are listed in ascending, contiguous `reading_order` from 1. The list order is
195not silently changed.
197Every element has:
199- `id`, `type`, and `reading_order`
200- design coordinates `x_in`, `y_in`, `width_in`, `height_in`
201- one or more exact `source_ids`
202- `author_approved: true`
203- `allow_in_bleed`
205All boxes must stay on the canvas. Non-bleed elements must remain inside the physical
206safe area mapped to the canvas. Text can never be allowed in bleed.

elements

Elements are listed in ascending, contiguous reading_order from 1. The list order is not silently changed.

Every element has:

  • id, type, and reading_order
  • design coordinates x_in, y_in, width_in, height_in
  • one or more exact source_ids
  • author_approved: true
  • allow_in_bleed

All boxes must stay on the canvas. Non-bleed elements must remain inside the physical safe area mapped to the canvas. Text can never be allowed in bleed.

Raw lines 192 to 207
208### Text elements
210Text elements also specify:
212- `role`
213- exact `text`
214- `font_size_pt_design`
215- `font_face`
216- `bold`
217- horizontal and vertical alignment
218- `contrast_pair_id`
219- optional `line_color_id`
220- `line_width_pt`
221- `margin_in`
223Roles include title, authors, affiliation, heading, body, caption, reference,
224acknowledgement, contact, QR fallback, and other.
226Font size is checked after physical scaling. Text auto-shrink is disabled during
227generation.

Text elements

Text elements also specify:

  • role
  • exact text
  • font_size_pt_design
  • font_face
  • bold
  • horizontal and vertical alignment
  • contrast_pair_id
  • optional line_color_id
  • line_width_pt
  • margin_in

Roles include title, authors, affiliation, heading, body, caption, reference, acknowledgement, contact, QR fallback, and other.

Font size is checked after physical scaling. Text auto-shrink is disabled during generation.

Raw lines 208 to 228
229### Image elements
231Image elements also specify:
233- `asset_id`
234- `fit: "contain"`
235- `fallback_text_element_id`
236- `long_description_element_id`
238Contain fitting preserves aspect ratio and centers the image. A QR asset requires a
239square box and a fallback text element whose role is `qr_fallback` and whose text
240contains the exact `qr_target`. Other assets use null fallback IDs.
242`long_description_element_id` is null when approved alt text and adjacent native text
243are sufficient. For a complex figure that needs a longer explanation, it references
244an approved native text element with role `body`, `caption`, or `other`. That element
245must follow the image in reading order and include every source ID used by the image.
246QR assets use the required visible fallback text and therefore set this field to null.
247The reference is structural; a human must decide whether the description is complete.

Image elements

Image elements also specify:

  • asset_id
  • fit: "contain"
  • fallback_text_element_id
  • long_description_element_id

Contain fitting preserves aspect ratio and centers the image. A QR asset requires a square box and a fallback text element whose role is qr_fallback and whose text contains the exact qr_target. Other assets use null fallback IDs.

long_description_element_id is null when approved alt text and adjacent native text are sufficient. For a complex figure that needs a longer explanation, it references an approved native text element with role body, caption, or other. That element must follow the image in reading order and include every source ID used by the image. QR assets use the required visible fallback text and therefore set this field to null. The reference is structural; a human must decide whether the description is complete.

Raw lines 229 to 248
249## Approval
251Draft form:
253```json
255 "status": "draft",
256 "approved_by": null,
257 "approved_at": null,
258 "content_sha256": null
260```
262After all non-approval fields validate:
264```bash
265python -B scripts/validate_manifest.py poster.json \
266 --print-content-hash
267```
269Give the exact manifest and reported hash to the author. Approved form requires:
271- `status: "approved"`
272- nonempty `approved_by`
273- ISO 8601 `approved_at` with UTC offset
274- exact lowercase `content_sha256`
276The hash covers every top-level field except `approval`, using canonical sorted
277UTF-8 JSON. Any content, source, requirement, palette, coordinate, or asset-metadata
278change invalidates approval. The generator preserves the approval timestamp in its
279report and converts it to UTC for the PPTX created/modified core properties, as
280required by python-pptx; the original UTC offset is not stored in those properties.

Approval

Draft form:

{
  "status": "draft",
  "approved_by": null,
  "approved_at": null,
  "content_sha256": null
}

After all non-approval fields validate:

python -B scripts/validate_manifest.py poster.json \
  --print-content-hash

Give the exact manifest and reported hash to the author. Approved form requires:

  • status: "approved"
  • nonempty approved_by
  • ISO 8601 approved_at with UTC offset
  • exact lowercase content_sha256

The hash covers every top-level field except approval, using canonical sorted UTF-8 JSON. Any content, source, requirement, palette, coordinate, or asset-metadata change invalidates approval. The generator preserves the approval timestamp in its report and converts it to UTC for the PPTX created/modified core properties, as required by python-pptx; the original UTC offset is not stored in those properties.

Raw lines 249 to 281
Runs code scripts/validate_manifest.py :265
282## Validation modes and exit codes
284Normal validation reads and hashes assets and requires approval:
286```bash
287python -B scripts/validate_manifest.py poster.json
288```
290`--structure-only` skips file reads/hashes but still validates path syntax. Use it for
291planning/audit only, never generation.
293`--print-content-hash` permits draft approval but does not permit placeholders,
294unverified sources, unapproved elements, or false requirements.
296CLIs use:
298- exit 0: pass;
299- exit 1: completed audit found a release-blocking issue;
300- exit 2: invalid input, unsafe input, missing dependency, or command error.

Validation modes and exit codes

Normal validation reads and hashes assets and requires approval:

python -B scripts/validate_manifest.py poster.json

--structure-only skips file reads/hashes but still validates path syntax. Use it for planning/audit only, never generation.

--print-content-hash permits draft approval but does not permit placeholders, unverified sources, unapproved elements, or false requirements.

CLIs use:

  • exit 0: pass;
  • exit 1: completed audit found a release-blocking issue;
  • exit 2: invalid input, unsafe input, missing dependency, or command error.
Raw lines 282 to 300
Runs code scripts/validate_manifest.py :287