All PDF I/O through one structured model; raw canonical-PDF-library access banned.

PdfModel (sole PDF mutation surface)

Intent — Route all reads and writes of a complex file format through one structured model, with raw access to the underlying library banned by a lint, so the structure is compiler-checked and every mutation passes through a surface that encodes the format's invariants (our instance: PdfModel over the canonical PDF library).

SummaryAll PDF I/O through one structured model; raw canonical-PDF-library access banned.
TargetProduct · Canonical models & seams
Formtyped-ir
Movepackage — a constraint shipped with its sensors
Modelis-a-model — a structured model you check a system property against
EnforcementHard (deterministic) · blocking — a raw-PDF-library ban-lint fails the build on any raw library call; the structured model is construction, the ban-lint is the counted sensor
Derivationmodel-from-code — induced from the code, reconciled at build

Its place in the environment — the canonical mechanism for CONSTRAIN · Constrain where and how agents act. The variants and known uses that fold under it are gathered on the construction-kit page.

Motivation — the failure it kills

The raw canonical PDF library is a minefield of silent, invisible-at-the-call-site failures. Forget SetModified() on an indirect object and the write is silently dropped on save. Call tagPointer.AddTag or dict.Put directly and you can corrupt the /StructTreeRoot, the exact class that produced the v172 corruption. There is no single place to enforce these invariants, so scattered raw calls make the same PDF bug class recur at every call site.

Why it's not just "use the library carefully" (or "code-review the PDF calls")

The library's sharp edges are invisible where they're used — a missing SetModified() looks like correct code, and reviewers miss it because nothing in the diff flags it. PdfModel makes the raw API unreachable: typed mutators encode the invariants (they can't forget SetModified()), and the raw-PDF-library ban-lint fails the build on any raw constructor, AddTag, dict.Put, or structRoot.AddKid. The distinction is a typed sole-seam whose raw alternative is lint-banned versus disciplined use of a raw API. The structured model is construction: the bug becomes unrepresentable. The ban-lint is the counted detection sensor that keeps every call site on the seam.

Mechanism

Read via PdfModel.Read(path); write via the typed mutators in Primitives/. A raw-PDF-library ban-lint fails the build on raw library constructors, tagPointer.AddTag, dict.Put, and structRoot.AddKid. Each typed mutator wires the SetModified() discipline and stamp emission so a new verb cannot land un-wired.

Prerequisites

Consequences & costs

Known uses

Related mechanisms

Governed by

The mechanisms that hold this model true — inverted from their Governs edges at build time, never hand-written. A direct governor names this model; a trunk mechanism governs every model.