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
`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
was asked to finish: a release is a chain of sessions, so an instruction to work until a release is
done names the chain, not the session. An open PR is a chunk already in flight, and finishing it is
the session.
one chunk, starting from the first item under the earliest release, and stops when that chunk
merges, whatever it was asked to finish: a release is a chain of sessions, so an instruction to
work until a release is done names the chain, not the session. An open PR is a chunk already in
flight, and finishing it is the session.
Per chunk:
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
Application developers embedding the library, in four personas. All four rely on the guarantees below and on `code` being a closed list; none may
rely on an error message's wording, which is free text.
Application developers embedding the library, in four personas. All four rely on the guarantees
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
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;
no I/O, no configuration.
Serves Goals 1, 2 and 7. Pure functions, each taking a whole document and returning a whole
result; no I/O, no configuration. Every conversion goes through ADF, so `markdownToHtml` keeps
exactly what ADF holds.
```ts
adfToMarkdown(doc: AdfDocument): Result<string>
@@ -143,8 +145,8 @@ read replaces mentions, attachments and macros with text.
## The errors
Serves Goal 1. An ADF node type this version does not know is not an error: the lossless pair 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)).
Serves Goal 1. An ADF node type this version does not know is not an error: the lossless pair
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`,
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.
- 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
([`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`
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
@@ -239,8 +241,8 @@ Serves Goals 1, 3 and 4.
## The package
Serves Goal 7. ESM only, no runtime dependencies, public npm. Built JavaScript with `.d.ts` beside it.
Pure ECMAScript at an ES2022 baseline, reaching for no host API; the test suite runs under Node,
Serves Goal 7. ESM only, no runtime dependencies, public npm. Built JavaScript with `.d.ts`
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.
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.
+3 -4
View File
@@ -88,10 +88,9 @@ write `!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
one escape. A node CommonMark can spell takes that spelling, never a directive. Not CommonMark's
generic-directives proposal: its `:::` claims a form prose writes, and its fence-length discipline
ties a container's opener to its own body, where closing from the opener nests by itself and leaf
versus container falls out of the node's content model.
one escape. Not CommonMark's generic-directives proposal: its `:::` claims a form prose writes, and
its fence-length discipline ties a container's opener to its own body, where closing from the
opener nests by itself and leaf versus container falls out of the node's content model.
## 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 { ConvertError, ConvertErrorCode, ConvertErrorPath, ParseError, Result, SourcePosition } from './result.ts'
export type { JsonValue } from './json-value.ts'
+8 -4
View File
@@ -3,10 +3,11 @@
## 0.2.0
- **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
one way — shaped like a directive, a pipe table or a `~~` pair — the flavour claims (Goals 3 and
4). A caller names the markdown it hands in: CommonMark, read as its spec says, or the lossless
flavour, read as `spec/flavour.md` says. Breaking: `MIGRATION.md` says which call a caller takes.
`markdownToAdf` reads CommonMark and the lossless flavour as one input: text shaped like a
directive, a pipe table or a `~~` pair becomes a flavour node where CommonMark reads plain text
(Goals 3 and 4). A caller names the markdown it hands in: CommonMark, read as its spec says, or
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.**
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
@@ -64,6 +65,9 @@
`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
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