Skip to content

Latest commit

 

History

History
340 lines (260 loc) · 11.7 KB

MANIFEST-DIALECT-SPEC.adoc

File metadata and controls

340 lines (260 loc) · 11.7 KB

A2ML Manifest Dialect Specification

Abstract

This document specifies the manifest dialect of A2ML: the ----delimited frontmatter surface used by 0-AI-MANIFEST.a2ml and its siblings. At 894 well-formed files it is the largest A2ML surface in the estate, and until now it was described by no specification at all — SPEC.adoc §2 has no key-value production, and neither it nor RECORD-DIALECT-SPEC.adoc mentions frontmatter.

Like RECORD-DIALECT-SPEC.adoc, this is a specification of a deployed surface. It was written from a census of every .a2ml file in standards, and it describes what is there. Where the corpus is silent, this document says so rather than inventing a rule.

1. 1. Status and scope

Status: Draft. Not ratified and not yet wired into CI. It has, however, been exercised by a reference validator against the full corpus:

$ bash a2ml/actions/validate/validate-manifest-dialect.sh
  well-formed frontmatter files : 894
  CONFORM to the spec as written: 894  (100%)
  rejected                      : 0

The validator is a real gate, not a formality — injecting an excluded construct (a YAML anchor) into one file gives 893/894 and exit 1.

It MUST NOT be cited as a ratified standard until it is owner-ratified and wired into CI (§9).

This dialect is one of several surfaces over the shared A2ML typed core. The core is normative and lives in a2ml/src/A2ML/; see docs/DIALECT-ARCHITECTURE.adoc for the family design and SPEC.adoc §3 for the core itself. A surface is legitimate only if it defines a translation into that core (§7).

2. 2. Census — what this specifies

All 1,543 .a2ml files in standards, 2026-08-03:

Shape Files Note

Frontmatter, --- opened and closed

894

Specified by this document

--- opened, never closed

19

Not this dialect — see §8

Other dialects (record, markup) and unclassified

630

RECORD-DIALECT-SPEC.adoc, SPEC.adoc §2

Within the 894 well-formed blocks: 2,706 key-value lines, 29 distinct keys, and a value vocabulary of five kinds.

3. 3. Document structure

a2ml-manifest  ::=  header-comments  open-delim  frontmatter  close-delim  body
open-delim     ::=  "---" LF
close-delim    ::=  "---" LF
header-comments

Zero or more lines that are blank or begin with # or //. In 904 of 913 observed files this is exactly one line — the SPDX identifier.

open-delim

A line whose entire trimmed content is ---. It MUST be the first non-comment, non-blank line. A document whose first non-comment line is not --- is not this dialect.

frontmatter

The subject of §4. MAY be empty.

close-delim

The next line whose entire trimmed content is ---. REQUIRED. See §8 for why this is stated so strongly.

body

Everything after close-delim. Not specified here; it is prose or markup-dialect content, and every one of the 894 observed files has a non-empty body (median 3 lines).

4. 4. Frontmatter grammar

frontmatter  ::=  ( entry | seq-item | comment | blank )*
entry        ::=  indent key ":" SP value LF
           |  indent key ":" SP block-intro LF block-body
indent       ::=  ( SP SP )*                    ; 0, 2 or 4 spaces observed
key          ::=  ALPHA-or-"_" ( ALNUM | "_" | "." | "-" )*
value        ::=  dq-string | integer | nested | flow-seq | bare-scalar
seq-item     ::=  indent "-" SP any* LF
block-intro  ::=  ( "|" | ">" ) ( "-" | "+" )?
block-body   ::=  ( block-line )*
block-line   ::=  <any line indented MORE than its introducing entry, verbatim>
comment      ::=  indent "#" any* LF

block-body is opaque. Its lines are not parsed as entries, comments or delimiters; they are content. This matters — the only corpus use of a block scalar is a PEM-armoured signature:

signature: |
      -----BEGIN HYBRID SIGNATURE-----
      BASE64_Ed448+Dilithium5_SIGNATURE_OF_THIS_FILE
      -----END HYBRID SIGNATURE-----

A grammar that admits | but not its continuation lines would reject exactly the construct A2ML exists to carry. A # inside a block body is signature data, not a comment, and a line beginning --- inside one does not close the frontmatter.

Indentation is spaces only. Tabs MUST NOT be used; none appears in the corpus.

Observed indent widths: 0 (2,684 lines), 4 (15), 2 (7). Nesting is therefore rare — 22 of 2,706 entries — but real, and a conforming parser MUST support it.

4.1. 4.1 Values

Kind Count Form

dq-string

1,799

" … ". Double quotes only.

integer

880

Optional -, then digits.

nested

19

Empty after the colon; the following more-indented lines are a nested mapping.

bare-scalar

6

Unquoted, no leading/trailing space, terminated by end of line.

flow-seq

2

[ item ( , item )* ]

A conforming producer SHOULD emit dq-string for all string values. Bare scalars are permitted for compatibility with the six existing occurrences and are NOT RECOMMENDED for new documents: they are the construct most likely to be misread as a boolean, null or number.

Sequences may also appear in block form (- item on its own line); 29 such lines were observed.

4.2. 4.2 Excluded YAML constructs

This dialect is not YAML. The following are NOT PERMITTED, and none occurs anywhere in the corpus:

Construct Occurrences Rationale for exclusion

Anchors &name

0

Aliasing makes a document’s meaning non-local, which defeats attestation over a canonical hash form.

Aliases *name

0

As above; also the basis of billion-laughs style expansion attacks.

Tags ! / !!

0

Type coercion by tag lets the same bytes mean different things to different parsers.

Flow mappings {…}

0

No occurrences; excluding it removes a whole nesting path from the grammar.

Single-quoted strings

0

Two string forms with different escaping rules is a parser-differential risk for no expressive gain.

Multi-document streams --- … --- …

0

The second --- is the close delimiter. See §8.

Block scalars | >

2

Permitted but NOT RECOMMENDED — see below.

Block scalars appear twice. They are permitted for those two files rather than retroactively invalidating them, but new documents SHOULD use a quoted string. Their chomping and folding rules are the single largest source of disagreement between YAML implementations.

Note

Excluding anchors, aliases and tags is not a restriction — it is a description. They are absent from all 894 files. Writing them out of the grammar costs nothing and removes the three constructs most often implicated in YAML parser differentials.

5. 5. Key vocabulary

29 distinct keys across the corpus. The ten most frequent:

id · level · parent · version · context · algorithm · value · integrity · meta · generated

This document does not fix the vocabulary. Key semantics belong to the base record vocabulary and the profile mechanism in SPEC.adoc; this dialect specifies only the surface in which keys are written. A future profile MAY constrain which keys are required.

6. 6. Conformance

A document conforms to the manifest dialect at level R1 when:

  1. its first non-comment, non-blank line is ---;

  2. a matching --- close delimiter exists;

  3. every non-blank, non-comment line between them parses as entry;

  4. no excluded construct from §4.2 appears;

  5. indentation is spaces only, in multiples of two.

A validator MUST reject a document failing 1–5 rather than skipping it. This matters: a2ml/actions/validate/validate-a2ml.sh currently exempts AI-MANIFEST*.a2ml and AI.a2ml from identity checks, treating them as "markdown prose". That exemption existed because there was no grammar to check against. With this document, the exemption should be removed — see §9.

7. 7. Translation into the core

The mapping into a2ml/src/A2ML/:

Manifest surface Core

Frontmatter block

The document’s metadata mapping

entry with dq-string / bare-scalar

String value

entry with integer

Numeric value

entry with nested

Sub-mapping

entry with sequence

List value

Body after the close delimiter

Markup-dialect block content, per SPEC.adoc §2

This is the part that makes the dialect A2ML rather than "YAML in a file with an unusual extension". Translator.idr and Converters.idr are where it belongs; neither currently implements it, which is tracked in §9.

Round-tripping — surface → core → surface — is a property to be proved, not assumed. Proofs.idr is the place for that obligation.

8. 8. The 19 unterminated files are NOT this dialect

Nineteen files open with --- after their comment header and never close it. A naive classifier reads them as malformed manifests. They are not:

# SPDX-License-Identifier: MPL-2.0
# must.manifest.a2ml — Trident coherence manifest for the must verb.

---
trident_version = "1.0.0"      <-- equals, not colon: record dialect
verb = "must"

## Files (three; exactly)      <-- markup heading

Of the 19: 7 use key = value (record dialect), 12 use ## heading (markup dialect). The --- is a horizontal rule, not a frontmatter delimiter.

This is a genuine ambiguity in the family and this specification resolves it one way only: in the manifest dialect, a --- as the first non-comment line opens frontmatter. A document that uses --- as a rule MUST NOT also place it first, or it is indistinguishable from a manifest whose close delimiter is missing.

Two consequences:

  • A manifest parser fed one of these 19 files would consume the entire file as frontmatter and fail. That is correct behaviour under this spec.

  • The 19 files should be corrected — either by removing the leading --- or by moving it below their first content line. They are recorded here so the fix is a known task rather than a surprise.

The wider point for SPEC.adoc as family root: --- is currently ambiguous across dialects, and the family spec should say which dialect claims it in first position.

9. 9. Open items before ratification

  1. Reference validator. ✅ Done — a2ml/actions/validate/validate-manifest-dialect.sh, 894/894 conforming. It found one spec bug during drafting: the grammar admitted the block-scalar introducer | but not its continuation lines, so it rejected a PEM-armoured signature — the very construct A2ML exists to carry. Fixed in §4. Still to do: wire it into CI.

  2. Remove the blanket exemption. validate-a2ml.sh skips identity checks on AI-MANIFEST*.a2ml. Once the validator above exists, the exemption should go.

  3. Implement the translation. §7 in Translator.idr / Converters.idr, with a round-trip proof obligation in Proofs.idr.

  4. Fix the 19. §8.

  5. Register the dialect. Add dialect=manifest to the family media type — see docs/DIALECT-ARCHITECTURE.adoc §4 and RECORD-DIALECT-SPEC.adoc §14.

10. 10. Versioning

Versioned with SemVer, independently of SPEC.adoc and RECORD-DIALECT-SPEC.adoc, but within the same era (v1) and over the same core.

A change that would reject a currently-conforming corpus document is a MAJOR bump and requires a migration note and a deprecation window. Permitting a construct currently excluded by §4.2 is a MINOR bump — but the burden is on the proposer to show the construct is needed, since each one re-opens a parser-differential surface that is presently closed.