01 — Overview

Atto Documents.

v0

Every Atto document is a single plain-text file. Writing is handled by Markdown markup language A plain-text writing format that uses simple symbols (like bold and # Heading) to mark structure and emphasis while staying readable as raw text. Created in 2004; widely used for documentation, blogs, and notes. , math is handled by LaTeX | lā-tek | typesetting system A typesetting system designed for mathematical and scientific documents. Authors write formulas as code (e.g. \frac{a}{b} for a fraction) and the system renders them as properly typeset notation. The standard for academic publishing since the 1980s. , and structure (signatures, credit checks, parties) is handled by Atto directives. The three live together in one file, parsed once, producing one document.

Every Atto Document (AD) is a .atto file: human-readable, git-diffable, and stable under round-trip serialization. Equal ASTs produce equal byte streams.


02 — Document Header

Document Header.

Every Atto document MUST begin with a ::atto-doc block. It declares document-level metadata and the cast of parties, and it MUST appear before any body content, sections, or directives. The content between ::atto-doc and the closing :: is parsed as YAML.

atto-doc.atto
Source
::atto-doc
  title: Residential Lease Agreement
  type: lease
  jurisdiction: California
  effective-date: 2026-06-01
  parties:
    - id: landlord
      name: Meridian Property Group LLC
      role: Landlord
      email: leasing@meridianpg.com
    - id: tenant
      name: Jordan Ellis
      role: Tenant
      email: jordan.ellis@email.com
::
Rendered

Lease · Effective 2026-06-01 · California

Residential Lease Agreement

Core fields

Field Type Required Description
title string required Human-readable document title. Displayed in the platform UI and audit chain entries.
type string required Document type identifier. Drives schema validation and platform behavior. Examples: lease, contract, invoice, report.
effective-date date (YYYY-MM-DD) optional The date on which the document takes legal effect. ISO 8601 format.
jurisdiction string optional Governing jurisdiction. Plain text. Used by platform tooling for jurisdiction-aware validation.
parties list conditional Required if the document contains any ::signature-block, required-signatory attribute, or :::credit-check directive. Omit for documents with no execution or signing requirements.

Parties schema

The parties list within ::atto-doc is the single source of truth for party identity in the document. The parser resolves every party id reference in the document body — in ::signature-block, required-signatory, and :::credit-check — against this declaration.

Field Type Required Description
id string (kebab-case) required Machine-readable identifier. Referenced by ::signature-block, required-signatory, and chain entries. Lowercase letters, digits, and hyphens only.
name string required Legal name of the party. Always the primary identifier in rendered output and chain entries.
role string required Document-level role label. Displayed alongside the legal name in all rendered views. Cannot be overridden — only supplemented by a local label on a ::signature-block.
email string optional Contact address used by the platform to deliver recipient tokens and signing notifications.

Parser rules

::atto-doc MUST appear as the first line of the file. The parser MUST reject any document where:

  • ::atto-doc is absent,
  • ::atto-doc appears after body content,
  • ::atto-doc appears more than once,
  • the parties list contains duplicate id values, or
  • a ::signature-block, required-signatory, or :::credit-check references an undeclared party id.

The content between ::atto-doc and the closing :: is parsed as YAML. Keys are serialized alphabetically on output for canonical byte stability. Unknown keys are preserved and round-tripped without modification but produce no platform behavior.

Reference & inheritance

Downstream constructs reference parties by id and inherit the canonical role label automatically. The party is declared once in ::atto-doc.parties; every other place it appears resolves through that declaration.

Sections inherit the label

:::section id="signatures" required-signatory="tenant landlord"

The platform displays this section as Required: Tenant, Landlord by resolving each id through ::atto-doc.parties. The :::section block does not re-declare the labels.

Signature blocks inherit the name

::signature-block
  party: tenant
  sign_order: 1
  date-required: true
::

The rendered signature line reads Tenant — Jordan Ellis, pulled from ::atto-doc.parties. The signature block does not re-state the name.

Local supplemental labels

The canonical role cannot be overridden. A ::signature-block MAY supplement it with a label for one specific signing context — e.g., Disclosing Party in an NDA appendix. The render appends the supplemental label after the role; it never replaces it.

supplemental-label.atto
Source
::signature-block
  party: tenant
  label: Disclosing Party
  sign_order: 1
  date-required: true
::
Rendered

The canonical role stays visible alongside the supplemental label so a reader — or an auditor reviewing the chain — can always trace the contextual label back to the underlying party declared in ::atto-doc.parties.


03 — Sections

Sections.

Atto documents are divided into sections. At the simplest level, a section is a Markdown heading. At the protocol level, a section is a named, addressable unit of the document with its own identity in the audit chain. You choose how much structure you need.

Basic sections

Sections use standard Markdown headings, ## through ######. The parser tracks heading depth to build the section tree. Heading text becomes the section label in the sidebar and table of contents. The document title comes from ::atto-doc (§02); body sections start at ##.

sections.atto
Source
## Payment Terms

Client shall pay within 15 days of invoice.

### Late Fees

Overdue amounts accrue at 1.5% per day.

### Currency

All amounts are in USD unless otherwise stated.
Rendered

Payment Terms

Client shall pay within 15 days of invoice.

Late Fees

Overdue amounts accrue at 1.5% per day.

Currency

All amounts are in USD unless otherwise stated.

Named sections

Add a stable ID to any heading using the {#id} attribute. The platform uses this ID to label diffs, generate deep links, and track the section across publishes. Without a stable ID, the platform assigns one automatically — but authored IDs survive heading renames and reorders.

Use a named section whenever you expect the section to be referenced, linked, or signed independently.

named-sections.atto
Source
## Payment Terms {#payment-terms}

Client shall pay within 15 days of invoice.

### Late Fees {#late-fees}

Overdue amounts accrue at 1.5% per day.
Rendered

Payment Terms

Client shall pay within 15 days of invoice.

Late Fees

Overdue amounts accrue at 1.5% per day.

The rendered output is identical to a basic section. The difference is downstream: section links now resolve to /doc/{id}/v/{seq}#payment-terms — stable across edits, diff-friendly, deep-linkable.

:::section block

Wrap a section in a :::section block to make it a protocol-aware unit. Protocol sections can declare a required signatory, appear in the audit chain at publish time, and be shared as scoped recipient links. The content inside is identical to a basic section — the block adds metadata, not syntax.

A document with no :::section blocks is complete and valid. Protocol sections are additive.

Field Type Required Description
id string (kebab-case) optional Recommended. Stable identifier that survives heading renames and reorders. Without one, the platform auto-assigns an ID at first publish.
title string optional Display name in TOC and sidebar. Defaults to the first heading text inside the block.
required-signatory space-separated party IDs optional Party IDs from ::atto-doc.parties. The document cannot execute until every named party has signed this section. The platform resolves each id through the document header to display labels — e.g., "Required: Tenant, Landlord".

Minimal example

:::section id="payment-terms" title="Payment Terms"

## Payment Terms

Client shall pay within 15 days of invoice.

:::

With required signatories

:::section id="signatures" title="Signatures" required-signatory="tenant landlord"

## Signatures

::signature-block
  party: tenant
  sign_order: 1
  date-required: true
::

::signature-block
  party: landlord
  sign_order: 2
  date-required: true
::

:::

Section identity & stability

Section IDs follow a clear precedence:

  1. Authored ID on the :::section block (id="...").
  2. Authored ID on the heading ({#...}).
  3. Auto-generated ID derived from heading text at first publish.

Auto-generated IDs are stable within a publish version but may shift if the heading text changes. If a section will be signed or linked, always declare an explicit id.

If a section with an explicit ID is deleted in a later publish, any recipient tokens scoped to that section are automatically revoked and a revocation entry is written to the audit chain.


04 — Inline Formatting

Inline formatting.

Standard Markdown inline syntax: **bold**, *italic*, `code`, and [text](url). Raw HTML is rejected — the parser does not pass through tags. If Markdown cannot express what you need, use a directive.

Field Type Required Description
**bold** Strong optional Strong emphasis. Renders bold.
*italic* Emphasis optional Emphasis. Renders italic.
`code` Code optional Inline code span. Uses the mono font.
[text](url) Link optional Hyperlink. The parser validates URLs are absolute or atto://.
~~strike~~ Strikethrough optional Strikethrough for redlines and deletions.

Example

inline.atto
Source
Client shall pay within **15 days** of invoice.
See the [master agreement](https://example.com) for definitions, including *reasonable notice*.

Amounts invoiced under clause `3.1.a` are non-refundable once ~~delivered~~ accepted in writing.
Rendered

Client shall pay within 15 days of invoice. See the master agreement for definitions, including reasonable notice.

Amounts invoiced under clause 3.1.a are non-refundable once delivered accepted in writing.


05 — Inline LaTeX

Inline LaTeX.

Wrap an expression in single dollar signs: $…$. Renders in-line with surrounding prose at body text size. Dollar signs inside the expression must be escaped as \$.

Variables and operators

math-simple.atto
Source
The late fee is $L = B \times 0.015$ per day.
Present value equals $PV = FV / (1 + r)^n$.
Rendered

The late fee is L = B × 0.015 per day. Present value equals PV = FV / (1 + r)n.

Greek letters and fractions

math-greek.atto
Source
Interest accrues at rate $\alpha = \frac{r}{n}$ where $n$ is the number of compounding periods and $\beta \approx 0.05$ is the service margin.
Rendered

Interest accrues at rate α = r / n where n is the number of compounding periods and β ≈ 0.05 is the service margin.

Subscripts and aggregates

math-sub.atto
Source
Total liability is bounded by $L_{max} = \sum C_i$ across all invoices $i \in \{1, \ldots, n\}$.
Rendered

Total liability is bounded by Lmax = Σ Ci across all invoices i ∈ {1, …, n}.


06 — Display LaTeX

Display LaTeX.

Wrap an expression in double dollar signs: $$…$$ on their own lines. Renders as a centered display block, isolated from surrounding prose.

Compound interest

display-compound.atto
Source
The value after $t$ years of compounding:

$$
A = P\left(1 + \frac{r}{n}\right)^{nt}
$$
Rendered

The value after t years of compounding:

A = P(1 + rn)nt

Summation

display-sum.atto
Source
Post-money valuation aggregates pre-money plus all investment tranches:

$$
V_{post} = V_{pre} + \sum_{i=1}^{n} I_i
$$
Rendered

Post-money valuation aggregates pre-money plus all investment tranches:

Vpost = VpreΣ i=1 n  Ii

Aligned equations

display-aligned.atto
Source
The late-fee calculation, written out:

$$
\begin{aligned}
L &= B \times r \\
  &= B \times 0.015 \\
  &= 0.015 B \quad \text{(per day)}
\end{aligned}
$$
Rendered

The late-fee calculation, written out:

L   = B × r
     = B × 0.015
     = 0.015B  (per day)


07 — Content Blocks

Content blocks.

Content blocks are typed presentational compounds. They open with ::name on a line by itself, close with a bare ::, and accept YAML-shaped content between. They render as styled UI but produce no audit-chain entries. Their source still participates in content_hash, so a callout cannot be silently retitled and a review anchor cannot be moved without invalidating the document.

::callout

A typed admonition. The tone attribute selects the visual and semantic treatment; an optional title gives the callout a one-line header. The body is parsed as Markdown.

Field Type Required Description
tone 'note' | 'info' | 'warning' | 'danger' required Visual treatment and semantic severity.
title string optional One-line heading shown next to the tone label.

All tones

callout-tones.atto
Source
::callout
tone: note
title: Definitions
Capitalized terms take the meanings given in §1.
::

::callout
tone: info
title: Reference
See the master agreement for fallback provisions.
::

::callout
tone: warning
title: Review Required
This clause applies only on quarterly distributions.
::

::callout
tone: danger
title: Irrevocable
Once executed, this waiver cannot be revoked without both parties’ written consent.
::
Rendered

::review-anchor

Anchors a review thread to a specific AST node. Comments attach to the anchor by id, not to line numbers — edits around the anchor do not orphan the thread. The body is the content under review.

The anchor itself participates in content_hash like every other byte of the document. A reviewer’s anchor cannot shift silently: any edit that relocates the anchor or alters its body invalidates the document and forces a re-sign.

Field Type Required Description
id slug required Stable identifier for the review thread. Must be unique per document.
status 'open' | 'pending' | 'resolved' optional Review state. Defaults to 'open'.
assignee string optional Email of the reviewer responsible for resolving the thread.
tags string[] optional Free-form tags for filtering, e.g. [legal, pricing].
review-anchor.atto
Source
::review-anchor
id: late-fee-review
status: pending
assignee: counsel@example.com
tags: [legal, pricing]
The late fee calculation in §3.2 is pending counsel approval.
Current formula: $L = B \times 0.015$ per day.
::
Rendered

08 — Protocol Blocks

Protocol blocks.

Protocol blocks are the first-class trust primitives of the Atto Format. Each one produces a dedicated event kind on the document’s audit chain: a ::signature-block emits signature.executed when fulfilled, an ::attachment emits attachment.added at publish, and a :::credit-check emits directive.credit_check when its precondition resolves. The cryptographic verification model of an AD is incomplete without them.

The two syntactic forms are orthogonal to the tier. Most protocol blocks are primitive :: directives. The triple-colon form :::name { … } ::: is reserved for higher-level authoring surfaces that compile to one or more :: directives at document build time AND render a tenant-facing UI component the subject sees when they open the document.

Every ::: block is disclosure-first. Fields the author might otherwise omit — purpose, requesting party, privacy scope — are REQUIRED. The document is invalid if any required disclosure field is missing. The subject reads the rendered form; an auditor can read the block source and verify exactly what consent was granted.

::signature-block

Declares one or more signatures. Each entry binds a party — referenced by id from ::atto-doc.parties (§02) — to a sign_order. The Baldwinson Protocol layer enforces the order: signer 2 cannot countersign until signer 1 has. When a signer fulfills their entry, the block emits signature.executed on the audit chain.

Label and legal name resolve through ::atto-doc.parties automatically (see Reference & inheritance). A signature block doesn’t restate the party’s name; it only adds the fields the party itself can’t provide — the human representative for a corporation, the signing order, the date requirement.

Field Type Required Description
party string (party id) required References an id declared in ::atto-doc.parties. The signature line inherits the party's name and role label automatically.
sign_order integer required Queue position for signing, 1-indexed.
signer string optional Override the legal name pulled from ::atto-doc.parties. Use when the signing individual is distinct from the party itself — e.g., the natural-person representative of a corporation.
title string optional Signing individual's title at the party, e.g. CEO, Managing Partner. Only meaningful when `signer` is set.
label string optional Local supplemental label for this signing context. The canonical role from ::atto-doc.parties cannot be overridden — it stays visible alongside the supplement. See §02 Reference & inheritance for the rendered example.
date-required boolean optional Require a dated signature. Defaults to false.
signature-block.atto
Source
::signature-block
  - party: tenant
    sign_order: 1
    date-required: true
  - party: landlord
    signer: Alex Reynolds
    title: Director of Leasing
    sign_order: 2
    date-required: true
::
Rendered

The first entry resolves cleanly: a natural-person tenant signs as themselves — Tenant — Jordan Ellis. The second adds signer and title because the landlord party is a corporation; the rendered line reads Landlord — Alex Reynolds, Director of Leasing, with Meridian Property Group LLC attributed as the signing entity in the audit chain event.

::attachment

References an external file by content hash. The document treats the attachment as part of its canonical content; the freeze event verifies every hash before emitting doc.freeze, and a successful publish emits attachment.added on the audit chain.

Field Type Required Description
label string required Human-readable label, e.g. Schedule A, Exhibit 1.
uri uri required Location of the file. Accepts atto://, https://, or ipfs://.
sha256 hex required 64-character SHA-256 digest of the file contents.
media_type string optional IANA media type, e.g. application/pdf.
bytes integer optional File size in bytes. Used for UI display and integrity checks.
attachment.atto
Source
::attachment
label: Schedule A
uri: atto://attach/schedule-a.pdf
sha256: 4c1f...a7
media_type: application/pdf
bytes: 131072
::
Rendered

:::credit-check

Declares a credit-check precondition for document execution. The block compiles to an ::alp:precondition:credit-check directive evaluated by the Precondition Directive Evaluation Engine (PDEE), and simultaneously renders a tenant-facing consent form. The subject cannot sign the document until the precondition is satisfied.

Required disclosure fields

Field Type Required Description
id string required Unique identifier within the document. Referenced by the compiled ::alp:precondition:credit-check directive as precondition_id.
party string required party_id of the subject whose credit is being checked. MUST resolve to a party declared in the execution preamble.
purpose string required Plain-language reason for the check. Shown verbatim in the tenant's consent disclosure and reported to the bureau adapter as permissible-purpose context. Template placeholders are rejected.
requesting_party string required Legal name of the entity requesting the check. Shown verbatim in the consent disclosure. MUST match the landlord party's legal_name.
pull_type 'hard_pull' | 'soft_pull' required Hard pulls appear on the consumer's credit file; soft pulls do not. A mismatch with the bureau adapter's actual pull type is a fatal validation error.
bureau 'experian' | 'transunion' | 'equifax' | 'any' required 'any' permits the PDEE to select the bureau. The bureau actually used is recorded in execution metadata.
score_model 'FICO8' | 'FICO9' | 'VantageScore3' | 'VantageScore4' required Scoring model used for the pass/fail determination.
disclosed_to array of enum | party_id required Who receives the pass/fail outcome. Values: requesting_party, named_parties, all_signatories, or specific party_ids. The raw score is NEVER shared through this field — only the pass/fail result.
extent 'score_only' | 'full_report' | 'income_verified' required Breadth of the inquiry. See the extent reference below.
min_score integer 300–850 required Required when extent is score_only or income_verified. Minimum score for a pass outcome.
on_pass 'proceed' | 'notify_requesting_party' required PDEE action on pass. proceed advances the execution queue.
on_fail 'withdraw' | 'notify_requesting_party' | 'human_review' required PDEE action on fail. human_review pauses execution for review_window_hours before auto-withdrawing.

Optional fields

Field Type Required Description
immediate_feedback boolean optional Default false. When true, the rendered form shows the tenant a pass/fail result as soon as the bureau responds. When false, the tenant sees only a "submitted — awaiting review" state.
review_window_hours integer optional Only valid when on_fail = human_review. Default 48. Hours the requesting party has to decide before auto-withdrawal.
timeout_hours integer optional Default 48. Hours the PDEE waits for a bureau response before treating the check as failed.

Extent levels

Field Type Required Description
score_only Score only optional Credit score only. No tradeline detail, no account history. Lowest privacy impact. min_score is required.
full_report Full report optional Full consumer credit report including tradelines, inquiries, public records, and collections. Retained in execution metadata (encrypted, accessible only to requesting party). min_score optional.
income_verified Score + income optional Credit score plus income verification via payroll connector (Argyle, Pinwheel). Requires chained ::alp:precondition:income-verify. min_score is required and applies to the score component only.

Example — residential lease

:::credit-check
credit-check.atto
Source
:::credit-check {
  id               = "cc-residential-001"
  party            = "party-tenant-jane-doe"

  purpose          = "Residential tenancy application for 42 Elm Street,
                      Unit 3B, Los Angeles, CA 90024. Requested by
                      Westbrook Property Management LLC on behalf of
                      property owner."

  requesting_party = "Westbrook Property Management LLC"
  pull_type        = hard_pull
  bureau           = transunion
  score_model      = FICO8

  disclosed_to     = [requesting_party]
  extent           = score_only
  min_score        = 680

  on_pass          = proceed
  on_fail          = human_review
  review_window_hours = 72

  immediate_feedback = false
  timeout_hours    = 24
}
:::
Rendered

Compilation to ALP

The :::credit-check block compiles mechanically to an ::alp:precondition:credit-check directive at build time. The field mapping is exact:

Field Type Required Description
id → precondition_id optional Direct mapping.
party → subject_party_id optional Direct mapping.
min_score / bureau / score_model / pull_type / timeout_hours → same optional Direct mapping of PDEE-relevant fields.
on_fail = withdraw → failure_action = "withdraw" optional Document enters WITHDRAWN on fail.
on_fail = notify_requesting_party → failure_action = "notify_only" optional Record failure; notify landlord; await their decision.
on_fail = human_review → failure_action = "notify_only" + review_window annotation optional Pauses at PRECONDITION_PENDING for review_window_hours.
purpose / requesting_party / disclosed_to / extent → consent_scope.* fields optional Embedded in the consent-scope object sent to the bureau adapter as permissible-purpose context.
immediate_feedback → renderer directive only optional Not forwarded to the PDEE. Purely controls what the rendered form shows the subject.

Validation rules

A document containing a :::credit-check block is INVALID if any of the following are true:

  • purpose is absent, empty, or contains only template placeholder text (e.g. [property address]).
  • requesting_party does not match the legal_name of any declared party.
  • party does not resolve to a party_id in the execution preamble.
  • pull_type = hard_pull and consent_scope has not been completed before PDEE dispatch.
  • extent is score_only or income_verified and min_score is absent.
  • on_fail = human_review and review_window_hours is absent.
  • disclosed_to contains a party id not declared in the execution preamble.
  • Two :::credit-check blocks in the same document share an id.
  • immediate_feedback = true and on_fail = human_review simultaneously — these are contradictory.

Raw-score disclosure is non-negotiable: regardless of disclosed_to, the numeric score is NEVER exposed in the rendered document or any interface accessible to disclosed parties. Scores are stored encrypted in execution metadata, accessible only to the PDEE and, after execution, to the requesting party via a credentialed API call.


09 — Font References

Font references.

A document that can be signed must be renderable identically at any future time. The Atto Font Registry Protocol (AFRP) defines a portable identifier grammar, a registry manifest format, and a resolution algorithm that binds every executed document to the exact font binaries present at signing.

This section is a normative summary of AFRP v1.0. The full specification — including the JSON Schema, error code definitions, governance procedures, and security analysis — lives at spec.atto.tech/afrp.

Two tiers, three forms

AFRP defines two namespace tiers operating under one resolution protocol. The permissionless tier guarantees the governed tier can never act as a gatekeeper for the system.

Field Type Required Description
@/Typeface Form A · Tier 1 optional Canonical shorthand. No scope between @ and /. Resolves against the canonical Atto registry at https://fonts.atto.tech/. Portable across all compliant implementations without hardcoding a host.
@scope/Typeface Form B · Tier 1 optional Ratified scope shorthand. Tier 1 scopes are not self-serve — they are granted by invitation from the Atto Protocol Authority and ratified by the Technical Review Panel for foundational infrastructure providers. The criteria govern identity and permanence; they do not audit catalog size, originality, or creative merit.
host/Typeface Form C · Tier 2 optional Permissionless full URI. Any DNS host serving a compliant AFRP manifest is a valid registry. No registration, approval, or contact with any authority required. Equivalent openness to the Web itself.

Form A is distinguished from Form B by the absence of characters between @ and /. A resolver MUST NOT treat an unregistered Form B scope as a fallback to Form A — it emits SCOPE_NOT_FOUND and proceeds to the fallback chain.

Three paths to AFRP compliance

A font publisher has three ways to make their fonts available inside AFRP-compliant documents. The architectural principle is that Tier 1 exists to protect namespace identity for permanent infrastructure providers, not to gatekeep font publication.

  1. Self-host a Form C registry. Serve a compliant manifest at any DNS hostname you control. No registration, approval, or contact with any authority. Full technical responsibility rests with the publisher. See Registry manifest for the well-known endpoint and JSON Schema.

  2. Atto Hosted Registry Service (AHRS). Subscription-based managed hosting. The publisher provides font files and metadata; Atto operates the registry, computes integrity hashes, runs ARCTS, and serves a compliant manifest under hosted.fonts.atto.tech/{slug}/ or a custom domain. Resolves as Form C. See Hosted registry.

  3. Tier 1 ratified scope. Reserved for foundational infrastructure providers meeting the permanence and identity criteria. Invitation-only ratification by the Technical Review Panel. Resolves as Form B @scope/Typeface. See Tier 1 ratification.

The permissionless Form C tier guarantees that the Atto Protocol Authority can never act as a gatekeeper for the system as a whole — Tier 1 governs namespace identity only.

Sub-scope delegation

A registered scope MAY delegate sub-namespaces one level deep by declaring a delegations map in its registry manifest. The parent scope retains governance responsibility; the delegated registry MUST pass ARCTS before the delegation is published.

; Parent scope with two delegations
"adobe": {
  "base_url":    "https://afrp.adobe.com/",
  "delegations": {
    "monotype": "https://fonts.monotype.com/afrp/",
    "linotype": "https://afrp.linotype.com/"
  }
}

; Resolution
@adobe/HelveticaNeue            → https://afrp.adobe.com/
@adobe/monotype/HelveticaNeue   → https://fonts.monotype.com/afrp/
@adobe/linotype/Optima          → https://afrp.linotype.com/

Four-component identifiers like @a/b/c/Name are invalid per the ABNF. Delegated registries cannot further sub-delegate.

Identifier grammar

A font reference is a font identifier optionally augmented with typographic axis qualifiers. The identifier locates the asset; qualifiers select its typographic state. ABNF summary (RFC 5234):

font-reference    = font-identifier *( WSP qualifier )
font-identifier   = form-a / form-b / form-c

; Form A — Canonical Atto registry
form-a            = "@/" typeface-name [ version-specifier ]

; Form B — Registered scope (one-level sub-scope permitted)
form-b            = "@" scope "/" [ sub-scope "/" ] typeface-name [ version-specifier ]

; Form C — Full URI (permissionless)
form-c            = host-authority "/" typeface-name [ version-specifier ]

scope             = lc-alpha *( lc-alpha / DIGIT / "-" )
typeface-name     = tc-alpha *( tc-alpha / DIGIT / "-" / "_" )
lc-alpha          = %x61-7A                  ; lowercase a-z
tc-alpha          = %x41-5A / %x61-7A        ; A-Z or a-z

version-specifier = "@" version-value
version-value     = exact-version / range-caret / range-tilde / "latest" / "pinned"
exact-version     = major "." minor "." patch [ "-" pre-release ] [ "+" build-meta ]
range-caret       = "^" major [ "." minor [ "." patch ] ]
range-tilde       = "~" major "." minor [ "." patch ]

qualifier         = axis-tag "=" axis-value
axis-tag          = 4( ALPHA / DIGIT )       ; OpenType 4-char tag
axis-value        = 1*DIGIT [ "." 1*DIGIT ]

Version specifiers

Field Type Required Description
@X.Y.Z exact optional Resolves to exactly version X.Y.Z. MUST fail with VERSION_NOT_FOUND if that version is absent from the manifest.
@^X[.Y[.Z]] caret range optional Highest version ≥ X[.Y[.Z]] and < (X+1).0.0. Major version fixed. Forward-compatible with minor and patch updates.
@~X.Y[.Z] tilde range optional Highest version ≥ X.Y[.Z] and < X.(Y+1).0. Minor version fixed. Accepts patch updates only.
@latest symbolic optional Highest stable version available. SHOULD NOT be used in documents intended for signing. When a version specifier is absent entirely, behavior is equivalent to @latest.
@pinned symbolic optional Version recorded in document execution metadata. Valid only in EXECUTED state. A resolver encountering @pinned in a DRAFT document emits PINNED_IN_DRAFT and treats it as @latest.

Pre-release versions MUST NOT be matched by caret or tilde ranges unless the range itself is pre-release qualified. The version portion follows SemVer 2.0.0 exactly.

Reserved names

  • Scope reserved: atto, official, authority, registry, root, sys, localhost. Only the Atto Protocol Authority may use these.

  • Version reserved: latest and pinned MUST NOT appear as typeface names or scope names.

  • Case sensitivity: scopes are lowercase-only. Typeface names are case-sensitive and preserved exactly. Registered four-character axis tags use lowercase; custom axes registered by foundries use uppercase (e.g. GRAD, YOPQ).

Axis qualifiers

Variable-font axes are selected by whitespace-separated qualifiers of the form tag=value following the font identifier. Each qualifier pins a single OpenType registered axis. Values absent from a font reference default to the manifest’s variable_axes.default for that axis — or, if the manifest declares none, to the OpenType-registered default (wght=400, opsz=12, ital=0).

Field Type Required Description
wght 100–900 optional Weight from Thin (100) to Black (900). Alias: weight=. Equivalent to CSS font-weight.
wdth 75–125 optional Width from Condensed (75) to Extended (125). Equivalent to CSS font-stretch.
opsz 6–72 optional Optical size — letterforms optimized for the given point size.
ital 0–1 optional 0 = upright, 1 = fully italic. Continuous axis. Aliases: style=italic → ital=1; style=normal → ital=0.
slnt −15–0 optional Slant angle in degrees. Negative values lean right. Alias: style=oblique → slnt=−12 (registries MAY override the default oblique angle).
GRAD −50–150 optional Grade — adjusts weight without changing character advance widths. Useful for dark-on-light vs. light-on-dark compensation.

Critical for execution integrity. In EXECUTED state, every axis value — including those not explicitly qualified at the reference site — MUST be recorded in the execution metadata pin. An absent qualifier means “use the manifest default,” and that default must be frozen at signing so later manifest edits cannot alter visual output.

For non-variable fonts, only wght and ital are meaningful — they drive static-style selection. All other axis qualifiers MUST be ignored and an AXIS_NOT_SUPPORTED informational event is emitted.

Font declaration block

Every AD declares its font requirements in a dedicated ---atto-meta header block. The fonts array binds document-local names (id) to font references. Inline markup then refers to fonts by that id.

Field Type Required Description
id string required Document-local name, unique within the fonts block. Used in inline markup as {font=body}.
ref font-identifier required AFRP font identifier conforming to the §3.2 ABNF grammar.
weight integer | integer[] optional CSS weight 100–900. If an array, the renderer loads all listed weights. Defaults to 400.
style 'normal' | 'italic' | 'oblique' | string[] optional If an array, the renderer loads all listed styles. Defaults to normal.
axes object (tag → number) optional Explicit OpenType axis values for variable fonts. Absent axes default per §5.4. In EXECUTED state the complete resolved axis set MUST appear in the pin.
fallback font-identifier[] optional Ordered fallback chain evaluated per §7.1. Each entry MUST be a valid font identifier or a system: reference.
inline_manifest object optional Inline manifest for Form C fonts unreachable via well-known or per-font endpoints. MUST match execution metadata for EXECUTED documents.
fallback_to_atto boolean optional Per-font override of the document-level fallback_to_atto flag.
atto-meta-fonts.atto
Source
---atto-meta
protocol_version: "1.0"
fonts:
  - id:       body
    ref:      "@/Lineal"
    weight:   400
    style:    normal
    axes:
      wght:   400
      opsz:   14
    fallback: ["@velvetyne/Lineal", "system:sans-serif"]

  - id:       display
    ref:      "@velvetyne/Bagnard@2.1.0"
    weight:   [400, 700]
    style:    [normal, italic]

  - id:       mono
    ref:      "fonts.mycorp.com/Sligoil@^2"
    weight:   400
    fallback: ["system:monospace"]
---
Rendered

Services Agreement · Fonts declared

Services Agreement

Typography

Body text is set in @/Lineal at wght=400 opsz=14 (canonical, variable). Display headings use @velvetyne/Bagnard@2.1.0 (governed scope). A third entry declares an in-house monospace with a system fallback.

A parser MUST reject a document with duplicate id values in the fonts block and MUST emit MISSING_REF for any declaration missing a ref.

Inline font references

Font identifiers may appear inline via the AF span annotation notation {font=...}. An annotation accepts either a declared id or a direct font reference (identifier + optional axis qualifiers). Both forms resolve identically through the algorithm in §08.7.

inline-font-refs.atto
Source
Primary clause — this [Services Agreement]{font=@adobe/Garamond wght=400}
governs the relationship between the parties.

Defined term — the phrase [Corporate Steed]{font=@velvetyne/Bagnard wght=400 ital=1}
refers to the vehicle described in Exhibit A.

Record ID — transaction [SEC-2025-0412]{font=mono}
requires counter-signature.
Rendered

Primary clause — this Services Agreement governs the relationship between the parties.

Defined term — the phrase Corporate Steed refers to the vehicle described in Exhibit A.

Record ID — transaction SEC-2025-0412 requires counter-signature.

Note. The rendered preview above uses open-source stand-ins (EB Garamond for @adobe/Garamond, Playfair Display for @velvetyne/Bagnard, Geist Mono for the document-declared mono) purely to illustrate the typographic switch. A production AFRP resolver would pin the exact binary hashes declared by each registry per §08.6 and §08.8.

When a declared id is used, the resolver MUST use the ref, weight, and style from the corresponding declaration entry unless inline qualifiers explicitly override them for that span. Direct inline references in DRAFT mode activate fallback_to_atto: true behavior.

Registry manifest

A compliant AFRP registry serves a registry-level manifest at the well-known path /.well-known/atto-font-registry.json, returned with Content-Type: application/atto-font-manifest+json. Manifests MUST be served over HTTPS with valid TLS, carry Cache-Control headers, and set Access-Control-Allow-Origin: * for browser-based renderers.

Registries MAY additionally serve per-typeface manifests at /<TypefaceName>/manifest.json. When available, resolvers SHOULD prefer this endpoint to reduce bandwidth; a per-font response takes precedence over the registry-level manifest for that typeface.

// /.well-known/atto-font-registry.json
{
  "registry": {
    "name":             "Velvetyne Type Foundry Registry",
    "homepage":         "https://velvetyne.fr",
    "contact":          "registry@velvetyne.fr",
    "protocol_version": "1.0",
    "shorthand":        "velvetyne",
    "base_url":         "https://registry.velvetyne.fr/"
  },
  "fonts": [{
    "id":       "Bagnard",
    "designer": "Sébastien Sanfilippo",
    "foundry":  "Velvetyne Type Foundry",
    "license": {
      "spdx":              "OFL-1.1",
      "url":               "https://scripts.sil.org/OFL",
      "commercial_use":    true,
      "embedding_allowed": true
    },
    "versions": [{
      "version": "2.1.0",
      "styles": [{
        "weight": 400,
        "style":  "normal",
        "is_variable": false,
        "formats": [{
          "type":      "woff2",
          "url":       "https://registry.velvetyne.fr/Bagnard/2.1.0/Bagnard-Regular.woff2",
          "integrity": "sha256-abc123DEFghi456JKLmno789PQRstu012VWXyz3456A="
        }]
      }]
    }]
  }]
}

There is no manifest-level signature. Trust in the manifest flows from TLS certificate validation, HSTS, and certificate transparency monitoring — not from a JCS-canonicalized wire signature. Per-asset integrity hashes guarantee binary authenticity downstream of the manifest fetch.

Resolution algorithm

Resolution behavior depends on document state. An EXECUTED document renders identically at any future time using exactly the binaries present at signing.

BehaviorDRAFT modeEXECUTED mode
fallback_to_atto defaulttruefalse
System font substitutionPermittedForbidden
All-failure outcomeSystem sans-serifVisible error; rendering halted
TLS validation skipPermitted (with warning)Forbidden
@pinned specifierTreated as @latestMUST use pinned version
full_integrity checkOptionalMUST be applied

The 11-step algorithm in AFRP §5.2 is non-negotiable. Every compliant resolver MUST:

  1. Parse the font reference per the §3.2 ABNF. Fail fast on syntax errors.
  2. Translate reserved aliases (weight=wght=, style=italicital=1).
  3. Classify as Form A / Form B / Form C and derive the registry base URL.
  4. Fetch the manifest (see three-step discovery below), validate schema, protocol version, integrity-field format, and URL scheme.
  5. Locate the font entry by typeface name.
  6. Select a version satisfying the specifier per SemVer precedence.
  7. Select a style entry, then a format entry (woff2 preferred).
  8. Download the binary, compute SHA-256 over the decompressed body, compare constant-time against integrity.
  9. EXECUTED only: compare against full_integrity from the pin. Mismatch → INTEGRITY_VIOLATION, halt rendering.
  10. If license_info.commerce is present, validate the license token or acquire a use_receipt from payment_endpoint.
  11. Cache the verified asset keyed by (registry, typeface, version, format, weight, style, integrity).

Form C manifest discovery

For Form C identifiers, the resolver attempts manifest discovery in three ordered steps. The first success ends the search:

  1. Well-known: GET https://host/.well-known/atto-font-registry.json. If the typeface appears in the fonts[] array, resolution proceeds against this manifest.

  2. Per-typeface: GET https://host/&lt;TypefaceName&gt;/manifest.json. Takes precedence over the registry-level manifest when available.

  3. Inline: use the inline_manifest declared in the document’s fonts[] block. Final fallback. MUST match execution metadata in EXECUTED documents.

All three attempts failing → REGISTRY_UNREACHABLE. Resolvers MUST NOT construct heuristic URLs based on scope names. TLS relaxations apply only to localhost and loopback addresses in DRAFT mode.

Integrity & execution pin

AFRP uses SHA-256 subresource integrity hashes throughout, in the canonical SRI format sha256-<base64>. Hash comparison MUST use constant-time equality to prevent timing side-channels. A resolver MUST NOT cache or render with any asset whose hash fails verification.

When an AD is sealed to EXECUTED state, the signer freezes a complete execution pin for each declared font. The pin is covered by the document signature — tampering invalidates the whole document.

---atto-meta
protocol_version: "1.0"
execution_state:  "EXECUTED"
execution_timestamp: "2026-04-24T03:00:00Z"
fonts:
  - id:                body
    ref:               "@/Lineal"
    weight:            400
    style:             normal
    axes:
      wght:            400
      opsz:            14
    _resolved_version: "2.1.0"
    pinned_format:     "woff2"
    full_integrity:    "sha256-ZXh4mNAbCd12efGH34ijKL56mnOP78qrST90uvWX12Y="
    subset_integrity:  "sha256-Sb5eTz3nOpQr21StUv45WxYz67AbCd89EfGh01IjKl="
    subset_glyph_ids:  [32, 65, 66, 67, 68, 69, 70, 97, 98, 99]
---
Field Type Required Description
_resolved_version semver string required The concrete SemVer version selected by the resolver at signing time. The pinned version takes precedence over the ref specifier at render time.
pinned_format 'woff2' | 'woff' | 'ttf' | 'otf' required Format type selected at signing. Silent format fallback is forbidden in EXECUTED mode — PINNED_FORMAT_UNAVAILABLE halts rendering.
full_integrity sha256 SRI required SHA-256 SRI hash of the complete, unmodified font binary fetched from the registry. Verified against the current registry binary at render time.
subset_integrity sha256 SRI optional SHA-256 SRI hash of the subsetted binary embedded in this export. Subsetting is an export-time operation (PDF/DOCX) — MUST NOT occur during in-protocol resolution.
subset_glyph_ids integer[] optional Array of glyph IDs included in the subset. A validator MAY verify the subset contains all glyphs present in document text and no extras.
subset_unicode_ranges string[] optional Human-readable summary of covered Unicode ranges, e.g. ["U+0020-007E", "U+00A0-00FF"].
use_receipt object optional For per_execution or royalty commerce-model fonts: the Ed25519-signed receipt returned by payment_endpoint, verified against license_authority_key.

Two-layer integrity. subset_integrity alone is insufficient — it proves only that the embedded binary is unaltered, not that it was derived from the legitimate source. Both full_integrity and subset_integrity MUST be verified together for a complete integrity assertion.

Fallback policy

When primary resolution fails with an ERROR-level code, the resolver evaluates a four-step fallback chain. The first success ends the chain:

  1. F1 — Document-declared fallback. Each entry in the declaration’s fallback[] array is resolved sequentially through the full §5.2 algorithm.

  2. F2 — Implicit Atto fallback (Form B only). If the primary is Form B and fallback_to_atto is true, attempt to resolve @/{TypefaceName} against the canonical Atto registry. Form A and Form C MUST NOT trigger this step.

  3. F3 — System font reference. If fallback[] contains a system: entry (§7.3) and prior attempts failed, substitute the system font. DRAFT only.

  4. F4 — Terminal failure. DRAFT: system sans-serif + FONT_UNRESOLVED warning. EXECUTED: visible error indicator, rendering halted for that region. MUST NOT substitute any font.

System font references

System fonts use the system: prefix and are valid only as fallback entries. They MUST NOT appear as primary identifiers and MUST NOT be the sole font entry in a document intended for EXECUTED state — system fonts vary across platforms and cannot be integrity-pinned.

Field Type Required Description
system:sans-serif fallback-only optional System default proportional sans-serif. Equivalent to CSS font-family: sans-serif.
system:serif fallback-only optional System default proportional serif.
system:monospace fallback-only optional System default monospace.
system:ui fallback-only optional System default UI font (San Francisco, Segoe UI, etc.).

Offline fallback. Every compliant AFRP renderer MUST bundle a copy of @/Lineal with an integrity hash baked into the renderer build. DRAFT-mode offline resolution falls back first to this bundled binary (emitting FONT_SUBSTITUTED), then to the host system’s sans-serif. EXECUTED mode forbids all offline substitution.

Font Commerce Layer

AFRP embeds a native payments surface for fonts. A license_info.commerce block in the manifest declares one of five pricing models. Resolvers enforce the commerce contract during resolution (§5.2 step 10); the resulting use_receipt is embedded in the executed document’s pin.

Field Type Required Description
free no-cost optional No action. Resolution proceeds normally.
seat license-token optional Resolver validates the document-declared license_token against payment_endpoint. Absent or invalid → LICENSE_REQUIRED (DRAFT) or execution blocked (EXECUTED).
per_execution per-use optional Resolver POSTs to payment_endpoint with document ID + execution timestamp. On success, the returned use_receipt is embedded in execution metadata. On failure → LICENSE_PAYMENT_FAILED, execution blocked.
subscription token optional Resolver validates subscription token against payment_endpoint. On failure → LICENSE_REQUIRED, execution blocked.
royalty per-use optional Same acquisition flow as per_execution. Royalty terms carry distinct accounting semantics downstream of AFRP.

All use_receipt objects returned by payment_endpoint MUST be verified against the license_authority_key Ed25519 public key declared in the manifest before embedding. An unverifiable receipt is treated as LICENSE_PAYMENT_FAILED. A manifest declaring commercial_use: false on a document declaring commercial_use: true fails resolution with LICENSE_INCOMPATIBLE.

// license_info block with commerce
{
  "spdx":                  "LicenseRef-Proprietary",
  "url":                   "https://hydra.type/license",
  "commercial_use":        true,
  "embedding_allowed":     true,
  "commerce": {
    "model":                "per_execution",
    "price_usd_cents":      500,
    "payment_endpoint":     "https://commerce.hydra.type/v1/receipts",
    "license_authority_key": "MCowBQYDK2VwAyEA..."
  }
}

Tier 1 ratification

Tier 1 @scope grants are not available by self-serve application. They are initiated by the Atto Protocol Authority or by invitation, reviewed against the criteria below, and ratified by the Technical Review Panel. An entity may express interest by emailing registry@atto.tech, but interest does not constitute an application and does not guarantee review. Tier 1 is reserved for foundational infrastructure providers — for self-serve hosting, see the Hosted Registry Service.

The criteria govern identity, permanence, transparency, and technical compliance — none of them are content-restrictive. Catalog depth and originality were criteria in earlier drafts; they have been removed because they are content determinations the Authority is not positioned to make equitably across all cultural and organizational contexts. A Tier 1 grant requires satisfaction of all five criteria below.

  1. Infrastructure permanence. A foundational font infrastructure provider whose registry is expected to remain operational, publicly accessible, and independently maintained indefinitely. Evidence: organizational age of at least five years, institutional backing or endowment, a public commitment to long-term stewardship.
  2. Identity verification. The scope name MUST correspond to the applicant’s verified legal or organizational identity (e.g. @adobe for Adobe Inc., @velvetyne for Velvetyne Type Foundry). Verified by trademark, WHOIS-verified domain, or equivalent documentary evidence. Invented or speculative scope names are not eligible.
  3. License transparency. Every font served MUST include machine-readable SPDX metadata. Proprietary licenses MUST accurately declare commercial_use, embedding_allowed, and web_embedding_allowed. False declarations are grounds for revocation.
  4. Protocol compliance. Registry MUST pass the ARCTS test suite — schema conformance, per-asset integrity verification, TLS validity, version resolution behavior, cache headers, CORS. A passing report dated within 30 days of submission is required.
  5. Code of Conduct. Digitally signed agreement. Prohibits malware payloads, obfuscated binaries, homoglyph phishing fonts, false metadata, and using a granted scope inconsistently with the applicant’s verified identity.

Fee structure

Tier 1 grants are not tiered by catalog size or commercial status. The fee reflects the ongoing operational cost of maintaining the scope holder’s entry in the shorthand registry, running monthly ARCTS checks, weekly integrity spot-checks, and quarterly license audits — the same cost regardless of whether the holder is a two-person foundry or a global platform.

CategoryAnnual fee
All registered Tier 1 scope holders$2,500 / year

The fee is not a revenue instrument. It funds the compliance monitoring infrastructure and ensures scope holders maintain a continuing operational relationship with the registry. Suspended scopes may be reinstated within 180 days for the outstanding fee plus a $500 reinstatement charge; after 180 days, the scope enters a 12-month quarantine during which it cannot be granted to any party.

Ratification procedure

Express interest at registry@atto.tech. The Authority MUST acknowledge within ten business days; full ratification review MUST be completed within sixty calendar days of a complete submission. Approved scopes are added to the shorthand registry within two business days of ratification. Appeals are heard by the three-person Technical Review Panel with balanced open-source and commercial representation; panel decisions are final.

Hosted Registry Service

The Atto Hosted Registry Service (AHRS) provides managed, AFRP-compliant registry hosting for font publishers who have high-quality original fonts but lack the infrastructure or technical resources to operate a self-hosted Form C registry at production availability. The publisher provides font binary files and manifest metadata; Atto operates the registry infrastructure, computes integrity hashes, serves compliant manifests, maintains SLA guarantees, and runs ongoing ARCTS compliance verification.

Hosted registries resolve as Form C identifiers under hosted.fonts.atto.tech/{publisher-slug}/. Studio tier and above may configure a CNAME so that fonts.theirfoundry.com/TypefaceName resolves through Atto-hosted infrastructure. AHRS does not confer Tier 1 @scope shorthand eligibility — Tier 1 governance is independent (see §6).

Service tiers

TierFamiliesStorageBandwidthSLACustom domainAnnual / Monthly
Indie31 GB10 GB / mo99.9%$99 / $12
Studio2010 GB100 GB / mo99.9%Yes$399 / $49
FoundryUnlimited50 GB1 TB / mo99.95%Yes — priority DNS$1,599 / $199
EnterpriseUnlimitedNegotiatedNegotiatedNegotiatedYesNegotiated

Bandwidth overages are billed at $0.08/GB; storage overages at $0.20/GB/mo. Overage rates apply to Studio and Foundry only — Enterprise negotiates inclusive limits.

Onboarding

  1. Publisher registration. Identity verification matching the intended publisher slug. The slug must correspond to the publisher’s verified name or a name they demonstrably control. Squatting a slug to prevent a legitimate entity from using their own name is prohibited and grounds for termination.
  2. Font file submission. Publisher provides woff2 (required), woff (recommended), and ttf (optional) binaries for each typeface family and style.
  3. Metadata declaration. Per-font manifest metadata: designer, foundry, SPDX license, commercial-use flags, variable-axis definitions where applicable.
  4. Atto manifest generation. Atto computes SHA-256 integrity hashes for all submitted binaries, generates the AFRP-compliant manifest, and provisions the hosted endpoint.
  5. ARCTS verification. Atto runs a full ARCTS suite against the newly provisioned registry before making it publicly resolvable.
  6. Publisher review. Publisher confirms manifest accuracy — particularly license metadata — before the registry goes live.

Onboarding acknowledgement within two business days; registry live within five business days of complete submission. Apply at registry.atto.tech/apply.

Publisher obligations

Publishers using AHRS agree that submitted font binaries are original designs (or open-source fonts the publisher has rights to distribute), that license metadata accurately reflects actual distribution terms, that font files contain no malware or homoglyph phishing payloads, and that publisher slugs correspond to verified identity. False declarations are grounds for immediate termination — terminated registries return REGISTRY_UNREACHABLE in EXECUTED-mode rendering, so publishers are advised to keep local copies of submitted binaries to ease migration to self-hosted infrastructure.

Upgrade path to Tier 1

A publisher operating under AHRS may apply for Tier 1 @scope ratification if they subsequently meet the criteria in §6. AHRS history is neither a prerequisite nor an accelerator. The infrastructure permanence criterion is evaluated independently of Atto-hosted infrastructure — an applicant relying exclusively on AHRS does not satisfy permanence, since their registry’s availability depends on a commercial relationship with Atto rather than their own independently operated infrastructure. Upon ratification, existing AHRS-hosted Form C identifiers remain valid indefinitely and a forwarding manifest redirects resolvers to the new @scope endpoint.

Error codes

AFRP emits codes at three severity levels. ERROR halts resolution or rendering. WARNING indicates degraded, user-visible behavior. INFO is diagnostic or audit-only. A curated ERROR-level subset follows; the full table lives in AFRP §5.8.

CodeLevelDescription
INVALID_IDENTIFIERERRORIdentifier does not conform to the §3.2 ABNF grammar.
SCOPE_NOT_FOUNDERRORForm B scope not present in the shorthand registry.
VERSION_NOT_FOUNDERRORNo version in the manifest satisfies the specified range.
REGISTRY_UNREACHABLEERRORAll three Form C discovery steps failed; no manifest obtained.
MANIFEST_SCHEMA_ERRORERRORManifest response body does not conform to the §4.2 JSON Schema.
MALFORMED_INTEGRITY_FIELDERRORA format-entry.integrity value does not match the SRI SHA-256 pattern.
INSECURE_ASSET_URLERRORA format-entry.url uses a non-HTTPS scheme for a non-localhost registry.
INTEGRITY_VIOLATIONERRORSHA-256 of the downloaded asset does not match the manifest or pin. Halts rendering in EXECUTED.
PINNED_FONT_UNAVAILABLEERRORIn EXECUTED mode, the pinned binary is unavailable. No substitution permitted.
LICENSE_PAYMENT_FAILEDERRORCommerce payment_endpoint request failed or returned an unverifiable receipt. Blocks execution.
LICENSE_INCOMPATIBLEERRORFont’s commercial_use: false conflicts with document’s commercial_use: true.
TLS_CERTIFICATE_ERRORERRORTLS validation failed for the registry or asset host.
FONT_UNRESOLVEDWARNINGAll resolution attempts including the fallback chain failed. Terminal DRAFT-mode outcome.
FONT_SUBSTITUTEDINFOA font was unavailable and an offline fallback was applied (DRAFT only). Payload names the substitute.

10 — Serialization Rules

Serialization rules.

Serialization is deterministic. Two ASTs that are structurally equal serialize to byte-identical output. The implications:

  • Trailing whitespace is stripped on every line.
  • Every block is separated by exactly one blank line.
  • YAML keys inside ::atto-doc and directives are sorted alphabetically.
  • Line endings are LF, encoding is UTF-8.
  • The final byte is a single newline.

This makes git diff reflect semantic change, not formatting drift.


11 — AST Mapping

Abstract Syntax Tree mapping.

Each surface construct maps to a node type. The set is closed: the parser rejects unknown directives rather than silently passing them through.

document      → Document { header, children[] }
::atto-doc    → AttoDoc { title, type, jurisdiction, effective_date, parties[] }
##...######   → Section { depth, title, children[] }
paragraph     → Paragraph { inlines[] }
**x**         → Strong { children[] }
*x*           → Emphasis { children[] }
`x`           → Code { value }
[text](url)   → Link { url, children[] }
$x$           → MathInline { tex }
$$x$$         → MathDisplay { tex }
::name        → Directive { name, attrs, body }
:::name       → ProtocolBlock { name, fields, compiled[] }
@/.../...     → FontReference { tier, scope, name, version }

12 — MVP Scope

MVP scope.

The v0 parser implements the full set described above. The MVP runtime implements: the ::atto-doc document header (§02), sections, inline formatting, inline and display LaTeX, the two content blocks (§07), and the three protocol blocks (§08). Anything outside that set is a post-v0 extension.

In v0 the signing pipeline targets ::signature-block; the remaining protocol blocks (::attachment, :::credit-check) parse, validate, and render but do not yet emit their audit-chain events. attachment.added and directive.credit_check land with the post-v0 ALP runtime. The ::atto-doc header and the content blocks never produce chain events by design — they declare bound context that other constructs reference.

Font references parse in v0 with the full identifier grammar, but the AFRP resolver — manifest fetch, schema validation, SHA-256 integrity checks, execution-pin freezing at signing — ships as a follow-on milestone. Documents authored today that declare font references will be compatible with the resolver when it lands.

::: protocol blocks parse in v0 with validation, compile to their target :: directives, and render their UI components. Live precondition evaluation (PDEE dispatch, bureau integration) is coordinated through the Atto Leasing Protocol spec and ships in the ALP runtime.