&ND Core v2 Proposal
This document records the frozen proposal baseline for &ND Core v2. It is not a published
specification and does not supersede the v1 draft.
The purpose of this file is to define the selected syntax, compatibility rules, and test strategy while v2 remains in proposal lifecycle. Changes to this frozen baseline require an explicit reviewed revision together with corresponding AST, canonical, fixture, migration, and consumer-guidance updates.
1. Proposal Status
| Field | Value |
|---|---|
| Stage | Proposal |
| Stability | Frozen proposal baseline |
| Publication status | Not published |
| Relationship to v1 | Compatible extension of the v1 draft |
2. Working Goal
&ND Core v2 defines document-language extensions beyond the current v1 draft while preserving
the properties that make v1 useful:
deterministic parsing
explicit structure
fail-closed behavior
non-executable documents
a small core syntax surface
The frozen compatibility rule is that v1 strict documents remain valid v2 strict documents unless v1 itself changes before publication.
3. Non-Goals
This proposal does not:
publish v2 or change its proposal lifecycle
supersede the v1 draft
require implementation support
activate a published CTS lane
The grammar, compatibility boundary, AST, and canonical output are fixed for this proposal baseline.
4. Compatibility Stance
The frozen proposal follows these rules:
Documents accepted by v1 strict mode should be accepted by v2 strict mode.
Already-valid v1 syntax should keep the same structural meaning in v2.
v2-only syntax should prefer forms that v1 reserves and rejects.
v2 should avoid reinterpreting existing valid v1 constructs.
v1 strict implementations should fail closed when presented with v2-only declarations or syntax.
The version declaration controls the grammar; parser capability does not override it:
| Declared document | v1-only parser | v2-capable parser |
|---|---|---|
v1 syntax under &ND v1 | accept | accept as v1 |
v2 syntax under &ND v1 | reject | reject as v1 |
v1 syntax under &ND v2 | reject unsupported version | accept as v2 |
v2 syntax under &ND v2 | reject unsupported version | accept as v2 |
Standalone v2 input MUST declare &ND v2. Headerless input MUST receive its effective version from
its embedding profile or typed channel.
Implementations MUST NOT infer v2 from the presence of v2-looking syntax.
The reference API separates parser capability from the effective grammar:
parseAnd(standaloneSource, { allowV2: true });
parseAnd(embeddedSource, { allowV2: true, version: "v2" });
parseInline(inlineSource, { allowV2: true, version: "v2" });
allowV2 declares capability. version selects the grammar only for headerless input. A source
declaration takes precedence, and successful document parses report the effective version beside
the AST.
5. Frozen Proposal Surface
The current proposal surface is grouped into nine work areas.
5.1 Header and Versioning
The explicit standalone declaration is &ND v2. Embedded content may omit it only when an enclosing
profile or typed channel supplies v2 as the effective version. The declaration is metadata and does
not become a content block.
Executable seeds:
seed-v2-header-recognizedseed-v2-header-rejected-by-v1-strict
5.2 Inline Forms and Local Links
Core v1 reserves several inline forms. V2 promotes the forms below while reusing the inherited link form for local navigation.
Frozen forms:
| Form | Core meaning | Disposition |
|---|---|---|
[# ...] | scalar document-local anchor | Core |
[@ #id | label] | inherited rich-label link with resolved local target | Core |
[~ source | alt | mode] | inline image with required alt text and a closed display-mode enum | Core |
[! ...] | rich warning or admonition content | Core syntax + convention |
[? ...] | rich question or hint content | Core syntax + convention |
[+ ...] | scalar consumer-defined tag | Core syntax + convention |
[- ...] | rich struck content | Core |
[" ...] | rich quoted inline content | Core |
[' ...] | rich inline comment content | Core |
[:type = scalar] | exact AEON typed syntax over the closed inline-scalar subset | Core syntax + convention |
[= ...] | rich highlighted content | Core |
[_ ...] | rich underlined content | Core |
[.] | inline line break | Core |
“Core syntax + convention” is part of the single v2 strict grammar, not an optional parser gate.
Core guarantees the AST and canonical spelling while leaving consumer vocabularies, workflow, and
presentation outside Core. Rich forms use nested inline children; identifiers and metadata remain
scalar.
Anchor IDs, the identifier portion of #id link targets, named footnotes, and semantic wrappers use
one shared v2-id grammar: [A-Za-z0-9][A-Za-z0-9._:-]*. Matching is exact and case-sensitive.
Anchors occupy one document-wide namespace. Forward links are allowed;
duplicate anchors and unresolved local targets fail declared-v2 strict parsing. Web and external
resources continue to use inherited [@ target | label] links.
The promoted image form accepts [~ source | alt] or [~ source | alt | mode]. Source and alt text
are required scalars, the omitted mode defaults to inline, and explicit modes are limited to
inline, half, and full. Canonical output always spells the resolved mode. These modes record
display intent; Core does not resolve the source or inspect image dimensions.
The reference HTML renderer preserves safe relative sources by default and accepts an explicit
credential-free HTTP(S) imageBaseUrl for deterministic WHATWG resolution. Resolved output retains
the authored source in data-and-source. Non-HTTP(S), credentialed, and protocol-relative sources are
omitted while mandatory alt text remains available; invalid bases fail with
invalid_image_base_url.
The promoted typed-value form adopts exact AEON anonymous typed-scalar syntax, including the
mandatory =, structured generic arguments and clarifiers, reserved datatype aliases, literal-family
compatibility, string escapes, and scalar canonicalization. Supported families are string, finite
number, infinity, NaN, null, Boolean, toggle, hex, radix, encoding, date/time/datetime/WTC,
separator literals, SANSA addresses, and custom datatype labels over those scalars. Structured
values, references, nested typed values, trimticks, prose, and multiline strings remain outside the
inline subset.
The reference implementation pins this boundary as machine-readable contract
and-v2-aeon-inline-scalar-v1, aligned with AEON TypeScript package version 0.12.0. Mandatory
dependency-free snapshots cover the &ND AST, canonical text, and HTML projection; an optional sibling
repository check detects lexer, parser, or canonicalizer drift in the corresponding AEON forms.
Executable seeds:
seed-v2-inline-anchor-tag-enabledseed-v2-inline-local-fragment-link-enabledseed-v2-inline-admonition-tag-enabledseed-v2-inline-question-tag-enabledseed-v2-inline-plus-tag-enabledseed-v2-inline-image-tag-modesseed-v2-inline-strike-tag-enabledseed-v2-inline-quoted-tag-enabledseed-v2-inline-comment-tag-enabledseed-v2-inline-typed-value-enabledseed-v2-inline-typed-value-aeon-scalarsseed-v2-inline-highlight-tag-enabledseed-v2-inline-underline-tag-enabledseed-v2-inline-line-break-marker-enabled
5.3 Contextual List, Marker, and Footnote Forms
Todo states and [n] are promoted through contextual prefixes. [% ...] defines footnotes and can
carry a shared v2 identity for later shorthand references.
Frozen forms:
| Form | V2 meaning | Status |
|---|---|---|
- [ ] content | todo item, unchecked | Core |
- [x] content | todo item, checked | Core |
- [,] content | todo item, in progress | Core |
- [;] content | todo item, cancelled | Core |
- [n] content | auto-number list item | Core |
[>] | forward marker | Core |
[<] | backward marker | Core |
[n] | heading auto-number marker | Core |
[% content] | anonymous footnote definition and reference | Core |
[% (id) content] | named footnote definition and first reference | Core |
[% (id)] | backward reference to an already-declared named footnote | Core |
Executable seeds:
seed-v2-todo-list-statesseed-v2-auto-number-list-enabledseed-v2-inline-directional-markers-enabledseed-v2-directional-list-markersseed-v2-heading-auto-number-marker-enabledseed-v2-footnote-anonymousseed-v2-footnote-named-reuse
A matching item prefix creates todo_list and todo_item nodes rather than a generic list carrying
inline markers. Every item in one list block must be the same kind. Bare todo markers, empty todo
items, ordered todo markers, malformed spacing, unknown states, and mixed ordinary/todo blocks fail
closed. Todo lists inherit ordinary nested-list structure and canonicalize as - [state] content.
Homogeneous - [n] content blocks similarly become auto_number_list nodes containing inherited
list_item nodes and canonicalize without authored numeric labels. Heading and list [n] require a
separator space and non-empty content; bare paragraph use is rejected. Core records numbering intent
but leaves sequence scope, restart behavior, and display formatting to consumers. V2 permits
ordinary, todo, and auto-number lists to begin an exact two-space-indented nested list immediately;
the reference HTML projection visibly numbers opted-in headings hierarchically by heading level.
A [>] or [<] marker in the first inline position of an unordered item's paragraph remains an
inline AST node but replaces that item's ordinary bullet in projection. Later markers remain inline,
ordinary and directional items may coexist, and ordered lists keep their normal numbering.
Footnote IDs use the shared v2-id grammar and may be declared once. Named references
must follow their definition. Definitions carry non-empty rich inline content and cannot contain
other footnotes. Core preserves the definition/reference graph and authored IDs; processors own
display numbers or symbols, hover/callout/endnote placement, and backlinks.
5.4 Code Block Forms
V2 inherits every v1 triple- and quadruple-backtick code block and both unnumbered tilde-dollar
forms, then adds [n] numbered-line intent:
~~~$
code
~~~$
~~~$ language
code
~~~$
~~~$ [n]
code
~~~$
~~~$ [n] language
code
~~~$
The optional language matches [A-Za-z][A-Za-z0-9_-]* and canonicalizes to lowercase. [n]
records numbered-line intent in the inherited code_block.ordered field. Every new form closes with
bare ~~~$ or a v2 captioned closer such as ~~~$ (Example A: description), and payload text
retains inherited raw-code behavior and resource budgets.
V1 accepts ~~~$ and ~~~$ language but rejects the v2-only [n] variants. Backtick and dollar
fences remain accepted by v2 readers. Canonical v2 output prefers ~~~$, including for code parsed
from backticks, and falls back to the matching inherited backtick fence when a bare or
caption-shaped ~~~$ closer line occurs in the payload. Canonical v1 output prefers backticks and falls back to unnumbered ~~~$ for
an exact triple-backtick payload line. The
briefly introduced ~~~language and ~~~~language forms have been removed and reject with
deprecated_code_fence. Plain ~~~ remains ordinary paragraph text.
Executable seed:
seed-v2-code-block-dollar-fences
5.4.1 Block Captions
V2 permits one optional non-empty rich inline caption on the closing fence of every fenced block node. The grammar is a block closer, one ASCII space, and caption content enclosed by parentheses on that physical line. This covers inherited backtick and dollar code, opaque extensions, paired blocks, semantic blocks, and cards.
The reserved +++fallback region is not independently captionable. A caption on an extension's
primary closer preserves immediate fallback attachment. Card opener text remains its title and
collapsible label; a closer caption is independent descriptive content. Core preserves authored
labels such as Figure 1.1 without interpreting or automatically numbering them. Canonical v2
emission retains captions, HTML uses visible <figcaption> content, and non-visual projections
retain an equivalent description. V1 rejects captioned inherited closers with
block_caption_requires_v2.
Executable seed:
seed-v2-block-captions
5.5 Table Alignment and Horizontal Spans
V2 extends inherited tables with <--, -=-, and --> separator cells for left, center, and right
logical-column alignment. --- remains the default. The separator row defines logical width.
A content cell may start adjacent to its preceding pipe with one or more > characters, one ASCII
space, and non-empty content. Each marker adds one column: |> A+B | C | spans two columns and
|>> A+B+C | spans three. Padded | > literal | is ordinary content. Header and body cells may
span; separator cells may not. Every row's span sum must equal the separator width. Spanning cells
use their first covered column's alignment; row spanning is unsupported.
The AST adds optional table alignments and cell colSpan fields only when used, preserving exact
v1 table shapes. A table may also carry one optional rich inline caption in a separate caption
field. The caption line immediately follows the final row, uses exact |~ caption syntax with no
trailing pipe, and remains separate from header/body cells. Canonical output emits exact alignment
tokens, adjacent markers, and any caption after the last row. HTML emits a native <caption>.
Caption labels and numbering are authored rather than calculated by Core.
V1 rejects the new positions. Malformed spans or width under/overflow fail with
invalid_table_span. Empty captions fail with invalid_block_caption; malformed, orphan, or
duplicate caption markers fail with invalid_table_caption.
Executable seed:
seed-v2-table-alignment-and-spansseed-v2-table-caption
5.6 Card Blocks
V2 adds ~~~| / ~~~| as a visible card containing ordinary block children. The opener may add
one ASCII space and a non-empty rich inline title: ~~~| title. Title presence makes the card
collapsible; the title is visible content rather than an ID. Unnamed cards are always-visible
containers. Empty bodies, malformed title spacing, and missing exact closers reject with stable
card-family diagnostics. Direct same-level card nesting is unavailable because the unnamed opener
and closer are identical. V1 reserves and rejects the opener.
Executable seed:
seed-v2-card-blocks
5.7 Paired Block Forms
Core v1 reserves several block-ish text forms. V2 promotes the forms below into deterministic paired block constructs that fail closed when malformed.
Frozen forms:
highlight paragraph block
opener: ~~~=
closer: ~~~=
strong paragraph block
opener: ~~~*
closer: ~~~*
emphasis paragraph block
opener: ~~~/
closer: ~~~/
underline paragraph block
opener: ~~~_
closer: ~~~_
hint paragraph block
opener: ~~~?
closer: ~~~?
attention paragraph block
opener: ~~~!
closer: ~~~!
comment block
opener: ~~~'
closer: ~~~'
header text block
opener: ~~~#
closer: ~~~#
disclaimer block
opener: ~~~^
closer: ~~~
semantic block
opener: ~~~(<id>)
closer: ~~~
inline semantic wrapper
[(<id>) rich inline content]
Grammar productions: v2-id ::= AlphaNumeric V2IdContinue*; AlphaNumeric ::= "A".."Z" | "a".."z" | "0".."9"; V2IdContinue ::= AlphaNumeric | "." | "_" | "-" | ":".
This is the same case-sensitive v2-id grammar used by anchors and named footnotes.
Executable seeds:
seed-v2-block-highlight-paragraph-enabledseed-v2-block-strong-paragraph-enabledseed-v2-block-emphasis-paragraph-enabledseed-v2-block-underline-paragraph-enabledseed-v2-block-question-paragraph-enabledseed-v2-block-admonition-paragraph-enabledseed-v2-block-comment-enabledseed-v2-block-header-text-enabledseed-v2-block-disclaimer-enabled
The executable proposal requires non-empty rich inline payloads, uses exact deterministic closers,
preserves v2 through nested block contexts, and applies the same maxBlockSize resource budget used
by inherited raw blocks. Plain ~~~ remains inherited ordinary paragraph text when it is not the
closer of a ~~~^ disclaimer or ~~~(id) semantic block. Header-text and disclaimer blocks are
untagged Core forms. Semantic wrapper IDs remain available to consumers in the AST but are not
exposed by the reference HTML projection; their content otherwise projects as ordinary block or
inline content.
5.8 Structural Block Escapes
At a v2 block-open position, one leading \ may suppress a block command and make its decoded text
an ordinary paragraph. This is a structural escape, not a global extension of the inline escape set.
It covers headings, lists, blockquotes, horizontal rules, extension blocks, inherited backtick code
fences, v2 dollar-code fences, removed tilde-language openers, v2 paired, semantic, and card fences, and
reserved legacy block openers. Table recognition continues to use
the inherited \| escape at the first pipe.
The escaped form is accepted only when removing the backslash would expose a real block opener.
Mid-line escapes and unnecessary forms such as \#hashtag or \~~~ reject with invalid_escape.
Core v1 keeps its existing escape rules. Canonical v2 output restores the escape whenever omitting
it would change the decoded paragraph's block type.
5.9 Compatibility and Canonicalization
V2 defines compatibility and canonicalization as part of the frozen syntax surface.
Executable boundaries:
seed-v2-accepts-v1-strict-coreseed-v2-canonical-roundtrip-core-subsetseed-v2-forward-compat-boundaryinherited opaque extension blocks remain syntactically accepted; unsupported consumers use fallback content or an explicit unsupported-extension diagnostic
unpromoted reserved syntax remains a strict
unknown_inline_typefailureno recovery or forward-compatibility mode is currently defined
The companion AST contract defines the promoted node shapes, effective-version metadata, and canonical emission boundary.
6. Deferred Ideas
These ideas are not rejected, but they should not be part of the first v2 activation slice:
other unpromoted reserved syntax
profile-gated syntax inside Core strict mode
HTML passthrough
executable or evaluatable constructs
semantic interpretation of links, references, or typed values inside Core
7. Test Strategy
The v2 proposal remains test-first.
The implementation repository contains an executable 174-fixture v2 proposal lane. It is design
pressure, not a published conformance requirement. The normative v1 lane remains independently
reviewable. The proposal runner additionally checks v1 compatibility, headerless effective-version
equivalence, standalone and embedded canonical fixed points, inert HTML projection, nested v2
contexts and rich inline content, local-fragment integrity, resource budgets, opaque extensions,
and the strict forward boundary. Machine-readable contract and-v2-projection-v1 additionally pins
48 exact source-span assertions and a 39-entry cross-form interaction matrix.
Move from proposal notes to active v2 fixtures only when:
The promoted syntax has a written parse shape.
The promoted syntax has at least one accepted fixture and one rejected fixture.
v1 strict rejection behavior is defined where relevant.
Canonical output expectations are documented and reach a parse–emit fixed point.
A v2 adapter strategy is written for the CTS runner.
8. Embedding Decision
The Core-facing embedding question is resolved: only a host-controlled typed channel may select v2
for headerless input, and it must explicitly supply both v2 capability and version: "v2".
Declarations take precedence over external version options. Named embedding-profile registries remain
deferred.
Image resolution and AEON scalar drift are now pinned. Migration and consumer-convention work are published as proposal-stage companion guidance rather than unresolved Core syntax questions.
9. Acceptance Criteria for a First v2 Draft
A first v2 draft can be written when:
The version/header model is decided.
The first promoted syntax slice is chosen.
Compatibility behavior with v1 strict mode is documented.
Canonical output behavior is documented for every promoted construct.
CTS fixtures exist for accepted and rejected cases.
Implementation adapters can run those fixtures without reducing v1 coverage.
Exact standalone/embedded canonical and inert HTML snapshots cover every promoted family.
Source-span and cross-form interaction matrices cover the new v2 node families.
The public API contract types v2 capability, effective version, AST additions, and projection options.
Migration and consumer-convention companion guidance is available.
10. Current Readiness Result
The executable grammar, AST, strict rejection boundary, v1 compatibility, AEON inline-scalar
contract, image-resolution policy, CLI, and playground form a frozen first-draft candidate. The
documented promotion gates are satisfied. Exact standalone/embedded canonical, inert HTML,
source-span, and cross-form interaction snapshots are pinned by machine-readable contract
and-v2-projection-v1. Migration and non-Core ownership are defined by
migration guide and
consumer-conventions boundary.
The track remains proposal-stage until an explicit reviewed lifecycle change promotes the formal documents and CTS metadata together; passing readiness checks does not publish a draft.
Other unpromoted reserved forms, recovery modes, v2-specific editor tooling, automatic numbering, image fetching, and consumer vocabularies remain explicitly deferred and do not block the first draft.