Appearance
Backlog Workflow
This workflow maintains the fork's backlog ledger, docs/backlog.yml. It is a project backlog: a record of work this fork intends to do and decisions it has made. It holds two kinds of entry:
- Downstream needs — generic PPTX behavior a downstream consumer needs that belongs in this package (
type: downstream-need,source: downstream). These are the primary, ongoing source of new work, and they are recorded anonymously: describe the missing PPTX behavior and its generic reproduction, never a private consumer's name, file paths, or content. - Retained upstream-derived signals — a set of gitbrent/PptxGenJS issues and PRs that were judged relevant to this fork before upstream tracking was retired. They carry a github reference (
owner/repo#N) insourceand remain as historical context and standing feature ideas.
Upstream tracking is retired. This fork no longer fetches upstream issues or reconciles the ledger against GitHub, and the
backlog:check:upstreamtooling has been removed. Do not re-add a sync step. New entries should be project needs (downstream-need); the github-sourced entries already in the file are kept as-is unless a local change closes one.
The source field still discriminates the two kinds, and the validator enforces it: github references for the retained legacy entries, the bare token downstream for downstream needs (never a consumer path — that would leak private structure).
Out-Of-Target Work
Do not use the backlog to reintroduce dropped package targets:
- CommonJS package support;
- IIFE or global browser bundles;
- direct CDN script-tag workflows;
- old generated artifact names under
dist/; - upstream release matrix or build-system compatibility work.
Source Of Truth
The decision ledger is backlog.yml. It records what has been dismissed, what is under consideration, and what should be implemented locally.
The ledger is intentionally metadata-first for the retained github entries: do not copy full upstream issue or PR bodies into this repository. For downstream-need items the full design rationale is welcome (see Downstream Needs below).
For the shape of an individual entry — every field, in write order, with realistic annotated values for both an implemented downstream-need and a retained github entry — see the reference backlog-item-template.yml. It is not validated and not part of the ledger; it exists so the structure survives the items: list being emptied. The authoritative field shape is still buildItemSkeleton in scripts/backlog-ledger.mjs (what pnpm run backlog -- add emits), and the legal values are the vocabulary: block in backlog.yml.
Review Inputs
Before classifying or promoting a candidate, read the local project boundaries:
When a candidate affects emitted OOXML, follow the OOXML workflow before making source changes. Use the ooxml MCP server for ECMA-376 structure and the microsoft_learn MCP server for Microsoft or PowerPoint-specific behavior.
Ledger Tooling
Use the local ledger command to inspect and maintain entries in docs/backlog.yml:
bash
pnpm run backlog -- list
pnpm run backlog -- list --status needs-repro --type downstream-need
pnpm run backlog -- show dn-some-slug other-slug
pnpm run backlog -- show --status non-target --json
pnpm run backlog -- values status
pnpm run backlog -- validateThe default list output is intentionally compact: item id, status, priority, current-project applicability, and summary. It is not the full record — to review rationale fields (non_target_reasons, current_project_notes, evidence, …) use one of the full-detail paths instead of hand-parsing the YAML:
list --jsonprints the complete items (lossless), not a compact projection, for any other tool or agent that needs structured output.showprints full items as readable text. It takes one or more ids (show a b c) or, with no id, every item matching the list filters (show --status non-target). Add--jsonfor the structured form.--print-limit 0makes a filteredlistprint every matching row.
Use values status to see which status values are currently used in the ledger and how many entries use each one.
The command also supports exact-ID maintenance operations:
bash
pnpm run backlog -- set-status dn-some-slug implemented
pnpm run backlog -- remove dn-some-slugMutation commands validate the ledger before writing and refuse ambiguous or duplicate ids. Use --dry-run to check the intended mutation without writing.
Classification
Classify each item with one status:
needs-repro: plausible, but no current-project reproduction exists yet.target: likely relevant to this fork; worth scoping.accepted: worth implementing or opening a local task for.interesting-with-tweaks: useful signal, but the original fix or framing does not fit this project as-is.non-target: dismissed because it conflicts with current goals.watch: incomplete signal; revisit only when new evidence appears.deferred: relevant, but intentionally not scheduled now.implemented: fixed locally with test or fixture evidence.partially-implemented: part of the work has landed; the remainder is tracked in the entry'snext_action.superseded: covered by another local fix or decision.
Use these priority values:
p0: corrupt or unopenable deck, PowerPoint repair prompt, data loss, invalid package relationship, or invalid content type.p1: Open XML validator failure, broken chart/table/media/shape serialization, or a high-value missing PPTX feature with a clear OOXML path.p2: feature request that maps cleanly to the current API and package target.p3: docs, examples, ergonomics, or compatibility polish.none: outside the current project target.
Target Areas
Use one or more target areas:
powerpoint-repairinvalid-ooxmlschema-orderrelationship-or-content-typechart-ooxmltable-ooxmlimage-svg-mediaspeaker-notes-masters-layoutsmissing-pptx-featuretypescript-apibrowser-modern-esmpackage-boundary
Use one or more non-target reasons when dismissing an item:
commonjsiife-globalcdn-script-taglegacy-dist-artifactunsupported-runtimeupstream-build-systemrelease-matrixdocs-only-for-legacy-workflowexisting-pptx-importnot-reproducible-in-current-projectinsufficient-evidenceout-of-project-scopeescape-hatch-footgun
Decision Questions
For each item, answer these in the ledger note:
- Is this about generated
.pptxcorrectness, current package behavior, or real feature coverage? - Does it still apply under the TS-first, ESM-only package shape?
- Is any proposed fix tied to legacy architecture this fork dropped?
- Can this checkout reproduce the behavior?
- Would a local fix live in
src/with focused tests intest/? - Does the item require OOXML schema lookup, Microsoft implementation docs, the validator, or a PowerPoint-authored comparison?
Evidence Requirements
Do not mark an item accepted without at least one current-project evidence path:
- a minimal PptxGenJS reproduction;
- generated
.pptxoutput; - extracted package XML path and observed problem;
pnpm run test:schemaresult or planned fixture;- PowerPoint repair/open result when available;
- Open XML SDK or Microsoft documentation reference when PowerPoint behavior is not obvious from schema alone.
For emitted OOXML changes, the implementation handoff should require a focused fixture in test/schema.test.js and pnpm run test:schema when practical.
Fixture-Gated Work: Ask For The Fixture, Don't Guess
When a feature can only be tested against OOXML that must be genuine PowerPoint output — a read-model accessor validated against real Office XML, or a write-side behaviour whose target XML is "what PowerPoint authors" (preset IDs, part wiring, namespaces, inheritance) — and that fixture/oracle does not yet exist, do not implement against synthetic, hand-typed, or write→read round-tripped XML. Guessing the target XML produces circular or wrong evidence.
Instead, record the fixture as the blocking precondition in the backlog and stop:
- If a backlog entry already gates the feature, set its
next_actionto authoring the fixture (e.g.await-reader-then-author-<construct>-fixture) and describe the exact construct the oracle must contain incurrent_project_notes. - If none exists, add a
downstream-needentry whosecurrent_project_notesstates the "do not implement without it" fixture dependency and what the oracle must capture, then leave the feature unimplemented until the fixture lands. - Tag the entry with the relevant
constructs:key(s) (see thevocabulary.constructslist inbacklog.yml, e.g.custom-geom,style-ref-color,group-rot-flip) so a downstream replication audit can join the detected construct to this gating entry.
Author the fixture itself with the powerpoint-fixture-authoring skill, verify it with scripts/verify-powerpoint-fixture.ps1, record provenance + SHA-256 in test/read/fixtures/README.md, then wire the test to the fixture (read harness for read accessors; a test/schema.test.js comparison/inspection check for write-side oracles). Only then implement and close the entry.
Reopening Dismissed Items
Reopen a non-target or superseded item only when one of these changes:
- the documented project target changes;
- a reproduction that applies to this checkout appears;
- a local bug proves the same root cause;
- PowerPoint or Open XML SDK behavior shows that the previous dismissal was too narrow.
Update last_reviewed, status, and current_project_notes when reopening.
Implementation Handoff
When a ledger item moves to accepted, create a local implementation task with:
- the source reference;
- local reproduction steps;
- expected generated package or XML behavior;
- relevant
src/andtest/files; - OOXML and Microsoft references, if applicable;
- verification commands to run.
Keep the fix local to the current package target.
Closing Implemented Items
After fixing an item, update backlog.yml in the same work session. Do not leave the entry at accepted, target, or needs-repro after the local fix has landed.
For each fixed item:
- set
statustoimplemented; - update
current_project_noteswith the local commit or fix summary; - add the source and test files to
evidence.local_files; - set
schema_fixtureandvalidator_resultwhen a schema fixture was added; - add relevant OOXML or Microsoft references used for the fix;
- set
next_actiontonone; - remove the downstream workaround the entry gated (tracked downstream by the in-code comment that references this entry's id, not by any field here).
Validate the ledger before finishing:
bash
pnpm run backlog -- validate
pnpm run backlog -- show <id>Downstream Needs
A downstream consumer of this package (not part of its source) is the main source of new backlog work. When a consumer task exposes a generic PPTX gap that belongs here — an OOXML serialization fix, an API/typing gap, a repeated layout primitive, media/SVG handling, post-processing that patches generated XML — record it as a downstream-need instead of leaving a one-off workaround undocumented.
Record it anonymously. This ledger is public; the consumer is not. Describe the missing PPTX behavior and how any consumer would reproduce it. Do NOT name the consumer project, quote its file paths, deck/client names, or content. Frame the rationale generically ("a consumer building an assessment grid needs …"), and let evidence.local_files point only at files in THIS repo.
A downstream need is something we already believe is valuable, so the full generic design rationale and any long-form analysis are welcome in current_project_notes.
Add one with the ledger CLI, then write the rationale into the file:
bash
pnpm run backlog -- add --id dn-<slug> --type downstream-need \
--source downstream \
--summary "<one generic line>" --priority p2add writes a valid skeleton (defaults: status: target, priority: p2, applies_to_current_project: yes, today's dates) and validates the result. Then edit the entry to add target_area, evidence, and the (generic) design essay under current_project_notes (a | block scalar).
There is no stopgap field: the temporary workaround lives downstream and is tracked there by an in-code comment referencing this entry's id, keeping the consumer's paths out of this public ledger. When the fix lands here, flip status to implemented and remove that downstream workaround.
id uses a dn-<slug> prefix.
Promotion Checklist (before moving a candidate into the fork)
- Prove the need with a minimal, consumer-agnostic reproduction.
- Reduce the behavior to a minimal PptxGenJS fixture.
- Add a PptxGenJS regression or schema test.
- Pack or link the fork into the downstream consumer to verify.
- Run the consumer's build/render/lint/eval path against the linked fork.
- Keep only generic code in PptxGenJS; keep project policy downstream.
Keep Downstream (not fork candidates)
These encode a specific consumer's brand, content, or deck workflow and stay downstream — do not raise them as backlog items:
- Brand guidance, workflow-specific scripts, and consumer content.
- A consumer's default font choice.
- Icon-set policy, imports, aliases, and provenance manifests.
- External stock-asset sourcing helpers.
- Lint quality thresholds, annotated screenshots, and human-review artifacts.
- Slide semantics manifests as agent-facing design-intent contracts.
- Greenfield deck eval prompts, scorecards, and generator-adapter behavior.
- LibreOffice/ImageMagick rendering orchestration for local visual QA.