Compare commits

2 Commits

Author SHA1 Message Date
lilleman 5c62b07530 Extend the merge grant through 0.2.0 and drop the finished reserved acts
CI / publish (push) Successful in 3s
CI / gate (push) Successful in 17s
2026-09-13 11:43:48 +02:00
lilleman 1e20b0b6cc Tick 3k and milestone 3, moving their text to todo-history.md
CI / gate (push) Successful in 17s
CI / publish (push) Successful in 4s
2026-09-13 11:10:41 +02:00
3 changed files with 39 additions and 41 deletions
+4 -5
View File
@@ -323,17 +323,16 @@ worth deliberating; what matters is that nothing is left undone in the end. Per
gate result (commit and outcome); a reviewer does not re-run `ci.sh` or the tests when a gate result (commit and outcome); a reviewer does not re-run `ci.sh` or the tests when a
result exists for the commit under review, or when the diff since that result cannot affect result exists for the commit under review, or when the diff since that result cannot affect
it (docs-only) — re-run only what its own findings or fixes invalidate. it (docs-only) — re-run only what its own findings or fixes invalidate.
3. Merge the PR (standing authorization, this repo only, granted through the `0.1.0` release — 3. Merge the PR (standing authorization, this repo only, granted through the `0.2.0` release —
PR #3), check the box in `todo.md` and move the item's text to `todo-history.md`, leaving its the maintainer, 2026-09-13), check the box in `todo.md` and move the item's text to
title behind, report, stop. The next chunk gets a fresh session. `todo-history.md`, leaving its title behind, report, stop. The next chunk gets a fresh session.
Ask, don't guess: any choice where what the maintainer would pick is not near-certain gets asked, Ask, don't guess: any choice where what the maintainer would pick is not near-certain gets asked,
and the answer lands as a decision in this file. The confidence bar is very high — asking too and the answer lands as a decision in this file. The confidence bar is very high — asking too
often is the accepted cost, guessing wrong is not. often is the accepted cost, guessing wrong is not.
Reserved for the maintainer, never the agent: changing `version` in `package.json` (a bump on Reserved for the maintainer, never the agent: changing `version` in `package.json` (a bump on
`main` publishes, §9 — every release including `0.1.0` is the maintainer's), making the repo `main` publishes, §9 — every release is the maintainer's) and the `NPM_TOKEN` secret.
public, and creating the `NPM_TOKEN` secret.
A continuous loop session (`/loop`) counts as a chain of sessions: one chunk per iteration, each A continuous loop session (`/loop`) counts as a chain of sessions: one chunk per iteration, each
iteration starting by re-reading `AGENTS.md` and `todo.md` and trusting them over anything iteration starting by re-reading `AGENTS.md` and `todo.md` and trusting them over anything
+33 -3
View File
@@ -154,9 +154,19 @@ The done `todo.md` items in full, as they were written. `todo.md` keeps a one-li
2f raises what 1d's unspelled block separation costs: a single `localId` on a paragraph 2f raises what 1d's unspelled block separation costs: a single `localId` on a paragraph
beside a plain one now refuses every container body that is a directive's — a panel, an beside a plain one now refuses every container body that is a directive's — a panel, an
expand, a table cell — where before 2f the attribute refused the document anyway. expand, a table cell — where before 2f the attribute refused the document anyway.
- [x] **3 — `markdownToAdf` (`0.1.0`).** Each sub-item lands the fixtures its own code reads, and
Under **3 — `markdownToAdf` (`0.1.0`)**: the runner grows a parse half as they do: readers for `corpus/normalization/` (setext,
indented code, loose lists, `*`/`+`
bullets, entity references, soft wraps — one-way, the markdown not canonical) and
`corpus/errors/` (a markdown input per named error, the code in a `.error` beside it) with
the first fixture each. `commonmark-subset/` cannot be the first to green — `::paragraph`
and `:hardBreak{}` sit in it — so 3b through 3f answer to their own tests and the one-way
fixtures they land, and 3g is where the first directory reads back. The raw-HTML element
mapping is empty until milestone 6, so at `0.1.0` every raw-HTML construct in input — a
block, an inline tag, a comment, a processing instruction — is a named error. Input is where
unbounded nesting actually arrives, so §11's 500 binds all three of the emitter's guards
here: block depth at 3c and again at 3f's container fences, inline and mark depth at 3f and
3i, a carried value's JSON at 3j, where `isJsonValue` already bounds it.
- [x] **3a — The hierarchy.** Mechanical, ahead of the first parser file: `src/adf/` and - [x] **3a — The hierarchy.** Mechanical, ahead of the first parser file: `src/adf/` and
`src/markdown/` (`html/` arrives with its first file, 6-7), the grammar module shared `src/markdown/` (`html/` arrives with its first file, 6-7), the grammar module shared
inside `markdown/`, and `emphasis-matching.ts` beside it — the parser reuses it whole, inside `markdown/`, and `emphasis-matching.ts` beside it — the parser reuses it whole,
@@ -386,6 +396,26 @@ Under **3 — `markdownToAdf` (`0.1.0`)**:
`index.ts` gains `markdownToAdf` here, and the README's status line with it: this is the `index.ts` gains `markdownToAdf` here, and the README's status line with it: this is the
last parser chunk, so `parsingDirectories` becomes `emittingDirectories` and the whole last parser chunk, so `parsingDirectories` becomes `emittingDirectories` and the whole
corpus round-trips both ways — `0.1.0`'s proof, which 4 widens rather than replaces. corpus round-trips both ways — `0.1.0`'s proof, which 4 widens rather than replaces.
- [x] **3k — The CommonMark spec suite (`0.2.0`).** Checked in at `corpus/commonmark-spec/`,
pinned to the version it ships — the one `commonmark-grammar.ts` names for its start
conditions — `corpus/README.md` gaining the kind.
**Settled** (the maintainer, 2026-08-27): three checks an example must pass, the reference
HTML each ships read as corpus data — which adds no format and no direction (§1). §2's
canonical fixpoint: a named error, or markdown that parses and emits to itself byte for
byte. That HTML's text, tags stripped and entities decoded, against the parsed document's
concatenated `text`. And a count of the dozen elements the CommonMark subset covers
against the marks and nodes they map to — counting distinct mark types per text node, since
3e collapses a spelling nested inside its own kind and `*(*a*)*` is two `<em>` against one
`em`. The fixpoint alone is self-consistency a parser
returning the empty document passes, and the text alone one dropping every emphasis; the
counts close both. The exception list stays the maintainer's, and one entry is owed
already: 3h continues a list across the marker change CommonMark splits on, so an example
the reference HTML gives two `<ul>` counts one `bulletList`. One outcome is no
exception and must not be filed as one: a fixable §2 hole — valid CommonMark parsing to a
document `adfToMarkdown` refuses — which is what `corpus/unspellable/` held until 3c, 3e
and 3h landed their answers and emptied it. The permanent ones — a link destination or
title no escape spells, a paragraph opening with a code span — are the exceptions, named
by AGENTS.md §2.
- [x] **5a — Rename to `@larvit/adf-codec` (`0.1.0`).** Before the first publish, the name being - [x] **5a — Rename to `@larvit/adf-codec` (`0.1.0`).** Before the first publish, the name being
the published identity: `package.json` `name` and `repository`, the Gitea repo and its the published identity: `package.json` `name` and `repository`, the Gitea repo and its
remote, the README title, §6's published-as line, the checkout directory. remote, the README title, §6's published-as line, the checkout directory.
+2 -33
View File
@@ -29,19 +29,7 @@ The numbering is the order the work was planned in, not the order it ships.
- [x] **2e4 — The carry's fallback triggers.** - [x] **2e4 — The carry's fallback triggers.**
- [x] **2e5 — Combined documents and the collision property.** - [x] **2e5 — Combined documents and the collision property.**
- [x] **2f — The attributes CommonMark cannot hold.** - [x] **2f — The attributes CommonMark cannot hold.**
- [ ] **3 — `markdownToAdf` (`0.1.0`).** Each sub-item lands the fixtures its own code reads, and - [x] **3 — `markdownToAdf`.**
the runner grows a parse half as they do: readers for `corpus/normalization/` (setext,
indented code, loose lists, `*`/`+`
bullets, entity references, soft wraps — one-way, the markdown not canonical) and
`corpus/errors/` (a markdown input per named error, the code in a `.error` beside it) with
the first fixture each. `commonmark-subset/` cannot be the first to green — `::paragraph`
and `:hardBreak{}` sit in it — so 3b through 3f answer to their own tests and the one-way
fixtures they land, and 3g is where the first directory reads back. The raw-HTML element
mapping is empty until milestone 6, so at `0.1.0` every raw-HTML construct in input — a
block, an inline tag, a comment, a processing instruction — is a named error. Input is where
unbounded nesting actually arrives, so §11's 500 binds all three of the emitter's guards
here: block depth at 3c and again at 3f's container fences, inline and mark depth at 3f and
3i, a carried value's JSON at 3j, where `isJsonValue` already bounds it.
- [x] **3a — The hierarchy.** - [x] **3a — The hierarchy.**
- [x] **3b — The leaf blocks.** - [x] **3b — The leaf blocks.**
- [x] **3c — The container blocks.** - [x] **3c — The container blocks.**
@@ -52,26 +40,7 @@ The numbering is the order the work was planned in, not the order it ships.
- [x] **3h — The block nodes.** - [x] **3h — The block nodes.**
- [x] **3i — The inline nodes and the marks.** - [x] **3i — The inline nodes and the marks.**
- [x] **3j — The carry and the combinations.** - [x] **3j — The carry and the combinations.**
- [ ] **3k — The CommonMark spec suite (`0.2.0`).** Checked in at `corpus/commonmark-spec/`, - [x] **3k — The CommonMark spec suite.**
pinned to the version it ships — the one `commonmark-grammar.ts` names for its start
conditions — `corpus/README.md` gaining the kind.
**Settled** (the maintainer, 2026-08-27): three checks an example must pass, the reference
HTML each ships read as corpus data — which adds no format and no direction (§1). §2's
canonical fixpoint: a named error, or markdown that parses and emits to itself byte for
byte. That HTML's text, tags stripped and entities decoded, against the parsed document's
concatenated `text`. And a count of the dozen elements the CommonMark subset covers
against the marks and nodes they map to — counting distinct mark types per text node, since
3e collapses a spelling nested inside its own kind and `*(*a*)*` is two `<em>` against one
`em`. The fixpoint alone is self-consistency a parser
returning the empty document passes, and the text alone one dropping every emphasis; the
counts close both. The exception list stays the maintainer's, and one entry is owed
already: 3h continues a list across the marker change CommonMark splits on, so an example
the reference HTML gives two `<ul>` counts one `bulletList`. One outcome is no
exception and must not be filed as one: a fixable §2 hole — valid CommonMark parsing to a
document `adfToMarkdown` refuses — which is what `corpus/unspellable/` held until 3c, 3e
and 3h landed their answers and emptied it. The permanent ones — a link destination or
title no escape spells, a paragraph opening with a code span — are the exceptions, named
by AGENTS.md §2.
- [ ] **4 — Round-trip property tests (`0.2.0`)**, widening 3j's corpus round-trip past the - [ ] **4 — Round-trip property tests (`0.2.0`)**, widening 3j's corpus round-trip past the
documents a human wrote — the thing that proves 2 and 3 beyond them. Editor-normal (§2) is documents a human wrote — the thing that proves 2 and 3 beyond them. Editor-normal (§2) is
finished here, on 3i's merging — `toEditorNormal(doc)` and the equality the round-trip finished here, on 3i's merging — `toEditorNormal(doc)` and the equality the round-trip