Repository navigation
FA: format audit for 0.14 (FA-01…FA-17) - #429
Merged
Merged
Conversation
The root narrative is a string (catalog id, URL or pkg: reference); the Narrative
and NarrativeBeat definitions leave opf.schema.json and a custom narrative is a
catalogs.narratives.records entry. Narrative records use duration {min,max},
beat type and layout; slideCount and shape are gone. All 48 records and the
example decks are migrated. Lint warns about unknown beats and a duration outside
the narrative's range; the audit reports unused beats.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…kind vocabulary placeholders[].type is the content-kind vocabulary (picture and diagram become image, media becomes video). A layout's design object (DesignHints) replaces the contentType*/slide* metadata; contentType, contentMultiple, slideTitle, slideSubtitle, slideTag, boolean slideImage and contentTypeListHeading are removed and layoutContent(record) derives kind, count and headings from the placeholders. All 100 bundled records migrated; composition, tests, docs and check:spec read the new shape. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…nization descriptions
Built-in variables (deck.*, speaker.*, speakers, organization.*, and by-id
forms) resolve in resolveVariables with the existing {{...}} and var: syntax.
HeaderFooterItem.speaker draws the first speaker's name and title. The
validator checks unique speaker/organization ids and Speaker.organizationId.
Speaker and Organization descriptions now say what is drawn.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…atalog index schema Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Delete the 50 deprecated chart-type records and the 6 deprecated audience records; the bundled catalog holds no deprecated record. Drop the -3x suffix from the eight stacked chart-type ids (no alias). Chart-type records: `name` is the human display name, `label` and `slideNumber` are gone, and so are the template-workbook fields no engine reads (workbookRange, columns, dataColumns, helperColumns, sampleData, categories, seriesGroups, useSecondaryCategories). `series` and `complexity` stay (the editor picker reads them). The deprecation field, validator warning and lint rule stay for after v1. The sync guard gets an explicit per-id waiver, --allow-removed. Examples, tests, docs, the audit chart-skip list, chartOptionTarget, the registry golden and the gallery tracker follow. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Hex color-scheme slots and roles, ColorRef background colors, TextRun.link pattern, gradient minItems 2, Watermark.src required, no slide-level dimensions, root audience object; remove ColorScheme.custom, Asset.format, ChartDataSource and Font objects; FontScheme.app powerpoint|google-slides, languageFamily eastAsian|complexScript; true descriptions for FontScheme.code, catalog sources and video. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Metric.sentiment (positive | negative | neutral) says whether a change is good news. The trend arrow keeps the direction of trend; the arrow, trend word and delta text colour follow the sentiment. Absent, up is positive, down negative and flat neutral, which is exactly the colour drawn before. Without a trend the sentiment has no visible effect (only the trend mark is coloured). - schema and generated reference text; layoutMetric validates it and passes it through as MetricLayout.sentiment; metricTrendColor/metricTrendMark take it - Markdown metric fence key, metric table Sentiment column, metric to text loss - tests for every trend x sentiment, absent-sentiment parity, composition, validation, markdown and table conversion Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Per-slide SVG/PNG, zip and PDF output skip slides marked hidden unless --include-hidden (named --slides are always written; the PPTX keeps hidden slides). Output files use the root filename, else the slugified name, else the input stem, the rule opf-editor already uses. The hidden and filename schema descriptions state the real behavior. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Adds resolveColorRoles, isDarkColor and defaultSlideBackground: the roles (primary, secondary, accent, background, surface, text, textSecondary) and the hyperlink slot resolve once. The audit uses them, resolves background var: references like the preview, and the schema role descriptions state the rules. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Quote gains `role` (title and organization, its own footer line) and `photo` (an Asset headshot drawn as a circle at the start edge of the footer row). layoutQuote places the footer text beside the photo, sizes the photo from the footer font size (so minFontSize is respected), mirrors it in a right-to-left deck and reports `photo-fit` when it cannot fit. Quotes without a role or photo lay out exactly as before (digest-identical over the 126 example decks). The missing-alt-text audit rule covers quote.photo; quote-to-text conversion folds the role into the attribution and reports the lost photo; Markdown writes a quote with role or photo as an opf-block. Adds a testimonial reference deck. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ial presets
Schema, shared geometry, validation, Markdown, pagination, docs and tests for the six small conveniences:
code.highlight (line bands and dimming helpers, warnings), Watermark.text (layoutWatermark), TextRun.code
and TextRun.lang (fragment style, Markdown backticks and {lang=}), the 1:1, 4:5 and 9:16 presets, and the
items-versus-bullets rule.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…s test Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Schema field, layout geometry (marker status, ring, strokeWidth; part status; bold current label), shared timelineMarkerShapes/timelineTextColor helpers, Markdown task-list prefix, loss notes in conversions, contrast audit sample, docs, skill example and tests. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Add chart.highlight { series?, categories? }: the engines color highlighted marks
with the deck primary and mute every other mark from the theme. A mark is
highlighted when its series OR its category is named.
- schema: Chart.highlight and ChartHighlight (no color field)
- core: chartOptionSupport().highlight per chart type, resolveChartOptions().highlight,
chartHighlightMarks and chartHighlightColors (shared by both engines)
- validation: chart-highlight-unknown-name (error, via resolveChartData),
chart-highlight-adapted (warning), chart-option-adapted for unsupported types
- docs: chart-options.md support matrix, schema reference, skills
- example: examples/technical/chart-highlight.opf.json (127th deck, +3 golden
slides; the coordinated core golden gains them, the other 805 hashes are unchanged)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… layout) Every shared design key (titleAlignment, contentAlignment, contentBox, contentDirection, chartPrimary, imageFill, listBullet) resolves with one merge, per key: slide design, then deck design, then the layout record's design, then the engine default. resolveDesignHints() computes it once; composeSlide() returns it as SlideComposition.design so render, pptx, pagination and the audit read the same values. Schema text and docs state the full precedence. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A new chart type `combo` (catalog record, mixed barChart + lineChart composition) draws an amount beside a rate. `Chart.line` names the series drawn as lines (default: the last series), `Chart.secondaryAxis` puts lines on a secondary value axis in their column format, and `ChartAxisTitles.secondary` titles it. resolveChartData returns the plan (`combo`) and orders the series columns, primary lines, secondary lines; resolveChartOptions gives the line label position and adapts the fields on other types. Validation, docs, skills, the chart-type sampler example (new coordinated golden) and the gallery tracker follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s the family; lang description Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… TextRun[]) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…platform icon fields Give the 30 bare bundled layouts a summary, description, tags and (where the gallery data states one) design; point every layout preview at its published SVG; font-scheme languages hold languages catalog ids (resolveScriptFonts matches by id, check:spec rule j); drop the unset icon, iconLight and iconDark social-platform fields; rehash --match-gallery for a core-first edit of a mirrored kind. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…s keep the marker radius Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Delete the 50 deprecated chart-type records and the 6 deprecated audience records; the bundled catalog holds no deprecated record. Drop the -3x suffix from the eight stacked chart-type ids (no alias). Chart-type records: `name` is the human display name, `label` and `slideNumber` are gone, and so are the template-workbook fields no engine reads (workbookRange, columns, dataColumns, helperColumns, sampleData, categories, seriesGroups, useSecondaryCategories). `series` and `complexity` stay (the editor picker reads them). The deprecation field, validator warning and lint rule stay for after v1. The sync guard gets an explicit per-id waiver, --allow-removed. Examples, tests, docs, the audit chart-skip list, chartOptionTarget, the registry golden and the gallery tracker follow. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> # Conflicts: # docs/schema-reference.md # scripts/fixtures/README.md
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> # Conflicts: # docs/schema-reference.md # examples/technical/chart-data-sources.opf.json
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> # Conflicts: # docs/schema-reference.md
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: aedcb2b2-3998-4853-874b-c926b9fc1f66) |
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 7, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 7, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 7, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 7, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 7, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 7, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 7, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 7, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 7, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 7, 2026
This was referenced Oct 7, 2026
A merge_group run reads its head pull request from the queue branch (`[refs/heads/]gh-readonly-queue/<base>/pr-<n>-<sha>`) and resolves that pull request's Depends-On (its body read over REST), so a breaking coordinated change is checked against its open sibling pull requests, and their adopted golden, in the queue too. In a batch only the head pull request's Depends-On applies, so a coordinated change queues alone (documented). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 82c2f1e2-5f2d-493d-bf92-b27f04a14d07) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends-On: OpenPresentation/opf-render#151
Depends-On: OpenPresentation/opf-pptx#197
Depends-On: OpenPresentation/opf-editor#112
One integration PR for the whole format audit (FA-01 to FA-17), shipping together in breaking 0.14.0. Each item is merged with
git merge --no-ffin the program's order (C:\opf-work\fa-program\integration-branches.md), then one regeneration pass.Items
e0f09fbecccb1e25acfb922e90a25071fe2fa4e5daa744b1f9d3d7d5729c0e55917adb2aa03a14eb76bb92ef696fa017(native-verified fix, ahead of origin)e6ee17226fb2e32d(stacked on FA-03)8ef4c239(stacked on FA-01)366ca5af317a9d00(stacked on FA-01)No item was left out.
mainis merged on top twice (#427, then #404 and RR-56 #406 YAML); the RR-56 merge conflicted only indocs/markdown.md(main's numbered-list wording, FA-12's quote role/photo wording) and the CLI usage (FA-08--include-hiddenbeside RR-56--format).Resolved by hand
Generated files (schema/catalog references,
docs/audit.md, catalogindex.json/manifest.jsonhashes, golden fixture JSON,ecosystem.lock.jsongolden entry, gallery trackers) took one side and were regenerated below. Source conflicts, keeping both items' intent:spec/schemas/opf.schema.json: color-scheme roles keep FA-07's$ref HexColorwith FA-05's descriptions;Charthas FA-09altand FA-14highlightside by side; charttypetakes FA-15's description andcomboexample;Watermarkisrequired: [opacity]plusoneOf [{required:[src]},{required:[text]}](FA-07 + FA-13), with FA-07's src wording and the string/Asset default-opacity sentence;FontScheme.codestays FA-07's family string with FA-13's inline-code wording (also infont-scheme.schema.json);design.watermarkmentions both forms;Quotedrops "The text is a plain string" (FA-12) because FA-10 makes itstring | TextRun[]; FA-14's highlight description now listscomboamong the constructs that drop it (corechartOptionSupportgives combo no highlight support).spec/schemas/layout.schema.json: FA-01's kind description, plus FA-06's metric sentiment.composition.ts:layoutQuotecombines FA-12 (role, photo, photo-fit, Selection) with FA-10 (richTextRun[]body,heightOf), including the photo-overlap check throughheightOf;ComposeSlideOptions.presentationkeeps FA-04speakerand FA-17's design keys; exports keep FA-15ChartComboSeries, FA-17 design hints and FA-01layoutContent.audit-design.ts: FA-07 and FA-05 both made background colors ColorRefs; FA-05'sbackgroundColorRef/resolveColorRolesversion is kept and FA-07's now-unusedBackgroundColorhelper removed.chart-options.ts: FA-14 highlight and FA-15 combo/secondary axis together.lint.ts/validator.ts/opf-inspect skill: data warning codes are FA-07's set (nochart-data-source-unresolved) plus FA-14chart-highlight-adaptedand FA-13 code-highlight codes.audit-rules-a11y.ts: FA-09 chart-alt rule with FA-10's rich-subtitle test; FA-12 quote-photo alt kind next to FA-09's chart kind.pagination.ts: FA-13 code-highlight slicing plus FA-10 rich quote slicing.convert/content.ts: FA-12 role/photo loss plus FA-10 rich quote runs.markdown/canon.ts: FA-09 alt without FA-07's removedsrcdata source.examples/technical/chart-data-sources.opf.json: FA-07's removal of the data-source slides.docs/markdown.mdno longer says a chart fence takes asrcdata source.script-fonts.test.mjs: FA-07app: 'powerpoint'with FA-16 language ids.Cross-item fix: table banding on dark themes
Commit "FA-05: table banding stays visible on dark themes". The editor's banded rows used the
backgroundrole, which FA-05 made the slide background; on a theme whose background is the darksurface(minimal: dark2) the bands vanished. NewColorRefrolesurfaceAlt, derived in core bysurfaceAltColor(surface, text)(surface mixed 10% towards the text, further until 1.1:1 against the surface while the text keeps 4.5:1, else away from the text).resolveColorRolesreturns it andresolveColorRef("surfaceAlt")derives it from the surface and text roles both engines already pass, so preview and PPTX agree with no engine change (checked: minimal rows #011842 / bands #1A2F55 in SVG and PPTX; classic #F0F0F0 / #D8D8D8). New exports:surfaceAltColor,SURFACE_ALT_MIX,SURFACE_ALT_MIN_CONTRAST. Test:test/surface-alt.test.mjs(minimal and classic, every catalog scheme on its default, dark1 and dark2 backgrounds). The editor'sBAND_FILLmust becomesurfaceAlt(opf-editor#112). No example deck uses banding, so no golden change.Regeneration
node scripts/generate-schema-docs.mjs;node scripts/sync-gallery-catalog.mjs --rehash --match-gallery(font-schemes is a mirrored kind whose records FA-07/FA-16 changed);pnpm exec biome check --write(kept only in files this PR changes; main is not biome-clean elsewhere);pnpm build;node scripts/build-audit-docs.mjs;pnpm build:gallery-tracker(stale because FA-13 adds the 1:1, 4:5 and 9:16 presets).Tests
Local runs on Windows, Node 24, at the head:
pnpm typecheckis clean.pnpm testpasses: every package and CLI test, and all root checks, includingcheck:registry-goldenagainst the transitional lock golden below.pnpm test:ecosystempasses against the linked sibling integration worktrees.test/golden.mjswith the FA renderer passes againstopf-examples-png.fa-0-14.sha256.json: 807 slides, 127 decks.Golden: two fixtures (the release supervisor's design)
The lock's golden means what the locked renderer renders core's examples to. Main's locked renderer (opf-render 759017e) predates FA, so this PR carries two fixtures:
scripts/fixtures/opf-examples-png.fa-0-14-locked-render.sha256.jsonis TRANSITIONAL, and the lock selects it until the roll. It was produced on Linux byregenerate-core-golden.ymldry run 37554992751: the guard reproduced main byte for byte, then it rendered this branch with the locked renderer. 59 slides in 48 decks move, because the old renderer draws the renamed chart type ids the old way (40+ gallery chart slides at v0.2.0 release tracking: packed-package smoke #2 and Release @openpresentation/opf 0.3.0 #6) and ignores FA-05'stextrole. With this fixture, this PR's merge-group run checks exactly what main will render. It is deleted after the roll.scripts/fixtures/opf-examples-png.fa-0-14.sha256.jsonis the true FA set, rendered with the FA renderer (opf-render#151) on this core using the opf#367 method:golden-overridein its ci.yml, so its own CI, with Depends-On this PR, verifies it on Linux. The roller adopts it as the lock's golden.The true set moves 22 slides in 15 decks against RR-20 (16 changed, 4 added, 2 removed):
technical/design-backgrounds#0–#4textrole now applies.technical/chart-highlight#0–#2 (added)technical/chart-type-sampler#2 (added)technical/chart-data-sources#1–#2 (removed)ChartDataSourceremoved.technical/asset-source-forms#3data.srcreplaced by inlinerows. Where the deck used a removed alias, the clean id applies (dumbbell and dot-plot become scatter,canadabecomesworld).The RR-20
opf-examples-png.example-decks.sha256.jsonis restored to main's bytes and kept inRETAINED_CORE_GOLDENSfor the published core 0.13.0. The intermediate FA-03chart-idsand FA-15combo-chartfixtures are removed.Tooling, so that the roller adopts a core fixture:
scripts/ecosystem-roll.mjsaccepts a renderergolden-overridethat namesopf/scripts/fixtures/<name>.sha256.json. The path must passisSafeRelativePath, andplan()fails the roll if the fixture is missing at the rolled core SHA.scripts/ecosystem-roll.test.mjs.Landing sequence
Depends-Onthen resolves to this PR's merge commit, so re-run their CI after this lands.golden-override, so the lock ends with the FA renderer andopf-examples-png.fa-0-14.sha256.json, and the roll PR's queue run verifies that pair.golden-overrideto''. A stale override broke a roll once. The same step, or RR-55, deletes the transitionalfa-0-14-locked-renderfixture.pptx-gallery#110 waits for the 0.14 release. RR-55 #423 reuses this two-fixture pattern.
🤖 Generated with Claude Code
Note
High Risk
Breaking pre-v1 schema, catalog, and validation changes across the whole OPF surface, plus coordinated golden/ecosystem lock behavior that gates merge-queue and sibling repos.
Overview
FA 0.14 lands as one coordinated format-audit integration: breaking schema and catalog changes (FA-01–FA-17), new composition/audit/chart APIs, and docs/changelog for each item.
Format and catalogs: Layout records use a unified
design+placeholdersvocabulary; narratives become catalog pointers with renamed beat fields; chart-type/audience catalogs are cleaned (deprecated ids removed,-3xsuffix dropped, record shape slimmed); validation tightens colors/links/gradients and removes dead keys includingChartDataSource; additive features include built-in variables,resolveColorRoles/surfaceAlt, metric sentiment, chartaltandhighlight, combo charts, rich headings, timeline status, quote role/photo, code highlight, and full layoutdesignmerge viaresolveDesignHints.CLI and tooling:
opf render/exportskip hidden slides by default (--include-hidden), name outputs from deckfilename/name, and the published-packages matrix runs the release-tag font-switch harness so unreleased catalog shapes in the checkout do not break CI.Ecosystem CI:
Depends-Onapplies on merge_group (queue head PR); opf-render Depends-On can adopt that PR'sgolden-override; the roller can adopt a core fixture golden from renderer override (FA-19 / roller notes in changesets).Reviewed by Cursor Bugbot for commit d18ddfe. Configure here.