<!-- Generated from sources/and/v2/and-core-v2-proposal.aeon; do not edit. -->

<a id="nd-core-v2-proposal"></a>
# &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.

<a id="proposal-status"></a>
## 1. Proposal Status

| Field | Value |
| :--- | :--- |
| Stage | Proposal |
| Stability | Frozen proposal baseline |
| Publication status | Not published |
| Relationship to v1 | Compatible extension of the v1 draft |

*V2 proposal status*

<a id="working-goal"></a>
## 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.

<a id="non-goals"></a>
## 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.

<a id="compatibility-stance"></a>
## 4. Compatibility Stance

The frozen proposal follows these rules:

1. Documents accepted by v1 strict mode should be accepted by v2 strict mode.
2. Already-valid v1 syntax should keep the same structural meaning in v2.
3. v2-only syntax should prefer forms that v1 reserves and rejects.
4. v2 should avoid reinterpreting existing valid v1 constructs.
5. 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 |

*Parser compatibility by declared document version*

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:

```js
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.

<a id="candidate-work-areas"></a>
## 5. Frozen Proposal Surface

The current proposal surface is grouped into nine work areas.

<a id="header-and-versioning"></a>
### 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-recognized`
- `seed-v2-header-rejected-by-v1-strict`

<a id="inline-forms-and-local-links"></a>
### 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 |

*Frozen V2 inline forms and local links*

“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-enabled`
- `seed-v2-inline-local-fragment-link-enabled`
- `seed-v2-inline-admonition-tag-enabled`
- `seed-v2-inline-question-tag-enabled`
- `seed-v2-inline-plus-tag-enabled`
- `seed-v2-inline-image-tag-modes`
- `seed-v2-inline-strike-tag-enabled`
- `seed-v2-inline-quoted-tag-enabled`
- `seed-v2-inline-comment-tag-enabled`
- `seed-v2-inline-typed-value-enabled`
- `seed-v2-inline-typed-value-aeon-scalars`
- `seed-v2-inline-highlight-tag-enabled`
- `seed-v2-inline-underline-tag-enabled`
- `seed-v2-inline-line-break-marker-enabled`

<a id="contextual-list-marker-and-footnote-forms"></a>
### 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 |

*Frozen V2 contextual lists, markers, and footnotes*

Executable seeds:

- `seed-v2-todo-list-states`
- `seed-v2-auto-number-list-enabled`
- `seed-v2-inline-directional-markers-enabled`
- `seed-v2-directional-list-markers`
- `seed-v2-heading-auto-number-marker-enabled`
- `seed-v2-footnote-anonymous`
- `seed-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.

<a id="code-block-forms"></a>
### 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:

```text
~~~$
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`

<a id="block-captions"></a>
#### 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`

<a id="table-alignment-and-horizontal-spans"></a>
### 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-spans`
- `seed-v2-table-caption`

<a id="card-blocks"></a>
### 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`

<a id="paired-block-forms"></a>
### 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:

```text
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]
```

```ebnf
v2-id ::= AlphaNumeric V2IdContinue*
AlphaNumeric ::= "A".."Z" | "a".."z" | "0".."9"
V2IdContinue ::= AlphaNumeric | "." | "_" | "-" | ":"
```

*v2 identifier grammar*

This is the same case-sensitive `v2-id` grammar used by anchors and named footnotes.

Executable seeds:

- `seed-v2-block-highlight-paragraph-enabled`
- `seed-v2-block-strong-paragraph-enabled`
- `seed-v2-block-emphasis-paragraph-enabled`
- `seed-v2-block-underline-paragraph-enabled`
- `seed-v2-block-question-paragraph-enabled`
- `seed-v2-block-admonition-paragraph-enabled`
- `seed-v2-block-comment-enabled`
- `seed-v2-block-header-text-enabled`
- `seed-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.

<a id="structural-block-escapes"></a>
### 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.

<a id="compatibility-and-canonicalization"></a>
### 5.9 Compatibility and Canonicalization

V2 defines compatibility and canonicalization as part of the frozen syntax surface.

Executable boundaries:

- `seed-v2-accepts-v1-strict-core`
- `seed-v2-canonical-roundtrip-core-subset`
- `seed-v2-forward-compat-boundary`
- inherited 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_type` failure
- no recovery or forward-compatibility mode is currently defined

The companion [AST contract](./and-core-v2-ast-contract.md#nd-core-v2-ast-contract) defines the promoted
node shapes, effective-version metadata, and canonical emission boundary.

<a id="deferred-ideas"></a>
## 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

<a id="test-strategy"></a>
## 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:

1. The promoted syntax has a written parse shape.
2. The promoted syntax has at least one accepted fixture and one rejected fixture.
3. v1 strict rejection behavior is defined where relevant.
4. Canonical output expectations are documented and reach a parse–emit fixed point.
5. A v2 adapter strategy is written for the CTS runner.

<a id="embedding-decision"></a>
## 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.

<a id="acceptance-criteria-for-a-first-v2-draft"></a>
## 9. Acceptance Criteria for a First v2 Draft

A first v2 draft can be written when:

1. The version/header model is decided.
2. The first promoted syntax slice is chosen.
3. Compatibility behavior with v1 strict mode is documented.
4. Canonical output behavior is documented for every promoted construct.
5. CTS fixtures exist for accepted and rejected cases.
6. Implementation adapters can run those fixtures without reducing v1 coverage.
7. Exact standalone/embedded canonical and inert HTML snapshots cover every promoted family.
8. Source-span and cross-form interaction matrices cover the new v2 node families.
9. The public API contract types v2 capability, effective version, AST additions, and projection options.
10. Migration and consumer-convention companion guidance is available.

<a id="current-readiness-result"></a>
## 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-v1-to-v2-migration.md) and
[consumer-conventions boundary](./and-v2-consumer-conventions.md).

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.

---

## Related documents

- [&ND Core v1 — Normative Specification (Draft)](./and-core-v1-draft.md)
- [&ND Core v2 AST Contract](./and-core-v2-ast-contract.md)
- [&ND Core v2 Consumer-Conventions Boundary](./and-v2-consumer-conventions.md)
- [&ND Core v1 to v2 Migration Guide](./and-v1-to-v2-migration.md)
