Repository navigation
RR-55: short-verb API, one validate, Finding schema, stats (core 0.14.0, breaking) - #423
Merged
Merged
Conversation
michaeljgrimm
added a commit
to OpenPresentation/opf-pptx
that referenced
this pull request
Oct 7, 2026
…ndings) Lockstep with OpenPresentation/opf#423. Exported PPTX bytes are unchanged (414 A/B exports of 138 decks and the determinism fixtures hash identically). - toPptx takes { fonts } (the fonts handle; core's Fonts) and no longer reads a top-level textMeasurement. - fromPptx(bytes, { signals: true }) resolves to { presentation, signals }. - OPFPptxError carries findings (and report) or diagnostics, not issues. - inventoryPptxTypefaces/checkPptxTypefaces are inventoryTypefaces/checkTypefaces and checkTypefaces takes { families }; FontSchemeDiagnostic comes from core. - Each slide is composed with the options of core's resolveSlideContext instead of a hand-built copy; an unresolved theme is reported as unresolved-theme. - validatePresentation becomes validate(x, { only: ['format'] }); the engine names import from @openpresentation/opf/composition; the fallbacks for older cores (number-format stubs, feature detection, missing script-font and chart option paths) are removed. - New tests: core-features (every core name src imports exists) and slide-context (composition uses the deck's resolved font families). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Oct 7, 2026
michaeljgrimm
force-pushed
the
codex/rr-55-short-verb-api
branch
from
October 7, 2026 06:20
47cd47f to
0c48821
Compare
michaeljgrimm
added a commit
to OpenPresentation/opf-pptx
that referenced
this pull request
Oct 7, 2026
…ndings) Lockstep with OpenPresentation/opf#423. Exported PPTX bytes are unchanged (414 A/B exports of 138 decks and the determinism fixtures hash identically). - toPptx takes { fonts } (the fonts handle; core's Fonts) and no longer reads a top-level textMeasurement. - fromPptx(bytes, { signals: true }) resolves to { presentation, signals }. - OPFPptxError carries findings (and report) or diagnostics, not issues. - inventoryPptxTypefaces/checkPptxTypefaces are inventoryTypefaces/checkTypefaces and checkTypefaces takes { families }; FontSchemeDiagnostic comes from core. - Each slide is composed with the options of core's resolveSlideContext instead of a hand-built copy; an unresolved theme is reported as unresolved-theme. - validatePresentation becomes validate(x, { only: ['format'] }); the engine names import from @openpresentation/opf/composition; the fallbacks for older cores (number-format stubs, feature detection, missing script-font and chart option paths) are removed. - New tests: core-features (every core name src imports exists) and slide-context (composition uses the deck's resolved font families). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
michaeljgrimm
marked this pull request as ready for review
October 7, 2026 06:21
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: 497e8a3d-702e-4419-9496-e3f91bdae259) |
michaeljgrimm
force-pushed
the
codex/rr-55-short-verb-api
branch
from
October 7, 2026 06:34
0c48821 to
43d051c
Compare
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: 8b944de7-a41d-45d0-89cf-9fa06407e3eb) |
….0, breaking), on the FA 0.14 integration RR-55 for core 0.14.0, restacked onto codex/fa-0-14-integration (opf#429) as one commit (the branch merged its parts A1 and A3). No deprecations, aliases or shims, and no migration guide: the renamed and removed names are listed in the changes/rr-55-*.md fragments. - One checker: validate(input, options?) with the shared Finding format (spec/schemas/finding.schema.json), six categories, opf/<rule> ids; opf validate is the only checking command and --fail-on replaces --strict. - Short verbs: paginate, bundle, format, diff, merge, fromMarkdown, toMarkdown, importData, to/fromExcelNumberFormat, OPF*Error classes; result fields and options named document are presentation. - stats and opf stats; resolveSlideContext; the fonts handle (ComposeSlideOptions.fonts is fontFamilies); engine names on /composition. - Unresolved layout, theme and colour scheme ids fall back and never throw. FA fold: - FA exports placed per FA-EXPORTS (engine helpers on /composition; listBuiltinVariables and normalizeLanguageFamily on the root; FA-13 helpers no engine imports stay internal). - Every FA rule or diagnostic is an opf/<id> finding with a category (64 rules); opf/chart-data-source-unresolved is gone. - resolveSlideContext follows FA-17 (design hints are resolved by composeSlide, not passed as options) and FA-05 (darkBackground from resolveColorRoles). - RR-56 /yaml: fromYaml returns the deck and its validate report with located findings; lintYamlSource and yamlLocator are folded into fromYaml + validate. - CLI: opf validate reads YAML; from-yaml takes --fail-on. - The core packed smoke skips the release plan's published siblings while the candidate core is on a newer minor line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
michaeljgrimm
force-pushed
the
codex/rr-55-short-verb-api
branch
from
October 7, 2026 07:23
43d051c to
2c6c2eb
Compare
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: 98442b17-2bcd-4f71-bdf4-05508296183a) |
michaeljgrimm
added a commit
to OpenPresentation/opf-pptx
that referenced
this pull request
Oct 7, 2026
…196) * RR-55: adopt the core 0.14 API (fonts handle, resolveSlideContext, findings) Lockstep with OpenPresentation/opf#423. Exported PPTX bytes are unchanged (414 A/B exports of 138 decks and the determinism fixtures hash identically). - toPptx takes { fonts } (the fonts handle; core's Fonts) and no longer reads a top-level textMeasurement. - fromPptx(bytes, { signals: true }) resolves to { presentation, signals }. - OPFPptxError carries findings (and report) or diagnostics, not issues. - inventoryPptxTypefaces/checkPptxTypefaces are inventoryTypefaces/checkTypefaces and checkTypefaces takes { families }; FontSchemeDiagnostic comes from core. - Each slide is composed with the options of core's resolveSlideContext instead of a hand-built copy; an unresolved theme is reported as unresolved-theme. - validatePresentation becomes validate(x, { only: ['format'] }); the engine names import from @openpresentation/opf/composition; the fallbacks for older cores (number-format stubs, feature detection, missing script-font and chart option paths) are removed. - New tests: core-features (every core name src imports exists) and slide-context (composition uses the deck's resolved font families). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * RR-55: no layout record for a layout-less slide; unknown ids never throw A slide with no layout, or an unknown layout id, composes with no layout record (automatic composition, as in the preview). Theme, colour scheme, layout, font scheme and darkBackground come from core's resolveSlideContext; its unresolved-* diagnostics are forwarded and catalog-resolution-failed is gone. The exporter's own theme and colour-scheme record resolution and the blank default are removed. Not yet run against the core commit 7808c7ec (the shared core checkout has to be rebuilt first). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * RR-55: FA tests follow the 0.14 names (validate, renderSlideSvg, loadFonts, /composition engine names) The format-audit tests used validatePresentation, the slide-level renderSvg, prepareNodeFonts and root imports of engine names; core-features.mjs also lists the FA core functions the exporter now imports statically. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * RR-55: default font scheme from core in importedCodeFamily; drop the unreachable watermark-not-exported emit DEFAULTS no longer exists, so importedCodeFamily threw on every fromPptx call; it reads core's DEFAULT_FONT_SCHEME. layoutWatermark returns null only for text that draws nothing, which now skips silently (FA-07 removed the diagnostic). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
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#150
Depends-On: OpenPresentation/opf-pptx#196
Depends-On: OpenPresentation/opf-editor#116
Summary
RR-55 for core 0.14.0 (breaking, no deprecation, no aliases, no stubs): the whole API cleanup in one PR.
validate(input, options?)replacesvalidatePresentation,lintSource,lintPresentation,auditSourceandauditPresentation; the report is{ valid, findings, counts, schemaValid, checks }with the newFindingformat (spec/schemas/finding.schema.json).opf validateis the only checking command (opf lint,opf auditand--strictare gone;--fail-onreplaces it). Part A1.statsand one slide context.stats(presentation)andopf statsreport neutral facts, never severities.resolveSlideContext(presentation, index, { fonts })is the one place the slide, deck, theme, font-scheme chain is resolved: core pagination andvalidate's layout rules use it, so no hand-built chain is left in core.ComposeSlideOptions.fontsis nowfontFamilies; deck-level verbs take{ fonts }. The package root keeps app-level names: 235 engine names (values and types) moved to/compositionand/symbol-font-encodings. Part A3.paginatePresentationispaginate,bundlePresentationisbundle,formatPresentationisformat,diffPresentationsisdiff,mergePresentationsismerge,markdownToOpfisfromMarkdown,opfToMarkdownistoMarkdown,createDataContentisimportData,excelNumberFormat/numberFormatFromExcelaretoExcelNumberFormat/fromExcelNumberFormat,PatchError/PatchValidationError/FormatErrorareOPFPatchError/OPFPatchValidationError/OPFFormatError. Result fields and options nameddocument(markdown result,applyPatchWithInverseresult,/convertoption) arepresentation. The CLI verbs are also exported from the root. Part A2 (this branch merges A1 and A3 and does the sweep).No migration guide (there are no users yet): the renamed and removed names are listed in the
changes/rr-55-*.mdfragments. Validation guide: docs/validate.md. Stats: docs/stats.md.Ordering
One commit on
mainafter the FA integration (opf#429,eb4a130a). It queues alone, with the lockstep sibling PRs named in the Depends-On lines above; a release-prep PR then cuts 0.14.0 for every package.check:breakingcompares onlyspec/(the minor bump allows its breaking changes).Restacked onto the format-audit integration (opf#429)
One commit on top of
mainafter the FA integration squash-merged (eb4a130a, opf#429): RR-55's seven commits squashed (the branch had a merge of A1 and A3), with every FA addition folded in. There is no migration guide:docs/migrations/0.14.0.mdis deleted (owner: no users yet) and the renamed and removed names are listed in thechanges/rr-55-*.mdfragments; the FA fragments are rewritten to the final 0.14 names. The release-prep to-do list that lived in the guide (CLI peer calls, registry-pinned scripts) is in the release-readiness progress log.FA fold decisions (vetoable):
/composition:layoutContent,LAYOUT_BODY_KINDS,resolveColorRoles,isDarkColor,defaultSlideBackground,DARK_BACKGROUND_LUMINANCE,surfaceAltColor,SURFACE_ALT_MIX,SURFACE_ALT_MIN_CONTRAST,timelineMarkerShapes,timelineTextColor,TIMELINE_*,codeHighlightLines,codeHighlightBands,codeHighlightColors,codeLineNumbers,layoutWatermark,chartHighlightMarks,chartHighlightColors,CHART_HIGHLIGHT_*,resolveDesignHints,DESIGN_HINT_KEYS. Root:listBuiltinVariables(BuiltinVariableInfo),normalizeLanguageFamily(LanguageFamilyName),ChartComboSeries. Types follow their module (QuotePhoto,MetricSentiment,CodeHighlight*,WatermarkText*,TimelineStatus, ... on/composition). Internal (no engine imports them, checked in the three restacked siblings):codeHighlightList,codeHighlightSlice,codeHighlightContrast,codeLineCount,CODE_HIGHLIGHT_DIM,CODE_HIGHLIGHT_BAND_TINT,WATERMARK_TEXT_*.formaterrors:opf/variable-unknown-builtin,opf/chart-highlight-unknown-name.referenceswarnings:opf/unknown-beat,opf/slide-theme-dimensions.contentwarnings:opf/variable-builtin-missing,opf/chart-highlight-adapted,opf/code-highlight-out-of-range,opf/code-highlight-range-reversed,opf/duration-outside-narrative,opf/narrative-duration-range;contentinfo:opf/unused-beat. 64 rules in all;opf/chart-data-source-unresolvedis gone withChartDataSource. Deviation from FA-EXPORTS:chart-highlight-unknown-nameisformat, notreferences, because it is a validator error like its siblingchart-mapping-unknown-column(formatsince A1), andvalidate(deck, { only: ['format'] })must keep answering exactly what the format check answered. The FA-04 deck-metadata errors (duplicate speaker or organization id, anorganizationIdthat names nothing, a variable namedspeakers) stayopf/schema(format) for the same reason.slide-theme-dimensionsisreferences: the document is well-formed, the mismatch only exists through the theme record the slide names.resolveSlideContext. FA movedtitleAlignment,contentAlignmentandcontentBoxout of the composition options:composeSlideresolves them (and every other design hint) from the slide,presentation.designand the layout record and returns them asSlideComposition.design.resolveSlideContextno longer sets them, exactly like FA's own pagination and audit chains, so the renderer, the exporter and the editor get the same options FA's engines built (canvas, layout,presentation, slide index/number/count, font families,darkBackground, social platforms, measurement, date).darkBackgroundisresolveColorRoles(scheme, { background }).dark, the one rule FA-05 made shared, so it cannot disagree with the card surface the engines take fromresolveColorRoles.resolveColorRoles/defaultSlideBackgroundpath inrule-design.ts; the duplicate helpers are deleted./yamlfolds intofromYaml+validate.fromYaml(text, { aliases, validate })returns{ presentation, valid, findings, counts, schemaValid, checks }(thevalidatereport of the deck, every finding located in the YAML;validatetakestrue,falseorValidateOptions, likefromMarkdown).lintYamlSourceandyamlLocatorare deleted;YamlDiagnosticisYamlFinding;toYamlvalidates the format only and itsinvalid-documenterror carriesfindings. YAML syntax errors areyaml/<rule>findings of categoryformat.opf lintandopf auditstay removed;opf validatereads YAML (a.yaml/.ymlname or--input-format yaml) throughfromYaml, reports a YAML syntax error as ayaml/<rule>finding and exits 1, like invalid JSON.render,exportandimportcheck YAML through the same path.from-yamltakes--fail-oninstead of--strict. FA-08's--include-hiddenand deck-named output files are kept.packed-install-smoke.mjsinstalls the release plan's published renderer, editor and PPTX next to the packed core; they target core 0.13 and cannot run with 0.14 (the editor importsPatchError). The smoke now skips them when the plan's core is on an older minor line and says so;test:packed-ecosystemchecks the candidate siblings, and the release-prep PR that moves the plan turns the check back on. (Without this, CI's "Verify packed package install" could not pass before release.) Also fixed: the smoke's patch/diff snippet shadoweddiffafter the rename.Vetoable calls
Part A2 (integration and sweep):
opf/variable-unfilledis aformatrule, notcontent: an error in a deck that is not a template, a warning in a template. Sovalidate(deck, { only: ['format'] }),assertValid, pagination, patch validation and every write command (opf fill,paginate,edit,create) reject an unfilled required variable exactly asvalidatePresentationdid (new tests in core and the CLI). Consequence: the stray{{token}}warning (a deck that declares no variables but has{{name}}text) is the same rule, so it now shows in format-only runs too, as a warning.TypeErrorguards for a leftoverfontsoption oncomposeSlide/layoutXand a top-leveltextMeasurementonpaginate/paginateSlideare deleted, with their tests. Unknown options are not read. Risk: a sibling site that still passesfonts: { heading, body }tocomposeSlidedegrades silently to default families; each sibling PR has to carry a test that composition uses the resolved families.Presentationwhere the short name is taken by the slide type:PresentationPaginationOptions,PresentationPaginationResult,PresentationDiff,PresentationStats. Renamed types:MarkdownToOpf{Options,Result}toFromMarkdown{Options,Result},OpfToMarkdown{Options,Result}toToMarkdown{Options,Result},DataContentOptionstoImportDataOptions.documenttopresentationcovers result fields and options only (markdown result,applyPatchWithInverseresult,ConvertOptions). Not renamed: error codesinvalid-documentandpatch-invalid-document, Findingscope: "document", and parameter names of the generic JSON Pointer helpers.prepareNodeFonts, thedocumentkey offromPptx(..., { signals: true })) are unchanged here: the pinned peers (render 0.12.2, PPTX 0.12.4) still have them, and the CLI moves with the peer bump in the release-prep PR.lint(inopf import/opf render) renamed tocheck; A1's internal slide-rule type isRuleSlideand its modulerule-slides.ts, soSlideContextis only the publicresolveSlideContexttype.Part A1 (checker):
only,ignore,severityandignorePathstake full rule ids, bare names (text-contrast) or category names; an unknown name, option or threshold throws aTypeError, so a typo cannot silently disable a check. Old rule ids (audit/...,json/...) are not accepted.fromMarkdown/fromYaml). Invalid JSON text is an invalid document (exit 1,opf/json-syntax), no longer a usage error.assertValid(value, options?)takes a parsed presentation; a string is aTypeError.OPFValidationErrorcarries thereportand the errorfindings.overflow: "error"is a warning inopf/text-overflow, sovalidnever depends on font metrics; render and export still refuse such a slide.ValidateFonts.textMeasurementmay also be a function of the slide index (per-slide script-aware measurement).catalogs.<kind>.sourceare not judged unless the host passes that source's records (the lint report warned;validatePresentationdid not).checksalso states three fixed limits (backgroundPixels: "not-read",imageBytes: "embedded-only",nativeExport: "not-checked").font-family-count,slide-word-count,title-position,small-cell) and their thresholds are deleted;audit/invalid-documentis gone (a schema failure reports itsformatfindings withschemaValid: false).Part A3 (stats and context):
statsreads the JSON only (no layout, no fonts, no validation) and estimates speaking time from notes words at 130 wpm, labelledestimate;valuesandwordsPerMinuteare its options.resolveSlideContextnever throws for an unresolved layout, theme or font scheme (it returns a diagnostic and the documented fallback); it throws aRangeErrorfor an index outside the deck.slideOptionshook of pagination is removed (nothing used it)./compositionstays catalog-free;resolveSlideContextlives at the root because it loads catalogs.Cost
Measured by A1 on bundled decks with Node 24:
only: ['format']0.06 to 0.64 ms,['format', 'references']0.7 to 7.6 ms, everything 1.7 to 32 ms (6 to 10 slide decks: about 24 to 32 ms full, 0.2 to 0.6 ms format-only); the proposal's "about 11 ms" is not used anywhere. See the table indocs/validate.md.Test results
Local, Windows, Node 24.21, pnpm 10.33, on
0c488217, with the restacked siblings linked (render4cf2529, pptxd0dbfee, editor3f89734):pnpm build: ok.pnpm test: core 2065/2065, CLI 91/91, root checks 26/26 (includingcheck:spec,check:schema-docsand the gallery font checks).pnpm lint: 0 errors (557 warnings).typecheck: ok.check:breaking: exit 0 against 0.13.0.check:examples: 0 failures.test:skills: 6 skills, 17 helper checks.check:release-report: 8/8.test:cli:packed: 92 command checks.packages/javascript/test/packed-install-smoke.mjs: passes (the release plan's published 0.13 siblings are skipped, see the fold section).node scripts/test-package-ecosystem.mjs(every plan step, withOPF_GOLDEN_BASELINEset toscripts/fixtures/opf-examples-png.fa-0-14.sha256.json, the renderer's golden-override that CI adopts): exit 0. Render 86 tests and golden 807 slides / 127 decks, editor 60, pptx 105, font switch matrix 61/61,test:packed-ecosystem(local tarballs) andtest:cli:packedpass.node scripts/test-packed-ecosystem.mjs --registry: pass (all five release-plan versions).New tests: root exports (every CLI verb is a root function and the binding of its subpath, old names absent,
presentationresult fields),validateuses theresolveSlideContextfamilies and thefontsmeasurement (and builds no layout foronly: ['format']),opf/variable-unfilledis a format error for a deck (core and CLI:validate --only format,create,edit,paginate,fill) and a warning for a template.🤖 Generated with Claude Code
Note
High Risk
Breaking rename and removal across core, CLI, and docs with no migration aliases; hosts must adopt
validate,{ fonts },/compositionimports, and lockstep sibling releases.Overview
RR-55 (core 0.14.0) unifies validation, renames the public API to short verbs, and splits the package surface so app-level helpers stay on the root and layout/composition engines move to subpaths.
One checker:
validate(input, options?)replacesvalidatePresentation, alllint*/audit*entry points, andassertValidPresentation→assertValid. Reports use a sharedFindingshape (valid,findings,counts,schemaValid,checks) with stableopf/<rule>ids and six categories../lintand./auditare removed;docs/audit.mdis dropped in favor ofdocs/validate.mdanddocs/finding-schema-reference.md. CLI: onlyopf validate(opf lint/opf auditgone;--strict→--fail-on).Renames (no aliases):
paginatePresentation→paginate,bundlePresentation→bundle,formatPresentation→format,diff/merge,fromMarkdown/toMarkdown,importData, Excel format helperstoExcelNumberFormat/fromExcelNumberFormat, error typesOPF*Error, and result/optiondocument→presentation. README and docs sweep old names tovalidateand the new verbs.New APIs:
stats(presentation)/opf statsfor structural deck facts;resolveSlideContextcentralizes slide/theme/layout/font resolution for pagination and layout rules.ComposeSlideOptions.fonts→fontFamilies;paginate/paginateSlidetake{ fonts }(not top-leveltextMeasurement). ~235 composition symbols move from the root to@openpresentation/opf/composition(and symbol encodings to its subpath).YAML:
fromYamlreturns the deck plus the samevalidatereport; lint-yaml helpers removed. FA change notes are updated so audit/lint wording points atvalidateand new rule ids.Reviewed by Cursor Bugbot for commit 2c6c2eb. Configure here.