01 — Overview
Atto Documents.
v0Every 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
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
:: Lease · Effective 2026-06-01 · California
Residential Lease Agreement
Core fields
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.
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-docis absent,::atto-docappears after body content,::atto-docappears more than once,- the
partieslist contains duplicateidvalues, or - a
::signature-block,required-signatory, or:::credit-checkreferences 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.
::signature-block
party: tenant
label: Disclosing Party
sign_order: 1
date-required: true
:: 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 ##.
## 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. 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.
## Payment Terms {#payment-terms}
Client shall pay within 15 days of invoice.
### Late Fees {#late-fees}
Overdue amounts accrue at 1.5% per day. 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.
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:
- Authored ID on the
:::sectionblock (id="..."). - Authored ID on the heading (
{#...}). - 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.
**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
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. 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
The late fee is $L = B \times 0.015$ per day.
Present value equals $PV = FV / (1 + r)^n$. The late fee is L = B × 0.015 per day. Present value equals PV = FV / (1 + r)n.
Greek letters and fractions
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. Interest accrues at rate α = r / n where n is the number of compounding periods and β ≈ 0.05 is the service margin.
Subscripts and aggregates
Total liability is bounded by $L_{max} = \sum C_i$ across all invoices $i \in \{1, \ldots, n\}$. 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
The value after $t$ years of compounding:
$$
A = P\left(1 + \frac{r}{n}\right)^{nt}
$$ The value after t years of compounding:
A = P(1 + r⁄n)nt
Summation
Post-money valuation aggregates pre-money plus all investment tranches:
$$
V_{post} = V_{pre} + \sum_{i=1}^{n} I_i
$$ Post-money valuation aggregates pre-money plus all investment tranches:
Vpost = Vpre + Σ i=1 n Ii
Aligned equations
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}
$$ 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.
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
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.
:: ::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.
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
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.
:: 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.
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
- party: tenant
sign_order: 1
date-required: true
- party: landlord
signer: Alex Reynolds
title: Director of Leasing
sign_order: 2
date-required: true
:: 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.
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
label: Schedule A
uri: atto://attach/schedule-a.pdf
sha256: 4c1f...a7
media_type: application/pdf
bytes: 131072
:: :::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
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
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
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 {
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
}
::: Compilation to ALP
The :::credit-check block compiles mechanically to an
::alp:precondition:credit-check directive at build time. The
field mapping is exact:
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:
purposeis absent, empty, or contains only template placeholder text (e.g.[property address]).requesting_partydoes not match thelegal_nameof any declared party.partydoes not resolve to aparty_idin the execution preamble.pull_type = hard_pullandconsent_scopehas not been completed before PDEE dispatch.extentisscore_onlyorincome_verifiedandmin_scoreis absent.on_fail = human_reviewandreview_window_hoursis absent.disclosed_tocontains a party id not declared in the execution preamble.- Two
:::credit-checkblocks in the same document share anid. immediate_feedback = trueandon_fail = human_reviewsimultaneously — 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.
@/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.
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.
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.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
@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:
latestandpinnedMUST 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).
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.
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
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"]
--- 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.
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. 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.
| Behavior | DRAFT mode | EXECUTED mode |
|---|---|---|
fallback_to_atto default | true | false |
| System font substitution | Permitted | Forbidden |
| All-failure outcome | System sans-serif | Visible error; rendering halted |
| TLS validation skip | Permitted (with warning) | Forbidden |
@pinned specifier | Treated as @latest | MUST use pinned version |
full_integrity check | Optional | MUST be applied |
The 11-step algorithm in AFRP §5.2 is non-negotiable. Every compliant resolver MUST:
- Parse the font reference per the §3.2 ABNF. Fail fast on syntax errors.
- Translate reserved aliases (
weight=→wght=,style=italic→ital=1). - Classify as Form A / Form B / Form C and derive the registry base URL.
- Fetch the manifest (see three-step discovery below), validate schema, protocol version, integrity-field format, and URL scheme.
- Locate the font entry by typeface name.
- Select a version satisfying the specifier per SemVer precedence.
- Select a style entry, then a format entry (
woff2preferred). - Download the binary, compute SHA-256 over the decompressed body, compare constant-time against
integrity. - EXECUTED only: compare against
full_integrityfrom the pin. Mismatch →INTEGRITY_VIOLATION, halt rendering. - If
license_info.commerceis present, validate the license token or acquire ause_receiptfrompayment_endpoint. - 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:
Well-known: GET
https://host/.well-known/atto-font-registry.json. If the typeface appears in thefonts[]array, resolution proceeds against this manifest.Per-typeface: GET
https://host/<TypefaceName>/manifest.json. Takes precedence over the registry-level manifest when available.Inline: use the
inline_manifestdeclared in the document’sfonts[]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]
---
_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:
F1 — Document-declared fallback. Each entry in the declaration’s
fallback[]array is resolved sequentially through the full §5.2 algorithm.F2 — Implicit Atto fallback (Form B only). If the primary is Form B and
fallback_to_attois true, attempt to resolve@/{TypefaceName}against the canonical Atto registry. Form A and Form C MUST NOT trigger this step.F3 — System font reference. If
fallback[]contains asystem:entry (§7.3) and prior attempts failed, substitute the system font. DRAFT only.F4 — Terminal failure. DRAFT: system sans-serif +
FONT_UNRESOLVEDwarning. 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.
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.
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.
- 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.
- Identity verification. The scope name MUST correspond to the applicant’s verified legal or organizational identity (e.g.
@adobefor Adobe Inc.,@velvetynefor Velvetyne Type Foundry). Verified by trademark, WHOIS-verified domain, or equivalent documentary evidence. Invented or speculative scope names are not eligible. - License transparency. Every font served MUST include machine-readable SPDX metadata. Proprietary licenses MUST accurately declare
commercial_use,embedding_allowed, andweb_embedding_allowed. False declarations are grounds for revocation. - 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.
- 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.
| Category | Annual 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
| Tier | Families | Storage | Bandwidth | SLA | Custom domain | Annual / Monthly |
|---|---|---|---|---|---|---|
| Indie | 3 | 1 GB | 10 GB / mo | 99.9% | — | $99 / $12 |
| Studio | 20 | 10 GB | 100 GB / mo | 99.9% | Yes | $399 / $49 |
| Foundry | Unlimited | 50 GB | 1 TB / mo | 99.95% | Yes — priority DNS | $1,599 / $199 |
| Enterprise | Unlimited | Negotiated | Negotiated | Negotiated | Yes | Negotiated |
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
- 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.
- Font file submission. Publisher provides woff2 (required), woff (recommended), and ttf (optional) binaries for each typeface family and style.
- Metadata declaration. Per-font manifest metadata: designer, foundry, SPDX license, commercial-use flags, variable-axis definitions where applicable.
- Atto manifest generation. Atto computes SHA-256 integrity hashes for all submitted binaries, generates the AFRP-compliant manifest, and provisions the hosted endpoint.
- ARCTS verification. Atto runs a full ARCTS suite against the newly provisioned registry before making it publicly resolvable.
- 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.
| Code | Level | Description |
|---|---|---|
| INVALID_IDENTIFIER | ERROR | Identifier does not conform to the §3.2 ABNF grammar. |
| SCOPE_NOT_FOUND | ERROR | Form B scope not present in the shorthand registry. |
| VERSION_NOT_FOUND | ERROR | No version in the manifest satisfies the specified range. |
| REGISTRY_UNREACHABLE | ERROR | All three Form C discovery steps failed; no manifest obtained. |
| MANIFEST_SCHEMA_ERROR | ERROR | Manifest response body does not conform to the §4.2 JSON Schema. |
| MALFORMED_INTEGRITY_FIELD | ERROR | A format-entry.integrity value does not match the SRI SHA-256 pattern. |
| INSECURE_ASSET_URL | ERROR | A format-entry.url uses a non-HTTPS scheme for a non-localhost registry. |
| INTEGRITY_VIOLATION | ERROR | SHA-256 of the downloaded asset does not match the manifest or pin. Halts rendering in EXECUTED. |
| PINNED_FONT_UNAVAILABLE | ERROR | In EXECUTED mode, the pinned binary is unavailable. No substitution permitted. |
| LICENSE_PAYMENT_FAILED | ERROR | Commerce payment_endpoint request failed or returned an unverifiable receipt. Blocks execution. |
| LICENSE_INCOMPATIBLE | ERROR | Font’s commercial_use: false conflicts with document’s commercial_use: true. |
| TLS_CERTIFICATE_ERROR | ERROR | TLS validation failed for the registry or asset host. |
| FONT_UNRESOLVED | WARNING | All resolution attempts including the fallback chain failed. Terminal DRAFT-mode outcome. |
| FONT_SUBSTITUTED | INFO | A 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-docand directives are sorted alphabetically. - Line endings are
LF, encoding isUTF-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.