Imposition
How to read imposition plans, imposed PDF output, evidence, and production limitations — plus the free in-browser booklet and N-up imposition tool pages.
The numbered phases below name implementation milestones, not deployed-service or production acceptance evidence. This page describes source contracts reviewed on 21 October 2026; availability still depends on the selected surface, configured runtime and evidence returned for the actual file.
Architecture note
Imposition math lives in ntp-pdf-imposition. Studio displays plans, collects settings, and
explains evidence status; it is not the source of placement math. The legacy PDF assembly
quarantine (ntp-pdf-imposition-compat) was destroyed outright (Karar-8); placement math comes
only from the canonical Rust planner.
Template ownership
The separate imposition-template storage API scopes records to the signed-in user and accepts opaque update identifiers, not paths. This storage contract does not mean a template-saving control is available in every Studio surface.
Internal alpha status
The advanced imposition authority remains internal alpha; the local browser tools below are available for diagnostic use. Download requires validated PDF bytes and an output receipt. Production acceptance is a separate decision: a plan, download or local postflight does not grant it.
Phase 2 verified contracts
Rust now defines and generates VerifiedImpositionInputV3, ImpositionCapabilityDecisionV1, and
ImpositionPlanV3. They bind verified source evidence, capability status, fixed-point placement
geometry, and canonical content digests. Studio passes immutable source PDF bytes to the committed
imposition-planning WASM binding; TypeScript carries intent and maps the opaque Rust result for
presentation, but does not author a second plan.
Wire validators prove structural and digest integrity only; they do not grant issuer trust or production authority. The opaque Rust chain verifies the measured input, capability and plan bindings. The signed server path additionally verifies the external preflight decision; the local measurement path below does not carry that signature.
Phase 3 implements the signed server handoff from immutable PDF bytes through foundation facts,
Rust preflight, and an externally signed decision into TrustedVerifiedImpositionInputV3. Rust
verifies the decision against trusted issuer/key metadata, time and replay policy. Only this
signed authority can mint a short-lived verifiedInputRef; its validity window starts at the
trusted current time and remains inside the verified decision receipt. TypeScript cannot recreate
that authority from a wire object.
The local browser path uses a separate LocalMeasurement authority: Rust reads the same immutable
bytes and derives the geometry and preflight facts, but no platform decision is signed. It can plan
and compose the supplied file. It cannot mint a transport ref, prepare a signed lease or authorize
an optimizer item for another service. A structurally valid caller-authored DTO cannot plan.
Phase 4 implements the canonical fixed-point planner. Its ImpositionPlanningRequestV3 binds the
opaque measured input, exact intent digest, Rust-evaluated capability and execution budget before
planning. Plannable capability states are Allowed and AllowedWithReview; neither is a production
release. The current six-mode matrix is described below. TypeScript maps the resulting plan for
presentation and does not change its placement rotations or transforms.
Phase 5 canonical Rust composer is as-built in ntp-pdf-compose. It accepts only immutable source
bytes, the opaque trusted input, and the opaque verified plan. It writes a fresh deterministic PDF,
uses Form XObjects, preserves supported inherited/shared resources through a bounded graph clone,
and never edits the source or recalculates placements. Its receipt binds source, input, plan,
composer options, the exact browser WASM or native runtime build identity, output hash/length, and
the page count verified after writing. The receipt explicitly has
productionReleaseAllowed=false: the composer receipt alone is not production evidence.
Before issuing that receipt, the composer reparses the output and verifies its page order and sheet
boxes plus every non-blank cell's exact placement matrix and deterministic /Fm{ordinal} resource binding,
Form BBox, identity matrix, decoded source-content SHA-256, and a bounded,
object-number-independent digest of the complete reachable Form resource graph. The receipt binds
the resulting semantic placement proof and its canonical placement/source-content/source-resource
manifests. The web output-validation receipt carries the exact composer receipt, all three manifest
digests, verification engine, build SHA-256, placement counts, and limitations so preflight and
passport consumers can audit the same proof identity. This proves deterministic
structural placement against the verified plan; it does not claim RIP equivalence or measured
raster evidence. A Form is keyed by source page, source window and optional clip: the first
window uses the source page index as its ordinal, and further windows receive distinct ordinals.
Its BBox is the clip when present, otherwise the source window.
Layered PDFs (optional content) are composed: layers and their on/off states are carried into the
output unchanged, with no merging or flattening, and the composer checks after writing that the
layer configuration matches the source. Only a malformed layer definition (an unresolvable or non-layer
reference) is refused, with compose.malformed. PDF/X-1a and PDF/X-3 forbid layers; preflight
reports that on the source, and composition does not change layer state. Annotations that do not
print (no Print flag, Hidden, popups) and links without an appearance stream (navigation, not
print content) are dropped. A form field that would print keeps its existing print appearance: the
appearance is carried into the sheet as static content, exactly where a full print places it, with
nothing redrawn or recoloured. A form field that is not printed (hidden or not flagged for print), or that
carries no print appearance stream, is dropped with a coded note in the receipt. If the form asks
viewers to regenerate field appearances (/NeedAppearances true), every printable field is refused
instead, because the stored appearance may be stale. A field whose appearance cannot be carried
safely is also refused, with compose.form-field-printable. Other annotations that would print
(stamps, free text, shapes, ink, watermarks, and links with their own appearance) are carried the
same way, in the same overlay, and the receipt lists their types in one coded line. Review markup
(sticky notes, highlights, underlines, strikeouts, squiggly underlines and carets) is never carried
onto the sheet, even when it is flagged for print: it is dropped and the receipt says so in one coded
line, compose.note.review-markup-not-carried.
Popups and markup that does not print are dropped without a note. A carried type with no print
appearance of its own, or whose appearance cannot be carried safely, is refused with
compose.annotation-printable (an appearance without its own resources is carried only when it
uses no named resource such as a font or image), as are annotation types that are never carried (sound, movie, 3D
and rich media, printer's marks, trap networks, redactions); flatten or remove them first. A
printable file attachment keeps its icon (its appearance is carried like a stamp's), but the
attached file itself is not carried. The source's own scripts and actions (JavaScript, Launch, GoToR and similar) are not carried into
the output; when the source had one, the receipt adds one coded line,
compose.note.interactive-actions-removed. An action inside graphics that are carried (page
resources, a carried appearance) is still refused with compose.interactive-action (only
navigation actions and web links may be carried there, and only under an action entry; an action dictionary stored anywhere else in those graphics is refused). The check
before imposition no longer stops a file for these scripts and actions: it notes that they are
removed, and your original file is kept unchanged. Embedded files (attachments) are not carried
into the output either: when the source had one, the receipt adds one coded line,
compose.note.embedded-files-removed, and the check before imposition no longer stops the file for
them. An embedded file inside graphics that are carried (for example attached to a carried form
XObject) is still refused with compose.embedded-file, as are links to external files, PDF
portfolios and rich media content. An external file reference without a type entry inside carried
graphics (for example a form XObject /AF entry or an output intent URL) is not refused separately
in this version: it is carried into the output and holds no embedded content. An encrypted file that opens without a password and whose
permissions allow changes is imposed into a new, unencrypted file without the source's password or
permission restrictions; the receipt adds compose.note.encrypted-source, and
compose.note.source-print-restricted when the source did not allow printing. An encrypted file that
needs a password or does not allow changes is still stopped (compose.encrypted-source), as is a
carried stream that names a /Crypt filter. The ordinary preflight report still flags JavaScript,
embedded files and encryption, and signed files, XFA forms, rich media and unknown active content are
still stopped before imposition. Signed PDFs, streams stored in external files, external Reference
XObjects, PostScript XObjects and OPI dictionaries also fail closed. A PDF 2.x
source is carried, not downgraded: its output is written with a %PDF-2.0 header, while a PDF 1.x
source produces PDF 1.7. Output boxes keep exact integer-
micropoint precision, and separate limits cap sides, placements, output objects, working memory,
and final bytes before unsafe materialization. Browser imposition-output WASM and the desktop
binding call this Rust composer/assurance authority and emit exact-source structural evidence.
That evidence remains deliberately non-production: it does not unlock a public or production
claim.
The authenticated Studio server-output route supports the canonical-v1 process protocol. Its
resolver is implemented: it obtains a signed preflight decision from the configured issuer and
selects trusted key/policy metadata from server configuration, not the public request or the
issuer's response. The route connects this resolver only when its configuration is complete;
missing configuration or a rejected resolution leaves export unavailable before the output process
starts. This source wiring does not establish the state or acceptance of a deployed App Hosting
runtime. The separate design-export route does not impose and returns IMPOSITION_V3_RUNTIME_REQUIRED.
Phase 6 post-imposition assurance is now as-built in Rust. It rechecks the exact composer output
hash and length, collects canonical print facts, and runs the fixed ntp.preflight.imposed-sheet profile with
Production execution policy. A blocked result remains visible evidence but cannot mint final assurance; there
is no fallback to a weaker screening profile. Optional measured render evidence must come from
native PDFium. The signed isolation V4 receipt proves the isolated execution only; it does not make
caller-provided raster evidence trusted. A separate supervisor-signed evidence envelope binds the
exact output, postflight/foundation/geometry, expected PDFium build, raster evidence digest,
isolation receipt digest, time window, trusted identity, and nonce. Rust verifies both signatures
and consumes replay state last. If native evidence is unavailable, constructor-only digest-bound
measured_unavailable records unique bounded limitations; invalid evidence is never downgraded
into that state. Browser/WASM/preview pixels cannot become measured evidence.
The final assurance also binds the digest of the complete signed render-proof envelope, its supervisor issuer/key/trust-store, proof nonce, and proof time window. Its Ed25519 payload includes the signed schema, full assurance envelope, algorithm, identity fields, and envelope digest, so a reused key cannot silently relabel the authority. Signature, identity, limitation, page, raster, and isolation-limit inputs are bounded before hashing or cloning.
The signed Phase 6 assurance receipt still has productionReleaseAllowed=false and
publicProductionClaimAllowed=false.
Phase 7 extends the existing enterprise job/runtime with a durable imposition boundary; it does
not create a second queue or TypeScript imposition engine. The externally signed, Rust-verified input lease is
bound to tenant, user, source artifact/SHA, TTL, and nonce, and only the Rust verifier can
rehydrate opaque authority. Source, lease, and intent are resolved as private immutable artifacts
with exact class, SHA, and byte-length checks; signed download URLs are not execution inputs. A
missing native Rust binding fails closed with imposition_native_unavailable. A job cannot
succeed without digest-bound plan, imposed PDF, postflight, and assurance manifests. The durable
job keeps the authenticated submitter identity; idempotency is tenant-and-subject scoped, and both
identities reach the Rust lease verifier. Result classes must be unique and allowlisted, requested
render evidence must match the proof mode, and evidenceId must identify the assurance receipt.
Lease and intent controls are each capped at 2 MiB before private bytes are resolved, and result
artifact IDs must exactly match the unique manifest entries.
Lease replay state is atomically bound to the first durable job ID: retries of that same job are
idempotent, while a different job cannot reuse the nonce. The Rust verifier requires this replay-guard contract;
the server adapter supplies its durable transaction-backed implementation. A process-local guard
alone does not prove protection across restarts.
The Phase 12 planner supports N-up, step-and-repeat, row/column-major cut-and-stack, fixed 2-up saddle booklets, bounded multi-booklets and gathered signature books. Nested half-fold folios use two slots per sheet side, left or right binding, LTR or RTL reading and 4–80 pages per section in multiples of four. Source-page, padded-page and sheet ranges are digest-bound to the placements. Sheet, placement, signature, contract and geometry-operation budgets are checked before allocation.
Gathered signature-book also supports CIP4 f8-1 and f16-1 catalog schemes: 2×2 and 2×4 grids,
with the top row rotated 180°. A section must have exactly the scheme's 8 or 16 pages. These
schemes require left binding, LTR reading, row-major fill and symmetric left/right and top/bottom
margins; f16-1 also requires the horizontal gap to equal twice the side margin. Both long-edge
and short-edge duplex are handled. Catalog creep is refused; bleed is handled by the actual
fold/cut edge roles and available space, rather than categorically refused. Other catalog fold
schemes and finishing-machine instructions are unsupported. Binding allowance and spine geometry
can be planned and checked, but do not execute perfect binding on a machine.
The Phase 9 canonical Rust optimizer provides a rectangular ganging and press digital-twin
recommendation from opaque verified-input geometry. It compares sheet count, waste, estimated
cost, and duration with checked integer units, immutable engine ceilings, explicit coordinate-axis
grain, and bounded deterministic search. All item/source-box facts, every candidate, objective,
budget, policy, and engine version are input-digest-bound; the opaque sealed result is semantically
and cryptographically reverified. Only items from one verified input are accepted:
cross-document compatibility and composition fail closed until signed authority exists. This is
not a global-optimum, true-shape-nesting, or production-release claim;
productionReleaseAllowed=false remains explicit and TypeScript ganging remains migration debt.
Phase 10 provides a 2 MiB bounded recommendation envelope. Its source tests include a deterministic 96-case resilience corpus and exact-count/N-1 search-budget cases; these are implementation tests, not a claim that a native or live run passed for this document. Decoded wire data proves structural and digest integrity only and cannot rehydrate opaque optimizer authority. Search work is an engine-reported deterministic counter, not independent replay evidence or a wall-clock promise. The optimizer does not provide multi-source PDF composition or signed cross-document compatibility; independent external conformance remains separate acceptance evidence.
These contracts do not activate public production claims. The local browser lane can create a
Rust V3 plan and imposed PDF without uploading the source. Studio's generic preview planning
adapter, the design-export imposition request and the anonymous MCP planning tool return
IMPOSITION_V3_RUNTIME_REQUIRED; they cannot estimate a canonical plan from declared dimensions.
This refusal is not a blanket claim about every server operation: the separately gated workflow
and durable native-assurance adapters have their own runtime bindings and admission limits.
Authenticated Studio users may also consent to server render or preflight processing; that lane
must not be described as local-only. productionReleaseAllowed=false and
publicProductionClaimAllowed=false remain explicit on the composer/assurance contracts.
Imposition places PDF pages onto press sheets for cutting, folding, binding, and production handoff. A good plan improves sheet usage, preserves page order for finishing, and gives the supplier a shared technical reference.
The critical distinction
An imposition preview plan is not an imposed PDF output.
A plan shows where pages land on each sheet side, which page boxes are used, and what transforms apply. An imposed PDF output is a separate export artifact and must be validated with an output receipt.
- A preview plan is for on-screen review.
- Imposed PDF output requires real PDF bytes, SHA-256, a safe file name, page count, and engine identity.
- Measured render evidence is never claimed without native PDFium render evidence and signed production policy.
- Browser preview pixels are not measured raster evidence or proof.
- The former TypeScript planning fallback is retired. A missing or rejected Rust V3 module returns a typed unavailable result and cannot create a plan, digest, token, or canonical export.
Operator workflow cockpit
The strongest lesson from Fiery Impose/JobMaster and FreeFlow Core is that imposition is an operator workflow, not a magic production button. NowToPrint Studio therefore shows the imposition step as a workflow summary, template, job ticket, sheet preview, and hold reason before any output claim.
- Workflow summary: explains the selected product intent, imposition mode, sheet, and mark policy.
- Job ticket: carries plan id, source preflight state, plan hash, output receipt, evidence state, and limitations.
- Template: identifies the built-in or user/org-scoped template version and audit boundary.
- Sheet preview: exposes front/back sides, page order, rotation, trim and bleed geometry, marks, utilization, and waste.
- Hold reason: keeps operator or supplier review visible until output receipt, post-imposition preflight, and required independent acceptance receipts are complete.
This cockpit is not automatic production approval. Choosing a workflow or template does not unlock production proof; it only clarifies how the plan should be reviewed and which evidence gaps keep the job on hold.
Document editing boundary
Foundation v1 is not full content editing. NowToPrint does not rewrite arbitrary text, images, color, transparency, fonts, or source PDF object streams as part of imposition. Page-level document operations such as reorder, rotate, delete, split, and merge are adjacent manifest-backed APIs; they are not imposition math.
Selected bleed, mark and legacy-mark-removal operations already have guarded implementations. Availability depends on the selected mode and runtime; their existence cannot unlock a production claim without operator approval, mutation policy, rollback receipt, post-operation preflight, and PDFium measured raster evidence. Measured raster evidence is visual review evidence only; it is not proof, RIP equivalence, separation authority, or an automated production acceptance.
Sheet viewer controls
Studio's sheet canvas can switch between sheet content and page-number view. Sheet content uses the PDFium preview rasters already generated for on-screen review; page-number view draws imposition placements and blank positions when content preview is not useful. Zooming out shows more sheet sides per row, while zooming in reserves more canvas space for inspection. This is preview UX only: it does not change output bytes, placement math, proof status, or production authority.
Selected sheet, effective sheet, and minimum sheet
The selected sheet is the sheet size chosen by the user. The effective sheet is the sheet size used by the current plan/preview. The minimum sheet is the smallest custom sheet NowToPrint can calculate for the current layout without silently scaling or overflowing pages.
If the selected sheet is too small, Studio may calculate a larger minimum sheet for preview. That is an adjusted plan, not an accepted output state. Export availability stays locked until the user accepts the minimum sheet or chooses a larger sheet, and the output path still needs the normal receipt/evidence chain.
If the output writer is unavailable in the current runtime, Studio keeps the download action disabled and shows the reason. A disabled export button should not call the endpoint. If the server returns a controlled unavailable/failure response, the UI should show the specific next action instead of raw 500/503 text.
Why page boxes matter
Imposition uses MediaBox, CropBox, TrimBox, and BleedBox from the ntp-pdf-core PageGeometryTruth model.
- TrimBox defines the finished product boundary.
- BleedBox describes the safe bleed extent after trimming.
- CropBox constrains the visible working area.
- Non-zero origin and rotation are handled explicitly so overlays do not drift.
Bleed content is not synthesized
If bleed is missing, NowToPrint does not paint, rasterize, or invent new artwork at the page edge. By default, missing bleed remains a finding, limitation, or customer action. If the artwork must change, upload a corrected PDF.
Only when the operator explicitly turns on bleed generation in the imposition settings is the margin built, and then from the page itself, never from new artwork. "Generate by scaling" enlarges the page slightly until it covers the bleed. "Mirror-tile" keeps the page at its own size and fills each bleed strip with the content next to that trim edge, reflected about the edge; the plan says so in a warning. The original PDF is not modified. The imposed output is a new file and includes the selected transformation; existing measured bleed is handled according to the selected policy.
Foundation modes
| Mode | Use case | Evidence language |
|---|---|---|
| N-up | Place multiple pages on one sheet | Placement, trim/bleed rectangles, utilization |
| Step-and-repeat | Repeat one source page across a grid | Repeat count, order, waste |
| Spine-to-spine | Duplex paired N-up sheets | Front/back pairing, spine alignment, utilization |
| Booklet | Fixed 2-up saddle-stitch planning | Front/back page pairing, blank padding; optional caliper-based creep |
| Cut-and-stack | Cut and stack production planning | Stack order, physical cell order, blank padding |
| Multi-booklet | Independent 4–80 page saddle sections | Exact section/page/sheet ranges and blank padding |
| Signature-book | Gathered 4–80 page signature sections | Exact manifest; nested folio or supported catalog scheme |
Phase 12 gives canonical Rust plan authority to N-up, step-and-repeat, cut-and-stack, booklet, bounded multi-booklet, and gathered signature-book contracts. Each signature manifest is domain-separated, budgeted, and post-write proof-bound. Spine-to-spine is a constrained N-up layout in the current Rust planner; it is not a separate production-approval mode. Canonical planning does not by itself grant public production activation: mode-specific composed output, PDFium proof, postflight, and release evidence must still pass the signed assurance boundary. The release verifier validates submitted proof-graph digests, matching output evidence from at least two independently identified runs, and native PDFium-to-preview visual parity evidence for all six modes at the exact source commit. It does not itself run the composer or render those files; browser preview pixels alone do not satisfy the required native evidence. Creep, press fold templates, perfect-binding execution, large-format tiling, packaging ganging, and true-shape nesting are not production-ready public claims.
Marks and guides
Supported mark families are crop marks, cut lines, registration targets, fold marks, collation marks, colour bars and a text slug (job label). The colour bar includes gray K patches; a separate gray-bar family is not exposed. QR/barcode marks are unsupported. Mode, style, glyph and available margin restrictions still apply; a mark that has no room may be omitted with a warning. On-screen guides do not automatically become PDF marks.
What creep means
Creep is the page shift in thicker saddle-stitch work. The V3 planner supports a source-window
translation (shift, the default) and optional proportional scaling (scale). Scaling keeps the
edge toward the selected creep direction fixed and reduces both dimensions uniformly; trim boxes
and marks stay in place. The source window grows and is clipped to the printable source extent,
so inspect the resulting edge content. A non-zero scale-mode creep cannot be combined with
mirror-tile bleed.
Compensation is disabled by default. Without an explicit sheet step, the planner uses twice the paper caliper per nested sheet; an operator-measured sheet step can override it. That default formula still needs checking on a physical press dummy. The chosen step, direction and mode are digest-bound calculations, not proof of the finishing result. Catalog fold schemes refuse creep; review the supported nested-folio result with the printer.
Free browser imposition tools
Two public tool pages run the canonical chain entirely in the visitor's browser:
- Booklet imposition — fixed 2-up saddle-stitch booklet planning and local composition, with optional paper-caliper creep compensation.
- N-up imposition — 2-up/4-up grid layout on one sheet.
In this local lane the source file is read on the device and is not uploaded; no account is required. File, page, time and memory limits still apply. Every downloadable output carries a sealed composition receipt (output SHA-256) and the result of the local post-imposition check, whose findings and unavailable evidence must be read separately. These pages are diagnostic self-service: the receipt language never claims production authority, and signed production decisions remain exclusive to the server lane described above.
Checks before production
A local browser download follows measured source intake, the Rust plan, composition and local postflight. It does not need a platform countersignature and does not claim production acceptance.
The signed assurance path has a further chain:
- Rust reads the source and verifies the external preflight decision.
ntp-pdf-impositionproduces the plan; the composer writes a derived PDF and structural receipt.- Postflight checks the exact bytes with
ntp.preflight.imposed-sheetunderProductionpolicy. - Requested native PDFium evidence must pass its signed supervisor/isolation checks. If measured evidence is unavailable, that state is explicit; invalid evidence is not silently substituted.
- An external issuer signs the final assurance envelope; Rust verifies its identity, bindings, time window and replay state. Both release/public claim flags remain false.
- The durable runtime adapter can connect this chain when its native binding is ready. A registered operation or implemented adapter does not prove deployment availability or printer acceptance.
The output receipt is a structural validation receipt: it proves that the derived PDF bytes were
produced and that header, hash, byte length, file name, and page count checks matched. It does not
prove that the imposed PDF is production-safe. Measured imposed-output raster evidence may only set
visual_evidence_available; production acceptance stays blocked until independent conformance,
supplier, and policy receipts are complete.
During imposition, NowToPrint does not convert RGB to CMYK, convert spot colors to process, flatten transparency, generate trapping, mutate overprint, or outline/substitute fonts. Supported page graphics and their resources are carried through the bounded composer; the annotation, action, attachment and encryption changes described above still apply.
Supplier handoff
Send the supplier the plan summary, selected profile, source preflight report id, plan hash, output receipt status, limitations, and post-imposition preflight/render evidence state. Raw storage refs, local paths, and debug JSON stay out of customer and public views.
Previous: PDF requirements | Next: Crop marks
Was this article helpful?