Skip to content

feat(pptx): add ShapeFragment safety system and validation engine#14

Merged
simongdavies merged 1 commit intohyperlight-dev:mainfrom
simongdavies:pptx-safety-spec
Mar 26, 2026
Merged

feat(pptx): add ShapeFragment safety system and validation engine#14
simongdavies merged 1 commit intohyperlight-dev:mainfrom
simongdavies:pptx-safety-spec

Conversation

@simongdavies
Copy link
Copy Markdown
Contributor

@simongdavies simongdavies commented Mar 26, 2026

Summary

Implements the PPTX Safety Spec — a comprehensive defence layer that prevents LLM-generated code from injecting raw XML into PowerPoint output.

Key Changes

ShapeFragment Branded Type System

  • All 22+ shape builders now return ShapeFragment (branded opaque type) instead of raw strings
  • addBody() validates ShapeFragment input — raw strings are rejected with a helpful error
  • _createShapeFragment() hidden from LLM discovery via underscore prefix
  • Internal callers use _addBodyRaw() for pre-validated XML

Validation Engine

  • NaN/Infinity detection — catches invalid numeric values in slide XML
  • Cross-slide duplicate shape ID check — warns on ID collisions across slides
  • Notes sanitisation — truncates to 4000 chars, strips XML tags at input stage
  • Relationship caps — enforces max relationships per slide

Chart Complexity Caps

  • 50 charts per deck, 24 series per chart, 100 categories per chart
  • Single source of truth for MAX constants in pptx-charts.ts

Test Coverage

  • 59 new safety tests in pptx-safety.test.ts:
    • All 24 shape builders verified to return ShapeFragment
    • addBody rejection tests (raw string, string array, fake object, real ShapeFragment)
    • Chart complexity cap enforcement
    • Notes sanitisation edge cases
    • Validation engine integration
    • Full deck regression tests

Documentation Updates

  • Module hint JSON files updated with ShapeFragment rules
  • skills/pptx-expert/SKILL.md updated with new API docs and anti-patterns

Quality Gate

  • just fmt — all code formatted
  • just lint — zero TypeScript errors
  • just test1742/1742 tests pass (31 files)

Copilot AI review requested due to automatic review settings March 26, 2026 19:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a PPTX “safety spec” layer across the builtin PPTX stack by moving slide composition from raw OOXML strings to a branded ShapeFragment type, adding pre-export validation, and updating docs/tests to match the new API expectations.

Changes:

  • Introduces branded ShapeFragment + fragmentsToXml() in ha:ooxml-core, and migrates PPTX/table/chart builders to return ShapeFragment.
  • Tightens slide composition by validating inputs in pres.addBody() / customSlide() and adding a buildZip() validation pass.
  • Adds/updates extensive Vitest coverage + updates module hints and the pptx-expert skill docs for the new rules.

Reviewed changes

Copilot reviewed 13 out of 15 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/pptx-validation.test.ts Updates assertions to handle ShapeFragment results via toXml() helper.
tests/pptx-safety.test.ts New safety-spec test suite covering fragment branding, addBody rejection, chart caps, notes sanitization, and validation integration.
tests/pptx-readability.test.ts Adjusts readability tests to stringify ShapeFragment outputs consistently.
tests/docgen-modules.test.ts Updates docgen tests to stringify ShapeFragment outputs for XML assertions.
skills/pptx-expert/SKILL.md Documents new ShapeFragment rules + anti-patterns (no +, no chart .toString()).
builtin-modules/src/types/ha-modules.d.ts Updates public typings to reflect ShapeFragment returns/inputs and chart cap constants.
builtin-modules/src/shared-state.ts Formatting-only change to stats() signature layout.
builtin-modules/src/pptx.ts Core migration to ShapeFragment, adds validation engine + notes sanitization, adjusts slide builders and composition APIs.
builtin-modules/src/pptx-tables.ts Tables now return ShapeFragment via _createShapeFragment().
builtin-modules/src/pptx-charts.ts Adds chart complexity caps; embedChart() returns { shape: ShapeFragment } and makes .toString() throw.
builtin-modules/src/ooxml-core.ts Adds ShapeFragment brand implementation (_createShapeFragment, isShapeFragment, fragmentsToXml).
builtin-modules/*.json Updates module hint metadata/hashes and safety guidance strings.

- Introduce ShapeFragment branded type to prevent raw XML injection
- addBody() now validates ShapeFragment, rejects raw strings
- Hide _createShapeFragment from LLM discovery (underscore prefix)
- Add validation engine: relationship caps, NaN/Infinity detection,
  cross-slide duplicate shape ID checks, notes sanitization
- Chart complexity caps: 50 charts/deck, 24 series, 100 categories
- Deduplicate MAX constants (single source in pptx-charts.ts)
- Update hints/prompts and SKILL.md with ShapeFragment API docs
- Add 59 safety tests covering all shape builders and edge cases

Signed-off-by: Simon Davies <simongdavies@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 15 changed files in this pull request and generated no new comments.

@simongdavies simongdavies merged commit 1e0e754 into hyperlight-dev:main Mar 26, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants