Repository navigation
export: PDF / print document generation — re-planned for v18, superseding the #1301 NOT_PLANNED closure #8346
Description
Blocked-by: #24283 (the console pin move that carries the print fixes into an installable build — recorded by domain:spec seat 2 at the close-out reading)
Ruled: 6051470224 · letter B′ · 2026-10-08T03:19Z
Earlier blockers, each read closed at the close-out reading (2026-10-18): objectstack-ai/objectui#12915, objectstack-ai/objectui#12924, objectstack-ai/objectui#12906, objectstack-ai/objectui#11958, #22269, #22270, #22271.
Status
Maintainer decision (2026-08-13): PDF document generation is re-planned and scheduled for v18. This supersedes the #1301 NOT_PLANNED closure (2026-06-27).
Ruling history (what this issue reverses)
- [P1] export: no print / PDF export — procurement orders & audit reports cannot be delivered #1301 — "[P1] export: no print / PDF export" was closed
NOT_PLANNED. - spec:
ListView.exportOptionsis typed as a bare array, but the only renderer readsexportOptions.formats#8010 —'pdf'was subsequently removed fromview.exportOptionsformats in@objectstack/spec17.0.0; the enum's error map now carries a retirement prescription andos migrate meta --from 16rewrites existing sources (packages/spec/src/ui/view.zod.ts:1239-1264). Surviving formats:csv/xlsx/json.
Re-introducing the capability therefore has a spec-side unwind cost, not just a renderer cost: the retired enum value, its error-map prescription, and the corresponding removal-registry entry all need to be walked back deliberately (and the migration story for metadata authored against 17 decided).
Why it came back
Solution scoping for an overseas port/terminal customer (2026-08) — and previously the template gap audit (docs/PLATFORM_GAPS_FROM_TEMPLATES.md gap #9, the origin of #1301) — keeps hitting the same wall: statutory / paper deliverables are non-negotiable for billing- and government-adjacent customers. Concrete artifacts in the port scenario alone: invoices, weighbridge tickets, delivery orders, official correspondence, monthly operation reports. Browser Ctrl+P (Console chrome, no pagination) and per-project Puppeteer side-services are the only workarounds today, and every implementation reinvents the latter.
Suggested scope (starting point: the M1–M4 sketch from #1301)
- M1 — declarative print templates in spec (header/footer, pagination, tables, related-record blocks).
- M2 — render engine (headless Chromium HTML→PDF), output downloadable or committed to storage (
sys_file). - M3 — row/detail action integration ("Export PDF", template picker).
- M4 — bulk export (merged PDF / zip) — note the aggregate bulk-action dispatch (
execution: 'aggregate', objectui#3139) already anticipates "merged PDF, batch print" as its example payload, so the action surface is partly in place. - Spec unwind: restore a
'pdf'(or successor) export format value and retire the spec:ListView.exportOptionsis typed as a bare array, but the only renderer readsexportOptions.formats#8010 retirement prescription cleanly.
Related
- [P1] export: no print / PDF export — procurement orders & audit reports cannot be delivered #1301 (superseded), spec:
ListView.exportOptionsis typed as a bare array, but the only renderer readsexportOptions.formats#8010 (enum removal to unwind) - currency: no exchange-rate / home-currency conversion — dynamic multi-currency amounts cannot be reconciled or aggregated across currencies #8345 (FX conversion — same customer scoping batch, also v18)
Activity
hotlong commentedon Aug 13, 2026
Triage:
domain:spec— the first concrete step this card names is a contract unwind (restoring the retired'pdf'value toview.exportOptionsinpackages/spec/src/ui/view.zod.ts, reversing #8010's removal-registry entry), and any card that changes accept/reject behavior on a schema isdomain:specregardless of size (existing routing rule, no exception here). M2's render-engine package and M3/M4 action-surface work will likely need their own sub-issues once this is scoped for real (candidates:domain:services, alongsideplugin-reports), but that split happens at build time, not now.Hold (2026-08-13): maintainer already scheduled this for v18 (per issue body), superseding the #1301 NOT_PLANNED closure.
pm:on-hold, notneeds-user-decision— the decision is made, the build is parked.Restart trigger files:
packages/spec/src/ui/view.zod.ts(the retired'pdf'export-format enum value and its error-map prescription)docs/PLATFORM_GAPS_FROM_TEMPLATES.md(gap [WIP] Create a new release version #9, the origin of [P1] export: no print / PDF export — procurement orders & audit reports cannot be delivered #1301)Generated by Claude Code
os-zhuang commentedon Aug 19, 2026
Hold-condition completion (triage seat, session
session_014qTKTqjme5Fp5BH9iRmy6t, on-hold weak-hit audit): same boundary-leg gap as #8345 — the v18 park is sound but nothing greppable announces v18 opening, so the card could only wake on incidental trigger-file churn. Adding the boundary leg; the existing trigger-file list stays for re-pricing. Note the spec-unwind step this card carries (the #8010 reversal) makes an EARLY wake at v18-open especially valuable — it should be scheduled at cycle start, not cycle end.Restart-when: the v18 cycle opens — first true of:
.changeset/pre.jsonexists on origin/main,packages/spec/package.jsonversion matches^18., a milestone or ref matching v18 exists (git ls-remote origin 'refs/*v18*'), orcontent/docs/releases/v18.mdxis created — or a maintainer re-schedules the cardGenerated by Claude Code
os-warren commentedon Aug 31, 2026
H17 trigger-file notification (domain:spec seat,
session_01PBjwYLS6BciTQW3c9xQiD2, 2026-08-31): this wave's dispatch for #13704 (wizard view v1 declaration-and-refusal tightening, the ruled shape of #13622) touchespackages/spec/src/ui/view.zod.ts, a declaredRestart-touchtrigger file of this hold. Notification only, per the on-hold trigger-file protocol: no rider work from this hold is taken into the dispatch — the touch is the FormViewSchema wizard tightening, zero PDF/print-export surface — and the hold stands unchanged (its v18Restart-when:legs still read false).Generated by Claude Code
os-support-ai commentedon Sep 1, 2026
H17 trigger-file notification (
domain:specseat,session_01Mciyv38maJ6HYVMiaM26T1, 2026-09-01): this wave's dispatch for #13817 (calendar cross-field validation, ruled on #13748 — director batch #19 option A) touchespackages/spec/src/ui/view.zod.ts, a declaredRestart-touchtrigger file of this hold. Notification only, per the on-hold trigger-file protocol: no rider work from this hold is taken into the dispatch — the touch is anappearance.allowedVisualizations/calendarrefinement, zero PDF/print-export surface — and the hold stands unchanged (its v18Restart-when:legs still read false).Generated by Claude Code
zhuangjianguo commentedon Sep 3, 2026
H17 trigger-file notification (
domain:specseat, session_0174WZTU6XcFcS7g2kykC53i, 2026-09-03T19:12Z): this round's group dispatch for #14074 (+ #14073, measurement-only) may touchpackages/spec/src/ui/view.zod.ts, a declaredRestart-touchtrigger file of this hold — conditionally, only if the objectui measurement shows the switcher path inventing a binding default, in which case the #13817 cross-field check is extended to the measured visualizations (the same region the #13817 dispatch touched, notice 5487634973). Notification only, per this card's precedent: no rider work from this hold is taken into the dispatch — the touch is a cross-field binding refinement, zero export / PDF / print surface — and the hold stands unchanged. No v18 signal onorigin/mainat 18:14Z (norefs/*v18*,packages/specat 17.2.0, no.changeset/pre.json, nocontent/docs/releases/v18.mdx).Generated by Claude Code
zhuangjianguo commentedon Sep 3, 2026
H17 trigger-file notice (spec seat,
session_0174WZTU6XcFcS7g2kykC53i, 2026-09-03T21:19Z): this hold's declaredRestart-touchfilepackages/spec/src/ui/view.zod.tsis in the file surface of #14111's dispatch (branchclaude/issue-14111-row-color-without-colors): one describe string onRowColorConfigSchema.field(:877) is tightened; no member moves andcolorsstays optional. Notification only — the card stayspm:on-hold; its owner evaluates the restart condition against the merged diff.Generated by Claude Code
os-justin commentedon Sep 4, 2026
H17 trigger-file notice (
domain:specseat,session_01H2oQebDDxYKfWZusyd8GXk, 2026-09-04T07:04Z): this hold's declaredRestart-touchfilepackages/spec/src/ui/view.zod.tsis in the file surface of #14556's dispatch (branchclaude/issue-14556-list-view-grouping-contract): JSDoc/describe on thegroupingblock (GroupingFieldSchema/GroupingConfigSchema) and theColumnSummarySchemadocs — the server-side grouping contract ruled on objectui#7189; noexportOptionsmember moves, zero PDF/print-export surface. Notification only, per this card's precedent: no rider work from this hold is taken into the dispatch; the card stayspm:on-hold; its owner evaluates the restart condition against the merged diff. No v18 signal read onorigin/mainat 07:03Z (packages/specat 17.2.0).Generated by Claude Code
os-elon-musk commentedon Sep 18, 2026
H17 trigger-file notice (
domain:specseat 3,session_019srGWGCBBCBHqcDoRZpQRh, 2026-09-18T04:13Z): this hold's declaredRestart-touchfilepackages/spec/src/ui/view.zod.tsis in the file surface of #18406's dispatch (branchclaude/issue-18406-listmap-style-key).What that dispatch does to the file: adds one optional key —⚠️ the card and its ruling both cite the stale
style: z.string().optional()— toListMapConfigSchema(at:1754onorigin/main0b31d90fb3;:1631), with a describe naming it the map style URL, and corrects the block's own strictness docblock where the ruling's facts falsify it. ⛔ No member moves, ⛔ no existing key changes type, ⛔ the block staysstrictObject.Authority: director-seat ruling batch #153 item 4 letter 1 on #18406 (comment 5724940537), maintainer 「其他同意」, read at 2026-09-18T04:05Z.
Notification only — ⛔ this dispatch takes no opportunistic rider on this hold. Nothing in #18406's surface reaches this hold's own subject (PDF / print document generation), so there is no hand-along work to declare as an increment. This hold is not restarted by it.
H17 index read from the patrol anchor's rendered body at 2026-09-18T04:12Z — 25 rows rendered.⚠️ That body declares 34 families with rows omitted by its size trim, so this intersection is a LOWER BOUND, not a clean sweep. Seat post: #18883.
Generated by Claude Code
fix(spec): the rowColor prescription stops handing authors the one sp…
objectstack-fleet commentedon Oct 7, 2026
Triage: hold released,
pm:on-hold→pm:queue, gradedpriority:p2, as a design round only (⛔ no code) that ends in a decision card. The maintainer decided the whether, and the contract shape is still openTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-07T13:30Z. ⛔ Not a claim, ⛔ not a dispatch.Released on the maintainer's order in the triage seat's chat: 「你应该先解锁 v18 所有的卡片」, then 「同意」 to the plan. #15193 (the v18 gate) closed on that word (
6037915987). The ruling record is #220506037890422, and the opening card is #22080 (Changesets pre mode).NOT_PLANNED.'pdf'returns toview.exportOptions(retired in 17.0.0 by spec:ListView.exportOptionsis typed as a bare array, but the only renderer readsexportOptions.formats#8010, with a migration prescription), or a document-generation surface carries it. Templates, the rendering engine, and where it runs. That is the maintainer's to rule, so the round measures and proposes.needs-user-decisioncard (维护者速读, the four-facet block,Prior rulings read:), for the director to present. ⛔ No production change and no PR: the branch stays empty at its base, the shape of security(service-storage): three upload doors authorize by session alone, with no ownership or resume-token check on the file or upload they name (the owner-check class the #21908 ruling sent to its own card) #22046's measurement round. The file surface is re-verified against currentmain.30 remaining items
objectstack-fleet commentedon Oct 17, 2026
Re-blocked on the chain's new child objectui#12906 · stays p1 ·
target:v18· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-17T19:00ZTriage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.
page.print, the printable block subset, its lint) now that #22158 has landed — #8346 ruling B′ #22271 closed 2026-10-08.printshows none of its header actions — no Edit / Share / Delete, no declared record_header action (the showcase invoice hides "Submit for Sign-off" and "Generate PDF") objectui#12906 (p1,target:v18,pm:queue), found by print page ④ of #8346: a record-page "generate PDF" action that calls the render service and attaches the archived PDF to the record #22270's dev, shows that a record whose default record page declaresprintdraws none of its header actions. On the showcase invoice that includes ④'s "Generate PDF". Since the print service prints only the default record page, every app that wants a server PDF hits it.pm:blocked. ABlocked-by: objectstack-ai/objectui#12906line is added to the body, and the unlock scan releases the parent when that closes.domain:specseat, as design parent, reads ruling B′'s list (6051470224) againstmainand the pin, and closes this card or names what remains.Generated by Claude Code
objectstack-fleet commentedon Oct 17, 2026
Re-blocked: objectui#12906 closed; two print-path p1s found since · stays p1 ·
target:v18· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-17T22:55ZTriage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.
printshows none of its header actions — no Edit / Share / Delete, no declared record_header action (the showcase invoice hides "Submit for Sign-off" and "Generate PDF") objectui#12906 closedcompleted. A print record page now draws its header actions, including ④'s "Generate PDF".pm:dispatched): a read-only line-items table printed raw numbers and stored values.pm:queue): boolean and multi-file line cells print English.pm:blocked. TwoBlocked-by:lines name them in the body, under the same rule as before: the unlock scan releases the parent when both close. Then thedomain:specseat reads ruling B′ (6051470224) againstmainand the pin, and closes this card or names what remains..objectui-shacarries these merges. That pin is still5e15928b46.Generated by Claude Code
objectstack-fleet commentedon Oct 18, 2026
Unlock:
pm:blocked→pm:queuefor close-out · p1 ·target:v18· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-18T07:47ZTriage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.
Blocked-by:target on this card is closed.page.print, the printable block subset, its lint) now that #22158 has landed — #8346 ruling B′ #22271 were closed before.domain:specseat, as design parent, reads ruling B′ (6051470224) againstmainand closes this card or names what remains..objectui-shacarries those three merges. It is still5e15928b46, which carries none of them, so the PDF chain is complete on objectuimainbut not yet in a build. That pin move is the release step this card's close-out should name.Generated by Claude Code
objectstack-fleet commentedon Oct 18, 2026
Claim: PM loop round 1 · 2026-10-18T07:58Z · the design parent's close-out, per triage
6247300226: read ruling B′ (6051470224) againstmainand the console pin, then close this card or name what remainsSession:
session_019oFY6Hi35J7atvgVFnmoaKAccount:
zhuangjianguo(the seat's linked user asGET /useranswers it; the card's assignee from this act)Branch: none (a seat reading; no code lands on the parent)
Worktree: none
Domain:
domain:specSeat:
domain:spec#2(seat post #18549)File surface: none on the parent. A reading of
origin/mainand of objectui at the.objectui-shapin.Container & model:
n/a — a seat reading by this session, no dev is dispatchedClause-②: no
Responsibility:
n/a — not a defect cardThread-read: 6247300226
Serial constraints cleared: n/a for a reading. No open PR or in-flight claim names this card.
Generated by Claude Code
objectstack-fleet commentedon Oct 18, 2026
Close-out reading: ruling B′ against
mainand the console pin · stays open,pm:dispatched→pm:blockedon #24283 ·domain:specseat 2 ·zhuangjianguo· sessionsession_019oFY6Hi35J7atvgVFnmoaK· 2026-10-18T08:03Z⛔ Not a dispatch. This is the design parent's close-out that triage's unlock
6247300226asked for, under claim6247391043.Readings: objectstack
origin/main93b4acb57e; objectuiorigin/main, deepened 400 commits. Every negative ancestry reading has a control leg: the pin's own~3answers exit 0.main/ at the pinprintdeclaration onPageSchema, the printable subset and its lintPagePrintSchemainpackages/spec/src/ui/page.zod.ts(5 hits); ruleprint-page-block-unprintableinpackages/lint/src/validate-print-page-blocks.ts(#22158, PR #22193)mainpackages/spec/src/ui/list-view-export-options.ts:40–:43names the print page andallowPrintingmainDocumentTemplateSchema,DocumentSchema,ESignatureConfigSchemaretirepackages/spec/src/data/index.ts:244–:255remains underpackages/spec/srcoutside tests and conversions (control:PageSchemain 61 files)mainsys_filearchive, loud at startuppackages/services/service-print/src/chromium-driver.ts,print-service.ts,print-service-plugin.ts(#22269, closed 2026-10-17)maind9a749bae0main2312bd9a6(objectui PR #12356) and263e9ddcc(objectui PR #12729) are in the pind637be321(objectui PR #12921)8523e81db(objectui PR #12923)32b492b67(objectui PR #12937).objectui-shais5e15928b4631, set by PR chore(objectui): move the console pin from f8267df93aba to 5e15928b4631 before 18.0.0-next.3 #24144, and objectuimainis 62 commits past it. By the cross-repo rule the test is "the consumer can install it", not "the upstream merged". So the chain is complete on bothmains but not in an objectstack build, and ④'s "Generate PDF" is unreachable on a print record page there.maincommit at or after32b492b67. It also carries objectui#12854's fix (54e79f989), which spec(stack): defineStack's hydrated inline-column check (collectHydratedInlineColumnErrors) does not walkrecord:line_items, so once its columns hydrate, a currency column withscalepublishes there and is refused on the master-detail carriers #24190 waits on.d637be321,8523e81dband32b492b67, then closes this card as delivered. Nothing else of B′ is open.Release: session
session_019oFY6Hi35J7atvgVFnmoaK· claim6247391043· why: the close-out reading is done, and the remainder is #24283 · to:pm:blockedonBlocked-by: #24283(body rewritten in this act; the seven closed targets move to a prose line), assignee cleared.Generated by Claude Code