Goals become one-line aims, their detail moves to the sections that meet them #152

Merged
lilleman merged 7 commits from goals-slogans into main 2026-10-02 21:58:15 +02:00
5 changed files with 29 additions and 24 deletions
Showing only changes of commit cd2b573372 - Show all commits
+4 -4
View File
@@ -131,10 +131,10 @@ One-line commit messages and PR titles; short PR summaries. No AI-attribution ma
## 7. The working loop ## 7. The working loop
`todo.md` lists what is left under the release that ships it, in shipping order. A session works `todo.md` lists what is left under the release that ships it, in shipping order. A session works
one chunk, starting from the first item under the earliest release, and stops there whatever it one chunk, starting from the first item under the earliest release, and stops when that chunk
was asked to finish: a release is a chain of sessions, so an instruction to work until a release is merges, whatever it was asked to finish: a release is a chain of sessions, so an instruction to
done names the chain, not the session. An open PR is a chunk already in flight, and finishing it is work until a release is done names the chain, not the session. An open PR is a chunk already in
the session. flight, and finishing it is the session.
Per chunk: Per chunk:
1. Fresh worktree off updated `origin/main`; implement tests-first (§3). 1. Fresh worktree off updated `origin/main`; implement tests-first (§3).
+13 -11
View File
@@ -37,8 +37,9 @@ The most useful ADF conversion library available, by these goals in priority ord
## Audience ## Audience
Application developers embedding the library, in four personas. All four rely on the guarantees below and on `code` being a closed list; none may Application developers embedding the library, in four personas. All four rely on the guarantees
rely on an error message's wording, which is free text. below and on `code` being a closed list; none may rely on an error message's wording, which is
free text.
- **Viewer/editor app** — shows a document, lets a human edit, posts it back. Relies on the - **Viewer/editor app** — shows a document, lets a human edit, posts it back. Relies on the
round-trip holding for whatever the site's editor wrote, unknown node types included, and on a round-trip holding for whatever the site's editor wrote, unknown node types included, and on a
@@ -68,8 +69,9 @@ if (result.ok) {
} }
``` ```
Serves Goals 1 and 7. Pure functions, each taking a whole document and returning a whole result; Serves Goals 1, 2 and 7. Pure functions, each taking a whole document and returning a whole
no I/O, no configuration. result; no I/O, no configuration. Every conversion goes through ADF, so `markdownToHtml` keeps
exactly what ADF holds.
```ts ```ts
adfToMarkdown(doc: AdfDocument): Result<string> adfToMarkdown(doc: AdfDocument): Result<string>
@@ -143,8 +145,8 @@ read replaces mentions, attachments and macros with text.
## The errors ## The errors
Serves Goal 1. An ADF node type this version does not know is not an error: the lossless pair carries it opaquely Serves Goal 1. An ADF node type this version does not know is not an error: the lossless pair
and restores it unchanged ([`docs/decisions.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/docs/decisions.md#unknown-nodes-ride-the-carry)). carries it opaquely and restores it unchanged ([`docs/decisions.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/docs/decisions.md#unknown-nodes-ride-the-carry)).
`ConvertError` is `{ code, message, path, position? }`. `code` is the exported `ConvertErrorCode`, `ConvertError` is `{ code, message, path, position? }`. `code` is the exported `ConvertErrorCode`,
stable across minors and safe to `switch` on exhaustively with no `default`; `message` is free text stable across minors and safe to `switch` on exhaustively with no `default`; `message` is free text
@@ -197,11 +199,11 @@ emit refuses:
Serves Goals 1, 3 and 4. Serves Goals 1, 3 and 4.
- Markdown means what the CommonMark spec says, and well-formed HTML what the HTML standard
parses, both in what this library reads and in what a conforming parser reads from what it
writes; the bullets below name every exception.
- `markdownToAdf(adfToMarkdown(doc))` equals `doc` — unknown node types included, carried opaquely - `markdownToAdf(adfToMarkdown(doc))` equals `doc` — unknown node types included, carried opaquely
([`docs/decisions.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/docs/decisions.md#unknown-nodes-ride-the-carry)). ([`docs/decisions.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/docs/decisions.md#unknown-nodes-ride-the-carry)).
- Markdown means what the CommonMark spec says — and, at `0.2.0`, well-formed HTML what the HTML
standard parses — both in what this library reads and in what a conforming parser reads back
from its output; the bullets below name every exception.
- Plain CommonMark is valid input to `markdownToAdf` apart from the raw HTML `unmappable-html` - Plain CommonMark is valid input to `markdownToAdf` apart from the raw HTML `unmappable-html`
names, with three carve-outs — literal text matching directive, pipe-table or strikethrough names, with three carve-outs — literal text matching directive, pipe-table or strikethrough
syntax is claimed (escapable — `spec/flavour.md`) — and one gap: a CommonMark image fits only as syntax is claimed (escapable — `spec/flavour.md`) — and one gap: a CommonMark image fits only as
@@ -239,8 +241,8 @@ Serves Goals 1, 3 and 4.
## The package ## The package
Serves Goal 7. ESM only, no runtime dependencies, public npm. Built JavaScript with `.d.ts` beside it. Serves Goal 7. ESM only, no runtime dependencies, public npm. Built JavaScript with `.d.ts`
Pure ECMAScript at an ES2022 baseline, reaching for no host API; the test suite runs under Node, beside it. Pure ECMAScript at an ES2022 baseline, reaching for no host API; the test suite runs under Node,
Deno and Bun, and a headless Firefox converts the corpus through the built entrypoint. Deno and Bun, and a headless Firefox converts the corpus through the built entrypoint.
Contract: [`docs/decisions.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/docs/decisions.md#any-es2022-engine), §Any Contract: [`docs/decisions.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/docs/decisions.md#any-es2022-engine), §Any
ES2022 engine to §Public on npm. ES2022 engine to §Public on npm.
+3 -4
View File
@@ -88,10 +88,9 @@ write `!adf:`.
Directives are one grammar for everything markdown lacks, namespaced under `!adf:`: Directives are one grammar for everything markdown lacks, namespaced under `!adf:`:
`!adf:panel info` … `!adf:/panel` blocks, `!adf:mention[@Mikael]{id=5b10a2}` inline, `\!adf:` the `!adf:panel info` … `!adf:/panel` blocks, `!adf:mention[@Mikael]{id=5b10a2}` inline, `\!adf:` the
one escape. A node CommonMark can spell takes that spelling, never a directive. Not CommonMark's one escape. Not CommonMark's generic-directives proposal: its `:::` claims a form prose writes, and
generic-directives proposal: its `:::` claims a form prose writes, and its fence-length discipline its fence-length discipline ties a container's opener to its own body, where closing from the
ties a container's opener to its own body, where closing from the opener nests by itself and leaf opener nests by itself and leaf versus container falls out of the node's content model.
versus container falls out of the node's content model.
## CommonMark is a subset ## CommonMark is a subset
+1 -1
View File
@@ -1,4 +1,4 @@
// Export only the conversions, their types, isAdfDocument and what checking a README guarantee needs. // Export only the conversions, their types, isAdfDocument and what a README guarantee or a persona needs.
export type { AdfAttributes, AdfDocument, AdfMark, AdfNode } from './adf/document.ts' export type { AdfAttributes, AdfDocument, AdfMark, AdfNode } from './adf/document.ts'
export type { ConvertError, ConvertErrorCode, ConvertErrorPath, ParseError, Result, SourcePosition } from './result.ts' export type { ConvertError, ConvertErrorCode, ConvertErrorPath, ParseError, Result, SourcePosition } from './result.ts'
export type { JsonValue } from './json-value.ts' export type { JsonValue } from './json-value.ts'
+8 -4
View File
@@ -3,10 +3,11 @@
## 0.2.0 ## 0.2.0
- **43 — Give each markdown input its own reader, strict to its own standard.** Today - **43 — Give each markdown input its own reader, strict to its own standard.** Today
`markdownToAdf` reads CommonMark and the lossless flavour as one input, so text CommonMark reads `markdownToAdf` reads CommonMark and the lossless flavour as one input: text shaped like a
one way — shaped like a directive, a pipe table or a `~~` pair — the flavour claims (Goals 3 and directive, a pipe table or a `~~` pair becomes a flavour node where CommonMark reads plain text
4). A caller names the markdown it hands in: CommonMark, read as its spec says, or the lossless (Goals 3 and 4). A caller names the markdown it hands in: CommonMark, read as its spec says, or
flavour, read as `spec/flavour.md` says. Breaking: `MIGRATION.md` says which call a caller takes. the lossless flavour, read as `spec/flavour.md` says. Breaking: `MIGRATION.md` says which call a
caller takes.
- **40 — Make `markdownToAdf(adfToMarkdown(doc))` deep-equal `doc` for every document it takes.** - **40 — Make `markdownToAdf(adfToMarkdown(doc))` deep-equal `doc` for every document it takes.**
Today it holds for editor-normal documents only: two adjacent text nodes with the same marks Today it holds for editor-normal documents only: two adjacent text nodes with the same marks
merge, an empty `attrs`, `marks` or `content` drops, and `-0` reads back `0` — shapes pipelines merge, an empty `attrs`, `marks` or `content` drops, and `-0` reads back `0` — shapes pipelines
@@ -64,6 +65,9 @@
`description` naming both, the lossy pair, and the flavours it writes and reads by name — GitHub `description` naming both, the lossy pair, and the flavours it writes and reads by name — GitHub
Flavored Markdown's alerts and task lists, Obsidian Flavored Markdown's callouts — so a search for Flavored Markdown's alerts and task lists, Obsidian Flavored Markdown's callouts — so a search for
either finds the package. either finds the package.
- **44 — Delete `AGENTS.md` §7's empty-release bullet, leaving the maintainer's global working loop
to rule it.** "An earliest release with no items left and nothing shipped toward it is planned as
the chunk" restates that loop, in a sentence its own prose rules ban.
## 0.3.0 ## 0.3.0