@openpresentation/opf 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-X22DFHMW.js → chunk-3GPZMY2W.js} +2 -2
- package/dist/{chunk-NEQAPMS2.js → chunk-JA5W5TVA.js} +173 -14
- package/dist/{chunk-HIY26FJV.js → chunk-ZGV6I23P.js} +1 -1
- package/dist/composition.d.ts +68 -4
- package/dist/composition.js +1 -1
- package/dist/docs.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/pagination.js +3 -3
- package/dist/validator.js +2 -2
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { assertValidPresentation } from './chunk-
|
|
2
|
-
import { resolveFontFamilies, resolveCanvasDimensions, composeSlide, tableRowBoundaries } from './chunk-
|
|
1
|
+
import { assertValidPresentation } from './chunk-ZGV6I23P.js';
|
|
2
|
+
import { resolveFontFamilies, resolveCanvasDimensions, composeSlide, tableRowBoundaries } from './chunk-JA5W5TVA.js';
|
|
3
3
|
import { catalogs } from './chunk-TWMRZ43O.js';
|
|
4
4
|
|
|
5
5
|
// src/pagination.ts
|
|
@@ -226,6 +226,154 @@ function layoutQuote(value, box, options = {}) {
|
|
|
226
226
|
if (diagnostics.length && options.overflow === "error") throw new OPFCompositionError(diagnostics);
|
|
227
227
|
return { algorithm: "quote-flow-v1", textMeasurement: options.textMeasurement ? "provided" : "estimated", parts, diagnostics, overflow: diagnostics.length > 0 };
|
|
228
228
|
}
|
|
229
|
+
function fitCodeText(text, box, size, minimum, step, measure) {
|
|
230
|
+
const layout = (fontSize) => {
|
|
231
|
+
const tabWidth = measure(" ", fontSize) * 4;
|
|
232
|
+
if (!Number.isFinite(tabWidth) || text.includes(" ") && tabWidth <= 0) throw new RangeError("Code tabs require a positive finite measured space advance.");
|
|
233
|
+
const measureLine = (start2, end2, record3 = false) => {
|
|
234
|
+
let x = 0, offset = start2;
|
|
235
|
+
const segments = [];
|
|
236
|
+
for (const [index, segment] of text.slice(start2, end2).split(" ").entries()) {
|
|
237
|
+
if (index) {
|
|
238
|
+
const next = (Math.floor(x / tabWidth + 1e-9) + 1) * tabWidth;
|
|
239
|
+
if (record3) segments.push({ kind: "tab", start: offset, end: offset + 1, x, width: next - x });
|
|
240
|
+
x = next;
|
|
241
|
+
offset++;
|
|
242
|
+
}
|
|
243
|
+
if (segment) {
|
|
244
|
+
const advance = measure(segment, fontSize);
|
|
245
|
+
if (record3) segments.push({ kind: "text", start: offset, end: offset + segment.length, x, width: advance });
|
|
246
|
+
x += advance;
|
|
247
|
+
offset += segment.length;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return { width: x, segments };
|
|
251
|
+
};
|
|
252
|
+
const width = (start2, end2) => measureLine(start2, end2).width;
|
|
253
|
+
const sourceLines = [];
|
|
254
|
+
let start = 0, end = 0;
|
|
255
|
+
const push = (last, nextStart, boundary) => {
|
|
256
|
+
sourceLines.push({ start, end: last, nextStart, boundary, ...measureLine(start, last, true) });
|
|
257
|
+
start = nextStart;
|
|
258
|
+
end = nextStart;
|
|
259
|
+
};
|
|
260
|
+
for (const token of text.matchAll(/\r\n|\r|\n|[^\S\r\n]+|[^\s]+/gu)) {
|
|
261
|
+
if (token.index === void 0) throw new Error("Missing code token source offset.");
|
|
262
|
+
const a = token.index, b = a + token[0].length;
|
|
263
|
+
if (/^[\r\n]/.test(token[0])) {
|
|
264
|
+
push(a, b, "hard");
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
if (width(start, b) <= box.width + 0.01) {
|
|
268
|
+
end = b;
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
if (end > start && /\S/u.test(text.slice(start, end))) push(a, a, "soft");
|
|
272
|
+
if (width(start, b) <= box.width + 0.01) {
|
|
273
|
+
end = b;
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
for (const segment of textSegments.segment(token[0])) {
|
|
277
|
+
const next = a + segment.index + segment.segment.length;
|
|
278
|
+
if (end > start && width(start, next) > box.width + 0.01) push(a + segment.index, a + segment.index, "soft");
|
|
279
|
+
end = next;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
push(end, end, "end");
|
|
283
|
+
const lineHeight = fontSize * 1.22;
|
|
284
|
+
return {
|
|
285
|
+
lines: sourceLines.map((line) => text.slice(line.start, line.end)),
|
|
286
|
+
sourceLines,
|
|
287
|
+
fontSize,
|
|
288
|
+
lineHeight,
|
|
289
|
+
tabSize: 4,
|
|
290
|
+
tabWidth,
|
|
291
|
+
overflow: sourceLines.length * lineHeight > box.height + 0.01 || sourceLines.some((line) => line.width > box.width + 0.01)
|
|
292
|
+
};
|
|
293
|
+
};
|
|
294
|
+
let result = layout(size);
|
|
295
|
+
while (result.overflow && size > minimum) {
|
|
296
|
+
size = Math.max(minimum, size - step);
|
|
297
|
+
result = layout(size);
|
|
298
|
+
}
|
|
299
|
+
return result;
|
|
300
|
+
}
|
|
301
|
+
function layoutCode(value, box, options = {}) {
|
|
302
|
+
const shorthand = typeof value === "string", code = shorthand ? { source: value } : value;
|
|
303
|
+
if (!code || Array.isArray(code) || typeof code.source !== "string" || [code.language, code.filename].some((field) => field !== void 0 && typeof field !== "string")) {
|
|
304
|
+
throw new TypeError("Code content must be a string or source object with optional string language/filename.");
|
|
305
|
+
}
|
|
306
|
+
const scale = options.scale ?? 1, minimum = (options.minFontSize ?? 16) * scale;
|
|
307
|
+
if (![box.x, box.y, box.width, box.height, box.x + box.width, box.y + box.height, scale, minimum, Math.max(18 * scale, minimum) * 1.22].every(Number.isFinite) || box.width <= 0 || box.height <= 0 || scale <= 0 || minimum <= 0) {
|
|
308
|
+
throw new RangeError("Code dimensions, scale and minimum font size must be finite and positive.");
|
|
309
|
+
}
|
|
310
|
+
if (options.overflow !== void 0 && !["warn", "error"].includes(options.overflow)) throw new RangeError("Invalid code overflow policy.");
|
|
311
|
+
const path = options.path ?? "code", inner = { x: box.x + 18, y: box.y + 18, width: box.width - 36, height: box.height - 36 };
|
|
312
|
+
const parts = [], diagnostics = [];
|
|
313
|
+
const add = (role, text, partPath, generated = false) => {
|
|
314
|
+
const requestedStyle = { fontFamily: options.fonts?.code ?? "monospace", fontWeight: role === "body" ? 400 : 700, italic: false, path: partPath };
|
|
315
|
+
const part = {
|
|
316
|
+
role,
|
|
317
|
+
path: partPath,
|
|
318
|
+
text,
|
|
319
|
+
sources: generated ? [] : [{ path: partPath, start: 0, end: text.length }],
|
|
320
|
+
generated,
|
|
321
|
+
box: { ...inner },
|
|
322
|
+
requestedFontSize: Math.max((role === "body" ? 18 : 14) * scale, minimum),
|
|
323
|
+
minFontSize: minimum,
|
|
324
|
+
requestedStyle,
|
|
325
|
+
style: resolveTextStyle({ ...requestedStyle }, options.textMeasurement)
|
|
326
|
+
};
|
|
327
|
+
parts.push(part);
|
|
328
|
+
return part;
|
|
329
|
+
};
|
|
330
|
+
if (code.filename) add("filename", code.filename, `${path}.filename`);
|
|
331
|
+
if (code.language) add("language", code.language, `${path}.language`);
|
|
332
|
+
if (!parts.length) add("language", "code", path, true);
|
|
333
|
+
const body = add("body", code.source, shorthand ? path : `${path}.source`), headers = parts.filter((part) => part !== body);
|
|
334
|
+
const usable = (area) => [area.x, area.y, area.width, area.height].every(Number.isFinite) && area.width > 0 && area.height > 0;
|
|
335
|
+
const fit = (part, area, size = part.requestedFontSize, floor = minimum) => usable(area) ? fitCodeText(part.text, area, size, floor, scale, textWidthMeasurer(part.style, options.textMeasurement)) : void 0;
|
|
336
|
+
if (usable(inner)) {
|
|
337
|
+
const combinations = headers.reduce((choices, part) => choices.flatMap((choice) => [.../* @__PURE__ */ new Set([part.requestedFontSize, minimum])].map((size) => [...choice, { part, size }])), [[]]);
|
|
338
|
+
let selected;
|
|
339
|
+
for (const combination of combinations) {
|
|
340
|
+
let y = inner.y;
|
|
341
|
+
const allocations = [];
|
|
342
|
+
for (const [index, { part, size }] of combination.entries()) {
|
|
343
|
+
const measured = fitCodeText(part.text, inner, size, size, scale, textWidthMeasurer(part.style, options.textMeasurement));
|
|
344
|
+
const area2 = { ...inner, y, height: measured.lines.length * measured.lineHeight };
|
|
345
|
+
allocations.push({ part, box: area2, fit: usable(area2) ? { ...measured, overflow: measured.sourceLines.some((line) => line.width > area2.width + 0.01) } : void 0 });
|
|
346
|
+
y += area2.height + (index < headers.length - 1 ? 8 : 12);
|
|
347
|
+
}
|
|
348
|
+
const area = { ...inner, y, height: inner.y + inner.height - y };
|
|
349
|
+
allocations.push({ part: body, box: area, fit: fit(body, area) });
|
|
350
|
+
const overflow = allocations.some(({ box: box2, fit: fit2 }) => !fit2 || fit2.overflow || !usable(box2) || box2.y + box2.height > inner.y + inner.height + 0.01);
|
|
351
|
+
const score = allocations.reduce((sum, { part, fit: fit2 }) => sum + (part.requestedFontSize - (fit2?.fontSize ?? minimum)) / scale, 0);
|
|
352
|
+
if (!selected || !overflow && (selected.overflow || score < selected.score) || overflow && selected.overflow) selected = { allocations, score, overflow };
|
|
353
|
+
}
|
|
354
|
+
if (selected) for (const { part, box: box2, fit: fit2 } of selected.allocations) {
|
|
355
|
+
part.box = box2;
|
|
356
|
+
part.fit = fit2;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
const report = (reason, part, roles, message) => diagnostics.push({ code: "text-overflow", reason, path: part.path, parts: roles, message });
|
|
360
|
+
for (const part of parts) {
|
|
361
|
+
if (!part.fit) report("invalid-part-box", part, [part.role], `Code ${part.role} has no usable space after metadata and insets; increase the cell or change the arrangement.`);
|
|
362
|
+
else if (part.fit.overflow) report("text-fit", part, [part.role], `Code ${part.role} exceeds its space at the readability floor; increase its space or change the arrangement.`);
|
|
363
|
+
const area = part.box;
|
|
364
|
+
if (usable(area) && (area.x < box.x || area.y < box.y || area.x + area.width > box.x + box.width + 0.01 || area.y + area.height > box.y + box.height + 0.01)) {
|
|
365
|
+
report("part-outside-cell", part, [part.role], `Code ${part.role} extends outside its cell; increase the cell or change the arrangement.`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
for (const [index, first] of parts.entries()) {
|
|
369
|
+
const second = parts[index + 1];
|
|
370
|
+
if (first.fit && second?.fit && first.box.y + first.fit.lines.length * first.fit.lineHeight > second.box.y + 0.01) {
|
|
371
|
+
report("part-overlap", first, [first.role, second.role], "Code part line boxes overlap; do not accept this layout without more space.");
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
if (diagnostics.length && options.overflow === "error") throw new OPFCompositionError(diagnostics);
|
|
375
|
+
return { algorithm: "code-flow-v1", textMeasurement: options.textMeasurement ? "provided" : "estimated", parts, diagnostics, overflow: diagnostics.length > 0 };
|
|
376
|
+
}
|
|
229
377
|
function fitRichText(input, box, requestedSize = 25, minFontSize = 16, options = { style: { fontFamily: "sans-serif", fontWeight: 400 } }) {
|
|
230
378
|
if (![box.width, box.height, requestedSize, minFontSize].every((value) => Number.isFinite(value) && value > 0)) throw new RangeError("Rich text dimensions and font sizes must be finite and positive.");
|
|
231
379
|
const layout = richTextLayouter(input, box, requestedSize, options), minimum = Math.min(requestedSize, minFontSize);
|
|
@@ -559,8 +707,15 @@ function composeSlide(input, options = {}) {
|
|
|
559
707
|
const amount = (settings.padding ?? 0) * Math.min(box.width, box.height);
|
|
560
708
|
return { x: box.x + amount, y: box.y + amount, width: box.width - amount * 2, height: box.height - amount * 2 };
|
|
561
709
|
};
|
|
562
|
-
const
|
|
563
|
-
const measureQuote = (node, box, settings) => layoutQuote(node.value,
|
|
710
|
+
const acceptedBox = (box) => ({ x: round(box.x), y: round(box.y), width: round(box.width), height: round(box.height) });
|
|
711
|
+
const measureQuote = (node, box, settings) => layoutQuote(node.value, acceptedBox(box), {
|
|
712
|
+
fonts: options.fonts,
|
|
713
|
+
textMeasurement: options.textMeasurement,
|
|
714
|
+
scale,
|
|
715
|
+
minFontSize: settings.minFontSize,
|
|
716
|
+
path: node.path
|
|
717
|
+
});
|
|
718
|
+
const measureCode = (node, box, settings) => layoutCode(node.value, acceptedBox(box), {
|
|
564
719
|
fonts: options.fonts,
|
|
565
720
|
textMeasurement: options.textMeasurement,
|
|
566
721
|
scale,
|
|
@@ -571,13 +726,13 @@ function composeSlide(input, options = {}) {
|
|
|
571
726
|
const text = contentText(node.field, node.value);
|
|
572
727
|
let score = Math.abs(Math.log(box.width / box.height / 1.6));
|
|
573
728
|
if (penalties) penalties.cellProportions += score;
|
|
574
|
-
if (node.field === "quote") {
|
|
575
|
-
const
|
|
576
|
-
const reduction =
|
|
577
|
-
score += reduction + (
|
|
729
|
+
if (node.field === "quote" || node.field === "code") {
|
|
730
|
+
const internal = node.field === "quote" ? measureQuote(node, box, settings) : measureCode(node, box, settings);
|
|
731
|
+
const reduction = internal.parts.reduce((sum, part) => sum + (part.fit ? (part.requestedFontSize - part.fit.fontSize) / scale : 0), 0);
|
|
732
|
+
score += reduction + (internal.overflow ? 1e3 : 0);
|
|
578
733
|
if (penalties) {
|
|
579
734
|
penalties.fontReduction += reduction;
|
|
580
|
-
penalties.textOverflow +=
|
|
735
|
+
penalties.textOverflow += internal.overflow ? 1e3 : 0;
|
|
581
736
|
}
|
|
582
737
|
} else if (text) {
|
|
583
738
|
const fit = fitContent(node.field, node.value, text, box, 25 * scale, (settings.minFontSize ?? 16) * scale, node.path);
|
|
@@ -651,18 +806,21 @@ function composeSlide(input, options = {}) {
|
|
|
651
806
|
} else {
|
|
652
807
|
const textValue = contentText(node.field, node.value);
|
|
653
808
|
const quoteLayout = node.field === "quote" ? measureQuote(node, box, settings) : void 0;
|
|
654
|
-
const
|
|
809
|
+
const codeLayout = node.field === "code" ? measureCode(node, box, settings) : void 0;
|
|
810
|
+
const internal = quoteLayout ?? codeLayout, body = internal?.parts.find((part) => part.role === "body");
|
|
811
|
+
const text = internal ? body?.fit : textValue !== void 0 ? fitContent(node.field, node.value, textValue, box, 25 * scale, (settings.minFontSize ?? 16) * scale, node.path) : void 0;
|
|
655
812
|
items.push({
|
|
656
813
|
path: node.path,
|
|
657
814
|
field: node.field,
|
|
658
815
|
type: node.type,
|
|
659
816
|
value: node.value,
|
|
660
817
|
payload: node.payload,
|
|
661
|
-
box:
|
|
818
|
+
box: internal ? acceptedBox(box) : box,
|
|
662
819
|
text,
|
|
663
|
-
textStyle:
|
|
820
|
+
textStyle: body?.style ?? styleFor(node.field, node.path),
|
|
664
821
|
composition: settings,
|
|
665
|
-
...quoteLayout ? { quoteLayout } : {}
|
|
822
|
+
...quoteLayout ? { quoteLayout } : {},
|
|
823
|
+
...codeLayout ? { codeLayout } : {}
|
|
666
824
|
});
|
|
667
825
|
if (box.width < 100 * scale || box.height < 60 * scale) diagnostics.push({ code: "small-cell", path: node.path, message: "Content cell is too small for comfortable reading; use fewer blocks or a different composition." });
|
|
668
826
|
}
|
|
@@ -675,6 +833,7 @@ function composeSlide(input, options = {}) {
|
|
|
675
833
|
for (const key of ["x", "y", "width", "height"]) item.box[key] = round(item.box[key]);
|
|
676
834
|
if (item.field === "table" && tableOverflows(item.value, item.box, scale, item.composition, options, item.path)) diagnostics.push({ code: "text-overflow", path: item.path, message: "Table cells do not fit; use fewer rows, fewer columns, or split the table across slides." });
|
|
677
835
|
if (item.quoteLayout) diagnostics.push(...item.quoteLayout.diagnostics);
|
|
836
|
+
else if (item.codeLayout) diagnostics.push(...item.codeLayout.diagnostics);
|
|
678
837
|
else if (item.text?.overflow) diagnostics.push({ code: "text-overflow", path: item.path, message: "Text exceeds its cell at the minimum font size; shorten it, increase its space, or split the slide." });
|
|
679
838
|
}
|
|
680
839
|
for (const group of groups) for (const box of [group.box, group.contentBox]) for (const key of ["x", "y", "width", "height"]) box[key] = round(box[key]);
|
|
@@ -690,10 +849,10 @@ function composeSlide(input, options = {}) {
|
|
|
690
849
|
return false;
|
|
691
850
|
});
|
|
692
851
|
const explanation = decisions ? {
|
|
693
|
-
algorithm: "grid-score-
|
|
852
|
+
algorithm: "grid-score-v3",
|
|
694
853
|
textMeasurement: options.textMeasurement ? "provided" : "estimated",
|
|
695
854
|
decisions,
|
|
696
|
-
unmeasuredPayloads: items.filter((item) => !headings.has(item.field) && !item.quoteLayout && !["text", "items", "bullets", "table"].includes(item.field)).map((item) => item.path)
|
|
855
|
+
unmeasuredPayloads: items.filter((item) => !headings.has(item.field) && !item.quoteLayout && !item.codeLayout && !["text", "items", "bullets", "table"].includes(item.field)).map((item) => item.path)
|
|
697
856
|
} : void 0;
|
|
698
857
|
if (failures.length) throw new OPFCompositionError(failures, explanation);
|
|
699
858
|
return { width, height, contentBox, items, groups, flows, diagnostics, composition, ...explanation ? { explanation } : {} };
|
|
@@ -716,4 +875,4 @@ function resolveCanvasDimensions(input) {
|
|
|
716
875
|
return { width, height };
|
|
717
876
|
}
|
|
718
877
|
|
|
719
|
-
export { MAX_COMPOSITION_DEPTH, OPFCompositionError, composeSlide, fitList, fitRichText, fitText, layoutQuote, layoutTable, measureText, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, tableGrid, tableRowBoundaries, textWidthMeasurer, wrapText };
|
|
878
|
+
export { MAX_COMPOSITION_DEPTH, OPFCompositionError, composeSlide, fitList, fitRichText, fitText, layoutCode, layoutQuote, layoutTable, measureText, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, tableGrid, tableRowBoundaries, textWidthMeasurer, wrapText };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MAX_COMPOSITION_DEPTH, tableGrid } from './chunk-
|
|
1
|
+
import { MAX_COMPOSITION_DEPTH, tableGrid } from './chunk-JA5W5TVA.js';
|
|
2
2
|
import { schemas } from './chunk-GQSK3T7X.js';
|
|
3
3
|
import { catalogSchemaNames } from './chunk-TWMRZ43O.js';
|
|
4
4
|
import Ajv2020 from 'ajv/dist/2020.js';
|
package/dist/composition.d.ts
CHANGED
|
@@ -95,10 +95,12 @@ interface ComposedItem {
|
|
|
95
95
|
value: unknown;
|
|
96
96
|
payload: Record<string, unknown>;
|
|
97
97
|
box: LayoutBox;
|
|
98
|
-
text?: TextFit | RichTextFit | ListFit;
|
|
98
|
+
text?: TextFit | RichTextFit | ListFit | CodeTextFit;
|
|
99
99
|
textStyle?: TextStyle;
|
|
100
100
|
/** Complete accepted quote internals; consumers must reuse these fits and styles. */
|
|
101
101
|
quoteLayout?: QuoteLayout;
|
|
102
|
+
/** Complete accepted code internals, including source lines and literal tab positions. */
|
|
103
|
+
codeLayout?: CodeLayout;
|
|
102
104
|
/** Effective container settings, including inherited readability constraints. */
|
|
103
105
|
composition: Composition;
|
|
104
106
|
}
|
|
@@ -123,7 +125,7 @@ interface ComposedFlow {
|
|
|
123
125
|
itemCount: number;
|
|
124
126
|
slotCount: number;
|
|
125
127
|
}
|
|
126
|
-
/** Additive penalties in grid-score-
|
|
128
|
+
/** Additive penalties in grid-score-v3; lower is preferred. These are not quality percentages. */
|
|
127
129
|
interface CompositionPenalties {
|
|
128
130
|
cellProportions: number;
|
|
129
131
|
fontReduction: number;
|
|
@@ -147,7 +149,7 @@ interface CompositionDecision {
|
|
|
147
149
|
candidates: CompositionCandidate[];
|
|
148
150
|
}
|
|
149
151
|
interface CompositionExplanation {
|
|
150
|
-
algorithm: 'grid-score-
|
|
152
|
+
algorithm: 'grid-score-v3';
|
|
151
153
|
/** Provided widths do not establish shaping, glyph coverage or native fidelity. */
|
|
152
154
|
textMeasurement: 'estimated' | 'provided';
|
|
153
155
|
decisions: CompositionDecision[];
|
|
@@ -238,6 +240,68 @@ interface QuoteLayoutOptions {
|
|
|
238
240
|
* check overflow before accepting the parts. Line boxes are not shaped glyph or native raster bounds.
|
|
239
241
|
*/
|
|
240
242
|
declare function layoutQuote(value: string | QuoteContent, box: LayoutBox, options?: QuoteLayoutOptions): QuoteLayout;
|
|
243
|
+
interface CodeContent {
|
|
244
|
+
source: string;
|
|
245
|
+
language?: string;
|
|
246
|
+
filename?: string;
|
|
247
|
+
}
|
|
248
|
+
interface CodeLineSegment {
|
|
249
|
+
kind: 'text' | 'tab';
|
|
250
|
+
start: number;
|
|
251
|
+
end: number;
|
|
252
|
+
/** Measured position relative to this displayed line's origin, in reference pixels. */
|
|
253
|
+
x: number;
|
|
254
|
+
width: number;
|
|
255
|
+
}
|
|
256
|
+
/** Exact half-open UTF-16 offsets into the part text, including consumed hard line breaks. */
|
|
257
|
+
interface CodeLineSource {
|
|
258
|
+
start: number;
|
|
259
|
+
end: number;
|
|
260
|
+
nextStart: number;
|
|
261
|
+
boundary: 'soft' | 'hard' | 'end';
|
|
262
|
+
width: number;
|
|
263
|
+
/** Explicit tab placement is required in SVG; CSS tab-size alone does not implement it. */
|
|
264
|
+
segments: CodeLineSegment[];
|
|
265
|
+
}
|
|
266
|
+
interface CodeTextFit extends TextFit {
|
|
267
|
+
sourceLines: CodeLineSource[];
|
|
268
|
+
/** Tabs advance to the next multiple of four measured spaces from each displayed line's origin. */
|
|
269
|
+
tabSize: 4;
|
|
270
|
+
tabWidth: number;
|
|
271
|
+
}
|
|
272
|
+
interface CodeTextPart {
|
|
273
|
+
role: 'filename' | 'language' | 'body';
|
|
274
|
+
path: string;
|
|
275
|
+
/** Original text, without case conversion, whitespace normalization or discarded newlines. */
|
|
276
|
+
text: string;
|
|
277
|
+
sources: {
|
|
278
|
+
path: string;
|
|
279
|
+
start: number;
|
|
280
|
+
end: number;
|
|
281
|
+
}[];
|
|
282
|
+
generated: boolean;
|
|
283
|
+
box: LayoutBox;
|
|
284
|
+
requestedFontSize: number;
|
|
285
|
+
minFontSize: number;
|
|
286
|
+
requestedStyle: TextStyle;
|
|
287
|
+
style: TextStyle;
|
|
288
|
+
fit?: CodeTextFit;
|
|
289
|
+
}
|
|
290
|
+
interface CodeLayoutDiagnostic extends LayoutDiagnostic {
|
|
291
|
+
reason: 'invalid-part-box' | 'part-outside-cell' | 'text-fit' | 'part-overlap';
|
|
292
|
+
parts: CodeTextPart['role'][];
|
|
293
|
+
}
|
|
294
|
+
interface CodeLayout {
|
|
295
|
+
algorithm: 'code-flow-v1';
|
|
296
|
+
textMeasurement: 'estimated' | 'provided';
|
|
297
|
+
parts: CodeTextPart[];
|
|
298
|
+
diagnostics: CodeLayoutDiagnostic[];
|
|
299
|
+
overflow: boolean;
|
|
300
|
+
}
|
|
301
|
+
interface CodeLayoutOptions extends QuoteLayoutOptions {
|
|
302
|
+
}
|
|
303
|
+
/** Shared filename/language/body allocation. Consumers must reuse the accepted fits and styles. */
|
|
304
|
+
declare function layoutCode(value: string | CodeContent, box: LayoutBox, options?: CodeLayoutOptions): CodeLayout;
|
|
241
305
|
interface RichTextRun {
|
|
242
306
|
text: string;
|
|
243
307
|
bold?: boolean;
|
|
@@ -362,4 +426,4 @@ declare function resolveCanvasDimensions(input: unknown): {
|
|
|
362
426
|
height: number;
|
|
363
427
|
};
|
|
364
428
|
|
|
365
|
-
export { type ComposeSlideOptions, type ComposedFlow, type ComposedGroup, type ComposedItem, type Composition, type CompositionCandidate, type CompositionDecision, type CompositionExplanation, type CompositionPenalties, type CompositionTrack, type FontFamilies, type LayoutBox, type LayoutDiagnostic, type ListEntryLayout, type ListFit, type ListText, type ListValue, MAX_COMPOSITION_DEPTH, type MeasureTextWidth, OPFCompositionError, type QuoteContent, type QuoteLayout, type QuoteLayoutDiagnostic, type QuoteLayoutOptions, type QuoteTextPart, type QuoteTextSource, type RichTextFit, type RichTextFragment, type RichTextLine, type RichTextOptions, type RichTextRun, type SlideComposition, type TableBorder, type TableCellLayout, type TableCellStyle, type TableGrid, type TableGridCell, type TableGridIssue, type TableLayout, type TableLayoutOptions, type TableRowLayout, type TextFit, type TextMeasurement, type TextStyle, composeSlide, fitList, fitRichText, fitText, layoutQuote, layoutTable, measureText, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, tableGrid, tableRowBoundaries, textWidthMeasurer, wrapText };
|
|
429
|
+
export { type CodeContent, type CodeLayout, type CodeLayoutDiagnostic, type CodeLayoutOptions, type CodeLineSegment, type CodeLineSource, type CodeTextFit, type CodeTextPart, type ComposeSlideOptions, type ComposedFlow, type ComposedGroup, type ComposedItem, type Composition, type CompositionCandidate, type CompositionDecision, type CompositionExplanation, type CompositionPenalties, type CompositionTrack, type FontFamilies, type LayoutBox, type LayoutDiagnostic, type ListEntryLayout, type ListFit, type ListText, type ListValue, MAX_COMPOSITION_DEPTH, type MeasureTextWidth, OPFCompositionError, type QuoteContent, type QuoteLayout, type QuoteLayoutDiagnostic, type QuoteLayoutOptions, type QuoteTextPart, type QuoteTextSource, type RichTextFit, type RichTextFragment, type RichTextLine, type RichTextOptions, type RichTextRun, type SlideComposition, type TableBorder, type TableCellLayout, type TableCellStyle, type TableGrid, type TableGridCell, type TableGridIssue, type TableLayout, type TableLayoutOptions, type TableRowLayout, type TextFit, type TextMeasurement, type TextStyle, composeSlide, fitList, fitRichText, fitText, layoutCode, layoutQuote, layoutTable, measureText, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, tableGrid, tableRowBoundaries, textWidthMeasurer, wrapText };
|
package/dist/composition.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { MAX_COMPOSITION_DEPTH, OPFCompositionError, composeSlide, fitList, fitRichText, fitText, layoutQuote, layoutTable, measureText, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, tableGrid, tableRowBoundaries, textWidthMeasurer, wrapText } from './chunk-
|
|
1
|
+
export { MAX_COMPOSITION_DEPTH, OPFCompositionError, composeSlide, fitList, fitRichText, fitText, layoutCode, layoutQuote, layoutTable, measureText, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, tableGrid, tableRowBoundaries, textWidthMeasurer, wrapText } from './chunk-JA5W5TVA.js';
|
package/dist/docs.js
CHANGED
|
@@ -40,7 +40,7 @@ var docsData = Object.freeze([
|
|
|
40
40
|
"slug": "dynamic-composition",
|
|
41
41
|
"file": "docs/dynamic-composition.md",
|
|
42
42
|
"title": "Dynamic composition",
|
|
43
|
-
"markdown": '# Dynamic composition\n\nOPF keeps authoring intent in JSON. Use `blocks` when content can reflow; use promoted regions when relative placement is meaningful. `composition` on a slide overrides fields in the resolved layout\'s `composition`. Existing documents remain valid.\n\n```json\n{\n "name": "Decision brief",\n "slides": [{\n "title": "Make the main idea clear",\n "composition": { "mode": "row", "weights": [2, 1], "overflow": "error" },\n "blocks": [\n { "text": "The evidence and recommendation receive twice the width." },\n { "text": "The supporting detail receives the remaining width." }\n ]\n }]\n}\n```\n\n`auto` evaluates candidate grids using text fit and cell proportions. `columns` limits its candidates. `grid` uses `columns` if given, otherwise a grid based on the canvas shape. `row` uses one row; `column` uses one column. Items retain source order. Weights size columns except in column mode, where they size rows. Missing weights are 1; unused weights have no effect. A partially filled final row retains its grid tracks.\n\n`gap` defaults to 1/30 and `padding` to 0.08, both fractions of the canvas\'s shorter edge. Large gaps are reduced when necessary to keep cells positive. `minFontSize` defaults to 16 reference pixels at a 720-pixel short edge. The reference coordinate system uses 96 pixels per inch. Explicit inch dimensions override presets independently for each axis.\n\nHeadings reserve space according to their wrapped text. Content that exceeds the number of preset placeholders reflows together; it is not drawn over already-bound content. Promoted regions keep the 3\xD73 vocabulary, including standalone `top`, `middle`, and `bottom`. They ignore flow direction and track weights.\n\n## Nested groups\n\nA block or promoted region can contain its own `blocks` and `composition`. The optional discriminator is `"type": "group"`. A group has at least one child and cannot mix children with leaf fields such as `text` or `image`.\n\n```json\n{\n "composition": { "mode": "row", "weights": [2, 1] },\n "blocks": [\n {\n "composition": { "mode": "column", "padding": 0.02 },\n "blocks": [{ "text": "Recommendation" }, { "text": "Supporting evidence" }]\n },\n { "text": "Context" }\n ]\n}\n```\n\nThe parent allocates a box to each group, then the group arranges its children inside that box. Group padding defaults to zero; padding and gap use the group\'s shorter edge. Only `minFontSize` and `overflow` inherit. A strict ancestor cannot be weakened by a child\'s `overflow: "warn"`. Font sizes remain relative to the canvas, not the group. Groups can nest up to 32 levels; cycles and deeper nesting fail with an explicit error.\n\nAutomatic grid scoring inspects descendant text using each descendant\'s explicit arrangement or geometric automatic seed. After selecting the parent\'s grid, it optimizes each child\'s automatic grid. This deterministic, bounded search avoids exponential combinations; it does not claim a globally optimal packing.\n\n`result.items` contains every leaf with its full source path and effective composition. `result.groups` contains group paths, outer bounds, and content bounds. The editor\'s `setGroupComposition(path, value)` validates and records undo/redo just like slide composition edits.\n\n## Inspecting and repairing layout\n\n```js\nimport { composeSlide } from \'@openpresentation/opf/composition\';\nconst result = composeSlide(deck.slides[0], { width: 1280, height: 720, layout: resolvedLayout });\nconsole.log(result.items); // Source paths, content, geometry, and text estimates\nconsole.log(result.diagnostics); // Path-specific text-overflow and small-cell messages\n```\n\nThis pure function expects a validated slide. The caller resolves catalog records and passes the canvas size. The rendering and export packages perform those steps at their boundaries. No network, DOM, system font, or AI dependency is required.\n\n### Explain automatic selection (next core release)\n\nPass `explain: true` to return `result.explanation`. This opt-in API requires core 0.8.0; it is absent from core 0.7.0. Enabling explanations adds no measurement calls and does not change geometry, source content, reading order, weights or selected arrangements within the same engine version.\n\n```js\nconst result = composeSlide(slide, {...resolvedOptions, explain: true});\nfor (const decision of result.explanation.decisions) {\n console.log(decision.path, decision.reason, decision.selectedColumns);\n console.table(decision.candidates);\n}\nconsole.log(result.explanation.textMeasurement);\nconsole.log(result.explanation.unmeasuredPayloads);\n```\n\n`resolvedOptions` supplies the same dimensions, layout, fonts and optional width provider as the preview. The versioned `grid-score-v2` explanation records each container in parent-before-child order. `lowest-score` reports the candidates actually tried; `configured-mode` respects resolved row/column/grid intent and returns no invented candidates. `promoted-regions` leaves region placement fixed and has no selected column count. Empty slides have no decisions. Automatic search tries one through `min(slotCount, columns ?? 6)` columns, in ascending order; ties retain the first candidate. Reserved placeholders count as slots. The schema caps an explicit candidate limit at twelve columns.\n\nEach candidate has `columns`, `rows`, `score` and additive `penalties`:\n\n| Penalty | Rule |\n| --- | --- |\n| `cellProportions` | Sum of `abs(log(cellAspect / 1.6))` for descendant leaves |\n| `fontReduction` | Reduction from 25 reference pixels for text-like leaves; quotes sum requested-minus-fitted sizes for both parts, divided by canvas scale |\n| `textOverflow` | 1,000 per overflowing text-like leaf or complete quote, regardless of the number of quote failure reasons |\n| `tableOverflow` | 1,000 per table whose shared cell layout overflows |\n| `smallCells` | 100 per leaf narrower than 100 or shorter than 60 reference pixels |\n| `emptySlots` | 2 per unused position in the candidate grid\'s final row |\n\nScores are preference costs, not quality percentages or guarantees. Floating-point summation can make the component total differ slightly from `score`. Parent scoring uses descendant explicit arrangements or geometric automatic seeds; child automatic grids are optimized only after selecting the parent. Candidate scores therefore describe the bounded search, not a full assessment of the final optimized subtree. Heading fit remains in ordinary diagnostics, outside body-grid scoring. A strict-fit rejection exposes the explanation on `OPFCompositionError` when requested.\n\n`textMeasurement` is `estimated` without a provider and `provided` with one. A provided width function does not establish font provenance, glyph coverage, shaping or native raster fidelity. Text, rich text, lists, quotes and table cells participate in the current fit model. `unmeasuredPayloads` identifies images, video, charts, metrics, timelines and code whose complete internal layout is not assessed. Both quote parts use shared geometry; code source is scored but its language label and insets remain incomplete. Media aspect ratios, chart labels, metric labels and timeline annotations remain gaps. A zero score or empty diagnostics is not proof that those payloads fit.\n\nThis milestone exposes the existing search for inspection. Guarded layout repairs, automatic weight allocation, content-aware candidate improvements, a common payload-internal measurement model, CLI explanations and a canvas **Auto arrange** preview/undo operation remain subsequent work. It does not silently paginate or rewrite a document.\n\nWith `overflow: "warn"` (default), the result retains all text and returns diagnostics. SVG emits all lines and marks overflowing groups with `data-opf-overflow="true"`; text may extend beyond its box or canvas. Consumers can collect diagnostics using `onDiagnostic`. With `overflow: "error"`, the layout rejects content that does not fit. Shorten the affected content, give it more space, or explicitly split it into another slide. Use the explicit pagination transform below to produce additional editable slides.\n\nThe editor exposes `editor.composeSlide(index)` and `editor.setComposition(index, value)`. The latter validates the change, records JSON Patch history, and supports undo/redo.\n\n## Pagination\n\n```js\nimport { paginateSlide, paginatePresentation } from \'@openpresentation/opf/pagination\';\nconst { presentation, pages } = paginatePresentation(deck);\n// Review, save, render, or export `presentation`; pages maps output fragments to source paths.\nconst single = paginateSlide(deck.slides[0], { width: 1280, height: 720, minFontSize: 24 });\n```\n\nPagination is an authoring operation. It produces ordinary OPF slides; previews and PPTX export consume those exact pages. It preserves the input, body order, nested groups, promoted regions, rich-text formatting, and source text characters. Plain text and rich runs split at grapheme boundaries, preferring sentence/paragraph breaks and then word breaks. Lists split between items, tables between rows with column labels repeated, and code splits without rewriting its source. Indivisible payloads remain intact. Existing track weights continue to apply to positions on each resulting page.\n\nThe default readability target is 24 reference pixels. Core 0.8.0 returns slides that persist that floor in `composition.minFontSize`, including an already-fitting one-page result; existing higher minima and strict overflow policies remain intact. Quotes can raise their nominal body/footer sizes to the floor. Other small-format payloads such as table cells retain their existing typography caps. Pagination relies on the shared engine\'s estimates; it is not a guarantee that every host font renders identically. Headings repeat unchanged, speaker notes remain on the first page, and continuation IDs avoid existing deck IDs. `pages[].mappings` records full source/output paths and half-open text or item ranges. Text offsets use UTF-16, so source strings can be reconstructed exactly. Quote bodies split at grapheme boundaries and repeat complete attribution/source fields on each page. An irreducible footer rejects the whole operation, including a quote with an empty body after earlier content.\n\nIf a heading, individual list item, table row, or other atomic payload cannot fit on an otherwise empty page, `OPFPaginationError` returns actionable diagnostics. There is no partial output. `maxSlides` defaults to 100, and a layout-evaluation limit bounds work on pathological input. Specialized chart and timeline internals still require visual inspection; their complete density models remain outstanding.\n\nThe editor\'s `editor.paginateSlide(index)` is one validated transaction with undo/redo. It returns `{change, pagination}`. The next coordinated editor release commits a one-page readability-policy change too; repeating the operation after the policy is recorded returns `change: null`. The playground includes an overflowing draft and **Split overflow** action. The CLI writes a new file and refuses to overwrite an existing one:\n\n```sh\nnode packages/cli/dist/index.js paginate input.opf.json output.opf.json\n```\n\n## Fidelity boundary\n\nThe shared engine provides identical body and heading geometry to SVG and editable PPTX export. Text measurements default to deterministic estimates. For actual font advances, use the shared provider described in [measured fonts](font-fidelity.md). Complex scripts, fallback fonts, PowerPoint text rendering, rich text, charts, tables, and images still need visual verification. Dynamic composition is not a guarantee of pixel-identical PowerPoint output. List density includes rich runs, descriptions and nesting via `fitList`, with the same hanging indents used in preview and export. Only text-like payloads currently receive content-density estimates; small-cell diagnostics also cover non-text content.\n\nSVG embeds raster data URI images locally. Remote and file images require a host resolver that supplies a raster data URI; otherwise they appear as placeholders. `strictAssets` rejects unresolved images. The runtime never fetches them.\n\nSee [the complete example](../examples/technical/dynamic-composition.opf.json) and [local ecosystem verification](ecosystem-development.md).\n\n\n## Quote internals (unreleased coordinated integration)\n\nThe next core API adds `layoutQuote(value, box, options)` from the root or composition entrypoint. Pass validated quote content (object or string shorthand), its allocated reference-pixel box, resolved `fonts`, `textMeasurement`, `scale` (canvas short edge / 720), effective `minFontSize`, `overflow` policy and its source `path`.\n\nThe result contains `parts` for the body and any nonempty footer, exact display `text`, source mappings, requested and resolved text styles, and the available boxes/fits. Source ranges use half-open UTF-16 offsets in both the source field and display string; generated quotation marks and the footer separator have no source range. The original content is never modified. A supplied width provider is reported as `provided`; it does not certify shaping or font fidelity.\n\nCheck `overflow` and `diagnostics` before accepting the parts. Invalid available dimensions remain visible with `fit` absent, and `overflow: \'error\'` throws `OPFCompositionError`. Diagnostics distinguish invalid part space, parts outside their cell, text that exceeds its reserved space, and overlapping line rectangles. Those rectangles are conservative text-layout bounds, not measured glyph outlines. The readability floor is scaled once and can raise the nominal body (28) or footer (17) size; it is never silently capped below the selected floor.\n\n`quote-flow-v1` keeps 18-reference-pixel outer insets and an 18-pixel body/footer gap while fonts scale with the canvas. A 40-pixel footer is a whitespace preference. The allocator expands it for long sources or compacts it for dense bodies, trying at most the nominal and minimum footer sizes and selecting the fitting pair with least total font reduction. If neither fits, it returns floor-size failure diagnostics. This is a bounded internal allocation step, not a complete layout-repair engine.\n\n`composeSlide` scores both parts and accepts geometry against the final rounded item box. Each quote item carries `quoteLayout`; its compatibility `text` field is the same fit object as the quote body, including generated quotation marks. Consumers needing original offsets must use the explicit `sources` mappings. The coordinated renderer and PPTX consume these parts without another measurement/style-resolution pass. Missing geometry or invalid part boxes reject rendering/export rather than omitting content. This requires core 0.8.0 with renderer/PPTX 0.6.0; older core 0.7.0/renderer 0.5.1/PPTX 0.5.2 lack these changes. The coordinated rollout is a dependency-ordered release; use the published set recorded in `release-plan.json` until its registry verification advances.\n\nBrowser glyph bounds can extend slightly beyond advance-based part boxes into the reserved inset. Current loaded-font tests record those overhangs, verify glyph containment inside the full quote cell and check body/footer separation. Native PowerPoint fixtures separately verify text, sizes, cell containment, save/reopen and reimport. Neither test establishes universal pixel equivalence. Original requested-font provenance through host substitutions and non-quote payload internals remain open requirements.\n\n## Resizing in the preview\n\nChoose **Arrange** in the editor to reveal track dividers. Drag a divider to redistribute the space between adjacent columns (row/grid) or rows (column), including nested groups. Arrow keys make small changes; Shift makes larger changes. Escape discards a pointer draft. One drag creates one undo step, and no content is removed. Strict overflow rejects a resize that violates its fit constraints.\n\nResizing an automatic layout makes its chosen columns explicit as `mode: grid` with `columns`. This prevents the number of columns from changing under the pointer. The adjacent share clamps to 5\u201395%, with positive schema-valid weights. Other track proportions and unrelated document fields remain intact. Promoted regions retain their positions; their nested groups can still be resized. Layouts with reserved placeholder slots need an explicit arrangement first. Flows with more than twelve tracks need grouping before the current resize controls can express all weights.\n\n`createCanvasEditor(container, {layoutEditing: true, ...options})` enables dividers initially. `canvas.setLayoutEditing(boolean)` toggles them, and `canvas.commit()` / `canvas.cancel()` also handle an active resize. `onDraft` receives the proposed document; the session stays unchanged until commit. Changes to the resized container cancel a stale draft; unrelated updates are retained.\n\nThe shared engine exposes `geometry.flows`: each flow has its container path, content box, resolved column/row tracks (offset and size), clamped gap, effective composition, item count, and reserved slot count. This is renderer geometry, not new OPF document fields.\n\nAgents can prepare the same guarded change without a DOM:\n\n```js\nimport {prepareTrackResize} from \'@openpresentation/opf-editor/layout\';\nimport {resolvePresentation} from \'@openpresentation/opf-render/svg\';\nconst geometry = resolvePresentation(editor.document, renderOptions).slides[0].geometry;\nconst flow = geometry.flows.find(flow => flow.path === \'slides.0\');\nconst prepared = prepareTrackResize(editor.document, flow, 0, 0.65);\n// Boundary 0: give the first track 65% of the adjacent pair\'s combined space.\n// Preview prepared.document with the same renderer and font provider before applying.\neditor.applyPatch(prepared.patches, {rejectInvalid: true});\n```\n\nThe patch contains a `test` guard for the container before changing its composition. Failed tests do not mutate the document or its history. A test-only patch is read-only. Rendering is preflighted by the canvas; headless callers should likewise render a candidate to enforce font and overflow constraints.\n\nVerification: editor layout model tests, `/layout-tests.html` browser keyboard checks and trusted-pointer specimens, and `pnpm test:layout` for measured SVG/native PPTX coordinate parity. Shape-coordinate checks do not establish PowerPoint raster pixel parity.\n\n\n## Reordering and moving blocks\n\nIn **Arrange**, drag a numbered block handle to reorder siblings. The insertion marker shows the destination; the shared renderer reflows the slide after drop. Arrow keys on a handle move the whole block earlier or later. Click a handle for **Earlier**, **Later**, or an explicit destination and insertion position. The destination menu supports existing groups and block-based slides, including moving a child out of a group or moving a whole group to another slide. `canvas.openBlockMenu(path)` opens the same controls programmatically.\n\nA move preserves the entire block and its nested content, formatting, data, and references. Parent composition weights describe positions, so they stay in place. Moving to another container can change the block\'s inherited design and readability constraints; the canvas renders the candidate before committing it. Strict overflow or an unavailable required font rejects the move. A move cannot leave an empty block container or put a group inside its own descendants. Move the group or add another block first when the source has only one child.\n\n```js\nimport {prepareBlockMove, listBlockContainers} from \'@openpresentation/opf-editor/layout\';\nconst containers = listBlockContainers(editor.document);\nconst prepared = prepareBlockMove(editor.document,\n \'/slides/0/blocks/0\', \'/slides/0/blocks/1\', 1);\n// Insert the first block before child 1 of the second block\'s group.\n// Destination indexes refer to the document before removal.\n// prepared.path reports the moved block\'s address after any index shifts.\neditor.applyPatch(prepared.patches, {rejectInvalid: true});\n```\n\n`prepareBlockMove` returns `{document, patches, path, changed}`. It validates the complete result and emits guarded remove/add patches, so the editor or CLI can apply it atomically. No-op moves return `changed: false` and no patches. `listBlockContainers(document, {slideIndex})` optionally limits discovery to a single slide and excludes arbitrary extension data. Headless callers should render the candidate with their intended font provider before applying. The browser and installed-package block harnesses exercise nested moves, undo, stale menus, keyboard access, strict-fit rejection, and native drag reordering.\n\nCreation and deletion use the same layout engine: insertions can normalize implicit payloads into explicit blocks; deletions prune empty groups while retaining the slide. Existing track weights stay positional. See the [editor creation guide](live-editor.md#create-duplicate-and-delete-content) for the guarded APIs and canvas controls.\n'
|
|
43
|
+
"markdown": '# Dynamic composition\n\nOPF keeps authoring intent in JSON. Use `blocks` when content can reflow; use promoted regions when relative placement is meaningful. `composition` on a slide overrides fields in the resolved layout\'s `composition`. Existing documents remain valid.\n\n```json\n{\n "name": "Decision brief",\n "slides": [{\n "title": "Make the main idea clear",\n "composition": { "mode": "row", "weights": [2, 1], "overflow": "error" },\n "blocks": [\n { "text": "The evidence and recommendation receive twice the width." },\n { "text": "The supporting detail receives the remaining width." }\n ]\n }]\n}\n```\n\n`auto` evaluates candidate grids using text fit and cell proportions. `columns` limits its candidates. `grid` uses `columns` if given, otherwise a grid based on the canvas shape. `row` uses one row; `column` uses one column. Items retain source order. Weights size columns except in column mode, where they size rows. Missing weights are 1; unused weights have no effect. A partially filled final row retains its grid tracks.\n\n`gap` defaults to 1/30 and `padding` to 0.08, both fractions of the canvas\'s shorter edge. Large gaps are reduced when necessary to keep cells positive. `minFontSize` defaults to 16 reference pixels at a 720-pixel short edge. The reference coordinate system uses 96 pixels per inch. Explicit inch dimensions override presets independently for each axis.\n\nHeadings reserve space according to their wrapped text. Content that exceeds the number of preset placeholders reflows together; it is not drawn over already-bound content. Promoted regions keep the 3\xD73 vocabulary, including standalone `top`, `middle`, and `bottom`. They ignore flow direction and track weights.\n\n## Nested groups\n\nA block or promoted region can contain its own `blocks` and `composition`. The optional discriminator is `"type": "group"`. A group has at least one child and cannot mix children with leaf fields such as `text` or `image`.\n\n```json\n{\n "composition": { "mode": "row", "weights": [2, 1] },\n "blocks": [\n {\n "composition": { "mode": "column", "padding": 0.02 },\n "blocks": [{ "text": "Recommendation" }, { "text": "Supporting evidence" }]\n },\n { "text": "Context" }\n ]\n}\n```\n\nThe parent allocates a box to each group, then the group arranges its children inside that box. Group padding defaults to zero; padding and gap use the group\'s shorter edge. Only `minFontSize` and `overflow` inherit. A strict ancestor cannot be weakened by a child\'s `overflow: "warn"`. Font sizes remain relative to the canvas, not the group. Groups can nest up to 32 levels; cycles and deeper nesting fail with an explicit error.\n\nAutomatic grid scoring inspects descendant text using each descendant\'s explicit arrangement or geometric automatic seed. After selecting the parent\'s grid, it optimizes each child\'s automatic grid. This deterministic, bounded search avoids exponential combinations; it does not claim a globally optimal packing.\n\n`result.items` contains every leaf with its full source path and effective composition. `result.groups` contains group paths, outer bounds, and content bounds. The editor\'s `setGroupComposition(path, value)` validates and records undo/redo just like slide composition edits.\n\n## Inspecting and repairing layout\n\n```js\nimport { composeSlide } from \'@openpresentation/opf/composition\';\nconst result = composeSlide(deck.slides[0], { width: 1280, height: 720, layout: resolvedLayout });\nconsole.log(result.items); // Source paths, content, geometry, and text estimates\nconsole.log(result.diagnostics); // Path-specific text-overflow and small-cell messages\n```\n\nThis pure function expects a validated slide. The caller resolves catalog records and passes the canvas size. The rendering and export packages perform those steps at their boundaries. No network, DOM, system font, or AI dependency is required.\n\n### Explain automatic selection (core 0.8.0 and later)\n\nPass `explain: true` to return `result.explanation`. This opt-in API requires core 0.8.0; it is absent from core 0.7.0. Enabling explanations adds no measurement calls and does not change geometry, source content, reading order, weights or selected arrangements within the same engine version.\n\n```js\nconst result = composeSlide(slide, {...resolvedOptions, explain: true});\nfor (const decision of result.explanation.decisions) {\n console.log(decision.path, decision.reason, decision.selectedColumns);\n console.table(decision.candidates);\n}\nconsole.log(result.explanation.textMeasurement);\nconsole.log(result.explanation.unmeasuredPayloads);\n```\n\n`resolvedOptions` supplies the same dimensions, layout, fonts and optional width provider as the preview. Core 0.8.0 identifies its explanation as `grid-score-v2`; core 0.9.0 advances to `grid-score-v3` to include complete code metadata/body measurements. Both record containers in parent-before-child order. `lowest-score` reports the candidates actually tried; `configured-mode` respects resolved row/column/grid intent and returns no invented candidates. `promoted-regions` leaves region placement fixed and has no selected column count. Empty slides have no decisions. Automatic search tries one through `min(slotCount, columns ?? 6)` columns, in ascending order; ties retain the first candidate. Reserved placeholders count as slots. The schema caps an explicit candidate limit at twelve columns.\n\nEach candidate has `columns`, `rows`, `score` and additive `penalties`:\n\n| Penalty | Rule |\n| --- | --- |\n| `cellProportions` | Sum of `abs(log(cellAspect / 1.6))` for descendant leaves |\n| `fontReduction` | Reduction from 25 reference pixels for text-like leaves; quotes and code in core 0.9 sum requested-minus-fitted sizes across their parts, divided by canvas scale |\n| `textOverflow` | 1,000 per overflowing text-like leaf, complete quote or complete code payload, regardless of the number of internal failure reasons |\n| `tableOverflow` | 1,000 per table whose shared cell layout overflows |\n| `smallCells` | 100 per leaf narrower than 100 or shorter than 60 reference pixels |\n| `emptySlots` | 2 per unused position in the candidate grid\'s final row |\n\nScores are preference costs, not quality percentages or guarantees. Floating-point summation can make the component total differ slightly from `score`. Parent scoring uses descendant explicit arrangements or geometric automatic seeds; child automatic grids are optimized only after selecting the parent. Candidate scores therefore describe the bounded search, not a full assessment of the final optimized subtree. Heading fit remains in ordinary diagnostics, outside body-grid scoring. A strict-fit rejection exposes the explanation on `OPFCompositionError` when requested.\n\n`textMeasurement` is `estimated` without a provider and `provided` with one. A provided width function does not establish font provenance, glyph coverage, shaping or native raster fidelity. Text, rich text, lists, quotes, table cells and code in core 0.9 participate in the fit model. `unmeasuredPayloads` identifies images, video, charts, metrics and timelines whose complete internal layout is not assessed. Core 0.8 also reports code as incomplete; core 0.9 measures its filename/language/body and insets. Media aspect ratios, chart labels, metric labels and timeline annotations remain gaps. A zero score or empty diagnostics is not proof that those payloads fit.\n\nThis milestone exposes the existing search for inspection. Guarded layout repairs, automatic weight allocation, content-aware candidate improvements, a common payload-internal measurement model, CLI explanations and a canvas **Auto arrange** preview/undo operation remain subsequent work. It does not silently paginate or rewrite a document.\n\nWith `overflow: "warn"` (default), the result retains all text and returns diagnostics. SVG emits all lines and marks overflowing groups with `data-opf-overflow="true"`; text may extend beyond its box or canvas. Consumers can collect diagnostics using `onDiagnostic`. With `overflow: "error"`, the layout rejects content that does not fit. Shorten the affected content, give it more space, or explicitly split it into another slide. Use the explicit pagination transform below to produce additional editable slides.\n\nThe editor exposes `editor.composeSlide(index)` and `editor.setComposition(index, value)`. The latter validates the change, records JSON Patch history, and supports undo/redo.\n\n## Pagination\n\n```js\nimport { paginateSlide, paginatePresentation } from \'@openpresentation/opf/pagination\';\nconst { presentation, pages } = paginatePresentation(deck);\n// Review, save, render, or export `presentation`; pages maps output fragments to source paths.\nconst single = paginateSlide(deck.slides[0], { width: 1280, height: 720, minFontSize: 24 });\n```\n\nPagination is an authoring operation. It produces ordinary OPF slides; previews and PPTX export consume those exact pages. It preserves the input, body order, nested groups, promoted regions, rich-text formatting, and source text characters. Plain text and rich runs split at grapheme boundaries, preferring sentence/paragraph breaks and then word breaks. Lists split between items, tables between rows with column labels repeated, and code splits without rewriting its source. Indivisible payloads remain intact. Existing track weights continue to apply to positions on each resulting page.\n\nThe default readability target is 24 reference pixels. Core 0.8.0 returns slides that persist that floor in `composition.minFontSize`, including an already-fitting one-page result; existing higher minima and strict overflow policies remain intact. Quotes can raise their nominal body/footer sizes to the floor. Other small-format payloads such as table cells retain their existing typography caps. Pagination relies on the shared engine\'s estimates; it is not a guarantee that every host font renders identically. Headings repeat unchanged, speaker notes remain on the first page, and continuation IDs avoid existing deck IDs. `pages[].mappings` records full source/output paths and half-open text or item ranges. Text offsets use UTF-16, so source strings can be reconstructed exactly. Quote bodies split at grapheme boundaries and repeat complete attribution/source fields on each page. An irreducible footer rejects the whole operation, including a quote with an empty body after earlier content.\n\nIf a heading, individual list item, table row, or other atomic payload cannot fit on an otherwise empty page, `OPFPaginationError` returns actionable diagnostics. There is no partial output. `maxSlides` defaults to 100, and a layout-evaluation limit bounds work on pathological input. Specialized chart and timeline internals still require visual inspection; their complete density models remain outstanding.\n\nThe editor\'s `editor.paginateSlide(index)` is one validated transaction with undo/redo. It returns `{change, pagination}`. Editor 0.5.0 commits a one-page readability-policy change too; repeating the operation after the policy is recorded returns `change: null`. The playground includes an overflowing draft and **Split overflow** action. The CLI writes a new file and refuses to overwrite an existing one:\n\n```sh\nnode packages/cli/dist/index.js paginate input.opf.json output.opf.json\n```\n\n## Fidelity boundary\n\nThe shared engine provides identical body and heading geometry to SVG and editable PPTX export. Text measurements default to deterministic estimates. For actual font advances, use the shared provider described in [measured fonts](font-fidelity.md). Complex scripts, fallback fonts, PowerPoint text rendering, rich text, charts, tables, and images still need visual verification. Dynamic composition is not a guarantee of pixel-identical PowerPoint output. List density includes rich runs, descriptions and nesting via `fitList`, with the same hanging indents used in preview and export. Only text-like payloads currently receive content-density estimates; small-cell diagnostics also cover non-text content.\n\nSVG embeds raster data URI images locally. Remote and file images require a host resolver that supplies a raster data URI; otherwise they appear as placeholders. `strictAssets` rejects unresolved images. The runtime never fetches them.\n\nSee [the complete example](../examples/technical/dynamic-composition.opf.json) and [local ecosystem verification](ecosystem-development.md).\n\n\n## Code internals (core 0.9.0 and coordinated packages)\n\nCore 0.9.0\'s `layoutCode(value, box, options)` API accepts the schema\'s string shorthand or `{source, language?, filename?}` object. It returns measured filename/language/body parts with exact original text, requested/resolved styles, readability floors, available boxes and diagnostics. Renderer/PPTX 0.7.0 and editor 0.6.0 are its coordinated release targets for shared rendering, native export, source/metadata edits and undo. [Release gates](plans/shared-code-release.md) distinguish prepared versions from verified publication. Core 0.8.0 does not include this API and retains the [recorded code-label, filename and whitespace defects](plans/layout-repair.md).\n\n`grid-score-v3` charges code font reductions across all metadata/body parts and one overflow penalty per failing leaf. It preserves explicit modes, weights, regions and source order. Accepted `item.codeLayout` is fitted to the same rounded cell exposed as `item.box`; `item.text` and `item.textStyle` alias the body, not the first metadata part. Strict ancestor settings apply to internal `.source`, `.filename` and `.language` diagnostics. Code no longer appears in `explanation.unmeasuredPayloads`, which concerns the core advance-based model only. It does not mean browser/native fidelity is verified.\n\nPagination slices the code body at grapheme boundaries, repeats filename/language and returns contiguous UTF-16 body ranges while preserving all source bytes and the evaluated readability floor. Irreducible metadata rejects all output, including when the body is empty or earlier content could have fitted. Consumers must preview/export the returned document. The [integration checkpoint](plans/shared-code-integration.md) separates source, installed browser, Windows PowerPoint and remaining release gates.\n\nEach fitted part retains every space and explicit CR/LF/CRLF break. `fit.lines` contains exact source slices, and `fit.sourceLines` records half-open UTF-16 `start`, `end` and `nextStart` offsets, the measured width and a `soft`, `hard` or `end` boundary. A hard break occupies `[end, nextStart)`; soft wrapping consumes no source character. Joining `part.text.slice(line.start, line.nextStart)` reconstructs the original part. Blank lines and a final empty line are retained, and long tokens split only at grapheme boundaries. Filename and language text are not case-converted. An absent/empty metadata pair creates a generated `code` label with no source range.\n\n`code-flow-v1` uses 18-reference-pixel outer insets, an eight-pixel gap between filename and language, and a twelve-pixel gap before the body. Nominal metadata/body sizes are 14/18 reference pixels, raised when necessary to respect the selected minimum, then scaled once. At most four metadata nominal/floor combinations are tried; each body fit tries at most 19 sizes regardless of canvas scale. The fitting combination with least font reduction wins. Irreducible metadata/body failures retain all text and diagnostic paths; invalid available boxes have no fit. `overflow: \'error\'` rejects rather than returning partial output.\n\nTabs remain literal characters in part text and displayed-line slices. Measurement advances to the next multiple of four measured spaces from that line\'s origin; `fit.tabSize` and `fit.tabWidth` expose the rule. Each source line\'s `segments` contains exact text/tab source ranges plus measured `x`/`width` values relative to its origin. Consumers must reuse those positions: an Edge probe showed that SVG treats a tab as one space despite CSS `tab-size: 4`. The candidate SVG renderer uses positioned spans and geometric precision; native export uses accepted tab stops. Width measurements and source preservation alone do not establish glyph-outline containment, shaping/bidi support or native fidelity. [Installed workflow evidence](evidence/shared-code-installed/summary.json) records the separate actual browser and native checks with their exact font/runtime scope.\n\nCandidate native export stores source boundaries in standard PowerPoint shape tags. Complete unique groups recover exact code/source metadata, with current native text taking precedence. Missing, damaged or ambiguous groups retain visible native shapes and report diagnostics. Reimport does not reconstruct native formatting, positioning, font theme or readability policy. Eight installed-export wide/portrait slides pass native edit/save/reopen and all 24 original/saved/edited imports on the recorded Windows PowerPoint build; this is not arbitrary PowerPoint round-trip or pixel equivalence. The editor preserves untouched CRLF/CR source around edits and keeps committed preview geometry separate from its active native textarea caret.\n\nThe JSON schema can accept strings that [XML 1.0 cannot represent](https://www.w3.org/TR/xml/#charsets). Candidate SVG/PPTX code output rejects forbidden controls, unpaired UTF-16 surrogates, U+FFFE and U+FFFF with `invalid-code-text`, the source field path and UTF-16 offset in the message. The input stays unchanged; the caller can correct that character explicitly. Tabs, CR/LF/CRLF and valid supplementary characters remain accepted for serialization. Schema support, format representability and glyph coverage are separate properties.\n\nThe controlled SVG harness requests `text-rendering="geometricPrecision"` as well as explicit segment placement. Initial Linux Chromium CI rounded glyph advances under default hinting, unlike Windows Edge with the same font bytes. The [SVG specification](https://www.w3.org/TR/SVG/painting.html#TextRenderingProperty) defines geometric precision as a rendering hint, so consumers still need actual browser checks with their exact fonts and supported environments; the hint alone does not certify agreement. The harness retains a 0.1-reference-pixel tolerance and records observations before assertions.\n\n## Quote internals (core 0.8.0 and coordinated packages)\n\nCore 0.8.0 exports `layoutQuote(value, box, options)` from the root or composition entrypoint. Pass validated quote content (object or string shorthand), its allocated reference-pixel box, resolved `fonts`, `textMeasurement`, `scale` (canvas short edge / 720), effective `minFontSize`, `overflow` policy and its source `path`.\n\nThe result contains `parts` for the body and any nonempty footer, exact display `text`, source mappings, requested and resolved text styles, and the available boxes/fits. Source ranges use half-open UTF-16 offsets in both the source field and display string; generated quotation marks and the footer separator have no source range. The original content is never modified. A supplied width provider is reported as `provided`; it does not certify shaping or font fidelity.\n\nCheck `overflow` and `diagnostics` before accepting the parts. Invalid available dimensions remain visible with `fit` absent, and `overflow: \'error\'` throws `OPFCompositionError`. Diagnostics distinguish invalid part space, parts outside their cell, text that exceeds its reserved space, and overlapping line rectangles. Those rectangles are conservative text-layout bounds, not measured glyph outlines. The readability floor is scaled once and can raise the nominal body (28) or footer (17) size; it is never silently capped below the selected floor.\n\n`quote-flow-v1` keeps 18-reference-pixel outer insets and an 18-pixel body/footer gap while fonts scale with the canvas. A 40-pixel footer is a whitespace preference. The allocator expands it for long sources or compacts it for dense bodies, trying at most the nominal and minimum footer sizes and selecting the fitting pair with least total font reduction. If neither fits, it returns floor-size failure diagnostics. This is a bounded internal allocation step, not a complete layout-repair engine.\n\n`composeSlide` scores both parts and accepts geometry against the final rounded item box. Each quote item carries `quoteLayout`; its compatibility `text` field is the same fit object as the quote body, including generated quotation marks. Consumers needing original offsets must use the explicit `sources` mappings. The coordinated renderer and PPTX consume these parts without another measurement/style-resolution pass. Missing geometry or invalid part boxes reject rendering/export rather than omitting content. This requires core 0.8.0 with renderer/PPTX 0.6.0; older core 0.7.0/renderer 0.5.1/PPTX 0.5.2 lack these changes. The complete published set, immutable verification refs and fresh registry evidence are recorded in `release-plan.json` and [the release plan](plans/shared-quote-release.md).\n\nBrowser glyph bounds can extend slightly beyond advance-based part boxes into the reserved inset. Current loaded-font tests record those overhangs, verify glyph containment inside the full quote cell and check body/footer separation. Native PowerPoint fixtures separately verify text, sizes, cell containment, save/reopen and reimport. Neither test establishes universal pixel equivalence. Original requested-font provenance through host substitutions and non-quote payload internals remain open requirements.\n\n## Resizing in the preview\n\nChoose **Arrange** in the editor to reveal track dividers. Drag a divider to redistribute the space between adjacent columns (row/grid) or rows (column), including nested groups. Arrow keys make small changes; Shift makes larger changes. Escape discards a pointer draft. One drag creates one undo step, and no content is removed. Strict overflow rejects a resize that violates its fit constraints.\n\nResizing an automatic layout makes its chosen columns explicit as `mode: grid` with `columns`. This prevents the number of columns from changing under the pointer. The adjacent share clamps to 5\u201395%, with positive schema-valid weights. Other track proportions and unrelated document fields remain intact. Promoted regions retain their positions; their nested groups can still be resized. Layouts with reserved placeholder slots need an explicit arrangement first. Flows with more than twelve tracks need grouping before the current resize controls can express all weights.\n\n`createCanvasEditor(container, {layoutEditing: true, ...options})` enables dividers initially. `canvas.setLayoutEditing(boolean)` toggles them, and `canvas.commit()` / `canvas.cancel()` also handle an active resize. `onDraft` receives the proposed document; the session stays unchanged until commit. Changes to the resized container cancel a stale draft; unrelated updates are retained.\n\nThe shared engine exposes `geometry.flows`: each flow has its container path, content box, resolved column/row tracks (offset and size), clamped gap, effective composition, item count, and reserved slot count. This is renderer geometry, not new OPF document fields.\n\nAgents can prepare the same guarded change without a DOM:\n\n```js\nimport {prepareTrackResize} from \'@openpresentation/opf-editor/layout\';\nimport {resolvePresentation} from \'@openpresentation/opf-render/svg\';\nconst geometry = resolvePresentation(editor.document, renderOptions).slides[0].geometry;\nconst flow = geometry.flows.find(flow => flow.path === \'slides.0\');\nconst prepared = prepareTrackResize(editor.document, flow, 0, 0.65);\n// Boundary 0: give the first track 65% of the adjacent pair\'s combined space.\n// Preview prepared.document with the same renderer and font provider before applying.\neditor.applyPatch(prepared.patches, {rejectInvalid: true});\n```\n\nThe patch contains a `test` guard for the container before changing its composition. Failed tests do not mutate the document or its history. A test-only patch is read-only. Rendering is preflighted by the canvas; headless callers should likewise render a candidate to enforce font and overflow constraints.\n\nVerification: editor layout model tests, `/layout-tests.html` browser keyboard checks and trusted-pointer specimens, and `pnpm test:layout` for measured SVG/native PPTX coordinate parity. Shape-coordinate checks do not establish PowerPoint raster pixel parity.\n\n\n## Reordering and moving blocks\n\nIn **Arrange**, drag a numbered block handle to reorder siblings. The insertion marker shows the destination; the shared renderer reflows the slide after drop. Arrow keys on a handle move the whole block earlier or later. Click a handle for **Earlier**, **Later**, or an explicit destination and insertion position. The destination menu supports existing groups and block-based slides, including moving a child out of a group or moving a whole group to another slide. `canvas.openBlockMenu(path)` opens the same controls programmatically.\n\nA move preserves the entire block and its nested content, formatting, data, and references. Parent composition weights describe positions, so they stay in place. Moving to another container can change the block\'s inherited design and readability constraints; the canvas renders the candidate before committing it. Strict overflow or an unavailable required font rejects the move. A move cannot leave an empty block container or put a group inside its own descendants. Move the group or add another block first when the source has only one child.\n\n```js\nimport {prepareBlockMove, listBlockContainers} from \'@openpresentation/opf-editor/layout\';\nconst containers = listBlockContainers(editor.document);\nconst prepared = prepareBlockMove(editor.document,\n \'/slides/0/blocks/0\', \'/slides/0/blocks/1\', 1);\n// Insert the first block before child 1 of the second block\'s group.\n// Destination indexes refer to the document before removal.\n// prepared.path reports the moved block\'s address after any index shifts.\neditor.applyPatch(prepared.patches, {rejectInvalid: true});\n```\n\n`prepareBlockMove` returns `{document, patches, path, changed}`. It validates the complete result and emits guarded remove/add patches, so the editor or CLI can apply it atomically. No-op moves return `changed: false` and no patches. `listBlockContainers(document, {slideIndex})` optionally limits discovery to a single slide and excludes arbitrary extension data. Headless callers should render the candidate with their intended font provider before applying. The browser and installed-package block harnesses exercise nested moves, undo, stale menus, keyboard access, strict-fit rejection, and native drag reordering.\n\nCreation and deletion use the same layout engine: insertions can normalize implicit payloads into explicit blocks; deletions prune empty groups while retaining the slide. Existing track weights stay positional. See the [editor creation guide](live-editor.md#create-duplicate-and-delete-content) for the guarded APIs and canvas controls.\n'
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
46
|
"slug": "ecosystem-development",
|
|
@@ -70,7 +70,7 @@ var docsData = Object.freeze([
|
|
|
70
70
|
"slug": "handoff-2026-09-08",
|
|
71
71
|
"file": "docs/handoff-2026-09-08.md",
|
|
72
72
|
"title": "OpenPresentation ecosystem handoff \u2014 2026-09-08",
|
|
73
|
-
"markdown": "# OpenPresentation ecosystem handoff \u2014 2026-09-08\n\n## Current checkpoint \u2014 installed browser CI merged; core/CLI release preparation\n\nCore [PR #48](https://github.com/OpenPresentation/opf/pull/48) merged as `abf32daa67543c30b29dbe813b17996456b90e34`, tree-identical to reviewed `565fbd2905006624c57a7c24c1b1fe62ac10ca4d`. Core Node 20/24 CI `34399051774`, complete coordinated source/tarball/registry CI `34399051732`, and Bugbot pass. CI now executes all seven installed-package browser suites against both tarballs and registry packages on Chromium 153, with 230 harness assertions and eight trusted input scenarios per run. All four stale/mutated-evidence guard cases pass on both runtimes. [Immutable CI evidence](evidence/installed-browser-ci-2026-09-09.json) complements the local Edge report below.\n\nContinue `codex/shared-quote-release-20260909`: it prepares **unpublished core 0.8.0 and CLI 0.6.0**, including the public type-tightening notice and versioned quote/pagination documentation. The [release gates and intended downstream versions](plans/shared-quote-release.md) keep actual registry refs unchanged until publication is verified. Complete release checks/review before tagging. Then update renderer, PPTX and editor dependencies/locks in order against published packages, renew exact package/browser/native evidence, and update the actual release plan and public deployments. The full objective remains active; releases do not complete bounded repair, Auto arrange or the font roadmap.\n\nProduction openpresentation.org now serves independent website #19 merge `31c84759c044480045a07f1e150149ecb2a423d3`, READY deployment `dpl_9q2ihhJXVxnWzcjizev6M2GSVMDS`. All six public Edge workflows pass (16.9s), live npm verifies the changelog dates/set, and all three showcase downloads match exact source/registry hashes. [Fresh production evidence](evidence/site-production-design-2026-09-09.json). Website #20 is still independent active work and is left untouched. A fresh seven-repository audit finds zero open Dependabot security alerts.\n\n## Previous checkpoint \u2014 shared quote core merged\n\nCore [PR #47](https://github.com/OpenPresentation/opf/pull/47) merged as `01e69ba1a6c3915778ede6aa12fb7ecda652ea42`, tree-identical to reviewed `c81b8b1cdf7004af186dce81c2b81cfb9a25be12`. Core Node 20/24 CI `34397006994`, complete coordinated source/tarball/registry CI `34397007028`, Windows/macOS CLI CI `34397007117`, and Bugbot pass. The [integration checkpoint](plans/shared-quote-integration.md) records quote allocation/scoring, pagination content-loss/readability fixes, downstream editor undo behavior, real Edge/PowerPoint evidence and the 41-slide raster review. Renderer, converter and editor retain their pinned `codex/shared-quote-integration-20260909` branches, with no downstream PRs yet. All changes remain unreleased; actual registry versions, release-plan refs and public deployments are unchanged by this milestone.\n\nCore branch `codex/installed-browser-checks-20260909` supplied the merged runner above. Keep the published registry baseline separate from the reviewed candidate footer changes. Native reimport retains editable quote text but loses quote structure/typography/readability policy; this remains an explicit gap. The full goal is active and substantially unfinished. No renewed permission is needed for already-authorized releases/deployments after their gates pass.\n\nThe [installed-browser report](evidence/installed-browser-2026-09-09.json) records four passing local runs: actual registry and candidate tarballs on Node 20/24 with Edge 152. Each runs seven suites, 230 harness assertions and eight trusted input scenarios, with zero external requests, writes or browser errors. Four evidence-rejection tests pass on both runtimes. Plain-to-rich conversion and bold formatting remain separate undo steps. This expands package/browser verification; it does not add native raster or public-deployment evidence.\n\nWebsite PR #20 (`claude/branch-icon-spacing-fixes-de47tz`, observed `6bf9b294a05a5943be77056f372c988266ad475b`) is separate active user work and was left untouched. Do not overwrite it during future package adoption. The original nine-PR backlog is resolved as recorded below.\n\n## Previous checkpoint \u2014 quote primitive merged; shared consumer integration next\n\nCore [PR #46](https://github.com/OpenPresentation/opf/pull/46) merged as `6d8df02940deec8f1fa89192d10576d6048de341`, tree-identical to reviewed `83e35649f91fc430c817c19492b0bf3d01212766`. Core Node 20/24 CI `34389245732`, coordinated source/registry CI `34389245620` (including the new real-font quote check), Windows/macOS CLI and packed-install CI `34389245733`, and Bugbot pass. The standalone quote API is now on main and remains unreleased. No package was republished or actual-release ref advanced.\n\nContinue from branch `codex/shared-quote-integration-20260909`. The [consumer integration audit](plans/shared-quote-integration.md) records exact downstream bases, candidate/accepted-fit reuse, strict descendant-path handling, atomic pagination, renderer and converter entrypoints, readability/rounding/source-map tests and the original requested-font provenance gap. Implement and verify the shared composition/preview/export path before claiming complete quote coverage, then continue code/metric/timeline/chart internals, bounded repair, Auto arrange and font/native fidelity. This is planned next work, not completed integration.\n\nA fresh audit after the original backlog resolution finds zero open Dependabot security alerts in all seven repositories. The only unrelated new PR is website [#19](https://github.com/Data-Advantage/openpresentation-site/pull/19), `claude/openpresentation-design-review-40j83i`, observed at `246aaa165d3dffb4c5e8b1a59376cfd4d47f760e`; it was recently updated and left untouched as independent work. All earlier PR dispositions and verified public deployments remain as recorded below. User authorization for pushes, PR updates, merges, tags, publication and deployments persists; remaining checks are release gates, not a request for renewed permission. The full goal stays active.\n\n## Previous checkpoint \u2014 standalone quote layout candidate; evidence checkpoint merged\n\nCore evidence [PR #45](https://github.com/OpenPresentation/opf/pull/45) merged as `24f64d67ef907282d73c25d04e80696879ab291f`, tree-identical to reviewed `b3659b0889414737ce82f552ea2753019bf9f1c5`. Core Node 20/24 CI `34387935655`, coordinated source/registry CI `34387935681`, Windows/macOS CLI and packed-install CI `34387935660`, and Bugbot pass. The failure email/budget questions and original PR backlog are resolved as recorded below.\n\nNext branch `codex/shared-quote-layout-20260909` adds standalone `layoutQuote` body/footer measurement with styles, source mappings and explicit internal failures. It is additive and unreleased: existing composition, preview, export and pagination are not switched to it. All 426 core tests plus preservation suites pass on Windows Node 20/24; six new quote cases and public declaration imports pass. The repeated actual-font wide/portrait check produces identical source/runtime/font-bound evidence on both runtimes. See [the implementation scope, report and remaining integration gates](plans/layout-repair.md#next-increments-and-acceptance-criteria). Finish CI/review before merging; connect all consumers before claiming shared accepted geometry or considering publication. The full deterministic repair, cross-surface workflow and font/native-fidelity goal remains active.\n\n## Previous checkpoint \u2014 original PR backlog resolved; YAML deployed; payload-fit gaps measured\n\npptx.dev [PR #28](https://github.com/Data-Advantage/pptx-dev/pull/28) merged as `b922f2f89fdb1e68f0e71a7f1df638be9c5314d4`, tree-identical to reviewed `dfdede29458bea1afb13f7f07d5e1079f9e9e515`. Linux/Windows application CI `34386017908`, artifact CI `34386017825` and Bugbot pass. Exact READY preview `dpl_6dXvANdwpkPgRPQ31oSKhrGqFHbx` passes eight Edge workflows (25.1s). Production `dpl_9B4YfiTrX3YCvK632T9qwtPTYpMs` is READY on that merge and serves www.pptx.dev, pptx.dev and the existing API/MCP aliases. All eight public Edge workflows pass (28.8s): author/import, quote preview/export, shared navigation, Inspector undo/download/reimport, offline Monaco, hostile SVG, installed-package toolkit and offline YAML/Markdown recovery. All 33 deployed font files and licenses still match actual registry renderer 0.5.1; [fresh font report](evidence/pptx-dev-yaml-fonts-2026-09-09.json). The previous native report remains bound to the adoption #25 download; this YAML deployment run does not add native raster-equivalence evidence.\n\nThe Data-Advantage budget increase restored CI execution. Two subsequent Linux attempts hit an external apt repository hash mismatch during Playwright dependency installation. The final pipeline uses the official matching Playwright 1.63.0 Noble image pinned to `sha256:eff16c30e6f3f4af0a03fa4b706120d5e9b0891c344a27d64559aff5900a4a27`; Linux executes all tests in it and Windows retains its native job. No checks were waived. All nine original PRs now have a disposition, and their feature/migration replacements are merged and publicly verified. Deferred TypeScript/Commander/Author-copy work remains explicit in issues, as recorded in [the backlog](pr-backlog-2026-09-09.md).\n\nCore [PR #44](https://github.com/OpenPresentation/opf/pull/44) merged as `94e4e019d28a1e16ac7e192b564596077dc2a6fa`, tree-identical to reviewed `8b09dd2757980fdae2471107a874d07bdf3a4fa0`. Coordinated Node 20/24 CI `34385371576`, core CI `34385371565`, Windows/macOS CLI and packed-install CI `34385371589`, and Bugbot pass. The earlier coordinated failure email was caused by a fixture copying the linker without its new package-manager helper; the final revision copies both and passes renewed checks. Windows linking uses junctions with checked target parents, and package-manager calls execute JavaScript entrypoints with literal arguments. No OS setting or elevated symlink privilege is required.\n\nThe next checkpoint, branch `codex/payload-fit-evidence-20260909`, corrects the unreleased explanation coverage to include incomplete code internals and adds a repeatable actual-registry probe. A schema-valid long quote footer produces no composition diagnostic but does produce renderer overflow; a long code label has measured advance 4200.68 pixels against 1128.8 available, with neither composition nor renderer reporting overflow. [Hash-bound evidence and next steps](plans/layout-repair.md#published-payload-fit-gaps) separate font-advance measurement from browser/native glyph behavior. These are priority inputs to shared internal measurement and bounded repair, not repaired layouts. The full layout/font goal remains active. No package was republished or publication ref advanced.\n\n## Previous checkpoint \u2014 layout explanations merged; Windows harness; YAML CI resumed\n\nCore [PR #43](https://github.com/OpenPresentation/opf/pull/43) merged as `1cc549183c6fd2e885f06410471e7142be69410a`, tree-identical to reviewed `d32b3eeedc0340ae3b8b3141a4677195346ddee5`. Node 20/24 core CI `34384042495`, coordinated source/registry CI `34384041071`, Windows/macOS CLI CI `34384041098` and Bugbot pass. Candidate explanations are now on main but remain unreleased. Full repair/font work remains open. Independent [PR #44](https://github.com/OpenPresentation/opf/pull/44), branch `codex/windows-test-harness-20260909`, fixes Windows junction/package-manager invocation and adds actual packed-install CI coverage; final combined-source checks and review remain gates.\n\nThe owner added $10 to the Data-Advantage GitHub Actions budget. YAML CI `34382820569` attempt 2 now starts and executes both Linux and Windows jobs. A missing exact-head Bugbot review was requested once; do not repeat while it is running. The initial billing failure below is retained as history, not a current reason to leave work idle. Finish the running checks/review and then merge/deploy PR #28 if clean.\n\nCore evidence PR #42 merged as `2c1cac7cbbc8d1afc9c26ca0b0fbdaa9b6ee3090`, tree-identical to reviewed `7b8def879883f3f8a42a9aff198620190470144c`, after Node 20/24 package CI `34381607903`, coordinated CI `34381607943` and Bugbot passed. The next source milestone is branch `codex/layout-repair-20260909`: opt-in candidate explanations preserve geometry and measurement calls and expose unsupported internal payload coverage. See [the layout plan and evidence](plans/layout-repair.md). This is unreleased source, not completed automatic repair; no package has been republished.\n\npptx.dev YAML PR #28 is now `e9f21ec007d3e382234c7bd8e062bc062fad471f`. The Escape fix passed both OS CI jobs `34381496268`; subsequent review found comment-only frontmatter, now fixed with parser-based empty-document handling and exact content/browser regression coverage. Latest local evidence: 598 tests, fresh production build and eight Edge workflows. Exact READY preview `dpl_CEw5yBz6cv622CbHvHfzNYvVqz5x` passes all eight workflows (25.8s). GitHub CI `34382820569` **did not start any steps**: both annotations report failed account payments or an insufficient spending limit. Leave the PR open and rerun Linux/Windows CI after GitHub Billing & plans is resolved; final review and public deployment remain gates. This is an infrastructure blocker, not a passing test result. Public pptx.dev remains the verified adoption #25 production below. Continue independent layout/font work while this gate is unavailable.\n\n## Latest checkpoint \u2014 public adoption verified; older PRs resolved or migrated\n\nRead [the current PR backlog and adoption checkpoint](pr-backlog-2026-09-09.md) before acting. Core #40/#13 and all three adoption PRs (website #17, gallery #23, pptx.dev #25) are merged. Exact READY production deployments pass public Edge workflows, including accurate published changelog, all six complete skills, all eight gallery bundle resources, 33 byte-matched renderer font files and offline editable export/reimport. Website #4's recovery #18 is also merged and verified live. The actual public pptx.dev export passes PowerPoint 16 native edit/save/reopen/reimport with a visually inspected raster. TypeScript #16, Commander #19 and the stale Author draft #6 are closed with explicit follow-up issues; js-yaml #20 is superseded by migration #28, with its current gate recorded above. Vercel duplicate comments are disabled and verified through the authenticated CLI; deployment checks and security alerts remain enabled. Schema-generator #13's public-type tightening is documented for a future release. No package was republished; the full layout/font/native-fidelity objective remains active.\n\n## Latest checkpoint \u2014 published content releases; expanded layout/font objective\n\nThe user's [updated objective](plans/ecosystem-objective-2026-09-09.md) supersedes the earlier goal. OPF must remain deterministic and independent of AI/model calls, keys, accounts and paid services. New explicit requirements include bounded layout candidate evaluation/repair with content/readability preservation, shared internal payload measurement, API/CLI/skills/canvas Auto arrange with preview/undo, and broad versioned open-font compatibility and native-platform evidence. The current releases do not complete that objective. Existing composition has heuristic auto-column scoring and explicit pagination; a full scored repair operation and its cross-surface workflow remain unfinished. Read `docs/font-fidelity.md` and the updated font roadmap before continuing that work. Width samples and baseline stability are not font/raster equivalence.\n\nRenderer **0.5.1** is published from `335ed01b2efbbb872894949f2ac0519e35651474`, workflow `34322801526`, npm timestamp `2026-09-09T07:14:52.658Z`. Renderer PR #9 corrected initially ineffective portrait fixtures; reviewed `12a3aa1dfb5196b3bcebe90d7e4ebb235627b0b4` merged as `d8696224e7a99618701e641ef7573ef394489885` after Node 20/24 CI `34323435532` and Bugbot. That test-only source is the new immutable verification/CI ref; the actual registry gitHead remains the publication merge. No renderer republish occurred.\n\nPPTX **0.5.2** is published from `383666b366b8c9b8ed8e7e72934d1d3fd0fb634d`, workflow `34370539691`, npm timestamp `2026-09-09T15:31:43.997Z`. PR #13 reviewed `22418c55b7e4140a7d325770510930f9e81b6b50` passed all Linux/Windows Node 20/24 jobs `34323665995` and renewed Bugbot; the quote-footer finding is resolved. npm processing finished before installation. Core PR #39 merged as `3d9321621486c95d06cc8153e2d30020c624f489` after renewed CI/review, closing the candidate linked-dependency gap.\n\nCore branch `codex/content-release-sync-20260909` updates the release plan, immutable CI refs and pinned registry content tests. Fresh full-set registry ecosystem/fidelity checks pass on Windows Node 20/24; all 805 renderer hashes remain unchanged. Registry signatures (64) and attestations (15) verify. Actual runtime/license payloads match release Git blobs exactly. The [published native report](native-content-release-2026-09-09.md) records actual-registry PowerPoint 16 checks on 19 feature slides, 24 imports and native object/edit preservation. A new registry/native quote verifier proves eight actual registry exports byte-identical to the native-tested wide/portrait files, with glyph separation, save/reopen and six valid imports on both runtimes. Native chart geometry and general text wrapping remain documented gaps. No proprietary fonts are distributed.\n\nDownstream adoption is saved on branch `codex/native-content-adoption-20260909` in each repository:\n\n- Website [PR #17](https://github.com/Data-Advantage/openpresentation-site/pull/17), `56069382de43c504e871cfc9d1e9cc88e83fb1ab`: accurate published changelog and registry showcase manifest. Build, registry dates, audit and four local Edge workflows pass.\n- Gallery [PR #23](https://github.com/Data-Advantage/pptx-gallery/pull/23), `58dd6957c7508d9459007cea4616e9c811f17383`: regenerated eight-resource registry editor/export bundle, full licenses and direct converter dependency. Builder validates/renders 854 documents; 106 tests, build, audit and both full local Edge workflows pass.\n- pptx.dev [PR #25](https://github.com/Data-Advantage/pptx-dev/pull/25), `a7f785da3c4fc0a819091efe617e0e46382531d1`: package adoption, installed-version font/preview labels and shared-hash navigation fix found by the new real wide/portrait quote E2E. Stale async loads and pending URL writes are guarded. 592 tests, typecheck, build, audit and six local Edge workflows pass.\n\nThese new site revisions are **not yet verified production deployments**. Next: complete core/site reviews and CI, verify exact previews, merge/deploy in order, verify public changelog, all bundle/font hashes and complete browser flows, and keep this handoff current. The previous production checkpoints below remain authoritative until replaced with observed READY deployments and public test evidence. The latest audit still finds zero open Dependabot security alerts across all seven repositories; four major compatibility reviews remain (core schema generator/TypeScript, pptx.dev Commander/js-yaml). Pending Vercel duplicate-comment sign-in and missing macOS native evidence remain explicit gaps, not reasons to stop independent layout/font work. Never republish completed versions.\n\n## Latest checkpoint \u2014 quote review fixes and renderer 0.5.1 release gate\n\nRenderer [PR #8](https://github.com/OpenPresentation/opf-render/pull/8), branch `codex/quote-footer-layout-20260909`, saves prepared **unpublished 0.5.1** at `e2d2a0260e7d83831d70e15bd17d173a1600ef0f`. A valid converter review finding also reproduced in the renderer: long quote text could cover its attribution/source footer. Reserving footer space before fitting fixes eight long-quote cases on wide/portrait canvases; two oversized cases retain diagnostics and strict rejection. Full local Node 20/24 suites preserve all 126-deck/805-slide raster hashes. Real Edge tests load the exact four open font faces used for measurement and verify eight actual SVG glyph layouts; renderer CI and publication now execute this browser suite and the existing JPEG suite. Exact-head CI `34322142453` and Bugbot pass. Fresh packed verification, merge/tree check, tag and trusted publication remain gates.\n\nCore [PR #39](https://github.com/OpenPresentation/opf/pull/39) addresses its valid review finding by rejecting candidate dependencies resolved outside installed `node_modules` and linked/non-registry lock records. The new same-version linked-dependency regression passes on Node 20/24. Converter [PR #13](https://github.com/OpenPresentation/opf-pptx/pull/13) has the corresponding quote fix and extended packed/browser checks in progress; its older `422f1e39e643cbb1c23260f0c9ddef7a3c6ec722` evidence is a historical candidate, not verification of subsequent edits. Next order: renderer 0.5.1 publication, converter registry dependency/lock update, refreshed packed/browser/native checks and review, then PPTX 0.5.2 publication and fresh registry/downstream adoption. No previously released package should be republished. Native chart geometry and general text wrapping remain measured fidelity gaps; the full goal remains active.\n\n## Latest checkpoint \u2014 Monaco deployed; native fixes in 0.5.2 review\n\npptx.dev PR #24 merged as `1e13e469bda257df197c79bb10948c62c3ea6535`, tree-identical to reviewed `3d372dde1c4e19fd7d59e39fba4c18c1349f5355`. Linux/Windows CI `34319106580` and Bugbot pass. All five Edge workflows pass on exact final preview `dpl_GQbmdzmR2vFzsCo48F5pN3cNaTYr` (18.4s) and public production `dpl_9LnTh1yQ9JzhUcmhBe7vbmsYZtEh` (20.4s), READY on that merge. This includes actual same-origin Monaco 0.56 JSON workers, schema diagnostics, offline completion and recovery. Dependabot #18 is closed as superseded; temporary preview browser credentials were removed. No OPF package was republished.\n\nCore PR #38 merged as `204cd42278992b58f6468a98e1eb168e3531df40` from reviewed `8910b9052c6c6854284d2e9e25506798f0a670d6`, after Node 20/24 coordinated CI `34319241226`, package CI `34319241251` and Bugbot. It preserves the 19-slide published baseline and the substantial native differences found by visual inspection.\n\nPPTX [PR #13](https://github.com/OpenPresentation/opf-pptx/pull/13), branch `codex/native-content-fidelity-20260909`, saves **unpublished 0.5.2** candidate `422f1e39e643cbb1c23260f0c9ddef7a3c6ec722`. Metrics, quotes, code and timelines now follow renderer geometry/shared core text fitting; native chart labels use readable theme text. Quote source/attribution survives, and timelines use editable native lines/markers. Full local Node 20/24 converter/corpus/styled suites pass; the new regression compares 34 text lines to actual renderer typography/geometry at two dimensions and checks chart contrast/native markers. Final candidate PowerPoint 16 checks pass for all 19 edits, 24 reimports, three native tables, one native chart and one picture. Hash-bound [candidate reports/contact sheets](https://github.com/OpenPresentation/opf-pptx/blob/422f1e39e643cbb1c23260f0c9ddef7a3c6ec722/docs/native-content-candidate.md) show the visual improvements; chart ticks/plot geometry and general scalar-text wrapping remain open.\n\nCore branch `codex/native-candidate-comparison-20260909` adds explicit candidate comparison with full runtime/vendor/package/lock hashes and matching registry core/renderer requirements. The default remains registry-only; missing/changed candidate evidence is rejected. The published baseline is retained unchanged. Next gates: review PPTX #13, complete Linux/Windows Node 20/24 packed/browser/native checks, address findings, finalize unreleased changelog/version, merge/tag/publish 0.5.2 only after gates pass, then fresh registry/native verification and downstream adoption. Do not republish 0.5.1 or advance actual-release verification refs early. Continue remaining native fidelity and dependency reviews (core schema generator/TypeScript, pptx.dev Commander/js-yaml), plus the previously pending Vercel duplicate-comment sign-in. The full goal remains active.\n\n## Latest checkpoint \u2014 expanded native coverage exposes export gaps\n\nCore PR #37 merged as `13fc56e0b1af8b24ca93ddd871cb6308bc4b77fa`, tree-identical to reviewed `f3f057cbcfa720e12eb3f46eca0cf8c7e5d9384b`, after Node 20/24 package/coordinated CI `34317326511` / `34317326517` and Bugbot.\n\nThe new [19-slide native feature matrix](native-feature-matrix-2026-09-09.md) uses actual registry core 0.7.0/render 0.5.0/PPTX 0.5.1, published examples and controlled local Calibri. PowerPoint 16 passes open/edit/save/reopen for every slide; Node 20/24 validates all 24 original/native-saved/native-edited deck imports and every native edit. Three native tables, one Office chart and one picture are verified. Hash-bound reports and all contact sheets are portable in `docs/evidence/native-feature-matrix/`.\n\nNative raster review found unresolved metric sizing, quote/source/attribution layout, flattened timeline, code panel styling, chart-axis contrast/ticks and text wrapping differences. Zero schema/converter errors did not detect them. The goal is active and these are priority export fixes; do not claim native equivalence from the successful file/edit checks. No package was republished.\n\npptx.dev Monaco migration is saved in [PR #24](https://github.com/Data-Advantage/pptx-dev/pull/24), branch `codex/monaco-worker-migration-20260909`. Supported worker exports and the new JSON API fix Dependabot #18's build failure. Initial application commit `e9d089462580f2d5c8f1b5d83b283b215a9b0a71` passes Linux/Windows CI `34318174221`, Bugbot, 592 tests and a 214-page build. All five Edge tests pass on exact preview `dpl_FGHxNYV6GDpReD9Ez8KYXNF59xno`; the final test-only revision fixes offline readiness/completion timing and requires renewed review/CI before merge, exact deployment verification and closing #18. Production remains the previously verified `fa94477f8fceb8bb1a0d62fa23d7e0d05423e94a` until that gate completes.\n\nContinue other explicit dependency compatibility reviews and pending Vercel duplicate-comment configuration as recorded below. The previously requested browser passkey sign-in remains separate from working CLI deployment access.\n\n## Latest checkpoint \u2014 pptx.dev browser workflow deployed and native-verified\n\npptx.dev PR #22 merged as `fa94477f8fceb8bb1a0d62fa23d7e0d05423e94a`, tree-identical to reviewed `c18b1fdd5d5e5e2e10b259957ba678def598a2ac`. Linux/Windows CI `34316394032` and renewed Bugbot pass; all three review threads are resolved. Production `dpl_4bQ6pSkG7kiCw8FNAPuEx9RtumTS` is READY on that merge and serves www.pptx.dev, pptx.dev and existing API/MCP aliases. All four actual public Edge tests pass: Inspector author/preview/source undo/redo/share/reimport/offline PPTX export; Author canvas edit/tab changes/undo/redo/source exports/copy/local requests/PPTX/undoable import/malformed-file recovery; hostile shared/imported document DOM checks; exact installed-package toolkit proofs. Local verification includes 592 tests in 60 files and all four starter decks (17 slides) rendered/exported/reimported with the published packages. Starter layout/theme aliases were migrated to resolvable public catalog IDs.\n\nAll 33 deployed font files and full licenses match the actual installed registry renderer, verified by the repeatable `node scripts/verify-deployed-browser-fonts.mjs <registry-consumer> https://www.pptx.dev` on Node 20/24. [Font hashes](evidence/pptx-dev-browser/fonts.json) and [production-native report](evidence/pptx-dev-browser/native-production.json) are portable. The actual Author production download has SHA-256 `383512f28856d1b0d86ddd378d63b5a529e9928983743d9ebac72d99200c8ac4`, identical to the final local candidate fixture. PowerPoint 16 exposes native editable title/table, preserves the title edit through save/reopen, rasterizes the slide and produces a schema-valid reimport with the table intact. The native-saved file hash is `9b1941ae5ae36653790375d28028b20695a197d54811cb6369b528ec9cbb1ffb`. See the [merged workflow and repeatable scripts](https://github.com/Data-Advantage/pptx-dev/blob/fa94477f8fceb8bb1a0d62fa23d7e0d05423e94a/docs/browser-opf-workflow.md). This remains targeted native editability evidence, not broad raster equivalence. Hosted account/AI calls and the legacy Decoder/API are separate from the tested free browser workflow.\n\nThe same continuation merged pptx.dev action maintenance PR #23 as `5c862d23c39f330e4fccdaa5a45bd053ae86a1dc`: real wheel/sdist artifact upload/download, exact filename/hash comparison and Twine checks pass on Linux/Windows in `34315591982`; full application CI `34315591938` and Bugbot also pass. Immutable upload 7.0.1/download 8.0.1 retain ZIP behavior and fatal digest checks. The missing `sdk/mcp` publisher was retired, and Dependabot PRs #16/#17 closed as superseded. PPTX parser lock PR #12 merged as `9c0abf1d6f296a62322fac7c4ef5c91d025a3705`, tree-identical to tested `5016051b45bb35a5d02591cc720a82dda95eae6e`, after all four Linux/Windows Node 20/24 jobs `34307685202`. It matches the parser graph already used by fresh 0.5.1 consumers. No packages were republished, and actual release verification refs stay unchanged.\n\nCore handoff PR #36 merged as `0bc35c24c5011af81ecb5d9a93626d901331fde2` after coordinated CI `34315154485`, package CI `34315154475` and Bugbot. A fresh audit of all seven repositories finds zero open Dependabot security alerts without dismissals. Remaining separate dependency reviews: core TypeScript #16 and schema-generator #13; pptx.dev Monaco #18, Commander #19 and js-yaml #20. Vercel redundant-comment settings still await the previously requested browser passkey sign-in; project protection/security notifications have not been weakened. Preserve unrelated website PR #4 and pptx.dev PR #6. Continue broader native/UX verification and the remaining compatibility reviews; the overall goal is active, not complete or blocked.\n\n## Previous checkpoint \u2014 gallery PowerPoint deployed; pptx.dev browser workflow in review\n\nThis section supersedes pending states in the historical checkpoints below. The goal remains active. No completed package release was republished.\n\nCore PR #35 merged as `264457659c7149e4e8684fab4c0b895388ad2344`, from reviewed `875ea7da4112ec10bb7549c7ca8ebd5053c9b304`, after coordinated CI `34313022598`, package CI `34313022602` and Bugbot. The release plan pins editor example source `eea4b3763026820798cb7e611f01574681c1742c` independently from actual published package verification refs. Registry gallery builds preserve runtime bytes and include complete linked license notices as an eighth hashed resource.\n\nGallery PR #22 merged as `73737dc5c50632c29234d7e5df2704e28a3ba121`, from reviewed `dae38538cb7c90090a9072247af16c8833a84b4f`, after CI `34313026600` and Bugbot. Production `dpl_7bZ8BZqmFTG57NNA48VEMrCVd4np` is READY on that exact merge. All eight deployed resources and registry integrities verify; both real Edge tests pass against https://www.pptx.gallery, including offline author/import, weighted layout, inline edit/undo/redo, OPF download, editable PowerPoint download/native merged-table XML, conversion and UI reimport equality, undo and redo. The full browser PowerPoint workflow is now public.\n\npptx.dev [PR #22](https://github.com/Data-Advantage/pptx-dev/pull/22), branch `codex/published-browser-workflow-20260909`, saves candidate `4c4e6cfb02abc8af62023674e65619dee27efca5`. Inspector and Author now use the published renderer for actual previews and the published converter for local PowerPoint export with shared font measurements. Author adds the published editable canvas and persistent validated undo session across source/preview tabs, plus local OPF/PPTX preview/import as one undoable replacement. These manual operations require no account or paid service; hosted APIs/AI remain separate. No Convex backend code changes.\n\nLocal Windows Node 24 checks pass: 591 tests in 59 files, typecheck, full 214-page production build, zero-advisory audit and all three real Edge E2E tests. Author testing caught and fixed offline canvas remounts losing their font registry. The final test verifies offline tab changes, inline edits, undo/redo, active-draft export, merged-table native XML, browser/Node import equality, import undo/redo and malformed-file recovery. Its actual downloaded file passes PowerPoint 16 native text edit/save/reopen/raster/reimport with one native table. Source SHA-256 `9744aed5c41da31187bb5a98dabec3ee3b0edacb9fe263f698039cb0a7c3b84b`; native-saved SHA-256 `cda33e17824abb265db10f02138797f3c6c36eb0e7231e0b93f3c2587fd928ee`. See [portable workflow/native evidence](https://github.com/Data-Advantage/pptx-dev/blob/4c4e6cfb02abc8af62023674e65619dee27efca5/docs/browser-opf-workflow.md) and its repeatable scripts. This one-slide native fixture does not establish broad raster equivalence.\n\nNext gates: review current pptx.dev PR #22, complete Linux/Windows CI and Vercel preview checks, address findings, merge/deploy, then run all three tests against the actual public deployment and update this handoff. Production pptx.dev remains on `f1f9e700ae2648467b36baf22b3393a216b78780` until then. Continue the remaining dependency-major/action reviews and broader native comparisons. Vercel duplicate-comment settings still await the user's previously requested passkey sign-in; no notification setting or security alert was suppressed. Preserve unrelated website PR #4 and pptx.dev PR #6. All source checkpoints are on GitHub; local generated artifacts are optional evidence, not required resume inputs.\n\n## Historical browser PowerPoint workflow candidate \u2014 September 9 UTC\n\nEditor PR #7 has now merged as `ccd42d9276f7e47a545205469dc2665e03c28a8f`, tree-identical to the fixed candidate below, after Node 20/24 CI `34312112286` and renewed Bugbot. Core PR #35 and gallery PR #22 save adoption. Their initial CI/reviews pass; a final linked-license packaging update requires renewed checks before merging/deployment. The registry builder now preserves runtime JavaScript untouched and includes full package notices plus pinned upstream license supplements in the eighth hashed resource, `playground.js.LEGAL.txt`. Both local gallery browser tests pass with this final packaging, including offline PowerPoint export/reimport. No notification settings were changed; the Vercel browser still requires the previously requested passkey sign-in.\n\nCore deployment checkpoint PR #34 merged as `4fcc217287ddf6f8ec3c6f4f351d9b1d4534df69` after package/coordinated CI and Bugbot. New work is saved in editor [PR #7](https://github.com/OpenPresentation/opf-editor/pull/7), branch `codex/browser-pptx-transfer-20260909`, candidate `eea4b3763026820798cb7e611f01574681c1742c`. Its playground accepts local PPTX in the existing preview/import dialog and exports editable PowerPoint using the preview's text measurements. Import remains a validated undoable change; export commits the active canvas draft and displays conversion notes. No package version changes or republishing are needed.\n\nLocal Node 20/24 full editor suites and offline-after-load Edge E2E pass. Actual downloaded PPTX contains native text and a merged table; PowerPoint 16 permits editing, save/reopen and valid reimport with its native table preserved. The portable [browser/native report and scripts](https://github.com/OpenPresentation/opf-editor/blob/eea4b3763026820798cb7e611f01574681c1742c/docs/browser-pptx-workflow.md) distinguish this targeted fixture from broad raster equivalence. Review caught the converted-image JSON size edge case; the fix retains schema/nesting/item validation and adds a real compressed-image regression on both runtimes. Renewed upstream CI/review must pass before merge.\n\nCore branch `codex/gallery-pptx-workflow-20260909` separates immutable example source refs from published package verification refs and includes the new host module in registry-only gallery builds. Gallery branch `codex/browser-pptx-transfer-20260909` carries regenerated assets and extends actual E2E to offline PowerPoint download/native-table inspection/reimport/undo. Its 106 unit tests, typecheck, audit and full build pass; the initial bundle passes both browser tests. Final fix bundle review, production deployment and public E2E remain gates. These candidate controls are not yet the deployed gallery. The main pptx.dev published renderer/editor/exporter integration and remaining dependency reviews remain open.\n\n## Latest checkpoint \u2014 all three 0.5.1 production deployments verified\n\nThis section supersedes pending merge/deployment states below. Core PR #33 merged as `188c32333a903fed9058d781caaaae4cd10b3d28`, from reviewed `1950afe9804d7e4f7037372d24e8b9d8b864f5fb`. Package CI `34309217317`, coordinated Node 20/24 CI `34309217315` and Bugbot pass. The release plan and immutable PPTX verification ref now select published 0.5.1 at `f7f30082da3568a4f911d42493ffc75c77dd4e14`. No package was republished.\n\n- openpresentation.org PR #16: merge `680be53dd69d99701f8b3f21e7e1c0f9b5f9390f`, production `dpl_9aR19f8JG7GHDukBnTLQv4b2hhTm`. All four public Edge tests pass: accurate changelog, six skill files and installer command, mobile layout and exact showcase downloads.\n- pptx.gallery PR #21: reviewed `93f9a720aa6ebe3b48a981f52012f809f6f8cd40`, merge `2ea8ccb75b9a6d9b64a93e6ec36d78100c044f8a`. CI `34309168015` and Bugbot pass. Production `dpl_5cooy8gD6MrZXu5vDDXNNxkBpFjN` is READY on that merge. The deployed manifest and all seven asset hashes verify; both real Edge tests pass, including JSON authoring, preview, inline edit/undo/redo, OPF download and reimport.\n- pptx.dev PR #21: reviewed `be44a1230dd17eb8ae8ca3889304aa2fb084b49c`, merge `f1f9e700ae2648467b36baf22b3393a216b78780`. Linux/Windows CI `34309892749` and Bugbot pass. Production `dpl_wkf6fiWCeyW1E562zHFU9RXwM92X` is READY on that merge. Both real Edge tests pass against https://www.pptx.dev: anonymous inspector author/preview/edit/undo/redo/OPF-download/shared-reimport and the toolkit's exact installed package versions plus render/edit/export proofs. Local self-hosted pages no longer request unavailable Vercel analytics; production analytics remains enabled. Its legacy direct PptxGenJS generator still requires the scoped image-size removal override.\n\nRemaining dependency reviews are explicit: pptx.dev Monaco #18 fails CI because 0.56 changes worker export paths; Commander #19 requires Node >=22.12 while its CLI promises Node 20; js-yaml #20 fails codec/API tests because version 5 changes exports. Evidence and migration requirements are posted on each PR; none was blindly merged. Core TypeScript #16 and schema-generator #13 remain separate compatibility reviews. pptx.dev actions #16/#17 and its obsolete missing-sdk/mcp publish workflow still need maintenance. Vercel duplicate comments await the previously requested browser passkey sign-in; no alert or notification setting has been suppressed.\n\nNext implementation milestone: free browser PPTX import/export and repeatable complete author/import \u2192 preview/layout \u2192 edit/undo \u2192 export/reimport coverage, then integration of the published renderer/editor/exporter in pptx.dev's main flow. The gallery currently exposes OPF transfer only, and pptx.dev's main preview/export still use custom implementations. Targeted native PowerPoint edit/save/reopen/raster evidence covers three slides, not broad native raster equivalence. Preserve unrelated website PR #4 and pptx.dev PR #6. Resume sources from the GitHub merge commits above; generated local artifacts are not required checkpoints.\n\n## September 9 UTC \u2014 PPTX 0.5.1 published and registry/native checks verified\n\nWebsite PR #16 is merged as `680be53dd69d99701f8b3f21e7e1c0f9b5f9390f` after CI `34308522871` and Bugbot. Production `dpl_9aR19f8JG7GHDukBnTLQv4b2hhTm` is READY on that commit; all four real Edge production tests pass, including the accurate 0.5.1 changelog, skill installer, mobile layout and unchanged showcase downloads. Gallery PR #21 and pptx.dev PR #21 save their 0.5.1 adoption candidates and await full review/deployment checks. pptx.dev's clean install, audit, 591 tests and typecheck pass; its legacy direct PptxGenJS generator still requires the scoped removal override.\n\nCore PR #33 records the new registry refs and native evidence. Its first coordinated run exposed a local preview-packer omission: the staging builder copied only `dist`, excluding declared vendored runtime/license files. The corrected builder copies every declared literal package payload, validates staging paths and uses portable Windows npm invocation. Fresh local preview packs and consumer checks now pass on Node 20/24; renewed coordinated CI is required before merging. Published tarballs and both registry fidelity suites passed independently.\n\n**PPTX security patch checkpoint:** PR #11 merged as `f7f30082da3568a4f911d42493ffc75c77dd4e14`, tree-identical to reviewed `13d404ab4a8f029622957c8afe53f339c4a6949f`. All four Linux/Windows Node 20/24 jobs in CI `34307186304` and Bugbot pass, including fresh packed installs and real Chromium suites. Actual local Edge and PowerPoint tests pass. Tag `opf-pptx-v0.5.1` triggered successful trusted publication `34307645895`; npm records publication at `2026-09-09T03:37:39.613Z`. Fresh Node 20/24 five-package installs and full pinned registry fidelity suites pass. The consumer audits clean, with 64 registry signatures and 15 attestations verified. The actual registry tarball also passes native PowerPoint edit/save/reopen/reimport and the unchanged three-slide raster measurements. Do not publish again. See the portable [PPTX evidence](https://github.com/OpenPresentation/opf-pptx/blob/f7f30082da3568a4f911d42493ffc75c77dd4e14/docs/security-0.5.1.md). The patch removes the unused parser from ordinary npm installations by shipping unmodified, licensed and hash-verified upstream runtime code. Vendored upstream advisory review remains separate from npm's installed-graph audit.\n\nCore documentation PR #32 merged as `900613f14ab7ed2d57aa6246f6ce7c3519cad39d`. Supported Node 20 types PR #31 merged as `47190652f436e80fa5dd0a947bc1ceeb6db709ff` after all package/coordinated/Windows/macOS checks. Website action PRs #12/#13 merged as `227088da3f2aa48724d53df8625d0dad7d052005` and `174fc0d953526454848da07db9013ab35ceb5e5e` after renewed combined CI. Gallery PR #20 merged as `d01cbfc24855d5e41adc6e092841554196a3e9cb` after full CI `34307438488`; action PRs #16/#17/#18 were closed as superseded. A false-positive missing-pnpm-tag finding was resolved with the live annotated tag and successful exact-head CI evidence. Open Dependabot security alerts were refreshed across all seven repositories: zero, without dismissals. This does not change historical published package graphs.\n\n**Production checkpoint:** pptx.dev PR #15 is now merged as `06ebef116608110fa88ac98cbcd6fe8ea6ad76f1`. Reviewed head `aad6b5ce29dc4ed5b03a7982121ff4a7ea4543bc` passed Linux/Windows CI `34304827786`, Bugbot, an actual adapter build and deployed preview E2E. Production `dpl_638zt5oC7grWNTYEXL3XM4cFMbGE` is READY on the merge, with www.pptx.dev, pptx.dev and API/MCP aliases. The real Edge inspector author/preview/edit/undo/redo/OPF-download/shared-reimport test passes on https://www.pptx.dev. GitHub open Dependabot alerts are now zero without dismissals. SDK/CLI source builds use the single audited root workspace, and standalone output remains supported outside Vercel. This is the first adoption baseline; the main custom preview/export still needs replacement.\n\nCore PR #30 merged as `6967b037c934c665e312086e232545cb71753bcf` after Node 20/24 package/coordinated checks, full Windows/macOS core/CLI checks and Bugbot. Renderer maintenance PR #7 merged as `ad59248ad8dbf11e519c1ba75e95d6d3fa4a39ed`; editor maintenance PR #6 merged as `aeb2871ba381bf97656e58418b5271ec764ed0d5`, both with Node 20/24 CI and Bugbot. These add grouped weekly Dependabot, unfiltered audits and reviewed immutable actions; no package version changed or was republished. Existing published verification refs remain correct.\n\nVercel duplicate bot-comment configuration requires a browser passkey sign-in. CLI authentication and production deployment work. The user was asked to complete the open login page when convenient; no notification/security setting has been changed yet. Continue unaffected work. pptx.dev action PRs #16/#17 remain for individual review; the obsolete missing-sdk/mcp publishing workflow also needs maintenance. Existing PPTX 0.5.0 keeps its older dependency graph; 0.5.1 fixes ordinary new installations without the incompatible downgrade.\n\nThis checkpoint supersedes the historical pending states below. Core PR #29 merged as `e49278514ca3f98b0e14e47ceaa4315adada00b1`. All five intended package releases and the six-skill npx installer remain published; do not republish them. The release plan already pins their actual immutable release commits.\n\nWebsite security PR #15 merged as `2f1b5428a06079e70f3ad67653768fa55a8c463c`; production `dpl_Bdxr6u3j6rdEjp9fJP9RbLp4f2pS` is READY on that commit. All four public-site browser tests pass, including the accurate changelog and complete skill files/clipboard command. Gallery security PR #19 merged as `7d661c074a73dc81487a713a2af040246e62a097`; production `dpl_3GbDE7grPv3zCyCzfzhgAKuCuTsg` is READY on that commit. Both public gallery browser tests pass, including exact bundle hashes and OPF author/edit/undo/download/reimport. Both upgrades passed CI and Bugbot before merging. See [September 9 security evidence](security-2026-09-09.md).\n\npptx.dev PR #15's earlier standalone/adapter packaging failure is resolved: ordinary builds preserve standalone self-hosting, while Vercel uses its adapter output. The exact final commit, full CI and production evidence are recorded above. Its primary renderer/exporter adoption remains incomplete.\n\nCore security work is on `codex/security-policy-20260909`: patched js-yaml/esbuild, unfiltered CI audit, consistent LF text checkouts, reviewed immutable actions in the portability workflow, and routine Node-type major-update policy. TypeScript 7 PR #16 remains deferred because of tsup declaration-bundler incompatibility. Schema-generator PR #13 changes the exported ContentPayload type and remains separate for consumer compatibility review; the security fix does not depend on it. Node 26 types PR #15 is closed because declarations must match the minimum Node 20 runtime. No security alert is dismissed.\n\nRemaining work: merge the updated core 0.5.1 verification refs and deploy downstream adoption/changelog (website PR #16 is prepared with verified npm dates and unchanged showcase bytes); finish application action PRs and redundant Vercel comments; free browser PPTX import/export controls and repeatable complete workflows; actual published renderer/editor/exporter integration in pptx.dev; broader native PowerPoint comparisons. Preserve website PR #4 and pptx.dev PR #6. Native PowerPoint evidence remains three targeted slides, not broad pixel equivalence.\n\n## Latest checkpoint \u2014 deployed installer and gallery; pptx.dev integration underway\n\nUpdate: pptx.dev [draft PR #15](https://github.com/Data-Advantage/pptx-dev/pull/15) saves the compatibility/security candidate at `08fab78`. A fresh Windows Node 24 frozen installation passes 588 tests, typecheck and compile build. Its root audit is now zero: an exact-version pnpm override removes PptxGenJS 4.0.1's unused image-size dependency, and an installed regression test confirms it cannot resolve while text/table/image export works. This does not patch image-size or change existing public npm packages; separate SDK lockfiles still have an esbuild advisory. Browser testing subsequently found missing-auth configuration assumptions on public inspector pages; fixes and repeatable E2E are being added before deployment. Core pnpm/action-setup PR #12 merged as `e43e263795c824b0fe6bddc4b37deb612a196766` after renewed combined Node 20/24 checks. Gallery GitHub open security alerts have now reached zero without dismissals.\n\nThis section supersedes pending states in the historical checkpoints below. All five intended packages are published: core 0.7.0, renderer 0.5.0, PPTX 0.5.0, editor 0.4.0 and CLI 0.5.0. Do not republish them. Core PR #28 merged as `51445f03b70bed896e53e346f2fb7b2c04293b94`, with renewed review and package/coordinated/Windows/macOS checks. The release plan and published CLI test source are pinned to the actual CLI release commit, independently of future local CLI development.\n\nWebsite PR #14 merged as `49d30c6a25d684e7f1a3cbdca44ec565e1b9472f`; production deployment `dpl_6iQrr4VNh9Mu61DvdJXJ6Xs9c8Rc` serves that commit. Four production browser tests pass: accurate releases, mobile layout, exact showcase downloads, and the copied npx installer command plus every served skill file hash. The changelog and supported skill installation documentation are live. Preserve unrelated website PR #4.\n\nGallery PR #15 merged as `188758dcde7248f70ceeb44238ba5986be4c91d0`; production deployment `dpl_6WQqZZAeS28tDCxuMLa6dJeWw7oo` serves that commit. Two production browser tests verify the seven deployed bundle files against their hashes and a real JSON-author/preview/inline-edit/undo/redo/OPF-download/reimport flow, including a styled merged table. Local verification passes 106 unit tests, a 1,925-page build, catalog checks and zero npm advisories. Browser PPTX import/export controls are still absent from the editor example: do not claim this OPF workflow proves PPTX UI coverage.\n\nCore Dependabot checkout PR #10 merged as `84c757e55234ea8c8706ba8717717d7a4c541005`; setup-node PR #11 merged as `414c40fb6bfa2f7f33714ddb949f43a7f8ce70d4`. Both received migration review and passing Node 20/24 checks. pnpm/action-setup PR #12 has a resolved adjacent-line merge conflict and renewed CI pending on `9f10ef3`. TypeScript 7 PR #16 remains unmerged: explicit Node globals fix its first error, but tsup's declaration bundler fails against the removed legacy TypeScript API. Failure evidence is posted on the PR. Review other majors individually; security alerts remain visible.\n\npptx.dev work is on Data-Advantage/pptx-dev branch `codex/published-ecosystem-adoption-20260908`, based on `4a1fc69af09addd37fe62500a1ab8b50fa63cbf8`. It upgrades the four OPF dependencies to the published set, updates vulnerable dependencies and replaces AI canaries with compatible stable releases. Its 575 existing tests, typecheck and compile build passed, followed by a new installed-package edit/undo/redo/export proof. Running the formerly Unix-only standalone playground tests then exposed unbounded palette traversal of recursive groups; the fix and regression coverage are in progress. No pptx.dev candidate is deployed yet. Its primary preview/export still use custom implementations, so dependency upgrades alone do not establish complete adoption. Preserve unrelated PR #6. Remaining high image-size advisories have no published patched version; do not dismiss them or claim a clean audit. SDK lockfile maintenance, application E2E, free browser PPTX workflows and broader native fidelity verification remain open.\n\n## Earlier checkpoint \u2014 CLI installer published; website changelog deployed\n\nCLI 0.5.0 is published. PR #27 merged as `7a2845f45bd7c6f48312b07100851c0ee29a9d1c`, tree-identical to `fcaa85fb50c06dd737f9e71419f3b9a40618184d`, after Linux/Windows/macOS Node 20/24 checks and successful renewed review. Tag `cli-v0.5.0` and trusted publish run `34261574915` succeeded. Registry gitHead/provenance and fresh global/npx-style installs pass on Windows Node 20/24. Do not republish CLI 0.5.0 or any earlier completed package release.\n\nThe supported command is `npx @openpresentation/cli@latest skills install`. It installs all six bundled skills, preserves project instructions and refuses to overwrite customized skills. Core follow-up branch `codex/cli-release-adoption-20260908` advances the release plan to CLI 0.5.0 and adds repeatable published CLI installer checks. Fresh complete registry ecosystem tests pass on Node 20/24.\n\nWebsite PR #11 merged as `c1cbbbb4e91911392612a157155441b523f187dc`. Vercel production deployment `dpl_ApPs9yCN43U6zVsGEkSmfQ6tFRTM` serves that commit. All three browser checks pass against https://www.openpresentation.org: published history and package links, mobile layout, and exact OPF/SVG/PPTX download hashes. The separate website changelog task is deployed. Follow-up branch `codex/skills-installer-site-20260908` adds the newly published CLI 0.5.0, installer quickstart and its immutable documentation snapshot. Four local browser tests pass, including actual command copying and every file hash in all six served skills. Follow-up CI/review/deployment remain pending.\n\nGallery adoption is in progress on `codex/published-ecosystem-adoption-20260908` in Data-Advantage/pptx-gallery. Targeted dependency updates pass 106 existing tests, a 1,925-page build and a zero-advisory audit. Its regenerated registry bundle uses core 0.7/render 0.5/PPTX 0.5/editor 0.4/CLI 0.5 and validates/renders 854 documents. Final bundle checks, browser workflows and deployment remain pending. The existing editor example lacks browser PPTX import/export controls; addressing that gap is separate from updating the bundle. pptx.dev adoption/security and the six core major Dependabot PRs remain open. Historical sections below are superseded by these checkpoints.\n\n## Windows continuation checkpoint \u2014 registry releases complete\n\nRenderer 0.5.0, PPTX 0.5.0 and editor 0.4.0 are all published with provenance after exact-head checks and review. Their published merge refs are recorded in `release-plan.json`; do not republish them, core 0.7.0 or CLI 0.4.0. Fresh full-set registry ecosystem and pinned rendering/export fidelity checks pass on Windows Node 20/24, including the unchanged 805-slide raster baseline. Registry editor pointer/keyboard typing, formatting and undo pass in Edge. Registry PPTX passes native PowerPoint open/edit/save/reopen/reimport and two targeted border raster assertions; broad pixel equivalence is not established.\n\nCore PR #26 merged as `533b53cd7db3cf58e9ebf5fbd987741323ea2699` after full Node 20/24 coordinated CI, package CI and successful Bugbot review on `3d1c2bbc7c68a3f74f68232d1ae320a4f41ccdfd`; merged tree is identical. The complete release plan and immutable CI refs are on main.\n\nContinue CLI 0.5.0 on `codex/skills-installer-20260908`, [PR #27](https://github.com/OpenPresentation/opf/pull/27). All six skills are bundled with safe install/update/status, offline packed installation and Windows checks. It remains unpublished. Review found overly strict ancestor-symlink rejection; canonical parent resolution now supports linked project directories while rejecting linked skill destinations, and macOS CI was added. Wait for final CI/review before release.\n\nMain website work is on Data-Advantage/openpresentation-site branch `codex/published-ecosystem-adoption-20260908`, [PR #11](https://github.com/Data-Advantage/openpresentation-site/pull/11), initial head `83ccb57`. It adds the accurate published changelog, core 0.7.0 and complete registry showcase, targeted security fixes with zero current local audit advisories, grouped Dependabot and browser/download CI. Local build and three browser tests pass; deployment remains pending. Gallery and pptx.dev adoption/security/full workflow E2E remain open. See [current Windows evidence](evidence-2026-09-08-windows.md). Historical checkpoints below are superseded where they describe unpublished downstream packages or stale lockfiles.\n\nThe user requested an immediate stop and remote checkpoint to move computers. Resume from GitHub; do not depend on the old computer's temporary worktrees, tarballs, logs, or browser state. The goal is ongoing, not completed or blocked. User authorization covers commits, pushes, PR creation/updates/merges, tags and npm publication. Recheck CI/reviews and exact commits before releases. Do not bulk-merge unrelated Dependabot PRs. No subagents unless requested.\n\n## Goal\n\nMake OpenPresentation a polished, reliable, fully open presentation ecosystem for people and AI agents: authoring JSON, dynamic layout, browser preview, intuitive WYSIWYG editing and editable PowerPoint export. Keep core free, open source, provider-neutral and usable without a paid service or AI account. Publish compatible packages in dependency order and prove the workflow using clean registry installations. Advance presets, rich text, tables, media, fonts and layout fidelity. Evaluate schema support, browser interactions, rendering and native PowerPoint compatibility separately. Public sites must showcase the same installable tools users receive.\n\nEarlier PR #8 reconciliation and the missing core 0.4.0 changelog entry are already handled; do not repeat them. The NEW public website changelog request below remains open.\n\n## Portable checkout map\n\nClone sibling repositories so the core ecosystem scripts can find their sources. Read each repository's AGENTS.md. Avoid resetting any existing user checkout.\n\n| Repository | Branch to resume | Remote checkpoint |\n| --- | --- | --- |\n| OpenPresentation/opf | codex/styled-table-release-sync-20260908 | [PR #26](https://github.com/OpenPresentation/opf/pull/26), this handoff and verification scripts |\n| OpenPresentation/opf-render | codex/styled-table-cells-20260908 | [PR #6](https://github.com/OpenPresentation/opf-render/pull/6), head `b47bba101ab78dc226d9ff848bb8622e3a0109e1` |\n| OpenPresentation/opf-pptx | codex/styled-table-cells-20260908 | [PR #10](https://github.com/OpenPresentation/opf-pptx/pull/10), head prefix `a0e9d14` |\n| OpenPresentation/opf-editor | codex/styled-table-cells-20260908 | [PR #5](https://github.com/OpenPresentation/opf-editor/pull/5), head prefix `21449a7` |\n| Data-Advantage/pptx-gallery | main | Deployed merge `12fcf77399cb6ae21d3bfcea5cfafb37c3323b79`, PR #14 |\n| Data-Advantage/openpresentation-site | main | Deployed merge `280a616701320cd1ca8d2484cf166fb91d882137`, PR #10 |\n| Data-Advantage/pptx-dev | master | Newly added integration scope; old checkout `4a1fc69af09addd37fe62500a1ab8b50fa63cbf8`, not yet audited or modified |\n\nUse fresh fetches to resolve full commit IDs/current PR states. The old machine's primary downstream checkouts were deliberately left untouched and lag origin; release work happened in temporary clones. Gallery's primary checkout contains a pre-existing untracked `pnpm-workspace.yaml`; not part of this work. Temporary PPTX `artifacts/` contains generated evidence/build outputs; source fixtures and builders are committed and can regenerate it.\n\n## Already published \u2014 do not republish\n\nCore PR #25 merged as `21e4cfca617ddfebeee85f79b09c35b2e82637e1`, with tree identical to reviewed head `e71f7c3d1b9a99bf210d038ceac613f72f41f894`.\n\n- `@openpresentation/opf@0.7.0`, tag `opf-v0.7.0`, successful publish run `34243706990`.\n- `@openpresentation/cli@0.4.0`, tag `cli-v0.4.0`, successful publish run `34244109903`.\n- Both registry gitHeads match the merge and have SLSA provenance. Tarball integrities matched the tested candidates. A fresh global CLI registry install reported CLI 0.4/core 0.7 and validated the styled fixture.\n- Core 404 tests, CLI 70 command checks, packed package checks, strict installed TypeScript fixture and coordinated Node20/24 CI passed before release. These results do not establish that later downstream edits are verified.\n\nCore 0.7 introduces strict styled cells `{value, style?, rowSpan?, colSpan?}` with covered positions `null`; merge ownership validation; shared anchor geometry and `.value` editing paths; padding, alignment and spanning row heights; pagination that keeps connected vertical merges. Equal column widths and content-fit row heights remain limitations for importing native arbitrary table geometry.\n\n## Immediate release gates\n\n### Renderer PR #6: draft, not published\n\nVersion 0.5.0, core dependency ^0.7.0, registry lockfile current. Prior head `b63bd0e` passed standalone Node20/24 full suites and unchanged 126-deck/805-slide raster baseline against actual registry core 0.7. A fresh candidate consumer passed and matched runtime bytes.\n\nBugbot review on that head completed neutral with two findings. They must be assessed, not treated as a passing review:\n\n1. Claimed vertical alignment was ignored. Core `layoutTable` already offsets `cell.textBox.y`; scalar and rich renderer paths consume that box. New baseline assertions prove top/middle/bottom movement. Do not add a second offset.\n2. Valid finding: default neighboring edges could cover custom borders. Follow-up commits `dabf91b` and `80ae8bb` render defaults before explicit edges and remove overlapping default segments, including zero-width/transparent/dashed edges and partial merge boundaries. Legacy tables without custom borders retain their prior rendering path.\n\nThe final head is `b47bba1`, including the regenerated tracked `dist/svg.js`. On the identical source/build from `80ae8bb`, focused styled-table regressions pass on Node20/24 and renderer syntax checks pass. Full suite/raster baseline, renewed CI/review, and a new packed candidate remain required. The previous tarball integrity is obsolete. Review threads were left open for evidence-based follow-up. PR description records these distinctions.\n\nNext: run checks on exact head, address review findings, mark ready, wait for CI/review, merge with exact-head protection, verify merged tree, tag `opf-render-v0.5.0`, monitor trusted npm publish, verify registry version/gitHead/provenance/integrity against the new tested tarball.\n\n### PPTX PR #10 and editor PR #5: draft release preparation\n\nTheir implementation and final README/CHANGELOG/package.json version changes are pushed. **Lockfiles still describe the preceding dependency set.** This is an explicit unfinished checkpoint because renderer 0.5.0 does not exist on npm yet. Do not merge or publish these drafts as-is.\n\nAfter renderer publication, regenerate lockfiles from the registry and run clean installs. PPTX targets 0.5.0; editor targets 0.4.0. Both require core ^0.7.0 and renderer ^0.5.0 (optional peer, exact 0.5.0 development dependency). Use Node20 and Node24; prior toolchain was npm11.16/pnpm10.33.2. Run standalone suites **without NODE_OPTIONS source loaders**. Pack final versions, test fresh consumers, verify runtime bytes, update PR evidence, review/merge and tag in dependency order. Inspect workflows for exact tag patterns (PPTX `opf-pptx-v0.5.0`; verify editor pattern before tagging).\n\nPPTX implementation preserves supported native fills/alpha, margins, alignments, borders/dashes, rich runs and dense merges; conditional styles resolve band/edge/corner precedence and archive-local line references. Malformed merges retain source text with diagnostics. Different border segments on merge continuations preserve anchor style with a diagnostic. Native arbitrary row/column geometry, effects and PowerPoint raster parity are incomplete.\n\nEditor uses `.value` inline paths, preserves styles/spans, rejects invalid structure, supports rich promotion/selection formatting and undo; covered slots have no editable target. Browser and model fixtures are committed.\n\n### Core release sync: draft\n\nThis branch adds installed-package styled editor browser fixture generation to `scripts/test-packed-ecosystem.mjs` and styled renderer/PPTX tests to `scripts/test-registry-fidelity.mjs`. The latter clears NODE_OPTIONS in child tests to prevent a source loader invalidating registry claims. Syntax and diff checks pass; final full registry checks are pending.\n\n`release-plan.json` still describes the previous complete published set. Update it and `.github/workflows/ecosystem-ci.yml` immutable downstream refs only after all new packages are available. Use the published core merge for core fixtures. Run fresh Node20/24 registry ecosystem/fidelity checks and actual installed-package browser interactions. Do not conflate generated browser bundles with executed UI tests.\n\nUseful core commands: `pnpm test:registry-ecosystem`, `pnpm test:registry-fidelity`, `pnpm prepare:gallery:registry`, `pnpm build:showcase:registry`. Read their scripts and release plan for arguments/setup. Source-coordinated tests may use `scripts/register-local-opf.mjs`; registry verification must not.\n\n## Evidence and public integration status\n\nBefore the final renderer border follow-up, actual Edge browser interaction verified:\n\n- PPTX native styled import: 12 checks; rich import: 20 cases; conditional table styles: 11 checks.\n- Editor legacy rich fixture: 14 checks. Styled fixture: 37 passing assertions including repeated style/undo checks, real Roboto/Roboto Mono loading, double-click/keyboard edits, empty values, scalar promotion, Bold, partial selection/Italic, cancellation, merged glyph containment and undo.\n- These were coordinated development builds; final installed-registry browser runs still remain. No styled-table native Keynote inspection was completed. No native PowerPoint raster equivalence claim is supported.\n\nGallery and main site were deployed and verified against the PREVIOUS full package set: core 0.6, renderer 0.4, PPTX 0.4, editor 0.3, CLI 0.3. Prior checks covered 854 gallery documents, 593 site routes, six skills and 584 raw resources. They do not yet showcase the full new styled release set. Update assets, docs and deployments only after final registry verification, then test actual public workflows. `pptx.dev` has not yet been assessed.\n\n## New user priorities to address after resume\n\n1. **Dependabot overload.** Inspect notices/open PRs across all relevant repos. Screenshot examples from core: TypeScript 5.9.3\u21927.0.2 (#16), @types/node20\u219226 (#15), Biome (#14), json-schema-to-typescript15\u219216 (#13), pnpm/action-setup5\u21926 (#12), setup-node4\u21927 and checkout4\u21927 (#10). These are examples, not a current authoritative PR inventory. Evaluate runtime/schema/build compatibility, security significance and CI; safely group/schedule updates and reduce redundant reviewer notifications where appropriate. Preserve security visibility. Do not blindly merge major upgrades or suppress useful alerts.\n2. **Public changelog.** Update https://www.openpresentation.org/changelog from actual published release contents and dates. Clearly distinguish live npm releases from upcoming drafts and ensure site deployment is verified. The earlier core CHANGELOG0.4 fix does not satisfy this request.\n3. **Easy skill installation.** User wants a supported npx-style skill installer like Convex's AI-file installation experience, documented and suggested in relevant CLI output. Current `docs/agent-skills.md` instructs copying entire self-contained folders; do not assume an npx installer already exists. Research current official Convex/installer guidance before choosing syntax, implement/test actual clean-project installation and sensible updates across supported agents, keep provider-neutral, document it on site/repo, and add concise actionable CLI guidance. Avoid overwriting existing user skill configuration without an explicit update flow. Six OPF skill entrypoints: author, layout, presets, edit, export, inspect.\n4. **Real downstream adoption and E2E quality.** Audit openpresentation.org, pptx.gallery and Data-Advantage/pptx-dev (https://pptx.dev) for exact dependencies/bundles and user workflows. Adopt the tested published set and assess quality visually and functionally. Inventory existing model, package, browser and E2E tests; automate missing end-to-end paths from author/import through layout/preview, editing/undo, export and reimport. Test deployment versions and editable native output; report native-app fidelity gaps explicitly. Do not answer \u201Call integrated\u201D or \u201CE2E complete\u201D from the existing unit/corpus evidence alone.\n\nContinue in reviewable milestones under existing authorization. Keep a concise evidence trail, preserve user work and stop relying on old-machine absolute paths.\n"
|
|
73
|
+
"markdown": "# OpenPresentation ecosystem handoff \u2014 2026-09-08\n\n## Current checkpoint \u2014 code integration merged; core/CLI release preparation\n\nCore [PR #54](https://github.com/OpenPresentation/opf/pull/54) merged as `8d9c9c80b788bbdc80e18ad2b6468f07b2e2321d`, tree-identical to reviewed `e8b520dd2c23e559a8d9affcfcb8772c8b8079b7`. Complete Linux coordinator `34441603873`, core CI `34441603829`, Windows/macOS CLI `34441603812` and Bugbot pass. [Portable final CI evidence](evidence/shared-code-ci-2026-09-09.json) records actual Chromium 153 code workflows, both seven-suite installed browser matrices, runtime/harness/package fingerprints and restored stale-evidence guards. The two Linux Node versions produce identical candidate tarball hashes. The separate corrected Windows installed/native evidence below remains authoritative for PowerPoint.\n\nContinue `codex/shared-code-release-20260909`. It prepares **unpublished core 0.9.0 and CLI 0.7.0**, versioned code/layout guidance and updated portable skills. The CLI-local changelog now includes the already published 0.6.0 history; no old version is republished. [Release gates and intended consumer versions](plans/shared-code-release.md) specify renderer/PPTX 0.7.0 and editor 0.6.0, with lockfile renewal and standalone checks after upstream publication. Complete core/CLI release checks and review before tagging. Keep `release-plan.json`, actual registry fixtures and all public deployments on the current verified published set until the new complete set exists.\n\nThe full repair, Auto arrange, metric/timeline/chart internals, font/multilingual/native-platform objective remains open. Preserve the exact previous package and deployment checkpoints below. New source behavior, actual installed browser interaction, schema validity and native text/raster scope remain separate claims.\n\n## Previous checkpoint \u2014 installed code workflows and coordinated CI prepared\n\nReview follow-up: renderer `b5a3722725338e8d964783e8b7f1f7b80ce28cd3` and converter `b4f4645cdaa2f5eff8a883f68533875d3b63f239` supersede the initial consumer commits below; editor remains `52e540b83e441892fd928e9f159bffbb29da5653`. A bounded installed probe found schema-valid controls emitted invalid XML and an unpaired surrogate became a replacement character. Both format boundaries now reject these with `invalid-code-text`, source path and UTF-16 offset while retaining the input. Each engine passes 132 source/metadata rejection cases and valid XML character boundaries on Node 20/24. This is separate from font coverage. [Renewed corrected-package evidence](evidence/shared-code-xml-boundary/summary.json) records passing continuous full source/tarball/browser/CLI/guard commands on both runtimes and renewed actual installed-native checks: all 24 original/saved/edited imports pass, and every native/SVG raster is byte-identical to the previously inspected valid-input fixture. The evidence below preserves the earlier checkpoint without relabeling its runtime hashes.\n\nCore PR #54's preceding `4f4a0b44584be945420f2b8d519f9417ee073e7d` passes complete Linux coordinator `34440657844`, core `34440657756`, Windows/macOS CLI `34440657695` and Bugbot. The latest CI pins now include the two character-preservation fixes and require a fresh run/review before merge. No version has been published.\n\nContinue `codex/shared-code-integration-20260909`. The four pushed source checkpoints below remain the tested runtime inputs; this checkpoint adds fresh installed-tarball code verification and pins coordinated CI to the exact consumer commits and reviewed code raster manifest. [Installed evidence](evidence/shared-code-installed/summary.json) binds all four local package hashes, lock integrity, runtime files, copied test harnesses and actual browser bundle inputs. Node 20.20.2 and 24.20.0 produce identical candidate tarballs and runtime bytes. They are private local preview packages, not published versions.\n\nThe installed checks execute 15 core code/composition tests, converter source/metadata guards, renderer measurement checks, and actual font-loaded offline renderer/editor workflows, including pointer/keyboard edits, CRLF, Tab/cancel, pagination floors, undo/redo and export/reimport. All seven prior packed browser suites also pass on both runtimes. Negative checks reject altered runtime bytes, incorrect lock integrity, external module links and loader environments, then restore the generated fixtures. CLI 69-command and standalone global/npx-style local-pack checks pass on both runtimes; Windows file-symlink privilege coverage remains in Unix CI.\n\nThe continuous Node 20 source/package wrapper passes. The first Node 24 wrapper passed its source checks but failed a new harness import; the corrected installed, tarball, browser, CLI and guard stages pass. The next harness iteration also needed to recognize esbuild's empty disabled-module stubs; it now accepts only zero-byte stubs with no imports and verifies every real bundle input stays inside the installed consumer. Neither failure changed a runtime or relaxed a product assertion. Renewed full Linux Node 20/24 CI and review remain the next gate.\n\nSeparate fresh registry installations pass the exact published package, seven browser and pinned fidelity suites on both runtimes, including 126 decks / 805 raster slides. These remain core 0.8.0, CLI 0.6.0, renderer/PPTX 0.6.0 and editor 0.5.0. `release-plan.json`, registry fixture refs and public deployments stay on that published set; these registry checks do not claim the new code feature.\n\nReal PowerPoint also passes against the fresh installed candidate runtime: eight wide/portrait slides, all 24 original/saved/edited imports, exact source/metadata and save/reopen. Native comparisons pass on both Node versions; four text-after-tab targets are within 0.007031 point of accepted stops (0.02-point gate). New native preparation validates the candidate lock/runtime against the executed browser report before copying the versioned native harness. Representative installed SVG/native rasters were inspected; baselines and glyph appearance differ. This proves the documented editable text and source-preservation scope, not pixel equivalence, substitute-font compatibility or arbitrary Office round trips. No proprietary fonts were copied or embedded; unrelated user decks stay open.\n\nCoordinated core [PR #54](https://github.com/OpenPresentation/opf/pull/54) is open. Finish its Linux CI and review, then prepare new versions and publish in dependency order. Consumers need the released coordinated core before their standalone release checks. Add actual registry code workflows only after those releases exist, update the published plan/refs, and repeat public adoption and deployed E2E. A renewed seven-repository audit still found zero open PRs and security alerts before opening this milestone. The full repair/Auto arrange/font/multilingual/native-platform objective remains active.\n\n## Previous checkpoint \u2014 shared code consumers and native round trips verified locally\n\nContinue `codex/shared-code-integration-20260909`. All source work is pushed: core implementation `8d11fd650eb14fad3473b918713d9caa95321b83`, renderer `343ffea275e2eff478fc6a355551379897b748df`, converter `860e9476520659bf65822c945bf96b253cbe6c01`, editor `52e540b83e441892fd928e9f159bffbb29da5653`. Fetch these GitHub branches/commits; the local worktree paths are disposable. No new versions are published and no consumer PR has been opened yet; standalone consumer checks still need a released coordinated core. Existing published versions, release-plan refs and public deployments remain authoritative.\n\nRenderer and converter now consume accepted filename/language/body code geometry, preserve whitespace/tabs/empty lines and avoid another fitting pass. Unspecified code layouts use shared automatic composition; explicit presets retain their slots. Editor metadata/body targets, CRLF-preserving edits, literal Tab, cancel, pagination and undo are tested offline. Guarded native shape tags reconstruct complete code/source-boundary metadata; native text edits take precedence. Damaged/deleted/duplicate groups retain visible shapes with diagnostics. Native font theme, formatting, geometry and readability policy are not reconstructed.\n\n[Portable consumer evidence](evidence/shared-code-consumers/summary.json) records 28 passing existing/targeted consumer script runs and four actual new code-browser reports across Node 20.20.2/24.20.0. The full renderer, PPTX and editor suites and existing browser/playground workflows pass on both. All 43 changed code rasters were reproduced against ordinary registry renderer 0.6.0 and visually reviewed, with four full-resolution inspections; the other 762 hashes are unchanged. A legacy test needed to read nested SVG tspans to keep checking code typography; its 36-line coverage passes without weakening its count gate. No lockfile changed.\n\nActual PowerPoint `16.0.20326.20132`, Windows `26200.9445`, passes eight wide/portrait code slides, editable source/metadata, tags and save/reopen. All 24 original/saved/edited slide imports recover exact code objects, including CR/LF/CRLF, blank/final lines and soft wraps. Four native text-after-tab targets differ by at most 0.007031 point against the 0.02-point gate. Node 20/24 comparisons agree. The native and resvg fixtures use the same local Courier New regular/bold bytes; representative wide/portrait rasters were inspected. This is neither substitute-font verification nor pixel equivalence. The first harness attempts had a missing expected cell reference and omitted explicit raster font files; corrected checks were regenerated and rerun, with no tolerance relaxation. No user presentations were closed.\n\nNext: add the new code cases to installed-tarball verification and coordinated CI, pin the three consumer commits with the reviewed code raster manifest, finish full coordinated Node 20/24 checks/review, then prepare releases in dependency order. Keep registry checks pinned to the currently published set until new releases exist. The full repair/Auto arrange/font/multilingual/native-platform objective remains active. Latest main coordinator `34434340695` succeeds; the old failed notification `34433357130` was the now-fixed Linux browser precision assertion, not an Actions billing rejection.\n\n## Previous checkpoint \u2014 code composition/pagination integration in progress\n\nCore [PR #53](https://github.com/OpenPresentation/opf/pull/53) merged as `7c978f8b7ef0cc649d8452f8f1b829f36a5ae6e3`, tree-identical to reviewed `f90f7c5152d4075a2c184959164df655ba05fa19`. The explicit SVG `geometricPrecision` correction passes Linux Chromium `153.0.8010.12` on Node 20/24 with the original 0.1-reference-pixel tolerance. Complete coordinator `34433911033`, core CI `34433911144`, Windows/macOS CLI `34433911057` and Bugbot pass. The initial browser rounding failure below remains historical evidence, not an open billing issue. [Preserved Linux report](evidence/shared-code-browser-linux-2026-09-09.json) supplements the separate Edge report.\n\nContinue branch `codex/shared-code-integration-20260909`. Core now measures filename/language/body in automatic candidates, exposes `item.codeLayout` using rounded accepted boxes, aliases compatibility `item.text` to the body, reports internal paths under strict ancestors and labels the changed scoring `grid-score-v3`. Existing pagination now evaluates the complete code payload. Six new integration tests plus all 448 core tests and preservation suites pass on Node 20.20.2/24.20.0; core/CLI typechecks pass. This is unreleased source. Renderer, converter and editor integration and the complete coordinated/browser/native gates remain unfinished; no new package/version/ref or public deployment is advanced.\n\nA repeatable native probe generates eight cases with the candidate core API, actual registry converter's PptxGenJS vendor and local Courier New regular/bold. Real PowerPoint preserves all literal tabs/spaces, native edits and save/reopen. Text after tabs begins at accepted stops within 0.010544 point (0.02-point gate). Native text widths differ by up to 0.78629 point; this is measured drift, not pixel equivalence. Current registry imports are schema-valid but trim leading/trailing whitespace, and whitespace-only shapes become placeholders. [Native evidence](evidence/shared-code-native-2026-09-09.json) and [integration audit/reproduction](plans/shared-code-integration.md) separate these observations from unimplemented OPF export/reimport integration. Native comparison passes on Node 20/24; original/saved/edited imports each have text loss. Preserve the user's PowerPoint session and all older worktrees.\n\nThe full repair/Auto arrange/font/multilingual/native-platform objective remains active. Finish the shared code consumer milestone, then continue metric/timeline/chart internals and the remaining roadmap. All published release and deployment checkpoints below remain authoritative.\n\n## Previous checkpoint \u2014 standalone shared code layout candidate\n\nCore [PR #53](https://github.com/OpenPresentation/opf/pull/53) continues on `codex/shared-code-layout-20260909`. The candidate adds `layoutCode` and public types for filename/language/body parts, original text, requested/resolved styles, readability floors, exact UTF-16 source/line ranges, explicit text/tab segment placement and bounded internal allocation. Missing space or irreducible content stays visible in diagnostics; strict mode rejects all output. This is an unreleased standalone API. Composition, pagination, renderer and converter integration remain next work, and the actual published code defects below still reproduce.\n\nLocal Node 20.20.2/24.20.0 checks pass: nine new tests, all 442 core tests plus composition/nesting/pagination/data/rich-text/list suites, public root/focused declaration checks, eight actual-font wide/portrait cases and eight controlled browser segment cases. [Geometry evidence](evidence/shared-code-layout-2026-09-09.json) binds the source, built runtime, registry packages and font bytes. [Browser evidence](evidence/shared-code-browser-2026-09-09.json) binds the same geometry to Edge `152.0.4191.66`, exact Cousine regular/bold and a 0.1-reference-pixel advance/segment-position tolerance; literal tabs and whitespace survive and no external requests/page errors occur. Both reports are identical across the two Node runtimes. The browser harness is not integrated OPF renderer or native PowerPoint output.\n\nThe Edge probe found SVG ignores the intended CSS-only tab spacing, so each accepted line now carries explicit text/tab segment positions and widths. The controlled harness reuses those positions with preserved literal tab text. Initial coordinator `34433357130` passes source/tarball/registry checks and actual-font geometry, then fails both Node versions' new browser check because Linux Chromium's default glyph advances round to whole pixels. Core CI `34433357078`, Windows/macOS CLI `34433357095` and Bugbot pass. The follow-up explicitly requests SVG `text-rendering=\"geometricPrecision\"`, retains the 0.1-pixel tolerance and writes observations before asserting, so CI preserves future failures. Renewed local Node 20/24 Edge evidence passes; renewed Linux coordinator/review remain required. This was a measured browser failure, not a billing-limit rejection.\n\nComplete review and both CI matrices of this primitive, then consume it in scoring, rounded accepted composition boxes, strict ancestor diagnostics, SVG, editable PPTX and the editor/pagination workflow. Native tab placement and source-preserving reimport need real PowerPoint tests. All previously published versions, immutable release-plan refs and verified public deployments remain unchanged.\n\n## Previous checkpoint \u2014 public documentation verified; code layout baseline\n\nCore public-evidence [PR #52](https://github.com/OpenPresentation/opf/pull/52) merged as `74f39c68585586cb2eb41a4adc96e60eeab8e9da`, tree-identical to reviewed `8fc5000bc78f5e89e5464d7efdfb3b96ed9cea01`. Core Node 20/24 CI `34429765513`, full coordinator `34429765488` and Bugbot pass. All five published packages and all three public adoptions remain verified as recorded below; never republish their versions.\n\nWebsite [PR #22](https://github.com/Data-Advantage/openpresentation-site/pull/22) merged as `e61319537de1c4defc2368b07ad92207e31c655b`, tree-identical to reviewed `f4cc87d10aa22370d5f2d7b901e85fa9bfbff449`, after CI `34429916760`, Bugbot and six exact-preview workflows passed (20.5s). It advances only the core 0.8.0 documentation pin to reviewed `8fc5000bc78f5e89e5464d7efdfb3b96ed9cea01`; no runtime dependency, lockfile or npm version changed. READY production `dpl_HaHBwTk5BW7LACfpLYUtFH1S37PY` passes all six public workflows (18.7s). Published-version reference headings, full LLM text, the complete six-skill/647-file manifest and exact raw documentation hashes match. [Website reference evidence](evidence/site-published-reference-2026-09-09.json). The accurate changelog and prior website/gallery/application browser/native evidence remain separate records. A renewed seven-repository audit finds no open PRs or security alerts.\n\nContinue core branch `codex/shared-code-layout-20260909` from that merged GitHub checkpoint. The first new baseline is reproduced on Node 20.20.2 and 24.20.0 with actual registry core 0.8.0/renderer 0.6.0 and bundled font bytes: an oversized language label receives no overflow diagnostic; a second valid fixture loses its filename and significant whitespace in serialized SVG, including spaces inside a string literal. Input JSON is unchanged. [Source and evidence](evidence/code-layout-gap-2026-09-09.json) and `scripts/probe-code-layout-gap.mjs` preserve the exact failing behavior. The helper asserts a historical defect and must not be used as a future quality-success gate. No browser glyph or native code-export claim is made.\n\nImplement the shared code payload API and consume its accepted geometry in composition, preview and export before claiming this gap fixed. Cover source/filename/language, meaningful whitespace/newlines, wrapped-line mappings, explicit readability floors, requested/resolved styles and irreducible failure. Then continue other payload internals, bounded repair/Auto arrange and the full font/native-platform roadmap. No new software permission is required; preserve existing worktrees and the user's PowerPoint session.\n\n## Previous checkpoint \u2014 all three public adoptions verified\n\nCore [PR #51](https://github.com/OpenPresentation/opf/pull/51) merged as `c2f6aefd63d1c428ac35ea3da0d600e6c009b367`, tree-identical to reviewed `ce014f1`. Core Node 20/24 CI `34426024145`, complete coordinator `34426024128` and Bugbot pass. The release plan and immutable CI refs now use the published core 0.8.0, CLI 0.6.0, renderer/PPTX 0.6.0 and editor 0.5.0 set. All individual publication and combined registry/browser/native evidence below is portable in GitHub. Never republish these versions. Continue core branch `codex/shared-quote-public-adoption-20260909` for deployment evidence and remaining work.\n\nWebsite [PR #21](https://github.com/Data-Advantage/openpresentation-site/pull/21) merged as `b0a7733cfa9a97fbb8bdb91f39bcd3075640005a`, tree-identical to reviewed `27dcdb25ef6db97db2342d106cf9b51bfd625f79`. CI `34425812307`, Bugbot and exact READY preview `dpl_2TPrYFLJuSmrmQduYeV3SDwp8xVG` pass; all six preview workflows pass (20.5s). Production `dpl_FXtMtDzuUddejNkmXv9R9SkAPMVg` is READY on that merge and serves both openpresentation.org aliases. All six public Edge workflows pass (18.8s), actual UTC npm dates and the full five-package showcase manifest agree, all downloads match hashes, and fourteen served JavaScript fingerprints are recorded. The [public changelog evidence](evidence/site-shared-quote-2026-09-09.json) and [visually inspected page](evidence/site-shared-quote-2026-09-09.png) are separate from native package raster observations. Temporary preview cookies stay in ignored local artifacts; Vercel protection remains unchanged.\n\nGallery [PR #24](https://github.com/Data-Advantage/pptx-gallery/pull/24) merged as `1403916aea3f50c7d39c965ec7136da6e4b7af32`, tree-identical to reviewed `8ed70324635c2e5fb69db5479cf13755d6635a0b`. It adopts the full set and immutable editor examples, regenerates the runtime/license manifest, and adds offline quote editing/readability/undo/export/reimport coverage. 106 unit tests, typecheck/build, all required catalog/production-markup/link checks and three local Edge workflows pass. Initial CI `34427001057` timed out after five seconds waiting for the initial preview. The reviewed fix gives only initial font/preview startup a bounded 20-second wait and uploads failure traces; renewed CI `34427426307`, Bugbot and all three exact-preview workflows pass (13.3s). READY production `dpl_ENk7dmxQ22Czhq18hKZujmcJaN9s` passes all three public workflows (10.4s) and all eight bundle/font/license/example hashes. No assertion or security alert was disabled.\n\npptx.dev [PR #29](https://github.com/Data-Advantage/pptx-dev/pull/29) merged as `482f769d4676b65ac16fe3fb4660aeaa03a77a44`, tree-identical to reviewed `ea89253de9a0e1400c297b75f295807f4a0b7239`. It adopts the four public libraries and core 0.8.0 schema/examples with otherwise unchanged dependencies. 598 tests, typecheck/build, SDK/CLI build gates, zero-advisory audit, Linux/Windows CI `34427524816`, Bugbot and all eight exact-preview workflows pass. Its actual browser download again passes native PowerPoint title/table editing, save/reopen and valid reimport; portable evidence in that PR binds the package lock, PowerPoint `16.0.20326.20132`, Windows build `26200.9445` and visually inspected raster.\n\nThe first public application run on READY deployment `dpl_6avWXN5F4L7WuqiWJG713M26oa9f` passes seven workflows but reports a lazy Monaco worker-download error when Author switches offline. Follow-up [PR #30](https://github.com/Data-Advantage/pptx-dev/pull/30) waits for a real JSON-schema diagnostic before that test goes offline and derives the canvas version marker from the installed editor package. It merged as `b9eefaac764c4a3ec009b17d363663f0c6cfe146`, tree-identical to reviewed `636da78c4b18f732530881cb09da3e5554bdcdd9`, after Linux/Windows CI `34428833533`, Bugbot and all eight exact-preview workflows passed. The readiness check also passed against the unchanged public runtime; no page-error assertion was suppressed.\n\nREADY production `dpl_F1LgvvbZ8QwcvCy8ZRnZ2WaunVDe` serves that follow-up merge and passes all eight public Edge workflows (29.4s). All [33 public font/license hashes](evidence/pptx-dev-shared-quote-fonts-2026-09-09.json) match actual renderer 0.6.0. [55 served JavaScript fingerprints](evidence/pptx-dev-shared-quote-bundles-2026-09-09.json) accompany installed-package toolkit proofs and the actual browser editor 0.5.0 marker; bundled assets are not asserted byte-identical to unbundled npm. The public Author download is byte-identical to the native-tested local/preview PPTX, SHA-256 `383512f28856d1b0d86ddd378d63b5a529e9928983743d9ebac72d99200c8ac4`. [Complete gallery/application evidence](evidence/gallery-app-shared-quote-2026-09-09.json) keeps the initial failure, reviewed fix, successful public run and native bridge separate. The original nine-PR backlog is resolved; the [fresh seven-repository audit](evidence/repository-adoption-audit-2026-09-09.json) finds zero open PRs and zero open security alerts.\n\nFinish review/merge of this core public-evidence checkpoint, then advance the website's `opfSource` documentation pin to the reviewed correction so its copied reference and LLM content use published-version wording. The release changelog itself is already accurate and live. Continue shared code-language/body measurement next, followed by metric/timeline/chart internals, bounded repair and Auto arrange, with the font/native-platform roadmap still required. No new package publication is needed for these documentation corrections.\n\nLocal setup: gallery has no own pnpm workspace file, so use `pnpm --ignore-workspace` when running its checkout nested under core artifacts. An initial gallery install touched the parent core lock; that unintended change was restored and gallery was reinstalled from its own lock. pptx.dev **does** have its own workspace policy: use its declared pnpm 11.1.3 normally, retaining `minimumReleaseAgeExclude: @openpresentation/*` and all existing supply-chain controls. Disabling its workspace discovery incorrectly bypasses that configuration and causes recent-release installation rejection. No OS settings or new user permissions are required. Preserve all old worktrees and unrelated local artifacts. Full repair/Auto arrange/font/multilingual/native-platform work remains active and substantially unfinished.\n\n## Previous checkpoint \u2014 all five packages published; coordinated registry adoption\n\nCore [PR #50](https://github.com/OpenPresentation/opf/pull/50) merged as `2a39a15cbdd750699bf8e3adac8f78420baa1fa9`, tree-identical to reviewed `edf0806e8d88d941f1dc6762cf41d045c383ebbe`. Core CI `34421921795`, coordinator `34421921845`, Windows/macOS CLI `34421921853` and Bugbot pass. Continue core branch `codex/shared-quote-registry-adoption-20260909` for the complete release-plan/CI update and final combined checks.\n\nPPTX [PR #14](https://github.com/OpenPresentation/opf-pptx/pull/14) merged as `898e3c27919a2488e1e3d384168d6b25aae4bd5c`, tree-identical to reviewed `268fcb523924c95b453acbe407d1b5359ea5f485`. Linux/Windows Node 20/24 CI `34422214063`, Bugbot and trusted publication `34422584331` pass. PPTX 0.6.0 is published. Fresh Node 20/24 registry installations verify all 19 shipped files, signatures/provenance, the 126-deck/805-slide corpus and five browser suites. Twelve fresh registry export fixtures pass real Windows PowerPoint glyph containment, editable save/reopen and six valid reimports. Exact heading/body/footer order and repeated-line counts survive; first quote lines can become subtitles and OPF quote semantics are not reconstructed. Raster differences remain observations without a pixel-equivalence threshold. [Publication](evidence/pptx-060-publication-2026-09-09.json) and [native evidence](evidence/pptx-060-native-registry-2026-09-09.json) bind the package bytes and PowerPoint build `16.0.20326.20132` on Windows build `26200.9445`.\n\nEditor [PR #8](https://github.com/OpenPresentation/opf-editor/pull/8) merged as `dba5fe5e5580a4172c052132c4db5851d1decc4c`, tree-identical to reviewed `4d056532328bdfb765701880cb35ff87a0cc8829`. Node 20/24 CI `34424194308`, final Bugbot review and trusted publication `34424531044` pass. The review's JSON-key-order no-op concern uses the existing structural comparison and has regression coverage preserving redo. Editor 0.5.0 is published and fresh Node 20/24 registry verification passes: all 32 shipped files, 67 signatures/18 attestations including test dependencies, nine model/component suites and offline author/edit/paginate/export/reimport/undo. [Editor publication evidence](evidence/editor-050-publication-2026-09-09.json).\n\nAll five published successors are independently verified. `release-plan.json` and immutable CI refs now select core 0.8.0, CLI 0.6.0, renderer/PPTX 0.6.0 and editor 0.5.0. Fresh isolated Node 20/24 combined source/tarball/registry checks pass: seven installed-browser suites, 230 assertions/eight trusted interactions per mode, four evidence guards, TypeScript/CLI checks, twelve pinned fidelity suites including 805 raster baselines, and the exact registry/native text bridge. Both registry consumers verify 64 signatures/15 attestations with zero advisories. [Coordinated evidence](evidence/shared-quote-coordinator-2026-09-09.json) records the tested core candidate `e635249` and published siblings; remote CI/review of this checkpoint remain gates. Never republish these versions. Use exact locally available runtimes Node `20.20.2`/`24.20.0` (floating `node@24` temporarily selected an unavailable version); no new software permission is required.\n\nThe three site adoption branches `codex/shared-quote-adoption-20260909` start from GitHub website main `e5dd771e6df3ddabb4544e8e435561b1dba178f3`, gallery main `b28d33564d7da2836f5c5d2e060ea461a7ac96bb` and pptx.dev **master** `b922f2f89fdb1e68f0e71a7f1df638be9c5314d4`. Website #20 has merged and its production deployment is `dpl_QKF3qGAtfGvizXu1sgPz43YReFdM`. Website [adoption PR #21](https://github.com/Data-Advantage/openpresentation-site/pull/21), head `27dcdb2`, updates the five releases, core source pin and registry showcase; production build, all registry dates and six local Edge workflows pass (8.0s). Preview/remote review/public verification remain gates. Gallery and pptx.dev adoption edits are next. All three public sites still use the previous complete set until deployments are verified. A fresh seven-repository audit found no open security alerts; the original nine-PR backlog remains resolved. The full repair/Auto arrange/font/native-platform objective remains active and substantially unfinished.\n\n## Previous checkpoint \u2014 core, CLI and renderer published; converter checks\n\nCore [PR #49](https://github.com/OpenPresentation/opf/pull/49) merged as `4dc292fa93bee52320bafa3fd0f5b05a2dc0a283`, tree-identical to reviewed `95f9982036a01a52e080992abe4c4350c4b72354`. Core CI `34400722403`, coordinated source/tarball/registry/browser CI `34400722391`, Windows/macOS CLI CI `34400722421` and Bugbot pass. Both `opf-v0.8.0` and `cli-v0.6.0` are published through trusted workflows `34401446306` and `34402210003`; never republish them. Fresh npm installs on Node 20/24 verify registry integrities, signatures, provenance, core's 519 entries/public imports/thirteen quote tests, and CLI's exact bundled versions/global executable/npx six-skill installation/69 command checks. [Actual publication evidence](evidence/core-cli-publication-2026-09-09.json) keeps local candidate archives separate from registry artifacts.\n\nRenderer [PR #10](https://github.com/OpenPresentation/opf-render/pull/10) merged as `7fe9905ad2d8a224efeef51b4a22d0aff0c413fe`, tree-identical to reviewed `95c1eb92a8b3be0c8e63917180dcb447aed0cfb8`. Node 20/24 CI `34420837605`, Bugbot and trusted tag publication `34421186727` pass. Renderer 0.6.0 is published and verified from fresh npm installs on Node 20/24: 16 shipped files match the release commit, signatures/provenance verify, seven fidelity suites and all 805 raster baselines pass, and actual loaded-font quote/JPEG browser suites pass on Edge 152. [Renderer publication evidence](evidence/renderer-060-publication-2026-09-09.json).\n\nContinue portable branch `codex/shared-quote-release-20260909` in the converter/editor repositories. PPTX 0.6.0 preparation (`bb449f954699a3ce46ce9c2fc864875cd3894cf8`) now has an npm lock resolving core 0.8.0 and renderer 0.6.0; full local installed/browser/native checks are underway before opening its release PR. Editor 0.5.0 preparation (`dc3d81d3a1de06c9923476d808328e22ffa625b2`) still waits for converter publication before its final lock. Renew Windows PowerPoint evidence against the actual installed candidate bytes and registry predecessors; do not relabel the earlier source report.\n\n`release-plan.json` still intentionally describes the last complete published set. The [release gates](plans/shared-quote-release.md) give explicit verifier commands for the newly published core/CLI without prematurely advancing the full set. After all five successors are verified, update immutable refs and actual registry quote/raster checks, adopt the set on all three public sites, and repeat deployed bundle/browser/native checks. Website #20 remains independent active work. The full repair/Auto arrange/font/native-platform objective remains active and substantially unfinished.\n\n## Previous checkpoint \u2014 installed browser CI merged; core/CLI release preparation\n\nCore [PR #48](https://github.com/OpenPresentation/opf/pull/48) merged as `abf32daa67543c30b29dbe813b17996456b90e34`, tree-identical to reviewed `565fbd2905006624c57a7c24c1b1fe62ac10ca4d`. Core Node 20/24 CI `34399051774`, complete coordinated source/tarball/registry CI `34399051732`, and Bugbot pass. CI now executes all seven installed-package browser suites against both tarballs and registry packages on Chromium 153, with 230 harness assertions and eight trusted input scenarios per run. All four stale/mutated-evidence guard cases pass on both runtimes. [Immutable CI evidence](evidence/installed-browser-ci-2026-09-09.json) complements the local Edge report below.\n\nContinue `codex/shared-quote-release-20260909`: it prepares **unpublished core 0.8.0 and CLI 0.6.0**, including the public type-tightening notice and versioned quote/pagination documentation. The [release gates and intended downstream versions](plans/shared-quote-release.md) keep actual registry refs unchanged until publication is verified. Complete release checks/review before tagging. Then update renderer, PPTX and editor dependencies/locks in order against published packages, renew exact package/browser/native evidence, and update the actual release plan and public deployments. The full objective remains active; releases do not complete bounded repair, Auto arrange or the font roadmap.\n\nProduction openpresentation.org now serves independent website #19 merge `31c84759c044480045a07f1e150149ecb2a423d3`, READY deployment `dpl_9q2ihhJXVxnWzcjizev6M2GSVMDS`. All six public Edge workflows pass (16.9s), live npm verifies the changelog dates/set, and all three showcase downloads match exact source/registry hashes. [Fresh production evidence](evidence/site-production-design-2026-09-09.json). Website #20 is still independent active work and is left untouched. A fresh seven-repository audit finds zero open Dependabot security alerts.\n\n## Previous checkpoint \u2014 shared quote core merged\n\nCore [PR #47](https://github.com/OpenPresentation/opf/pull/47) merged as `01e69ba1a6c3915778ede6aa12fb7ecda652ea42`, tree-identical to reviewed `c81b8b1cdf7004af186dce81c2b81cfb9a25be12`. Core Node 20/24 CI `34397006994`, complete coordinated source/tarball/registry CI `34397007028`, Windows/macOS CLI CI `34397007117`, and Bugbot pass. The [integration checkpoint](plans/shared-quote-integration.md) records quote allocation/scoring, pagination content-loss/readability fixes, downstream editor undo behavior, real Edge/PowerPoint evidence and the 41-slide raster review. Renderer, converter and editor retain their pinned `codex/shared-quote-integration-20260909` branches, with no downstream PRs yet. All changes remain unreleased; actual registry versions, release-plan refs and public deployments are unchanged by this milestone.\n\nCore branch `codex/installed-browser-checks-20260909` supplied the merged runner above. Keep the published registry baseline separate from the reviewed candidate footer changes. Native reimport retains editable quote text but loses quote structure/typography/readability policy; this remains an explicit gap. The full goal is active and substantially unfinished. No renewed permission is needed for already-authorized releases/deployments after their gates pass.\n\nThe [installed-browser report](evidence/installed-browser-2026-09-09.json) records four passing local runs: actual registry and candidate tarballs on Node 20/24 with Edge 152. Each runs seven suites, 230 harness assertions and eight trusted input scenarios, with zero external requests, writes or browser errors. Four evidence-rejection tests pass on both runtimes. Plain-to-rich conversion and bold formatting remain separate undo steps. This expands package/browser verification; it does not add native raster or public-deployment evidence.\n\nWebsite PR #20 (`claude/branch-icon-spacing-fixes-de47tz`, observed `6bf9b294a05a5943be77056f372c988266ad475b`) is separate active user work and was left untouched. Do not overwrite it during future package adoption. The original nine-PR backlog is resolved as recorded below.\n\n## Previous checkpoint \u2014 quote primitive merged; shared consumer integration next\n\nCore [PR #46](https://github.com/OpenPresentation/opf/pull/46) merged as `6d8df02940deec8f1fa89192d10576d6048de341`, tree-identical to reviewed `83e35649f91fc430c817c19492b0bf3d01212766`. Core Node 20/24 CI `34389245732`, coordinated source/registry CI `34389245620` (including the new real-font quote check), Windows/macOS CLI and packed-install CI `34389245733`, and Bugbot pass. The standalone quote API is now on main and remains unreleased. No package was republished or actual-release ref advanced.\n\nContinue from branch `codex/shared-quote-integration-20260909`. The [consumer integration audit](plans/shared-quote-integration.md) records exact downstream bases, candidate/accepted-fit reuse, strict descendant-path handling, atomic pagination, renderer and converter entrypoints, readability/rounding/source-map tests and the original requested-font provenance gap. Implement and verify the shared composition/preview/export path before claiming complete quote coverage, then continue code/metric/timeline/chart internals, bounded repair, Auto arrange and font/native fidelity. This is planned next work, not completed integration.\n\nA fresh audit after the original backlog resolution finds zero open Dependabot security alerts in all seven repositories. The only unrelated new PR is website [#19](https://github.com/Data-Advantage/openpresentation-site/pull/19), `claude/openpresentation-design-review-40j83i`, observed at `246aaa165d3dffb4c5e8b1a59376cfd4d47f760e`; it was recently updated and left untouched as independent work. All earlier PR dispositions and verified public deployments remain as recorded below. User authorization for pushes, PR updates, merges, tags, publication and deployments persists; remaining checks are release gates, not a request for renewed permission. The full goal stays active.\n\n## Previous checkpoint \u2014 standalone quote layout candidate; evidence checkpoint merged\n\nCore evidence [PR #45](https://github.com/OpenPresentation/opf/pull/45) merged as `24f64d67ef907282d73c25d04e80696879ab291f`, tree-identical to reviewed `b3659b0889414737ce82f552ea2753019bf9f1c5`. Core Node 20/24 CI `34387935655`, coordinated source/registry CI `34387935681`, Windows/macOS CLI and packed-install CI `34387935660`, and Bugbot pass. The failure email/budget questions and original PR backlog are resolved as recorded below.\n\nNext branch `codex/shared-quote-layout-20260909` adds standalone `layoutQuote` body/footer measurement with styles, source mappings and explicit internal failures. It is additive and unreleased: existing composition, preview, export and pagination are not switched to it. All 426 core tests plus preservation suites pass on Windows Node 20/24; six new quote cases and public declaration imports pass. The repeated actual-font wide/portrait check produces identical source/runtime/font-bound evidence on both runtimes. See [the implementation scope, report and remaining integration gates](plans/layout-repair.md#next-increments-and-acceptance-criteria). Finish CI/review before merging; connect all consumers before claiming shared accepted geometry or considering publication. The full deterministic repair, cross-surface workflow and font/native-fidelity goal remains active.\n\n## Previous checkpoint \u2014 original PR backlog resolved; YAML deployed; payload-fit gaps measured\n\npptx.dev [PR #28](https://github.com/Data-Advantage/pptx-dev/pull/28) merged as `b922f2f89fdb1e68f0e71a7f1df638be9c5314d4`, tree-identical to reviewed `dfdede29458bea1afb13f7f07d5e1079f9e9e515`. Linux/Windows application CI `34386017908`, artifact CI `34386017825` and Bugbot pass. Exact READY preview `dpl_6dXvANdwpkPgRPQ31oSKhrGqFHbx` passes eight Edge workflows (25.1s). Production `dpl_9B4YfiTrX3YCvK632T9qwtPTYpMs` is READY on that merge and serves www.pptx.dev, pptx.dev and the existing API/MCP aliases. All eight public Edge workflows pass (28.8s): author/import, quote preview/export, shared navigation, Inspector undo/download/reimport, offline Monaco, hostile SVG, installed-package toolkit and offline YAML/Markdown recovery. All 33 deployed font files and licenses still match actual registry renderer 0.5.1; [fresh font report](evidence/pptx-dev-yaml-fonts-2026-09-09.json). The previous native report remains bound to the adoption #25 download; this YAML deployment run does not add native raster-equivalence evidence.\n\nThe Data-Advantage budget increase restored CI execution. Two subsequent Linux attempts hit an external apt repository hash mismatch during Playwright dependency installation. The final pipeline uses the official matching Playwright 1.63.0 Noble image pinned to `sha256:eff16c30e6f3f4af0a03fa4b706120d5e9b0891c344a27d64559aff5900a4a27`; Linux executes all tests in it and Windows retains its native job. No checks were waived. All nine original PRs now have a disposition, and their feature/migration replacements are merged and publicly verified. Deferred TypeScript/Commander/Author-copy work remains explicit in issues, as recorded in [the backlog](pr-backlog-2026-09-09.md).\n\nCore [PR #44](https://github.com/OpenPresentation/opf/pull/44) merged as `94e4e019d28a1e16ac7e192b564596077dc2a6fa`, tree-identical to reviewed `8b09dd2757980fdae2471107a874d07bdf3a4fa0`. Coordinated Node 20/24 CI `34385371576`, core CI `34385371565`, Windows/macOS CLI and packed-install CI `34385371589`, and Bugbot pass. The earlier coordinated failure email was caused by a fixture copying the linker without its new package-manager helper; the final revision copies both and passes renewed checks. Windows linking uses junctions with checked target parents, and package-manager calls execute JavaScript entrypoints with literal arguments. No OS setting or elevated symlink privilege is required.\n\nThe next checkpoint, branch `codex/payload-fit-evidence-20260909`, corrects the unreleased explanation coverage to include incomplete code internals and adds a repeatable actual-registry probe. A schema-valid long quote footer produces no composition diagnostic but does produce renderer overflow; a long code label has measured advance 4200.68 pixels against 1128.8 available, with neither composition nor renderer reporting overflow. [Hash-bound evidence and next steps](plans/layout-repair.md#published-payload-fit-gaps) separate font-advance measurement from browser/native glyph behavior. These are priority inputs to shared internal measurement and bounded repair, not repaired layouts. The full layout/font goal remains active. No package was republished or publication ref advanced.\n\n## Previous checkpoint \u2014 layout explanations merged; Windows harness; YAML CI resumed\n\nCore [PR #43](https://github.com/OpenPresentation/opf/pull/43) merged as `1cc549183c6fd2e885f06410471e7142be69410a`, tree-identical to reviewed `d32b3eeedc0340ae3b8b3141a4677195346ddee5`. Node 20/24 core CI `34384042495`, coordinated source/registry CI `34384041071`, Windows/macOS CLI CI `34384041098` and Bugbot pass. Candidate explanations are now on main but remain unreleased. Full repair/font work remains open. Independent [PR #44](https://github.com/OpenPresentation/opf/pull/44), branch `codex/windows-test-harness-20260909`, fixes Windows junction/package-manager invocation and adds actual packed-install CI coverage; final combined-source checks and review remain gates.\n\nThe owner added $10 to the Data-Advantage GitHub Actions budget. YAML CI `34382820569` attempt 2 now starts and executes both Linux and Windows jobs. A missing exact-head Bugbot review was requested once; do not repeat while it is running. The initial billing failure below is retained as history, not a current reason to leave work idle. Finish the running checks/review and then merge/deploy PR #28 if clean.\n\nCore evidence PR #42 merged as `2c1cac7cbbc8d1afc9c26ca0b0fbdaa9b6ee3090`, tree-identical to reviewed `7b8def879883f3f8a42a9aff198620190470144c`, after Node 20/24 package CI `34381607903`, coordinated CI `34381607943` and Bugbot passed. The next source milestone is branch `codex/layout-repair-20260909`: opt-in candidate explanations preserve geometry and measurement calls and expose unsupported internal payload coverage. See [the layout plan and evidence](plans/layout-repair.md). This is unreleased source, not completed automatic repair; no package has been republished.\n\npptx.dev YAML PR #28 is now `e9f21ec007d3e382234c7bd8e062bc062fad471f`. The Escape fix passed both OS CI jobs `34381496268`; subsequent review found comment-only frontmatter, now fixed with parser-based empty-document handling and exact content/browser regression coverage. Latest local evidence: 598 tests, fresh production build and eight Edge workflows. Exact READY preview `dpl_CEw5yBz6cv622CbHvHfzNYvVqz5x` passes all eight workflows (25.8s). GitHub CI `34382820569` **did not start any steps**: both annotations report failed account payments or an insufficient spending limit. Leave the PR open and rerun Linux/Windows CI after GitHub Billing & plans is resolved; final review and public deployment remain gates. This is an infrastructure blocker, not a passing test result. Public pptx.dev remains the verified adoption #25 production below. Continue independent layout/font work while this gate is unavailable.\n\n## Latest checkpoint \u2014 public adoption verified; older PRs resolved or migrated\n\nRead [the current PR backlog and adoption checkpoint](pr-backlog-2026-09-09.md) before acting. Core #40/#13 and all three adoption PRs (website #17, gallery #23, pptx.dev #25) are merged. Exact READY production deployments pass public Edge workflows, including accurate published changelog, all six complete skills, all eight gallery bundle resources, 33 byte-matched renderer font files and offline editable export/reimport. Website #4's recovery #18 is also merged and verified live. The actual public pptx.dev export passes PowerPoint 16 native edit/save/reopen/reimport with a visually inspected raster. TypeScript #16, Commander #19 and the stale Author draft #6 are closed with explicit follow-up issues; js-yaml #20 is superseded by migration #28, with its current gate recorded above. Vercel duplicate comments are disabled and verified through the authenticated CLI; deployment checks and security alerts remain enabled. Schema-generator #13's public-type tightening is documented for a future release. No package was republished; the full layout/font/native-fidelity objective remains active.\n\n## Latest checkpoint \u2014 published content releases; expanded layout/font objective\n\nThe user's [updated objective](plans/ecosystem-objective-2026-09-09.md) supersedes the earlier goal. OPF must remain deterministic and independent of AI/model calls, keys, accounts and paid services. New explicit requirements include bounded layout candidate evaluation/repair with content/readability preservation, shared internal payload measurement, API/CLI/skills/canvas Auto arrange with preview/undo, and broad versioned open-font compatibility and native-platform evidence. The current releases do not complete that objective. Existing composition has heuristic auto-column scoring and explicit pagination; a full scored repair operation and its cross-surface workflow remain unfinished. Read `docs/font-fidelity.md` and the updated font roadmap before continuing that work. Width samples and baseline stability are not font/raster equivalence.\n\nRenderer **0.5.1** is published from `335ed01b2efbbb872894949f2ac0519e35651474`, workflow `34322801526`, npm timestamp `2026-09-09T07:14:52.658Z`. Renderer PR #9 corrected initially ineffective portrait fixtures; reviewed `12a3aa1dfb5196b3bcebe90d7e4ebb235627b0b4` merged as `d8696224e7a99618701e641ef7573ef394489885` after Node 20/24 CI `34323435532` and Bugbot. That test-only source is the new immutable verification/CI ref; the actual registry gitHead remains the publication merge. No renderer republish occurred.\n\nPPTX **0.5.2** is published from `383666b366b8c9b8ed8e7e72934d1d3fd0fb634d`, workflow `34370539691`, npm timestamp `2026-09-09T15:31:43.997Z`. PR #13 reviewed `22418c55b7e4140a7d325770510930f9e81b6b50` passed all Linux/Windows Node 20/24 jobs `34323665995` and renewed Bugbot; the quote-footer finding is resolved. npm processing finished before installation. Core PR #39 merged as `3d9321621486c95d06cc8153e2d30020c624f489` after renewed CI/review, closing the candidate linked-dependency gap.\n\nCore branch `codex/content-release-sync-20260909` updates the release plan, immutable CI refs and pinned registry content tests. Fresh full-set registry ecosystem/fidelity checks pass on Windows Node 20/24; all 805 renderer hashes remain unchanged. Registry signatures (64) and attestations (15) verify. Actual runtime/license payloads match release Git blobs exactly. The [published native report](native-content-release-2026-09-09.md) records actual-registry PowerPoint 16 checks on 19 feature slides, 24 imports and native object/edit preservation. A new registry/native quote verifier proves eight actual registry exports byte-identical to the native-tested wide/portrait files, with glyph separation, save/reopen and six valid imports on both runtimes. Native chart geometry and general text wrapping remain documented gaps. No proprietary fonts are distributed.\n\nDownstream adoption is saved on branch `codex/native-content-adoption-20260909` in each repository:\n\n- Website [PR #17](https://github.com/Data-Advantage/openpresentation-site/pull/17), `56069382de43c504e871cfc9d1e9cc88e83fb1ab`: accurate published changelog and registry showcase manifest. Build, registry dates, audit and four local Edge workflows pass.\n- Gallery [PR #23](https://github.com/Data-Advantage/pptx-gallery/pull/23), `58dd6957c7508d9459007cea4616e9c811f17383`: regenerated eight-resource registry editor/export bundle, full licenses and direct converter dependency. Builder validates/renders 854 documents; 106 tests, build, audit and both full local Edge workflows pass.\n- pptx.dev [PR #25](https://github.com/Data-Advantage/pptx-dev/pull/25), `a7f785da3c4fc0a819091efe617e0e46382531d1`: package adoption, installed-version font/preview labels and shared-hash navigation fix found by the new real wide/portrait quote E2E. Stale async loads and pending URL writes are guarded. 592 tests, typecheck, build, audit and six local Edge workflows pass.\n\nThese new site revisions are **not yet verified production deployments**. Next: complete core/site reviews and CI, verify exact previews, merge/deploy in order, verify public changelog, all bundle/font hashes and complete browser flows, and keep this handoff current. The previous production checkpoints below remain authoritative until replaced with observed READY deployments and public test evidence. The latest audit still finds zero open Dependabot security alerts across all seven repositories; four major compatibility reviews remain (core schema generator/TypeScript, pptx.dev Commander/js-yaml). Pending Vercel duplicate-comment sign-in and missing macOS native evidence remain explicit gaps, not reasons to stop independent layout/font work. Never republish completed versions.\n\n## Latest checkpoint \u2014 quote review fixes and renderer 0.5.1 release gate\n\nRenderer [PR #8](https://github.com/OpenPresentation/opf-render/pull/8), branch `codex/quote-footer-layout-20260909`, saves prepared **unpublished 0.5.1** at `e2d2a0260e7d83831d70e15bd17d173a1600ef0f`. A valid converter review finding also reproduced in the renderer: long quote text could cover its attribution/source footer. Reserving footer space before fitting fixes eight long-quote cases on wide/portrait canvases; two oversized cases retain diagnostics and strict rejection. Full local Node 20/24 suites preserve all 126-deck/805-slide raster hashes. Real Edge tests load the exact four open font faces used for measurement and verify eight actual SVG glyph layouts; renderer CI and publication now execute this browser suite and the existing JPEG suite. Exact-head CI `34322142453` and Bugbot pass. Fresh packed verification, merge/tree check, tag and trusted publication remain gates.\n\nCore [PR #39](https://github.com/OpenPresentation/opf/pull/39) addresses its valid review finding by rejecting candidate dependencies resolved outside installed `node_modules` and linked/non-registry lock records. The new same-version linked-dependency regression passes on Node 20/24. Converter [PR #13](https://github.com/OpenPresentation/opf-pptx/pull/13) has the corresponding quote fix and extended packed/browser checks in progress; its older `422f1e39e643cbb1c23260f0c9ddef7a3c6ec722` evidence is a historical candidate, not verification of subsequent edits. Next order: renderer 0.5.1 publication, converter registry dependency/lock update, refreshed packed/browser/native checks and review, then PPTX 0.5.2 publication and fresh registry/downstream adoption. No previously released package should be republished. Native chart geometry and general text wrapping remain measured fidelity gaps; the full goal remains active.\n\n## Latest checkpoint \u2014 Monaco deployed; native fixes in 0.5.2 review\n\npptx.dev PR #24 merged as `1e13e469bda257df197c79bb10948c62c3ea6535`, tree-identical to reviewed `3d372dde1c4e19fd7d59e39fba4c18c1349f5355`. Linux/Windows CI `34319106580` and Bugbot pass. All five Edge workflows pass on exact final preview `dpl_GQbmdzmR2vFzsCo48F5pN3cNaTYr` (18.4s) and public production `dpl_9LnTh1yQ9JzhUcmhBe7vbmsYZtEh` (20.4s), READY on that merge. This includes actual same-origin Monaco 0.56 JSON workers, schema diagnostics, offline completion and recovery. Dependabot #18 is closed as superseded; temporary preview browser credentials were removed. No OPF package was republished.\n\nCore PR #38 merged as `204cd42278992b58f6468a98e1eb168e3531df40` from reviewed `8910b9052c6c6854284d2e9e25506798f0a670d6`, after Node 20/24 coordinated CI `34319241226`, package CI `34319241251` and Bugbot. It preserves the 19-slide published baseline and the substantial native differences found by visual inspection.\n\nPPTX [PR #13](https://github.com/OpenPresentation/opf-pptx/pull/13), branch `codex/native-content-fidelity-20260909`, saves **unpublished 0.5.2** candidate `422f1e39e643cbb1c23260f0c9ddef7a3c6ec722`. Metrics, quotes, code and timelines now follow renderer geometry/shared core text fitting; native chart labels use readable theme text. Quote source/attribution survives, and timelines use editable native lines/markers. Full local Node 20/24 converter/corpus/styled suites pass; the new regression compares 34 text lines to actual renderer typography/geometry at two dimensions and checks chart contrast/native markers. Final candidate PowerPoint 16 checks pass for all 19 edits, 24 reimports, three native tables, one native chart and one picture. Hash-bound [candidate reports/contact sheets](https://github.com/OpenPresentation/opf-pptx/blob/422f1e39e643cbb1c23260f0c9ddef7a3c6ec722/docs/native-content-candidate.md) show the visual improvements; chart ticks/plot geometry and general scalar-text wrapping remain open.\n\nCore branch `codex/native-candidate-comparison-20260909` adds explicit candidate comparison with full runtime/vendor/package/lock hashes and matching registry core/renderer requirements. The default remains registry-only; missing/changed candidate evidence is rejected. The published baseline is retained unchanged. Next gates: review PPTX #13, complete Linux/Windows Node 20/24 packed/browser/native checks, address findings, finalize unreleased changelog/version, merge/tag/publish 0.5.2 only after gates pass, then fresh registry/native verification and downstream adoption. Do not republish 0.5.1 or advance actual-release verification refs early. Continue remaining native fidelity and dependency reviews (core schema generator/TypeScript, pptx.dev Commander/js-yaml), plus the previously pending Vercel duplicate-comment sign-in. The full goal remains active.\n\n## Latest checkpoint \u2014 expanded native coverage exposes export gaps\n\nCore PR #37 merged as `13fc56e0b1af8b24ca93ddd871cb6308bc4b77fa`, tree-identical to reviewed `f3f057cbcfa720e12eb3f46eca0cf8c7e5d9384b`, after Node 20/24 package/coordinated CI `34317326511` / `34317326517` and Bugbot.\n\nThe new [19-slide native feature matrix](native-feature-matrix-2026-09-09.md) uses actual registry core 0.7.0/render 0.5.0/PPTX 0.5.1, published examples and controlled local Calibri. PowerPoint 16 passes open/edit/save/reopen for every slide; Node 20/24 validates all 24 original/native-saved/native-edited deck imports and every native edit. Three native tables, one Office chart and one picture are verified. Hash-bound reports and all contact sheets are portable in `docs/evidence/native-feature-matrix/`.\n\nNative raster review found unresolved metric sizing, quote/source/attribution layout, flattened timeline, code panel styling, chart-axis contrast/ticks and text wrapping differences. Zero schema/converter errors did not detect them. The goal is active and these are priority export fixes; do not claim native equivalence from the successful file/edit checks. No package was republished.\n\npptx.dev Monaco migration is saved in [PR #24](https://github.com/Data-Advantage/pptx-dev/pull/24), branch `codex/monaco-worker-migration-20260909`. Supported worker exports and the new JSON API fix Dependabot #18's build failure. Initial application commit `e9d089462580f2d5c8f1b5d83b283b215a9b0a71` passes Linux/Windows CI `34318174221`, Bugbot, 592 tests and a 214-page build. All five Edge tests pass on exact preview `dpl_FGHxNYV6GDpReD9Ez8KYXNF59xno`; the final test-only revision fixes offline readiness/completion timing and requires renewed review/CI before merge, exact deployment verification and closing #18. Production remains the previously verified `fa94477f8fceb8bb1a0d62fa23d7e0d05423e94a` until that gate completes.\n\nContinue other explicit dependency compatibility reviews and pending Vercel duplicate-comment configuration as recorded below. The previously requested browser passkey sign-in remains separate from working CLI deployment access.\n\n## Latest checkpoint \u2014 pptx.dev browser workflow deployed and native-verified\n\npptx.dev PR #22 merged as `fa94477f8fceb8bb1a0d62fa23d7e0d05423e94a`, tree-identical to reviewed `c18b1fdd5d5e5e2e10b259957ba678def598a2ac`. Linux/Windows CI `34316394032` and renewed Bugbot pass; all three review threads are resolved. Production `dpl_4bQ6pSkG7kiCw8FNAPuEx9RtumTS` is READY on that merge and serves www.pptx.dev, pptx.dev and existing API/MCP aliases. All four actual public Edge tests pass: Inspector author/preview/source undo/redo/share/reimport/offline PPTX export; Author canvas edit/tab changes/undo/redo/source exports/copy/local requests/PPTX/undoable import/malformed-file recovery; hostile shared/imported document DOM checks; exact installed-package toolkit proofs. Local verification includes 592 tests in 60 files and all four starter decks (17 slides) rendered/exported/reimported with the published packages. Starter layout/theme aliases were migrated to resolvable public catalog IDs.\n\nAll 33 deployed font files and full licenses match the actual installed registry renderer, verified by the repeatable `node scripts/verify-deployed-browser-fonts.mjs <registry-consumer> https://www.pptx.dev` on Node 20/24. [Font hashes](evidence/pptx-dev-browser/fonts.json) and [production-native report](evidence/pptx-dev-browser/native-production.json) are portable. The actual Author production download has SHA-256 `383512f28856d1b0d86ddd378d63b5a529e9928983743d9ebac72d99200c8ac4`, identical to the final local candidate fixture. PowerPoint 16 exposes native editable title/table, preserves the title edit through save/reopen, rasterizes the slide and produces a schema-valid reimport with the table intact. The native-saved file hash is `9b1941ae5ae36653790375d28028b20695a197d54811cb6369b528ec9cbb1ffb`. See the [merged workflow and repeatable scripts](https://github.com/Data-Advantage/pptx-dev/blob/fa94477f8fceb8bb1a0d62fa23d7e0d05423e94a/docs/browser-opf-workflow.md). This remains targeted native editability evidence, not broad raster equivalence. Hosted account/AI calls and the legacy Decoder/API are separate from the tested free browser workflow.\n\nThe same continuation merged pptx.dev action maintenance PR #23 as `5c862d23c39f330e4fccdaa5a45bd053ae86a1dc`: real wheel/sdist artifact upload/download, exact filename/hash comparison and Twine checks pass on Linux/Windows in `34315591982`; full application CI `34315591938` and Bugbot also pass. Immutable upload 7.0.1/download 8.0.1 retain ZIP behavior and fatal digest checks. The missing `sdk/mcp` publisher was retired, and Dependabot PRs #16/#17 closed as superseded. PPTX parser lock PR #12 merged as `9c0abf1d6f296a62322fac7c4ef5c91d025a3705`, tree-identical to tested `5016051b45bb35a5d02591cc720a82dda95eae6e`, after all four Linux/Windows Node 20/24 jobs `34307685202`. It matches the parser graph already used by fresh 0.5.1 consumers. No packages were republished, and actual release verification refs stay unchanged.\n\nCore handoff PR #36 merged as `0bc35c24c5011af81ecb5d9a93626d901331fde2` after coordinated CI `34315154485`, package CI `34315154475` and Bugbot. A fresh audit of all seven repositories finds zero open Dependabot security alerts without dismissals. Remaining separate dependency reviews: core TypeScript #16 and schema-generator #13; pptx.dev Monaco #18, Commander #19 and js-yaml #20. Vercel redundant-comment settings still await the previously requested browser passkey sign-in; project protection/security notifications have not been weakened. Preserve unrelated website PR #4 and pptx.dev PR #6. Continue broader native/UX verification and the remaining compatibility reviews; the overall goal is active, not complete or blocked.\n\n## Previous checkpoint \u2014 gallery PowerPoint deployed; pptx.dev browser workflow in review\n\nThis section supersedes pending states in the historical checkpoints below. The goal remains active. No completed package release was republished.\n\nCore PR #35 merged as `264457659c7149e4e8684fab4c0b895388ad2344`, from reviewed `875ea7da4112ec10bb7549c7ca8ebd5053c9b304`, after coordinated CI `34313022598`, package CI `34313022602` and Bugbot. The release plan pins editor example source `eea4b3763026820798cb7e611f01574681c1742c` independently from actual published package verification refs. Registry gallery builds preserve runtime bytes and include complete linked license notices as an eighth hashed resource.\n\nGallery PR #22 merged as `73737dc5c50632c29234d7e5df2704e28a3ba121`, from reviewed `dae38538cb7c90090a9072247af16c8833a84b4f`, after CI `34313026600` and Bugbot. Production `dpl_7bZ8BZqmFTG57NNA48VEMrCVd4np` is READY on that exact merge. All eight deployed resources and registry integrities verify; both real Edge tests pass against https://www.pptx.gallery, including offline author/import, weighted layout, inline edit/undo/redo, OPF download, editable PowerPoint download/native merged-table XML, conversion and UI reimport equality, undo and redo. The full browser PowerPoint workflow is now public.\n\npptx.dev [PR #22](https://github.com/Data-Advantage/pptx-dev/pull/22), branch `codex/published-browser-workflow-20260909`, saves candidate `4c4e6cfb02abc8af62023674e65619dee27efca5`. Inspector and Author now use the published renderer for actual previews and the published converter for local PowerPoint export with shared font measurements. Author adds the published editable canvas and persistent validated undo session across source/preview tabs, plus local OPF/PPTX preview/import as one undoable replacement. These manual operations require no account or paid service; hosted APIs/AI remain separate. No Convex backend code changes.\n\nLocal Windows Node 24 checks pass: 591 tests in 59 files, typecheck, full 214-page production build, zero-advisory audit and all three real Edge E2E tests. Author testing caught and fixed offline canvas remounts losing their font registry. The final test verifies offline tab changes, inline edits, undo/redo, active-draft export, merged-table native XML, browser/Node import equality, import undo/redo and malformed-file recovery. Its actual downloaded file passes PowerPoint 16 native text edit/save/reopen/raster/reimport with one native table. Source SHA-256 `9744aed5c41da31187bb5a98dabec3ee3b0edacb9fe263f698039cb0a7c3b84b`; native-saved SHA-256 `cda33e17824abb265db10f02138797f3c6c36eb0e7231e0b93f3c2587fd928ee`. See [portable workflow/native evidence](https://github.com/Data-Advantage/pptx-dev/blob/4c4e6cfb02abc8af62023674e65619dee27efca5/docs/browser-opf-workflow.md) and its repeatable scripts. This one-slide native fixture does not establish broad raster equivalence.\n\nNext gates: review current pptx.dev PR #22, complete Linux/Windows CI and Vercel preview checks, address findings, merge/deploy, then run all three tests against the actual public deployment and update this handoff. Production pptx.dev remains on `f1f9e700ae2648467b36baf22b3393a216b78780` until then. Continue the remaining dependency-major/action reviews and broader native comparisons. Vercel duplicate-comment settings still await the user's previously requested passkey sign-in; no notification setting or security alert was suppressed. Preserve unrelated website PR #4 and pptx.dev PR #6. All source checkpoints are on GitHub; local generated artifacts are optional evidence, not required resume inputs.\n\n## Historical browser PowerPoint workflow candidate \u2014 September 9 UTC\n\nEditor PR #7 has now merged as `ccd42d9276f7e47a545205469dc2665e03c28a8f`, tree-identical to the fixed candidate below, after Node 20/24 CI `34312112286` and renewed Bugbot. Core PR #35 and gallery PR #22 save adoption. Their initial CI/reviews pass; a final linked-license packaging update requires renewed checks before merging/deployment. The registry builder now preserves runtime JavaScript untouched and includes full package notices plus pinned upstream license supplements in the eighth hashed resource, `playground.js.LEGAL.txt`. Both local gallery browser tests pass with this final packaging, including offline PowerPoint export/reimport. No notification settings were changed; the Vercel browser still requires the previously requested passkey sign-in.\n\nCore deployment checkpoint PR #34 merged as `4fcc217287ddf6f8ec3c6f4f351d9b1d4534df69` after package/coordinated CI and Bugbot. New work is saved in editor [PR #7](https://github.com/OpenPresentation/opf-editor/pull/7), branch `codex/browser-pptx-transfer-20260909`, candidate `eea4b3763026820798cb7e611f01574681c1742c`. Its playground accepts local PPTX in the existing preview/import dialog and exports editable PowerPoint using the preview's text measurements. Import remains a validated undoable change; export commits the active canvas draft and displays conversion notes. No package version changes or republishing are needed.\n\nLocal Node 20/24 full editor suites and offline-after-load Edge E2E pass. Actual downloaded PPTX contains native text and a merged table; PowerPoint 16 permits editing, save/reopen and valid reimport with its native table preserved. The portable [browser/native report and scripts](https://github.com/OpenPresentation/opf-editor/blob/eea4b3763026820798cb7e611f01574681c1742c/docs/browser-pptx-workflow.md) distinguish this targeted fixture from broad raster equivalence. Review caught the converted-image JSON size edge case; the fix retains schema/nesting/item validation and adds a real compressed-image regression on both runtimes. Renewed upstream CI/review must pass before merge.\n\nCore branch `codex/gallery-pptx-workflow-20260909` separates immutable example source refs from published package verification refs and includes the new host module in registry-only gallery builds. Gallery branch `codex/browser-pptx-transfer-20260909` carries regenerated assets and extends actual E2E to offline PowerPoint download/native-table inspection/reimport/undo. Its 106 unit tests, typecheck, audit and full build pass; the initial bundle passes both browser tests. Final fix bundle review, production deployment and public E2E remain gates. These candidate controls are not yet the deployed gallery. The main pptx.dev published renderer/editor/exporter integration and remaining dependency reviews remain open.\n\n## Latest checkpoint \u2014 all three 0.5.1 production deployments verified\n\nThis section supersedes pending merge/deployment states below. Core PR #33 merged as `188c32333a903fed9058d781caaaae4cd10b3d28`, from reviewed `1950afe9804d7e4f7037372d24e8b9d8b864f5fb`. Package CI `34309217317`, coordinated Node 20/24 CI `34309217315` and Bugbot pass. The release plan and immutable PPTX verification ref now select published 0.5.1 at `f7f30082da3568a4f911d42493ffc75c77dd4e14`. No package was republished.\n\n- openpresentation.org PR #16: merge `680be53dd69d99701f8b3f21e7e1c0f9b5f9390f`, production `dpl_9aR19f8JG7GHDukBnTLQv4b2hhTm`. All four public Edge tests pass: accurate changelog, six skill files and installer command, mobile layout and exact showcase downloads.\n- pptx.gallery PR #21: reviewed `93f9a720aa6ebe3b48a981f52012f809f6f8cd40`, merge `2ea8ccb75b9a6d9b64a93e6ec36d78100c044f8a`. CI `34309168015` and Bugbot pass. Production `dpl_5cooy8gD6MrZXu5vDDXNNxkBpFjN` is READY on that merge. The deployed manifest and all seven asset hashes verify; both real Edge tests pass, including JSON authoring, preview, inline edit/undo/redo, OPF download and reimport.\n- pptx.dev PR #21: reviewed `be44a1230dd17eb8ae8ca3889304aa2fb084b49c`, merge `f1f9e700ae2648467b36baf22b3393a216b78780`. Linux/Windows CI `34309892749` and Bugbot pass. Production `dpl_wkf6fiWCeyW1E562zHFU9RXwM92X` is READY on that merge. Both real Edge tests pass against https://www.pptx.dev: anonymous inspector author/preview/edit/undo/redo/OPF-download/shared-reimport and the toolkit's exact installed package versions plus render/edit/export proofs. Local self-hosted pages no longer request unavailable Vercel analytics; production analytics remains enabled. Its legacy direct PptxGenJS generator still requires the scoped image-size removal override.\n\nRemaining dependency reviews are explicit: pptx.dev Monaco #18 fails CI because 0.56 changes worker export paths; Commander #19 requires Node >=22.12 while its CLI promises Node 20; js-yaml #20 fails codec/API tests because version 5 changes exports. Evidence and migration requirements are posted on each PR; none was blindly merged. Core TypeScript #16 and schema-generator #13 remain separate compatibility reviews. pptx.dev actions #16/#17 and its obsolete missing-sdk/mcp publish workflow still need maintenance. Vercel duplicate comments await the previously requested browser passkey sign-in; no alert or notification setting has been suppressed.\n\nNext implementation milestone: free browser PPTX import/export and repeatable complete author/import \u2192 preview/layout \u2192 edit/undo \u2192 export/reimport coverage, then integration of the published renderer/editor/exporter in pptx.dev's main flow. The gallery currently exposes OPF transfer only, and pptx.dev's main preview/export still use custom implementations. Targeted native PowerPoint edit/save/reopen/raster evidence covers three slides, not broad native raster equivalence. Preserve unrelated website PR #4 and pptx.dev PR #6. Resume sources from the GitHub merge commits above; generated local artifacts are not required checkpoints.\n\n## September 9 UTC \u2014 PPTX 0.5.1 published and registry/native checks verified\n\nWebsite PR #16 is merged as `680be53dd69d99701f8b3f21e7e1c0f9b5f9390f` after CI `34308522871` and Bugbot. Production `dpl_9aR19f8JG7GHDukBnTLQv4b2hhTm` is READY on that commit; all four real Edge production tests pass, including the accurate 0.5.1 changelog, skill installer, mobile layout and unchanged showcase downloads. Gallery PR #21 and pptx.dev PR #21 save their 0.5.1 adoption candidates and await full review/deployment checks. pptx.dev's clean install, audit, 591 tests and typecheck pass; its legacy direct PptxGenJS generator still requires the scoped removal override.\n\nCore PR #33 records the new registry refs and native evidence. Its first coordinated run exposed a local preview-packer omission: the staging builder copied only `dist`, excluding declared vendored runtime/license files. The corrected builder copies every declared literal package payload, validates staging paths and uses portable Windows npm invocation. Fresh local preview packs and consumer checks now pass on Node 20/24; renewed coordinated CI is required before merging. Published tarballs and both registry fidelity suites passed independently.\n\n**PPTX security patch checkpoint:** PR #11 merged as `f7f30082da3568a4f911d42493ffc75c77dd4e14`, tree-identical to reviewed `13d404ab4a8f029622957c8afe53f339c4a6949f`. All four Linux/Windows Node 20/24 jobs in CI `34307186304` and Bugbot pass, including fresh packed installs and real Chromium suites. Actual local Edge and PowerPoint tests pass. Tag `opf-pptx-v0.5.1` triggered successful trusted publication `34307645895`; npm records publication at `2026-09-09T03:37:39.613Z`. Fresh Node 20/24 five-package installs and full pinned registry fidelity suites pass. The consumer audits clean, with 64 registry signatures and 15 attestations verified. The actual registry tarball also passes native PowerPoint edit/save/reopen/reimport and the unchanged three-slide raster measurements. Do not publish again. See the portable [PPTX evidence](https://github.com/OpenPresentation/opf-pptx/blob/f7f30082da3568a4f911d42493ffc75c77dd4e14/docs/security-0.5.1.md). The patch removes the unused parser from ordinary npm installations by shipping unmodified, licensed and hash-verified upstream runtime code. Vendored upstream advisory review remains separate from npm's installed-graph audit.\n\nCore documentation PR #32 merged as `900613f14ab7ed2d57aa6246f6ce7c3519cad39d`. Supported Node 20 types PR #31 merged as `47190652f436e80fa5dd0a947bc1ceeb6db709ff` after all package/coordinated/Windows/macOS checks. Website action PRs #12/#13 merged as `227088da3f2aa48724d53df8625d0dad7d052005` and `174fc0d953526454848da07db9013ab35ceb5e5e` after renewed combined CI. Gallery PR #20 merged as `d01cbfc24855d5e41adc6e092841554196a3e9cb` after full CI `34307438488`; action PRs #16/#17/#18 were closed as superseded. A false-positive missing-pnpm-tag finding was resolved with the live annotated tag and successful exact-head CI evidence. Open Dependabot security alerts were refreshed across all seven repositories: zero, without dismissals. This does not change historical published package graphs.\n\n**Production checkpoint:** pptx.dev PR #15 is now merged as `06ebef116608110fa88ac98cbcd6fe8ea6ad76f1`. Reviewed head `aad6b5ce29dc4ed5b03a7982121ff4a7ea4543bc` passed Linux/Windows CI `34304827786`, Bugbot, an actual adapter build and deployed preview E2E. Production `dpl_638zt5oC7grWNTYEXL3XM4cFMbGE` is READY on the merge, with www.pptx.dev, pptx.dev and API/MCP aliases. The real Edge inspector author/preview/edit/undo/redo/OPF-download/shared-reimport test passes on https://www.pptx.dev. GitHub open Dependabot alerts are now zero without dismissals. SDK/CLI source builds use the single audited root workspace, and standalone output remains supported outside Vercel. This is the first adoption baseline; the main custom preview/export still needs replacement.\n\nCore PR #30 merged as `6967b037c934c665e312086e232545cb71753bcf` after Node 20/24 package/coordinated checks, full Windows/macOS core/CLI checks and Bugbot. Renderer maintenance PR #7 merged as `ad59248ad8dbf11e519c1ba75e95d6d3fa4a39ed`; editor maintenance PR #6 merged as `aeb2871ba381bf97656e58418b5271ec764ed0d5`, both with Node 20/24 CI and Bugbot. These add grouped weekly Dependabot, unfiltered audits and reviewed immutable actions; no package version changed or was republished. Existing published verification refs remain correct.\n\nVercel duplicate bot-comment configuration requires a browser passkey sign-in. CLI authentication and production deployment work. The user was asked to complete the open login page when convenient; no notification/security setting has been changed yet. Continue unaffected work. pptx.dev action PRs #16/#17 remain for individual review; the obsolete missing-sdk/mcp publishing workflow also needs maintenance. Existing PPTX 0.5.0 keeps its older dependency graph; 0.5.1 fixes ordinary new installations without the incompatible downgrade.\n\nThis checkpoint supersedes the historical pending states below. Core PR #29 merged as `e49278514ca3f98b0e14e47ceaa4315adada00b1`. All five intended package releases and the six-skill npx installer remain published; do not republish them. The release plan already pins their actual immutable release commits.\n\nWebsite security PR #15 merged as `2f1b5428a06079e70f3ad67653768fa55a8c463c`; production `dpl_Bdxr6u3j6rdEjp9fJP9RbLp4f2pS` is READY on that commit. All four public-site browser tests pass, including the accurate changelog and complete skill files/clipboard command. Gallery security PR #19 merged as `7d661c074a73dc81487a713a2af040246e62a097`; production `dpl_3GbDE7grPv3zCyCzfzhgAKuCuTsg` is READY on that commit. Both public gallery browser tests pass, including exact bundle hashes and OPF author/edit/undo/download/reimport. Both upgrades passed CI and Bugbot before merging. See [September 9 security evidence](security-2026-09-09.md).\n\npptx.dev PR #15's earlier standalone/adapter packaging failure is resolved: ordinary builds preserve standalone self-hosting, while Vercel uses its adapter output. The exact final commit, full CI and production evidence are recorded above. Its primary renderer/exporter adoption remains incomplete.\n\nCore security work is on `codex/security-policy-20260909`: patched js-yaml/esbuild, unfiltered CI audit, consistent LF text checkouts, reviewed immutable actions in the portability workflow, and routine Node-type major-update policy. TypeScript 7 PR #16 remains deferred because of tsup declaration-bundler incompatibility. Schema-generator PR #13 changes the exported ContentPayload type and remains separate for consumer compatibility review; the security fix does not depend on it. Node 26 types PR #15 is closed because declarations must match the minimum Node 20 runtime. No security alert is dismissed.\n\nRemaining work: merge the updated core 0.5.1 verification refs and deploy downstream adoption/changelog (website PR #16 is prepared with verified npm dates and unchanged showcase bytes); finish application action PRs and redundant Vercel comments; free browser PPTX import/export controls and repeatable complete workflows; actual published renderer/editor/exporter integration in pptx.dev; broader native PowerPoint comparisons. Preserve website PR #4 and pptx.dev PR #6. Native PowerPoint evidence remains three targeted slides, not broad pixel equivalence.\n\n## Latest checkpoint \u2014 deployed installer and gallery; pptx.dev integration underway\n\nUpdate: pptx.dev [draft PR #15](https://github.com/Data-Advantage/pptx-dev/pull/15) saves the compatibility/security candidate at `08fab78`. A fresh Windows Node 24 frozen installation passes 588 tests, typecheck and compile build. Its root audit is now zero: an exact-version pnpm override removes PptxGenJS 4.0.1's unused image-size dependency, and an installed regression test confirms it cannot resolve while text/table/image export works. This does not patch image-size or change existing public npm packages; separate SDK lockfiles still have an esbuild advisory. Browser testing subsequently found missing-auth configuration assumptions on public inspector pages; fixes and repeatable E2E are being added before deployment. Core pnpm/action-setup PR #12 merged as `e43e263795c824b0fe6bddc4b37deb612a196766` after renewed combined Node 20/24 checks. Gallery GitHub open security alerts have now reached zero without dismissals.\n\nThis section supersedes pending states in the historical checkpoints below. All five intended packages are published: core 0.7.0, renderer 0.5.0, PPTX 0.5.0, editor 0.4.0 and CLI 0.5.0. Do not republish them. Core PR #28 merged as `51445f03b70bed896e53e346f2fb7b2c04293b94`, with renewed review and package/coordinated/Windows/macOS checks. The release plan and published CLI test source are pinned to the actual CLI release commit, independently of future local CLI development.\n\nWebsite PR #14 merged as `49d30c6a25d684e7f1a3cbdca44ec565e1b9472f`; production deployment `dpl_6iQrr4VNh9Mu61DvdJXJ6Xs9c8Rc` serves that commit. Four production browser tests pass: accurate releases, mobile layout, exact showcase downloads, and the copied npx installer command plus every served skill file hash. The changelog and supported skill installation documentation are live. Preserve unrelated website PR #4.\n\nGallery PR #15 merged as `188758dcde7248f70ceeb44238ba5986be4c91d0`; production deployment `dpl_6WQqZZAeS28tDCxuMLa6dJeWw7oo` serves that commit. Two production browser tests verify the seven deployed bundle files against their hashes and a real JSON-author/preview/inline-edit/undo/redo/OPF-download/reimport flow, including a styled merged table. Local verification passes 106 unit tests, a 1,925-page build, catalog checks and zero npm advisories. Browser PPTX import/export controls are still absent from the editor example: do not claim this OPF workflow proves PPTX UI coverage.\n\nCore Dependabot checkout PR #10 merged as `84c757e55234ea8c8706ba8717717d7a4c541005`; setup-node PR #11 merged as `414c40fb6bfa2f7f33714ddb949f43a7f8ce70d4`. Both received migration review and passing Node 20/24 checks. pnpm/action-setup PR #12 has a resolved adjacent-line merge conflict and renewed CI pending on `9f10ef3`. TypeScript 7 PR #16 remains unmerged: explicit Node globals fix its first error, but tsup's declaration bundler fails against the removed legacy TypeScript API. Failure evidence is posted on the PR. Review other majors individually; security alerts remain visible.\n\npptx.dev work is on Data-Advantage/pptx-dev branch `codex/published-ecosystem-adoption-20260908`, based on `4a1fc69af09addd37fe62500a1ab8b50fa63cbf8`. It upgrades the four OPF dependencies to the published set, updates vulnerable dependencies and replaces AI canaries with compatible stable releases. Its 575 existing tests, typecheck and compile build passed, followed by a new installed-package edit/undo/redo/export proof. Running the formerly Unix-only standalone playground tests then exposed unbounded palette traversal of recursive groups; the fix and regression coverage are in progress. No pptx.dev candidate is deployed yet. Its primary preview/export still use custom implementations, so dependency upgrades alone do not establish complete adoption. Preserve unrelated PR #6. Remaining high image-size advisories have no published patched version; do not dismiss them or claim a clean audit. SDK lockfile maintenance, application E2E, free browser PPTX workflows and broader native fidelity verification remain open.\n\n## Earlier checkpoint \u2014 CLI installer published; website changelog deployed\n\nCLI 0.5.0 is published. PR #27 merged as `7a2845f45bd7c6f48312b07100851c0ee29a9d1c`, tree-identical to `fcaa85fb50c06dd737f9e71419f3b9a40618184d`, after Linux/Windows/macOS Node 20/24 checks and successful renewed review. Tag `cli-v0.5.0` and trusted publish run `34261574915` succeeded. Registry gitHead/provenance and fresh global/npx-style installs pass on Windows Node 20/24. Do not republish CLI 0.5.0 or any earlier completed package release.\n\nThe supported command is `npx @openpresentation/cli@latest skills install`. It installs all six bundled skills, preserves project instructions and refuses to overwrite customized skills. Core follow-up branch `codex/cli-release-adoption-20260908` advances the release plan to CLI 0.5.0 and adds repeatable published CLI installer checks. Fresh complete registry ecosystem tests pass on Node 20/24.\n\nWebsite PR #11 merged as `c1cbbbb4e91911392612a157155441b523f187dc`. Vercel production deployment `dpl_ApPs9yCN43U6zVsGEkSmfQ6tFRTM` serves that commit. All three browser checks pass against https://www.openpresentation.org: published history and package links, mobile layout, and exact OPF/SVG/PPTX download hashes. The separate website changelog task is deployed. Follow-up branch `codex/skills-installer-site-20260908` adds the newly published CLI 0.5.0, installer quickstart and its immutable documentation snapshot. Four local browser tests pass, including actual command copying and every file hash in all six served skills. Follow-up CI/review/deployment remain pending.\n\nGallery adoption is in progress on `codex/published-ecosystem-adoption-20260908` in Data-Advantage/pptx-gallery. Targeted dependency updates pass 106 existing tests, a 1,925-page build and a zero-advisory audit. Its regenerated registry bundle uses core 0.7/render 0.5/PPTX 0.5/editor 0.4/CLI 0.5 and validates/renders 854 documents. Final bundle checks, browser workflows and deployment remain pending. The existing editor example lacks browser PPTX import/export controls; addressing that gap is separate from updating the bundle. pptx.dev adoption/security and the six core major Dependabot PRs remain open. Historical sections below are superseded by these checkpoints.\n\n## Windows continuation checkpoint \u2014 registry releases complete\n\nRenderer 0.5.0, PPTX 0.5.0 and editor 0.4.0 are all published with provenance after exact-head checks and review. Their published merge refs are recorded in `release-plan.json`; do not republish them, core 0.7.0 or CLI 0.4.0. Fresh full-set registry ecosystem and pinned rendering/export fidelity checks pass on Windows Node 20/24, including the unchanged 805-slide raster baseline. Registry editor pointer/keyboard typing, formatting and undo pass in Edge. Registry PPTX passes native PowerPoint open/edit/save/reopen/reimport and two targeted border raster assertions; broad pixel equivalence is not established.\n\nCore PR #26 merged as `533b53cd7db3cf58e9ebf5fbd987741323ea2699` after full Node 20/24 coordinated CI, package CI and successful Bugbot review on `3d1c2bbc7c68a3f74f68232d1ae320a4f41ccdfd`; merged tree is identical. The complete release plan and immutable CI refs are on main.\n\nContinue CLI 0.5.0 on `codex/skills-installer-20260908`, [PR #27](https://github.com/OpenPresentation/opf/pull/27). All six skills are bundled with safe install/update/status, offline packed installation and Windows checks. It remains unpublished. Review found overly strict ancestor-symlink rejection; canonical parent resolution now supports linked project directories while rejecting linked skill destinations, and macOS CI was added. Wait for final CI/review before release.\n\nMain website work is on Data-Advantage/openpresentation-site branch `codex/published-ecosystem-adoption-20260908`, [PR #11](https://github.com/Data-Advantage/openpresentation-site/pull/11), initial head `83ccb57`. It adds the accurate published changelog, core 0.7.0 and complete registry showcase, targeted security fixes with zero current local audit advisories, grouped Dependabot and browser/download CI. Local build and three browser tests pass; deployment remains pending. Gallery and pptx.dev adoption/security/full workflow E2E remain open. See [current Windows evidence](evidence-2026-09-08-windows.md). Historical checkpoints below are superseded where they describe unpublished downstream packages or stale lockfiles.\n\nThe user requested an immediate stop and remote checkpoint to move computers. Resume from GitHub; do not depend on the old computer's temporary worktrees, tarballs, logs, or browser state. The goal is ongoing, not completed or blocked. User authorization covers commits, pushes, PR creation/updates/merges, tags and npm publication. Recheck CI/reviews and exact commits before releases. Do not bulk-merge unrelated Dependabot PRs. No subagents unless requested.\n\n## Goal\n\nMake OpenPresentation a polished, reliable, fully open presentation ecosystem for people and AI agents: authoring JSON, dynamic layout, browser preview, intuitive WYSIWYG editing and editable PowerPoint export. Keep core free, open source, provider-neutral and usable without a paid service or AI account. Publish compatible packages in dependency order and prove the workflow using clean registry installations. Advance presets, rich text, tables, media, fonts and layout fidelity. Evaluate schema support, browser interactions, rendering and native PowerPoint compatibility separately. Public sites must showcase the same installable tools users receive.\n\nEarlier PR #8 reconciliation and the missing core 0.4.0 changelog entry are already handled; do not repeat them. The NEW public website changelog request below remains open.\n\n## Portable checkout map\n\nClone sibling repositories so the core ecosystem scripts can find their sources. Read each repository's AGENTS.md. Avoid resetting any existing user checkout.\n\n| Repository | Branch to resume | Remote checkpoint |\n| --- | --- | --- |\n| OpenPresentation/opf | codex/styled-table-release-sync-20260908 | [PR #26](https://github.com/OpenPresentation/opf/pull/26), this handoff and verification scripts |\n| OpenPresentation/opf-render | codex/styled-table-cells-20260908 | [PR #6](https://github.com/OpenPresentation/opf-render/pull/6), head `b47bba101ab78dc226d9ff848bb8622e3a0109e1` |\n| OpenPresentation/opf-pptx | codex/styled-table-cells-20260908 | [PR #10](https://github.com/OpenPresentation/opf-pptx/pull/10), head prefix `a0e9d14` |\n| OpenPresentation/opf-editor | codex/styled-table-cells-20260908 | [PR #5](https://github.com/OpenPresentation/opf-editor/pull/5), head prefix `21449a7` |\n| Data-Advantage/pptx-gallery | main | Deployed merge `12fcf77399cb6ae21d3bfcea5cfafb37c3323b79`, PR #14 |\n| Data-Advantage/openpresentation-site | main | Deployed merge `280a616701320cd1ca8d2484cf166fb91d882137`, PR #10 |\n| Data-Advantage/pptx-dev | master | Newly added integration scope; old checkout `4a1fc69af09addd37fe62500a1ab8b50fa63cbf8`, not yet audited or modified |\n\nUse fresh fetches to resolve full commit IDs/current PR states. The old machine's primary downstream checkouts were deliberately left untouched and lag origin; release work happened in temporary clones. Gallery's primary checkout contains a pre-existing untracked `pnpm-workspace.yaml`; not part of this work. Temporary PPTX `artifacts/` contains generated evidence/build outputs; source fixtures and builders are committed and can regenerate it.\n\n## Already published \u2014 do not republish\n\nCore PR #25 merged as `21e4cfca617ddfebeee85f79b09c35b2e82637e1`, with tree identical to reviewed head `e71f7c3d1b9a99bf210d038ceac613f72f41f894`.\n\n- `@openpresentation/opf@0.7.0`, tag `opf-v0.7.0`, successful publish run `34243706990`.\n- `@openpresentation/cli@0.4.0`, tag `cli-v0.4.0`, successful publish run `34244109903`.\n- Both registry gitHeads match the merge and have SLSA provenance. Tarball integrities matched the tested candidates. A fresh global CLI registry install reported CLI 0.4/core 0.7 and validated the styled fixture.\n- Core 404 tests, CLI 70 command checks, packed package checks, strict installed TypeScript fixture and coordinated Node20/24 CI passed before release. These results do not establish that later downstream edits are verified.\n\nCore 0.7 introduces strict styled cells `{value, style?, rowSpan?, colSpan?}` with covered positions `null`; merge ownership validation; shared anchor geometry and `.value` editing paths; padding, alignment and spanning row heights; pagination that keeps connected vertical merges. Equal column widths and content-fit row heights remain limitations for importing native arbitrary table geometry.\n\n## Immediate release gates\n\n### Renderer PR #6: draft, not published\n\nVersion 0.5.0, core dependency ^0.7.0, registry lockfile current. Prior head `b63bd0e` passed standalone Node20/24 full suites and unchanged 126-deck/805-slide raster baseline against actual registry core 0.7. A fresh candidate consumer passed and matched runtime bytes.\n\nBugbot review on that head completed neutral with two findings. They must be assessed, not treated as a passing review:\n\n1. Claimed vertical alignment was ignored. Core `layoutTable` already offsets `cell.textBox.y`; scalar and rich renderer paths consume that box. New baseline assertions prove top/middle/bottom movement. Do not add a second offset.\n2. Valid finding: default neighboring edges could cover custom borders. Follow-up commits `dabf91b` and `80ae8bb` render defaults before explicit edges and remove overlapping default segments, including zero-width/transparent/dashed edges and partial merge boundaries. Legacy tables without custom borders retain their prior rendering path.\n\nThe final head is `b47bba1`, including the regenerated tracked `dist/svg.js`. On the identical source/build from `80ae8bb`, focused styled-table regressions pass on Node20/24 and renderer syntax checks pass. Full suite/raster baseline, renewed CI/review, and a new packed candidate remain required. The previous tarball integrity is obsolete. Review threads were left open for evidence-based follow-up. PR description records these distinctions.\n\nNext: run checks on exact head, address review findings, mark ready, wait for CI/review, merge with exact-head protection, verify merged tree, tag `opf-render-v0.5.0`, monitor trusted npm publish, verify registry version/gitHead/provenance/integrity against the new tested tarball.\n\n### PPTX PR #10 and editor PR #5: draft release preparation\n\nTheir implementation and final README/CHANGELOG/package.json version changes are pushed. **Lockfiles still describe the preceding dependency set.** This is an explicit unfinished checkpoint because renderer 0.5.0 does not exist on npm yet. Do not merge or publish these drafts as-is.\n\nAfter renderer publication, regenerate lockfiles from the registry and run clean installs. PPTX targets 0.5.0; editor targets 0.4.0. Both require core ^0.7.0 and renderer ^0.5.0 (optional peer, exact 0.5.0 development dependency). Use Node20 and Node24; prior toolchain was npm11.16/pnpm10.33.2. Run standalone suites **without NODE_OPTIONS source loaders**. Pack final versions, test fresh consumers, verify runtime bytes, update PR evidence, review/merge and tag in dependency order. Inspect workflows for exact tag patterns (PPTX `opf-pptx-v0.5.0`; verify editor pattern before tagging).\n\nPPTX implementation preserves supported native fills/alpha, margins, alignments, borders/dashes, rich runs and dense merges; conditional styles resolve band/edge/corner precedence and archive-local line references. Malformed merges retain source text with diagnostics. Different border segments on merge continuations preserve anchor style with a diagnostic. Native arbitrary row/column geometry, effects and PowerPoint raster parity are incomplete.\n\nEditor uses `.value` inline paths, preserves styles/spans, rejects invalid structure, supports rich promotion/selection formatting and undo; covered slots have no editable target. Browser and model fixtures are committed.\n\n### Core release sync: draft\n\nThis branch adds installed-package styled editor browser fixture generation to `scripts/test-packed-ecosystem.mjs` and styled renderer/PPTX tests to `scripts/test-registry-fidelity.mjs`. The latter clears NODE_OPTIONS in child tests to prevent a source loader invalidating registry claims. Syntax and diff checks pass; final full registry checks are pending.\n\n`release-plan.json` still describes the previous complete published set. Update it and `.github/workflows/ecosystem-ci.yml` immutable downstream refs only after all new packages are available. Use the published core merge for core fixtures. Run fresh Node20/24 registry ecosystem/fidelity checks and actual installed-package browser interactions. Do not conflate generated browser bundles with executed UI tests.\n\nUseful core commands: `pnpm test:registry-ecosystem`, `pnpm test:registry-fidelity`, `pnpm prepare:gallery:registry`, `pnpm build:showcase:registry`. Read their scripts and release plan for arguments/setup. Source-coordinated tests may use `scripts/register-local-opf.mjs`; registry verification must not.\n\n## Evidence and public integration status\n\nBefore the final renderer border follow-up, actual Edge browser interaction verified:\n\n- PPTX native styled import: 12 checks; rich import: 20 cases; conditional table styles: 11 checks.\n- Editor legacy rich fixture: 14 checks. Styled fixture: 37 passing assertions including repeated style/undo checks, real Roboto/Roboto Mono loading, double-click/keyboard edits, empty values, scalar promotion, Bold, partial selection/Italic, cancellation, merged glyph containment and undo.\n- These were coordinated development builds; final installed-registry browser runs still remain. No styled-table native Keynote inspection was completed. No native PowerPoint raster equivalence claim is supported.\n\nGallery and main site were deployed and verified against the PREVIOUS full package set: core 0.6, renderer 0.4, PPTX 0.4, editor 0.3, CLI 0.3. Prior checks covered 854 gallery documents, 593 site routes, six skills and 584 raw resources. They do not yet showcase the full new styled release set. Update assets, docs and deployments only after final registry verification, then test actual public workflows. `pptx.dev` has not yet been assessed.\n\n## New user priorities to address after resume\n\n1. **Dependabot overload.** Inspect notices/open PRs across all relevant repos. Screenshot examples from core: TypeScript 5.9.3\u21927.0.2 (#16), @types/node20\u219226 (#15), Biome (#14), json-schema-to-typescript15\u219216 (#13), pnpm/action-setup5\u21926 (#12), setup-node4\u21927 and checkout4\u21927 (#10). These are examples, not a current authoritative PR inventory. Evaluate runtime/schema/build compatibility, security significance and CI; safely group/schedule updates and reduce redundant reviewer notifications where appropriate. Preserve security visibility. Do not blindly merge major upgrades or suppress useful alerts.\n2. **Public changelog.** Update https://www.openpresentation.org/changelog from actual published release contents and dates. Clearly distinguish live npm releases from upcoming drafts and ensure site deployment is verified. The earlier core CHANGELOG0.4 fix does not satisfy this request.\n3. **Easy skill installation.** User wants a supported npx-style skill installer like Convex's AI-file installation experience, documented and suggested in relevant CLI output. Current `docs/agent-skills.md` instructs copying entire self-contained folders; do not assume an npx installer already exists. Research current official Convex/installer guidance before choosing syntax, implement/test actual clean-project installation and sensible updates across supported agents, keep provider-neutral, document it on site/repo, and add concise actionable CLI guidance. Avoid overwriting existing user skill configuration without an explicit update flow. Six OPF skill entrypoints: author, layout, presets, edit, export, inspect.\n4. **Real downstream adoption and E2E quality.** Audit openpresentation.org, pptx.gallery and Data-Advantage/pptx-dev (https://pptx.dev) for exact dependencies/bundles and user workflows. Adopt the tested published set and assess quality visually and functionally. Inventory existing model, package, browser and E2E tests; automate missing end-to-end paths from author/import through layout/preview, editing/undo, export and reimport. Test deployment versions and editable native output; report native-app fidelity gaps explicitly. Do not answer \u201Call integrated\u201D or \u201CE2E complete\u201D from the existing unit/corpus evidence alone.\n\nContinue in reviewable milestones under existing authorization. Keep a concise evidence trail, preserve user work and stop relying on old-machine absolute paths.\n"
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
76
|
"slug": "handoff",
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ export { OPFValidationError, ValidationIssue, ValidationResult, assertValid, ass
|
|
|
4
4
|
export { SpecFileEntry, SpecFileKind, SpecFilePath, specFileEntries, specFileKinds, specFilePaths } from './spec-files.js';
|
|
5
5
|
export { LayoutPreviewIndex, LayoutPreviewRecord, getLayoutPreview, hasLayoutPreview, layoutPreviewIndex, layoutPreviewSlugs, layoutPreviews } from './previews.js';
|
|
6
6
|
export { P as Presentation } from './presentation-BMTdX6O1.js';
|
|
7
|
-
export { ComposeSlideOptions, ComposedFlow, ComposedGroup, ComposedItem, Composition, CompositionCandidate, CompositionDecision, CompositionExplanation, CompositionPenalties, CompositionTrack, FontFamilies, LayoutBox, LayoutDiagnostic, ListEntryLayout, ListFit, ListText, ListValue, MAX_COMPOSITION_DEPTH, MeasureTextWidth, OPFCompositionError, QuoteContent, QuoteLayout, QuoteLayoutDiagnostic, QuoteLayoutOptions, QuoteTextPart, QuoteTextSource, RichTextFit, RichTextFragment, RichTextLine, RichTextOptions, RichTextRun, SlideComposition, TextFit, TextMeasurement, TextStyle, composeSlide, fitList, fitRichText, fitText, layoutQuote, measureText, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, textWidthMeasurer, wrapText } from './composition.js';
|
|
7
|
+
export { CodeContent, CodeLayout, CodeLayoutDiagnostic, CodeLayoutOptions, CodeLineSegment, CodeLineSource, CodeTextFit, CodeTextPart, ComposeSlideOptions, ComposedFlow, ComposedGroup, ComposedItem, Composition, CompositionCandidate, CompositionDecision, CompositionExplanation, CompositionPenalties, CompositionTrack, FontFamilies, LayoutBox, LayoutDiagnostic, ListEntryLayout, ListFit, ListText, ListValue, MAX_COMPOSITION_DEPTH, MeasureTextWidth, OPFCompositionError, QuoteContent, QuoteLayout, QuoteLayoutDiagnostic, QuoteLayoutOptions, QuoteTextPart, QuoteTextSource, RichTextFit, RichTextFragment, RichTextLine, RichTextOptions, RichTextRun, SlideComposition, TextFit, TextMeasurement, TextStyle, composeSlide, fitList, fitRichText, fitText, layoutCode, layoutQuote, measureText, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, textWidthMeasurer, wrapText } from './composition.js';
|
|
8
8
|
export { OPFPaginationError, PaginatedPage, PaginationMapping, PaginationOptions, PaginationResult, PresentationPaginationOptions, PresentationPaginationResult, paginatePresentation, paginateSlide } from './pagination.js';
|
|
9
9
|
export { DataCell, DataContentOptions, DataImportOptions, OPFDataImportError, TabularData, createDataContent, parseTabularData } from './data.js';
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { specFileEntries, specFileKinds, specFilePaths } from './chunk-OZULJBSG.js';
|
|
2
2
|
export { getLayoutPreview, hasLayoutPreview, layoutPreviewIndex, layoutPreviewSlugs, layoutPreviews } from './chunk-PIQXLBBJ.js';
|
|
3
3
|
export { OPFDataImportError, createDataContent, parseTabularData } from './chunk-SOSOBKQ2.js';
|
|
4
|
-
export { OPFPaginationError, paginatePresentation, paginateSlide } from './chunk-
|
|
5
|
-
export { OPFValidationError, assertValid, assertValidCatalogRecord, assertValidPresentation, validate, validateCatalogRecord, validatePresentation } from './chunk-
|
|
6
|
-
export { MAX_COMPOSITION_DEPTH, OPFCompositionError, composeSlide, fitList, fitRichText, fitText, layoutQuote, measureText, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, textWidthMeasurer, wrapText } from './chunk-
|
|
4
|
+
export { OPFPaginationError, paginatePresentation, paginateSlide } from './chunk-3GPZMY2W.js';
|
|
5
|
+
export { OPFValidationError, assertValid, assertValidCatalogRecord, assertValidPresentation, validate, validateCatalogRecord, validatePresentation } from './chunk-ZGV6I23P.js';
|
|
6
|
+
export { MAX_COMPOSITION_DEPTH, OPFCompositionError, composeSlide, fitList, fitRichText, fitText, layoutCode, layoutQuote, measureText, resolveCanvasDimensions, resolveFontFamilies, resolveTextStyle, textWidthMeasurer, wrapText } from './chunk-JA5W5TVA.js';
|
|
7
7
|
export { audience, chartType, colorScheme, fontScheme, language, layout, narrative, presentation, purpose, schemaEntries, schemaNames, schemas, socialPlatform, theme, tone } from './chunk-GQSK3T7X.js';
|
|
8
8
|
export { audiences, catalogEntries, catalogIndexes, catalogKinds, catalogSchemaNames, catalogs, chartTypes, colorSchemes, fontSchemes, languages, layouts, narratives, purposes, socialPlatforms, themes, tones } from './chunk-TWMRZ43O.js';
|
package/dist/pagination.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { OPFPaginationError, paginatePresentation, paginateSlide } from './chunk-
|
|
2
|
-
import './chunk-
|
|
3
|
-
import './chunk-
|
|
1
|
+
export { OPFPaginationError, paginatePresentation, paginateSlide } from './chunk-3GPZMY2W.js';
|
|
2
|
+
import './chunk-ZGV6I23P.js';
|
|
3
|
+
import './chunk-JA5W5TVA.js';
|
|
4
4
|
import './chunk-GQSK3T7X.js';
|
|
5
5
|
import './chunk-TWMRZ43O.js';
|
package/dist/validator.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { OPFValidationError, assertValid, assertValidCatalogRecord, assertValidPresentation, validate, validateCatalogRecord, validatePresentation } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { OPFValidationError, assertValid, assertValidCatalogRecord, assertValidPresentation, validate, validateCatalogRecord, validatePresentation } from './chunk-ZGV6I23P.js';
|
|
2
|
+
import './chunk-JA5W5TVA.js';
|
|
3
3
|
import './chunk-GQSK3T7X.js';
|
|
4
4
|
import './chunk-TWMRZ43O.js';
|
package/package.json
CHANGED