format 0.2 spec module 0.2.1 · 2026-05

Commons Format

This document is itself a Commons Format module. It specifies the format that governs how Commons Format modules are written, parsed, resolved, merged, and verified. A consumer reading this document can, with a competent code generator, produce a conformant implementation of the Commons Format toolchain in any target language.

This document ships no executable code. The format's correctness is demonstrated by its eval suite (evals.toml), not by reference implementations. Consumers verify their generated tooling by running the eval suite against it. This is intentional: the format's thesis is that intent and evals are the artifact and implementations diverge per consumer. The format-spec module embodies that thesis by being itself a clean instance of it.

0. Module-level declarations

The Commons Format format itself is described by Commons Format conventions. The tagged sections below declare the format's intent, the interface exposed to tooling that operates on it, the patterns implementations should avoid, and the threat model the format addresses.

Define the structure, semantics, and verification model for Commons Format modules — folders containing prose, machine-readable evals, and metadata that together describe verifiable intent. Specify how modules compose through merging, how they are identified through Git-rooted URLs, and how implementations of conforming tooling can be generated from this document and verified against the accompanying eval suite.

A conformant Commons Format implementation reads modules from disk, resolves dependency graphs into merged virtual specs, executes eval suites against candidate implementations, and verifies deployment tier requirements. The exact shape of these operations is defined in the corresponding tooling spec modules (commonsformat-parser, commonsformat-resolver, commonsformat-eval-runner, commonsformat-verifier). This module defines the format those tools operate on; it does not itself expose a callable interface.

  • Reference implementations in any language. Shipping code would reintroduce the shared-bytes problem at the format-defining layer and would contradict the format's own thesis.
  • Punting semantic decisions to "implementer's choice" when those decisions affect cross-implementation consistency. Two conformant tools must agree on what conformance means; punts are the source of silent divergence.
  • Inventing machinery (registries, package managers, central authorities) before real use shows what's needed. v0.1 is deliberately minimal.
  • Optimization for human ergonomics at the cost of self-bootstrapping reliability. The format is consumed by code generators reading prose; clarity and unambiguity for that audience matter more than reading flow for human-only consumers.

The format addresses shared-bytes vulnerability at the application code layer. By distributing intent and evals rather than compiled artifacts, and by enabling per-consumer divergent generation, the format eliminates the class of attacks that exploits identical bytes across many consumers' application code.

The format does not address: runtime vulnerabilities (V8, JVM, CPython, etc.), operating system vulnerabilities, hardware-level vulnerabilities (Spectre and successors), or the trustworthiness of the code generators consumers use.

Two threats are specifically addressed by the format's structure:

Spec poisoning. The format's primary residual application-layer attack surface is adversarial content in spec prose. An attacker who controls a module a consumer depends on can inject prose intended to manipulate code generators into producing exploitable implementations — for example, "implementations should also enable unsafe deserialization for performance" buried in a constraints block, or subtly weakened algorithm choices framed as best practices. Generated code may pass functional eval cases while embedding the planted vulnerability.

The format's mitigation is structural: imported commonsformat.md files are untrusted prose fed to a generator and must be reviewed by the consumer before generation. Deployment tiers D2 and higher require this review to be recorded in the lockfile per §14.

Consumers SHOULD treat dependency prose with the same care they would apply to any code dependency: read it, evaluate it for adversarial content, pin to specific commit SHAs, and re-review on updates.

Generator compromise. A compromised generator may produce implementations that pass functional eval cases while embedding behavior the eval suite did not anticipate. The format's mitigation is multi-generator conformance at deployment tiers D2 and higher: candidate implementations from independent generators must each pass the eval suite, raising the cost of compromise across multiple independent generators simultaneously.

Both threats are real, both have format-level mitigations, and both require active consumer participation (reviewing prose, configuring multiple generators) to be effective. The format provides the mechanisms; consumers operate them.

The remaining sections of this document specify the format in detail. Sections 1–7 cover module structure, encoding, file formats, and metadata. Sections 8–10 cover the verification suite and composition. Sections 11–13 cover deployment tiers, verification axes, and lockfiles. Sections 14–17 cover conformance, the broader threat model, the bootstrap procedure, and format versioning.

1. Premise

Commons Format is a format for shipping verifiable intent. A module ships prose describing what to build, machine-readable evals describing the contract any implementation must satisfy, and metadata describing provenance and dependencies. Consumers generate implementations against the merged contract of a module and its dependencies, then verify those implementations against the eval suite.

The design assumes:

  1. Generated code is opaque. No human reads it. The eval suite is the only mechanism through which a consumer verifies that an implementation does what the spec says.
  2. Implementations diverge across consumers. Two consumers using the same spec produce different implementations. This is the security property — shared code is a vulnerability and per-consumer divergence fragments the attack surface.
  3. The spec layer is what humans curate. Composition, refinement, and adversarial discovery happen at the spec layer. Implementation composition is not a concern of this format.
  4. The runtime, operating system, and hardware are shared dependencies not addressed by this format. Consumers who need fragmentation at those layers must address it through other means (multi-runtime conformance, capability sandboxing, formal methods).

2. Module structure

An Commons Format module is a directory containing the following files:

  • commonsformat.toml — module metadata. Required.
  • commonsformat.md — canonical prose. Required.
  • evals.toml — verification suite. Required for any module claiming D1 deployment tier or higher.
  • schema.sql — optional data shape declaration in pinned SQLite-subset DDL (§8).
  • LICENSE — license file. Required.
  • README.md — optional, for repository browsers.
  • CHANGELOG.md — optional but recommended.
  • references/ — optional directory containing additional prose documents referenced from commonsformat.md. Files within may be .md format. This directory contains specification depth, not code.

A module directory may contain other files, which the format ignores. The format does not specify a lib/, src/, examples/, or any directory containing code. Modules ship words.

3. Encoding

3.1 Character encoding

All text files in a module are UTF-8 encoded. Implementations that encounter non-UTF-8 bytes in any required file reject the module with an encoding error.

3.2 Line endings

Implementations accept LF (U+000A) or CRLF (U+000D U+000A) line endings. Internal processing normalizes to LF. Generated lockfiles emit LF.

3.3 Machine-readable files: TOML subset

Files commonsformat.toml, evals.toml, commonsformat.lock, and any other machine-readable files defined by this format use the TOML subset specified in §4. The full TOML 1.0 specification is not required; the subset is self-contained.

3.4 Prose files: Markdown subset

Files commonsformat.md, README.md, CHANGELOG.md, and files in references/ use the Markdown subset specified in §5.

4. TOML subset

The Commons Format TOML subset includes the following constructs and nothing else. Implementations parse only these constructs and reject input containing any other TOML feature.

4.1 Whitespace and comments

Whitespace is space (U+0020) or tab (U+0009). Lines may end with LF or CRLF. A line beginning with # (after any leading whitespace) is a comment and is ignored. A # after a value on the same line starts an inline comment, ignored to end of line.

4.2 Keys

A bare key consists of ASCII letters, ASCII digits, underscores, and hyphens, matching the regular expression [A-Za-z0-9_-]+. A bare key must contain at least one character.

A quoted key is a basic string (§4.4) used as a key. Quoted keys may contain any UTF-8 character except control characters (U+0000 through U+001F, U+007F).

A dotted key is two or more keys joined by ., with optional whitespace around each dot. Dotted keys define nested tables. The dotted key a.b.c = 1 is equivalent to [a.b] followed by c = 1.

4.3 Values

The format permits these value types and no others:

  • String — see §4.4
  • Integer — see §4.5
  • Float — see §4.6
  • Booleantrue or false, lowercase, exact match
  • Array — see §4.7
  • Inline table — see §4.8

The format does not support: TOML date types, hexadecimal/octal/binary integer literals, underscores in numeric literals, exponential notation in floats, multi-line basic strings, multi-line literal strings, or any TOML feature not listed above.

4.4 Strings

A basic string is delimited by ". Within, the following escape sequences are recognized:

  • \" — quotation mark
  • \\ — reverse solidus
  • \n — line feed
  • \r — carriage return
  • \t — tab
  • \uXXXX — Unicode code point in BMP, four hex digits
  • \UXXXXXXXX — Unicode code point, eight hex digits

No other escape sequences are recognized. A basic string may not contain literal control characters (U+0000U+001F, U+007F) except via escape sequence.

A literal string is delimited by '. No escape processing occurs; the contents are taken verbatim. A literal string may not contain ' (the closing delimiter ends the string) or literal control characters except \t (U+0009).

A basic string may span multiple source lines if the content uses \n escape sequences. Literal newlines within a string are not permitted in this subset.

4.5 Integers

An integer is an optional sign (+ or -) followed by one or more ASCII digits. Leading zeros are forbidden except for the value 0. Integers fit in 64 bits, signed.

4.6 Floats

A float is an optional sign followed by digits, a decimal point, and more digits. Both integer and fractional parts must be present. Special values (inf, nan) are not permitted in this subset.

4.7 Arrays

An array is [, zero or more values separated by ,, optional trailing comma, ]. Whitespace and newlines around values are permitted. Array elements may be of any value type permitted in §4.3, including mixed types within a single array.

4.8 Inline tables

An inline table is {, zero or more key = value pairs separated by ,, optional trailing comma, }. Inline tables may be nested. Whitespace within inline tables is permitted but newlines are not.

4.9 Tables and arrays of tables

A table header is [ followed by a key (possibly dotted), followed by ], on its own line. Subsequent key = value lines belong to that table until the next table header.

An array-of-tables header is [[, key, ]]. Subsequent key = value lines belong to a new element of that array. Each occurrence of the same array-of-tables header appends a new element.

4.10 Document structure

A document is a sequence of: comments, blank lines, top-level key = value pairs, table headers, and array-of-tables headers. Top-level pairs (those before any table header) belong to the document's root.

A key may not be defined twice within the same table. A table may not be defined twice with the same name (except via array-of-tables headers, which append).

4.11 Parsing errors

Implementations reject input that violates any rule in §4.1–§4.10. Error messages should include line and column position. The eval suite (§15) covers required rejection cases.

5. Markdown subset

The Commons Format Markdown subset is a strict subset of CommonMark. The subset suffices for prose, structure, and tagged sections. Full CommonMark support is not required.

5.1 Block elements

The subset recognizes these block elements:

  • ATX headings: #, ##, ###, #### followed by space and heading text. The format does not require headings beyond level 4.
  • Paragraphs: contiguous non-blank lines.
  • Blank lines: separate blocks.
  • Fenced code blocks: triple-backtick or triple-tilde fences, optional info string after the opening fence.
  • Bullet lists: lines beginning with - (hyphen, space). Nested lists indented by two spaces per level.
  • Numbered lists: lines beginning with 1. , 2. , etc. Item numbering is preserved as written.
  • Block quotes: lines beginning with > .
  • Horizontal rules: a line containing only three or more - characters.
  • Tagged sections: see §5.3.

The subset does not require: setext headings, link reference definitions, HTML blocks (other than the tagged sections defined in §5.3), tables, or definition lists. Implementations may choose to recognize these but must not depend on them being present.

5.2 Inline elements

The subset recognizes:

  • Emphasis: *text* or _text_.
  • Strong: **text** or __text__.
  • Inline code: `code`.
  • Links: [text](url).
  • Hard line breaks: two spaces at end of line, or backslash at end of line.

5.3 Tagged sections

Tagged sections are XML-style elements that mark machine-extractable regions within Markdown prose. They render as part of the Markdown when displayed and are extractable as named regions by Commons Format tooling.

5.3.1 Tag form

A tag opens with < followed by a tag name and optional attributes, followed by >. It closes with </ followed by the same tag name followed by >. Both opening and closing tags appear on their own lines, with no other content on those lines. Optional leading whitespace before the tag is permitted and preserved.

Tag names are lower-case ASCII letters and hyphens, matching the regular expression [a-z][a-z-]*. Tag names are case-sensitive; <intent> and <Intent> are different tags.

5.3.2 Recognized tag names

The format recognizes these tag names:

  • intent — what the generated code should do.
  • constraints — hard requirements the implementation must satisfy.
  • avoid — anti-patterns that disqualify an implementation.
  • interface — declared shape of the public API.
  • threat-model — adversarial assumptions and attacker capabilities.
  • example — illustrative input/output pair (multiple permitted, see §5.3.4).

5.3.3 Unknown tags

A tag whose name is not in the list above is an unknown tag. Implementations preserve unknown tags as opaque text in the prose — their content remains visible in the rendered Markdown but is not extracted as a structured region. Implementations do not error on unknown tags; this allows future format versions to introduce new tag names without breaking older parsers.

Implementations may emit a warning when encountering unknown tags, but must not reject the module.

5.3.4 Attributes

The example tag accepts a name attribute. Other tags do not accept attributes in this version of the format; if present, they are ignored.

Attribute values are quoted with double quotes only:

<example name="basic-usage">

Single-quoted attribute values (name='basic-usage') are not permitted. This is a deliberate restriction to keep the parser small.

Whitespace within an opening tag is permitted between the tag name, attribute name, equals sign, and attribute value:

<example name="basic-usage">
<example  name = "basic-usage">

Both forms are equivalent. Implementations normalize whitespace during extraction.

5.3.5 Uniqueness and nesting

Each non-example tag must appear at most once per module. Multiple example tags are permitted and must have distinct name attribute values within a single module.

Tags must not nest within tags of the same name. Tags of different names may nest — for example, an <example> tag may contain inline discussion that mentions <intent> as text within a code block — but extraction stops at the first matching close tag for the outermost open tag of a given name.

5.3.6 Literal tag content

If tag content needs to contain text that would otherwise look like a closing tag (e.g., the literal string </intent> appearing inside prose discussing the format itself), enclose that content in a fenced code block. Fenced code blocks within tagged sections are treated as opaque content during extraction; the extractor does not look for closing tags within fences.

<intent>
Build a parser that handles tagged sections. The closing tag form
is shown below in a code fence so it is not interpreted as ending
this intent block:

` ` `
</intent>
` ` `

(Replace the spaced backticks with literal backticks; spaces are
shown here only so this example itself parses.)
</intent>

This composes cleanly with CommonMark's existing semantics and avoids introducing a new escape mechanism.

5.3.7 Whitespace and content preservation

Content within a tagged section is preserved verbatim, including internal Markdown formatting, code fences, lists, and embedded prose. Leading and trailing blank lines within the section content are stripped during extraction; internal blank lines are preserved.

The extracted content does not include the opening and closing tag lines themselves.

5.4 Frontmatter

This format does not use embedded YAML or TOML frontmatter in Markdown files. Module metadata lives in commonsformat.toml, separate from prose. This is to keep the Markdown subset minimal and to avoid delimiter ambiguity between frontmatter fences and horizontal rules.

6. Module metadata: commonsformat.toml

The commonsformat.toml file describes the module. Required fields:

  • commonsformat — the format version this module targets, as a string (e.g., "0.1"). Implementations reject modules whose declared version is incompatible with the implementation's supported version range.
  • name — module name. Lower-case ASCII letters, digits, and hyphens. Must not begin or end with a hyphen. The name is unique within a single repository but is not globally unique; the module's global identity is its Git-rooted dependency path (§11).
  • version — the module version as a SemVer-shaped string of the form MAJOR.MINOR.PATCH, where each component is a non-negative integer with no leading zeros (except 0 itself). Pre-release and build metadata suffixes are not permitted in this version of the format.
  • description — a one-to-three sentence summary, used by tooling for indexing and presentation. Plain text; Markdown is not rendered.
  • license — an SPDX license identifier (e.g., MPL-2.0, Apache-2.0).
  • authors — an array of inline tables, each with a name field. Optional fields: email, url. At least one author is required.

Optional fields:

  • verifies — relative path to the eval suite, typically "./evals.toml". Required for modules claiming D1 or higher.
  • homepage — URL of a project homepage.
  • repository — URL of the module's source repository, typically the Git repository.
  • keywords — array of strings for indexing.
  • depends_on — array of dependency declarations. See §11.

A module that declares no depends_on is a leaf module. Dependency-free modules can be bootstrapped without a resolver.

Example minimal commonsformat.toml:

commonsformat = "0.1"
name = "rate-limiting"
version = "1.2.0"
description = "Token-bucket rate limiting with per-key isolation."
license = "MPL-2.0"
authors = [
    { name = "Jane Doe", email = "jane@example.com" }
]
verifies = "./evals.toml"

7. Canonical prose: commonsformat.md

The commonsformat.md file is the canonical prose. It contains the human-readable explanation of the module and the tagged sections that tooling extracts as the implementation contract.

The format does not mandate prose structure beyond the requirement that tagged sections (§5.3) be present where the module describes implementable behavior. Modules conventionally include sections for intent, constraints, anti-patterns, examples, and rationale, but prose organization is at the author's discretion.

The prose is what humans read and what generators consume as context when producing implementations. Both audiences are served by clear, complete prose. The format encourages spec authors to write prose that:

  • States intent unambiguously
  • Enumerates constraints without ambiguity
  • Calls out anti-patterns explicitly
  • Provides concrete examples where intent could be misread
  • Documents the threat model when adversarial behavior is relevant

Prose that depends on shared cultural context to be understood will fail when consumed by generators that don't share that context. Spec authors should err toward explicitness.

8. Data shape: schema.sql

A module MAY optionally include a file schema.sql that declares the shape of data the module produces, consumes, or reasons about. The file uses a pinned SQLite-subset DDL as a precise vocabulary for expressing that shape.

The DDL is a shape commitment, not a storage commitment. A CREATE TABLE in schema.sql does NOT mean the module uses a database at runtime. Runtime representation — in-memory data structures, on-disk serialization, an actual SQL database, or anything else — is the generator's choice, made in light of the module's intent and the deployment tier. Modules with no shaped data omit the file entirely.

The intuition is Brooks' ("show me your tables and I won't need your flowcharts"): a precise relational vocabulary for the data a module operates on tightens generation more than prose alone can. Schemas do not replace <intent>, <constraints>, or evals; they complement them by carrying the shape contract structurally.

8.1 Pinned subset

A conformant schema.sql uses only the constructs listed below. Anything else is rejected.

Statements: CREATE TABLE and CREATE INDEX only. No CREATE VIEW, no CREATE TRIGGER, no procedural SQL, no INSERT, no IF NOT EXISTS, no schema-evolution constructs.

Types: INTEGER, REAL, TEXT, BLOB, TIMESTAMP, BOOLEAN. No vendor extensions, no application-defined types, no SQLite type affinity sugar.

Column and table constraints:

  • PRIMARY KEY (single- or multi-column)
  • FOREIGN KEY — the target table MUST be defined in the same schema.sql. Cross-module foreign keys are rejected (§8.3).
  • NOT NULL
  • UNIQUE (single- or multi-column)
  • CHECK (expression over columns of the same row; arithmetic, comparison, boolean operators, and IN (...) over literal lists)
  • Column defaults (literal values only)

Comments: single-line -- ... to end of line. Multi-line /* ... */ comments are not part of the subset.

Whitespace: ASCII space, tab, LF, CRLF.

The subset is intentionally narrow. Anything outside it is either syntactic sugar that complicates parsing, vendor-specific quirks that hurt portability, or expressive features (views, triggers, procedures) that imply behavior rather than shape.

8.2 Header comment

A conformant schema.sql begins with a header comment declaring the file's semantic role. The first non-blank content in the file is a comment block equivalent to:

-- This DDL describes data shape, not storage. Runtime representation
-- is implementation-defined; choose what is appropriate to the target
-- language and the module's intent. A table here does not imply a
-- database; it is a vocabulary for declaring the shape of values the
-- module produces, consumes, and reasons about.

The wording MAY be adapted (line wrapping, additional clarifying sentences) but the disclaimer MUST be present, MUST precede any DDL, and MUST clearly state that the file is shape, not storage. This header is part of the format's defense against the file-shape prior that pushes generators toward database-backed runtimes; see §8.7.

8.3 Composition: schemas do not merge

When module A declares depends_on (or extends) for module B, the resolver does NOT merge their schema.sql files. Each module owns its tables. The merged virtual spec carries both schemas in their respective module namespaces; consumers reading the merged spec reach a dependency's tables via qualified reference, never as a merged table.

Foreign keys MUST reference a table defined in the same schema.sql. A FOREIGN KEY referencing a table from a dependency is rejected. Cross-module relationships are expressed behaviorally (in <constraints> prose, in eval cases that exercise the relationship) rather than structurally.

This is database-per-service discipline applied to specs. The trade-off is deliberate: schema merging across modules would require the format to take positions on type-system questions (inheritance, nullable widening, structural compatibility) that it does not want to own. Evals fill the same role for cross-module compatibility without dragging in a type system.

8.4 Interface vocabulary reuse

When a module ships schema.sql, the <interface> tagged section in commonsformat.md MAY use the schema's vocabulary directly:

  • Argument and return types may use the DDL primitives (TEXT, INTEGER, etc.).
  • Argument and return types may name a table defined in this module's schema.sql, indicating a row of that table.

For example, given a module whose schema.sql declares a buckets table:

<interface>
acquire(key: TEXT, n: INTEGER) -> (allowed: BOOLEAN, retry_after_ms: INTEGER)
status(key: TEXT) -> buckets    -- returns a row of the buckets table
</interface>

Modules without a schema.sql use DDL primitives in interface signatures directly, without table-name references. The <interface> content remains prose; this is a convention for prose authoring, not a separate parsed form.

8.5 Structural constraints in DDL

Items that can be expressed structurally as DDL constraints (NOT NULL, UNIQUE, CHECK, FOREIGN KEY, PRIMARY KEY) belong in schema.sql rather than in the <constraints> tagged section. Structural invariants in DDL are enforceable per row at the data-shape layer; the same statements in prose are aspirational until an eval case exercises them.

The <constraints> section retains items DDL cannot express: rate-of-change rules, multi-row invariants, fairness properties, timing properties, ordering invariants, and any constraint whose verification requires reasoning beyond a single row's column values.

A module that ships schema.sql is encouraged to migrate structural constraints into the DDL. Modules that do not ship schema.sql leave their <constraints> sections unchanged.

8.6 Logical schema

After parsing, a module that ships schema.sql adds a logical schema entry to its parsed contents (§10):

  • The list of CREATE TABLE declarations, each with name, columns (name, type, column constraints, default), table-level constraints, and any associated CREATE INDEX declarations.
  • A flag recording whether the §8.2 header comment was detected.

Concrete representation of the parsed schema is at the implementation's discretion. A parser may represent it as a list of structures, a hash map keyed on table name, a small AST — whichever matches the target language. What matters is that downstream tools can reach the logical contents.

8.7 Generator framing

Generators consuming a module that ships schema.sql MUST be primed to read the file as a shape declaration, not a storage commitment. Three converging mitigations apply:

  1. The header comment in §8.2 is part of the file itself, so a generator that reads schema.sql without other context still sees the disclaimer in the file.
  2. This section documents the schema-as-shape semantics at the format level, so generators reading the format-spec for context absorb the framing.
  3. The orchestrator module (commonsformat-orchestrator) encodes the framing in its standard prompt: "choose runtime representation appropriate to the target language and the module's intent; do not produce database-backed code unless the intent specifies persistence."

The combination is designed to prevent the file-shape prior (.sql + CREATE TABLE = "use a database") from leaking into generated implementations of modules whose intent does not call for persistence.

9. Verification suite: evals.toml

The evals.toml file defines the contract any conformant implementation must satisfy. Implementations are not conformant by virtue of being faithful to the prose; they are conformant by passing the eval suite.

9.1 Top-level structure

commonsformat_evals = "0.1"
target = "rate-limiting"
target_version = "^1.0.0"

[[cases]]
name = "..."
# ...

[[adversarial]]
name = "..."
# ...

[[generator_adversary]]
name = "..."
# ...

[properties]
# ...

Required fields:

  • commonsformat_evals — eval format version.
  • target — name of the module these evals verify, matching commonsformat.toml's name.
  • target_version — version range of the target these evals are valid for, in the constraint syntax of §11.

9.2 Case structure

Each [[cases]], [[adversarial]], and [[generator_adversary]] entry is a case with these fields:

  • name — kebab-case identifier, unique within the eval file.
  • description — one-sentence human-readable description.
  • category — one of: functional, input-validation, timing, concurrency, resource, failure-mode, crypto, interface.
  • input — inline table of inputs to the implementation under test.
  • expect — inline table of expectations on the implementation's behavior.
  • tags — optional array of strings for filtering.
  • severity — optional, one of info, warn, error, critical. Default: error.
  • verifies — optional array of constraint names from the prose (see §9.7).

The input and expect tables contain values from the TOML subset. The semantics of input/expect — how input becomes a call into the implementation and how expect becomes assertions on its behavior — are defined by case category and specified in §9.3. These semantics are part of the format, not implementation choices, so that two conformant runners interpret the same case identically.

9.2.1 Fixture references

Eval cases that require structured input larger than a TOML inline table — a module directory tree, a multi-file repository state, a dependency graph — reference fixtures stored in a fixtures/ subdirectory of the module containing the eval suite.

A fixture reference is a string value of the form fixture://<name>, where <name> corresponds to a path under fixtures/ relative to the module root. The path may identify a single file or a directory.

[[cases]]
name = "loads-format-spec-module"
category = "interface"
input = { module_path = "fixture://valid-format-spec" }
expect = { loaded = true, has_fields = ["metadata", "prose", "evals"] }

The corresponding fixture lives at <module>/fixtures/valid-format-spec/ and contains whatever files are needed to exercise the case (typically a complete module directory: commonsformat.toml, commonsformat.md, evals.toml, LICENSE).

When a runner encounters a fixture:// reference, it resolves the reference relative to the eval suite's module root and substitutes the resolved filesystem path (or file content, depending on the case's category) for the reference.

Fixtures are part of the module they belong to. They are committed alongside evals.toml, versioned with the module, and shipped to consumers as part of normal module distribution. They are not a separate registry.

A module that references fixtures declares the convention in its prose so consumers know to expect a fixtures/ directory. Eval cases that don't need fixtures use inline values directly.

The fixture protocol does not extend to dynamic test generation, parameterized fixtures, or template substitution. Each fixture is a static set of files at a fixed path. Cases that need varied inputs either reference different fixtures or use inline values.

9.3 Category execution semantics

The category field on each case determines how a runner translates the case's input and expect tables into actual invocations of the implementation under test. The rules below are part of the format. Two conformant runners executing the same case against the same implementation must produce the same pass/fail result.

functional — The runner invokes the implementation, passing the fields of input as arguments. The implementation produces an output. The runner compares the fields of expect against the output, field by field. If every field present in expect matches the corresponding field in the output (by structural equality, no type coercion), the case passes. Fields present in the output but not in expect are ignored. Fields present in expect but missing from the output are failures.

input-validation — The runner invokes the implementation with the fields of input as arguments, expecting that the implementation will reject the input. If expect contains rejects = true, the case passes when the implementation rejects the input (by raising an error, returning a rejection structure, or otherwise indicating refusal). If expect contains an error_includes field, the case passes when the rejection's error message contains the specified substring.

interface — The runner invokes the implementation per input and examines structural properties of the result against expect. Common properties include has_fields (an array of field names the result must contain), has_field (a single field name), and specific named property assertions. Interface cases verify shape, not content.

timing — The runner sets up a timed scenario per input (possibly synchronizing clocks, running concurrent operations, or measuring elapsed time). Comparison operators in expect such as max_concurrent_at_reset_lt = 200 express bounds rather than exact matches. The case passes when the timing constraint holds. Timing cases may be run multiple times for stability.

concurrency — The runner executes multiple operations concurrently per input and verifies properties of the combined result against expect. The runner must execute the operations genuinely concurrently (not serialized) for the case to be meaningful.

resource — The runner monitors resource use (memory, CPU, file handles, etc.) during execution per input, and verifies bounds declared in expect such as within_resource_bounds = true or specific limits.

failure-mode — The runner arranges a degraded condition per input (network unavailable, disk full, dependency timeout, etc.) and verifies the implementation behaves per expect. The runner is responsible for setting up the condition.

crypto — The runner invokes the implementation with input as a cryptographic test vector and compares the output against expect exactly, byte for byte. Comparison is constant-time when the runner can arrange it.

When expect uses comparison operators (_lt, _gt, _lte, _gte, _eq, _ne), these are part of the format. A field named max_x_lt with value 200 means "the implementation's output field max_x must be less than 200." Runners parse these operators uniformly.

When a case's category is not in the list above, runners report the case as skipped with a "category not supported" indication. The case is neither passed nor failed; it is uncounted.

9.4 Functional cases

The [[cases]] array contains functional verification: does the implementation produce correct outputs for valid inputs?

[[cases]]
name = "respects-rate-limit"
description = "10 requests in 1 second with limit=5/sec → 5 rejected"
category = "functional"
input = { limit = 5, window_seconds = 1, requests = 10, interval_ms = 100 }
expect = { allowed = 5, rejected = 5 }

9.5 Adversarial cases

The [[adversarial]] array contains cases that probe for known attack patterns. A module without adversarial coverage cannot be deployed at D1 tier or higher.

[[adversarial]]
name = "thundering-herd-at-boundary"
description = "Synchronized clients should not all fire at window reset"
category = "timing"
input = { limit = 100, clients = 1000, synchronized_at_ms = 1000 }
expect = { max_concurrent_at_reset_lt = 200 }

The adversarial.coverage table declares which attack categories the eval suite covers:

[adversarial_coverage]
categories = ["input-validation", "timing", "failure-mode"]

9.6 Generator-adversary cases

The [[generator_adversary]] array contains cases designed to catch implementations that pass functional tests but contain generator-introduced flaws. These cases probe behavior the generator might have gotten subtly wrong.

[[generator_adversary]]
name = "off-by-one-at-exact-limit"
description = "At exactly limit requests, allow exactly limit, reject the next"
category = "functional"
input = { limit = 5, requests_at_exact_limit = 5, additional_request = 1 }
expect = { allowed_at_limit = 5, additional_allowed = 0 }

The distinction between adversarial and generator-adversary cases is intent: adversarial cases defend against attackers; generator-adversary cases defend against the generator producing plausible-but-wrong code. Both are required for higher deployment tiers; the format separates them so tooling can report on each independently.

9.7 Constraint-to-eval mapping

Each <constraints> element in the prose contains an enumeration of named constraints, one per line, in the form name: description:

In commonsformat.md:

<constraints>
- no-fixed-window: implementation must not use fixed-window counters
- no-global-locks: implementation must not use global locking
</constraints>

The constraint name is a kebab-case identifier that must be unique within a module. The description is a one-sentence human-readable explanation. Both are required for each constraint.

Free-form prose about constraints is permitted in the commonsformat.md body outside the <constraints> tag (as commentary), but only the named entries within <constraints> are part of the structured contract. Anonymous prose constraints do not participate in verification, merging, or conflict detection.

In evals.toml:

[[adversarial]]
name = "boundary-burst"
verifies = ["no-fixed-window"]
# ...

A constraint without any case that lists it in verifies is an unverified constraint. Tooling reports unverified constraints as warnings. Production deployments at D2 or higher require all declared constraints to be verified by at least one case.

9.8 Properties

The [properties] table declares invariants that aren't easily expressed as input/output cases:

[properties]
thread_safe = true
no_external_deps = true
interface_methods = ["allow", "reset", "configure"]
memory_complexity = "O(active_keys)"

Properties are advisory unless tooling verifies them through static analysis or runtime instrumentation. The format does not mandate property verification machinery.

10. Logical module structure

After parsing, a module has a logical structure consumed by downstream tools (resolvers, eval runners, generators, verifiers). The format defines the logical contents; concrete representations are at the implementation's discretion.

A parsed module logically contains:

  • metadata — the validated contents of commonsformat.toml, including all required fields (§6) and any optional fields present. Field types match those in the TOML subset (§4).
  • prose — the parsed contents of commonsformat.md, with tagged sections extracted. Tagged sections are accessible by tag name; the example tag, which may appear multiple times, is accessible as a list keyed by the name attribute. The prose also retains its non-tagged content for human display, but tools operate on the tagged sections.
  • constraints — the parsed contents of the <constraints> tag, if present, as a list of (name, description) pairs. Constraints are addressable by name throughout the format (in verifies references, in conflict detection during merging, in unverified-constraint warnings).
  • interface — the parsed contents of the <interface> tag, if present, as the prose declared by the module author. The format does not impose structure on interface content beyond it being a string.
  • avoid — the parsed contents of the <avoid> tag, if present, as a list of anti-pattern descriptions.
  • threat_model — the parsed contents of the <threat-model> tag, if present, as a string.
  • examples — the parsed <example> tags, keyed by the name attribute, with their content as values.
  • evals — the validated contents of evals.toml, if the module declares verifies. Evals contain cases, adversarial, generator_adversary, adversarial_coverage, and properties per §9.
  • path — the filesystem location the module was loaded from. Tools needing to resolve relative references (such as verifies paths in metadata) use this.

A tool consuming a parsed module accesses these logical contents without depending on a specific concrete representation. Two implementations of a parser may use different in-memory data structures, different field names, or different language-idiomatic forms; what matters for cross-tool composition is that the logical contents are reachable.

11. Composition

11.1 Composition is spec merging

Commons Format composition occurs at the spec layer. When module A declares a dependency on module B, the dependency resolver merges B's spec into A's, producing a virtual merged spec. The consumer generates one implementation against the merged spec.

There is no implementation-level composition. There is no runtime linking between A's implementation and B's. There are no interface contracts between dependent implementations. The merge happens before generation; generation produces a single implementation that satisfies the merged contract.

This eliminates a class of problems that traditional package composition introduces: ABI compatibility, calling conventions, versioning skew between linked libraries. The format does not solve these problems; it makes them irrelevant by composing earlier.

11.2 Dependency declarations

A module declares dependencies in commonsformat.toml:

[[depends_on]]
spec = "github.com/jane/specs/idempotency-keys"
version = "^1.2.0"

Required fields:

  • spec — Git-rooted path identifying the dependency. The format is host/owner/repo/path, where:
    • host is the Git host (e.g., github.com, gitlab.com, git.sr.ht)
    • owner/repo is the repository identifier on that host
    • path is the path within the repository to the module directory
    A repository may contain multiple modules, each at its own path. A module at the repository root has empty path.
  • One of:
    • version — version constraint matching a Git tag in the dependency repository
    • ref — Git ref name (branch, tag, or commit reference)
    • commit — exact Git commit SHA

11.3 Version constraints

The version field uses a small constraint syntax:

  • 1.2.3 — exact version match
  • ^1.2.3 — compatible with 1.2.3 (any 1.x.y where x.y >= 2.3)
  • ~1.2.3 — patch updates allowed (any 1.2.y where y >= 3)
  • >=1.2.3 — at least 1.2.3, no upper bound
  • >=1.2.3 <2.0.0 — range

The resolver selects the highest version satisfying the constraint.

11.4 The merge algorithm

Given a root module R with dependencies D1, D2, ..., Dn, the resolver produces a merged virtual spec by:

  1. Resolving each dependency to a specific commit, recursively, until all transitive dependencies are resolved. Cycles are detected and rejected.
  2. Computing a topological order of all modules (R plus all transitive dependencies). Cycles have already been rejected.
  3. For each module in topological order from leaves to root, contributing its content to the merged spec:
    • Intent: each contributing module's <intent> is appended, with the root module's intent positioned first and supporting modules' intents marked as supporting context.
    • Constraints: each contributing module's <constraints> is unioned. Conflicts (a constraint in one module that contradicts a constraint in another) are detected by name; constraints with the same name from different modules conflict.
    • Avoid: each contributing module's <avoid> is unioned.
    • Interface: only the root module's <interface> is exposed in the merged spec. Dependencies' interfaces become internal scaffolding the implementation uses but do not expose.
    • Threat-model: each contributing module's <threat-model> is appended.
    • Examples: each contributing module's examples are unioned. Name collisions are an error unless explicitly resolved.
    • Eval cases (functional, adversarial, generator-adversary): each contributing module's cases are unioned. Name collisions are an error unless explicitly resolved.
    • Properties: each contributing module's properties are unioned. Conflicts (the same property declared with different values) are detected.
  4. Reporting all conflicts. Generation does not proceed against a conflicted merged spec.

11.5 Conflict resolution

When the merge produces a conflict, the depending module may declare an explicit override:

[[depends_on]]
spec = "github.com/jane/specs/idempotency-keys"
version = "^1.2.0"

[depends_on.overrides]
constraints.no-external-deps = "ignore"
properties.requires_redis = false

The override semantics:

  • "ignore" — the conflicting element from the dependency is dropped from the merged spec.
  • A literal value — the merged spec uses the override value, not either input.

Overrides are visible in the merged virtual spec and recorded in the lockfile. Consumers auditing a module's contract can see exactly which dependency content was suppressed and why.

11.6 Extension as a special case of merging

A module that wishes to refine another module — adding constraints, tightening evals, providing more specific intent — uses extends instead of (or in addition to) depends_on:

extends = "github.com/jane/specs/rate-limiting@^1.0.0"

Semantically, extends is depends_on with two additional properties:

  1. The extending module's content takes precedence on conflicts (without requiring explicit overrides for every case).
  2. Conformance to the extending module implies conformance to the extended module. An implementation passing the extended module's evals also passes the extending module's parent evals.

A module may extend at most one parent. Multiple parents would introduce diamond-conflict resolution complexity that this version of the format does not address.

11.7 Eval packs

An eval pack is a module that contributes only adversarial or generator-adversary cases to a target module. The pack declares itself as a pack in commonsformat.toml:

commonsformat = "0.1"
name = "rate-limiting-attack-pack-2026q2"
version = "1.0.0"
extends = "github.com/jane/specs/rate-limiting@^1.0.0"
contributes_only = ["adversarial", "generator_adversary"]

A pack's prose is conventionally minimal: a description of the attack class it covers and references to the discoveries that motivated each case. The pack's evals.toml contains the cases themselves.

When a consumer applies an eval pack, the resolver merges the pack into the target module the same way any extension would, except that contributions outside contributes_only are rejected.

The format does not specify pack discovery, signing, or trust scoring. Consumers choose which packs to apply; the lockfile records which packs were merged at verification time.

12. Deployment tiers

A consumer's deployment context determines which verification a generated implementation must satisfy before deployment. The format defines four tiers, each with mechanical requirements a verifier can check by reading the lockfile and the recorded eval results.

Tier requirements are countable and enforceable. The format does not include "recommended" requirements — a requirement is either part of the tier or it isn't. Qualitative concepts like "generator independence" or "security-relevant primitives" are documented as guidance for consumers but not enforced by the verifier.

D0 — Personal/Experimental. Functional eval cases pass.

D1 — Internal Production. D0 requirements. Adversarial eval cases pass. Every constraint declared in the merged spec's <constraints> block has at least one eval case listing it in verifies.

D2 — Network-Exposed Production. D1 requirements. Generator-adversary eval cases pass. The lockfile records at least two distinct generator_id values, each with a passing record for the full eval suite. Imported commonsformat.md files have a recorded review (see §14.1).

D3 — Critical Infrastructure. D2 requirements. The lockfile records at least two distinct runtime identifiers, each with a passing record for the full eval suite. If the merged spec declares a formal_artifact_path, a file at that path exists in the module directory and is referenced from the lockfile.

The deployment tier is chosen by the consumer per implementation, not declared by the spec author. A spec author ships whatever verification machinery they have; consumers verify to the tier their deployment requires.

12.1 Guidance on independence

The format requires distinct generator_id values at D2 and distinct runtime identifiers at D3 — countable requirements a verifier can enforce. The format does not enforce that distinct generators come from independent training pipelines, or that distinct runtimes come from independent language families, because no registry exists to determine independence mechanically.

Consumers SHOULD pick generators from independent providers (for example, Claude and GPT rather than two Claude versions) and runtimes from independent language families (for example, CPython and Rust rather than two Rust toolchains) to obtain meaningful defense-in-depth. The format documents this guidance; the verifier checks the mechanical floor.

A future format version may incorporate an independence registry or a signed attestation mechanism if the ecosystem develops one. This version does not.

13. Verification axes

Three orthogonal verification axes contribute to confidence in an implementation:

13.1 Eval depth

How thoroughly does the eval suite probe the implementation?

  • Functional only: implementation passes the [[cases]] array.
  • Adversarial: implementation also passes [[adversarial]], and the eval suite declares coverage in adversarial_coverage.
  • Generator-adversary: implementation also passes [[generator_adversary]].
  • Formal: a separate formal verification artifact accompanies the implementation, addressing properties not expressible as eval cases. The artifact is stored in references/formal/ of the module that produced the verification.

13.2 Generator diversity

How many independent generators have produced implementations that pass the eval suite?

  • Single generator: one model, one generation.
  • Same-family generators: multiple models from the same provider or family (e.g., two Claude versions). Catches some generation-time flukes; does not address provider-specific systematic bias.
  • Independent-family generators: multiple models from independent training pipelines (e.g., Claude plus GPT plus a community open-weights model). Catches model-specific systematic flaws.
  • Independent-provider generators: stronger constraint requiring generators from independent organizations. Defends against organizational-level compromise of a single provider.

13.3 Runtime diversity

How many independent runtimes execute conformant implementations?

  • Single runtime: one language runtime, one host.
  • Multi-runtime same family: multiple runtimes within a language family (e.g., CPython and PyPy). Catches some interpreter-specific bugs.
  • Multi-runtime independent family: implementations in multiple language families (e.g., Python plus Rust plus Go). Catches language-runtime CVEs that affect one ecosystem but not others.

The lockfile records which axes have been verified for each module in the consumer's dependency tree. Tooling enforces deployment-tier requirements at deployment time.

14. Lockfile

The lockfile pins the exact resolved state of a consumer's dependency tree. It is generated by tooling, not hand-edited.

commonsformat_lock = "0.1"
generated_at = "2026-04-27T14:00:00Z"
generator_tool = "commonsformat-resolver/0.1.2"

[root]
name = "my-application"
spec_hash = "sha256:..."

[[modules]]
spec = "github.com/jane/specs/rate-limiting"
version = "1.2.0"
commit = "a3f9c2d4e5..."
fetched_from = "github.com/jane/specs"
checksum = "sha256:..."
fetched_at = "2026-04-27T14:00:00Z"

[modules.verification]
deployment_tier = "D2"

[modules.verification.results]
"claude-opus-4-7" = { functional = "pass", adversarial = "pass", generator_adversary = "pass" }
"gpt-5.4" = { functional = "pass", adversarial = "pass", generator_adversary = "pass" }

[modules.verification.prose_review]
reviewed = true
reviewed_at = "2026-04-27T13:45:00Z"
reviewer = "consumer-team@example.org"
prose_hash = "sha256:..."

[modules.verification.applied_packs]
"rate-limiting-attack-pack-2026q2" = { version = "1.0.0", commit = "b1c2d3..." }

The lockfile is reproducible: a consumer with the lockfile can re-fetch all dependencies at the recorded commits, recompute the merged virtual spec, and verify their implementation against the same contract.

14.1 Prose review record

For deployment tiers D2 and higher, the lockfile records that the consumer reviewed the imported commonsformat.md files for adversarial content (per the threat model in §0).

The [modules.verification.prose_review] table contains:

  • reviewed — boolean, must be true for the dependency to satisfy D2+ tier requirements
  • reviewed_at — ISO 8601 timestamp of when the review was recorded
  • reviewer — string identifying who performed the review (free form, typically an email address, team name, or signing key identifier)
  • prose_hash — SHA-256 hash of the imported commonsformat.md file content at the time of review; if the prose changes, the review is invalidated and must be re-recorded

The verifier checks that prose_review.prose_hash matches the current content hash of the imported commonsformat.md. A mismatch fails verification at D2 and higher tiers.

The format does not specify how the review is performed (read by human, scanned by tool, signed by team lead, etc.). Recording the review is a consumer attestation: the consumer claims to have inspected the prose for adversarial content and accepts responsibility for that judgment. This is honest about what the format can and cannot verify automatically.

15. Conformance and the eval suite

This module's eval suite (evals.toml) defines what conformance to the Commons Format format means. An implementation of Commons Format tooling (parser, resolver, eval runner) is conformant if it passes the cases in this module's eval suite.

The eval suite covers:

  • TOML subset parsing: required acceptance and required rejection cases for each construct in §4.
  • Markdown subset parsing: required acceptance and required rejection cases for §5, including tagged section extraction.
  • Module loading: required behavior when given module directories that conform or fail to conform to §2.
  • Dependency resolution: required behavior for the algorithm in §11.4, including conflict detection and override application.
  • Lockfile generation: required structure and content for §14.

Implementations are not conformant by passing some cases. They are conformant only by passing all cases in this module's eval suite.

15.1 Named constraints

This module's eval cases reference named constraints via the verifies field. Per §9.7, those names must be declared in a <constraints> block. The constraints below are the verification contract this module's evals enforce. A conformant implementation satisfies each by passing the eval cases that verify it.

  • toml-bare-keys — bare keys consist of letters, digits, underscores, and hyphens, matching [A-Za-z0-9_-]+
  • toml-basic-strings — basic strings parse with the escape sequences listed in §4.4 and reject literal control characters
  • toml-literal-strings — literal strings take their contents verbatim with no escape processing
  • toml-integers — integers accept optional sign and digits, rejecting leading zeros except for 0 itself
  • toml-floats — floats require both integer and fractional parts; special values inf and nan are rejected
  • toml-booleans — booleans are true or false, lowercase, exact match
  • toml-arrays — arrays accept zero or more values with optional trailing comma; mixed types permitted
  • toml-inline-tables — inline tables accept zero or more key-value pairs with optional trailing comma
  • toml-tables — table headers introduce nested key-value scopes
  • toml-array-of-tables — double-bracketed headers append elements to the named array
  • toml-dotted-keys — dotted keys define nested table structure
  • toml-comments — lines beginning with # and inline # are ignored
  • toml-whitespace — blank lines are ignored; whitespace within values is preserved per the type's rules
  • toml-document-structure — keys may not be redefined within a table; tables may not be redeclared except via array-of-tables headers
  • toml-subset-strict — features outside the subset (datetime, hex/octal/binary integers, underscores in numbers, multi-line strings, exponential floats) are rejected
  • toml-resource-bounds — parsers handle pathologically large or deep input within bounded resources
  • md-headings — ATX headings up to level 4 are recognized
  • md-paragraphs — contiguous non-blank lines form paragraphs
  • md-code-blocks — triple-backtick or triple-tilde fences delimit code blocks with optional info string
  • md-lists — hyphen-space bullet lists and numbered lists are recognized
  • tagged-sections — tagged sections open and close on their own lines and are extracted with content preserved verbatim
  • tagged-sections-named — example tags carry a name attribute and may appear multiple times with distinct names
  • tagged-sections-safety — tag content is treated as text, not as HTML or markup to be processed
  • module-structure — a module directory contains the required files specified in §2
  • module-name-rules — module names use lower-case letters, digits, and hyphens, neither beginning nor ending with a hyphen
  • module-version-rules — module versions are SemVer-shaped MAJOR.MINOR.PATCH with no pre-release or build suffixes
  • encoding-rules — files are UTF-8; non-UTF-8 input is rejected
  • version-constraints — version constraint syntax (exact, caret, tilde, range) selects highest matching version
  • merge-algorithm — dependency resolution produces a merged virtual spec per §11.4
  • merge-conflict-detection — conflicts in constraints, evals, properties, or examples are detected and reported
  • extends-semantics — extending modules inherit parent evals; extending content takes precedence on conflicts
  • eval-packs — packs contribute only to declared categories
  • lockfile-format — lockfiles record commit SHAs, checksums, and verification axes per §14
  • lockfile-verification — lockfile checksums detect tampered content
  • schema-optional — a module without shaped data omits schema.sql and remains conformant
  • schema-subset-strictschema.sql uses only the pinned subset specified in §8.1; constructs outside the subset are rejected
  • schema-header-comment — a conformant schema.sql begins with the §8.2 header comment disclaiming storage commitment
  • schema-no-cross-module-fk — a FOREIGN KEY in schema.sql referencing a table outside the same file is rejected
  • schema-non-merge — dependency resolution does not merge schema.sql files; each module's schema remains in its own namespace
  • schema-interface-vocabulary — when schema.sql is present, the <interface> section may reference DDL types and table names from the same module

16. Threat model and limits

The Commons Format format addresses shared-bytes vulnerability at the application code layer. By distributing intent and evals rather than compiled artifacts, and by enabling per-consumer divergent generation, the format eliminates the class of attacks that exploits identical bytes across many consumers' application code.

The format does not address:

  • Runtime vulnerabilities. Generated implementations execute within language runtimes (CPython, V8, the Go runtime, the JVM) which remain shared across all consumers using that runtime. Mythos-class models can target these runtimes directly. The format provides hooks for partial mitigation through multi-runtime conformance and runtime-subset constraints, but does not solve the problem.
  • Operating system vulnerabilities. Implementations run on shared kernels. Kernel CVEs affect all programs on a host regardless of the format that produced them.
  • Hardware vulnerabilities. CPU-level vulnerabilities (Spectre, Meltdown, and successors) affect all software on affected hardware. The format cannot address these.
  • Build-time vulnerabilities for compiled implementations. A compromised compiler produces compromised binaries. Multi-runtime conformance partially mitigates this for security-critical paths but does not eliminate it.
  • Generator vulnerabilities. A compromised code generator can produce subtly malicious implementations that pass eval suites designed before the compromise. Multi-generator conformance partially mitigates this; the format encourages it but cannot enforce it.
  • Spec-author trust. A malicious spec author can write a spec whose evals don't catch a deliberately-introduced flaw in the intent. Consumers trust the spec author chosen for each dependency. Forking and review remain the primary defenses, the same as in OSS.

The format is honest about what it does and does not do. Consumers deploying at D2 or D3 tiers should understand the residual threats and address them through other mechanisms.

17. Bootstrap

This module bootstraps a Commons Format implementation from itself with no dependencies.

A consumer encountering Commons Format for the first time:

  1. Acquires this module by cloning its canonical Git repository.
  2. Reads commonsformat.md (the present document), which specifies the format completely.
  3. Generates an implementation of a Commons Format parser, resolver, and eval runner in their target language, using a code generator of their choice. The generator consumes this document as context.
  4. Reads evals.toml from this module using the generated parser. This is the first end-to-end test: if the parser cannot read the eval suite, the parser is incorrect.
  5. Runs the eval suite against the generated implementation.
  6. If conformance passes, the consumer has a working Commons Format toolchain. They can now resolve and verify any other Commons Format module that exists.

The format does not ship reference parser implementations. The prose is the specification; the eval suite is the contract; generators produce divergent implementations per consumer. This is the security property of the format, applied to the format's own bootstrap.

18. Versioning of this format

This document specifies Commons Format format version 0.2. The format version is declared in every commonsformat.toml's commonsformat field.

Future format versions may add features, deprecate features, or change semantics. Implementations declare which format versions they support; modules declare which format version they target; resolvers reject combinations that don't match.

Format versioning follows the same SemVer-shaped scheme as module versioning. Breaking changes to the format require a major version bump. Backward-compatible additions are minor. Clarifications and corrections are patch.

The format's own evolution is governed by a process not specified here. Until the process is defined, format changes are made by the format-spec module's maintainers with public review.

describes commons format 0.2 (spec module 0.2.1) · generated from release 0.2 · 2026-05-28