record ADR-0033: series membership is structural

Answers the question that blocked sequences. A chapter belongs to the series it
is nested under, so the engine reads no `series` field; `order` stays, optional,
and a member without one sorts by name after every member carrying one.

This supersedes ADR-0016's membership clause and keeps its position rules — the
point of that ADR was that position never reaches a URL, which still holds. The
directory already states membership unambiguously; a second statement in
frontmatter can only agree or be a typo that silently orphans a chapter.

Cost, stated in the ADR: a series can never span directories, and membership now
rides on the bundle key, which ADR-0008 makes permanent.
This commit is contained in:
2026-07-30 03:03:06 +06:00
parent 5ecb5684e0
commit 5e7a70a747
2 changed files with 47 additions and 13 deletions
+19 -1
View File
@@ -161,7 +161,7 @@ boundary must route through the normaliser rather than accepting a raw string.
Revisit if: never for normalisation. Slug derivation rules change with the default locale.
## ADR-0016 — Sequence position is metadata and never appears in a URL
Date: 2026-07-28 · Status: accepted
Date: 2026-07-28 · Status: accepted; its membership clause is superseded by ADR-0033 (position rules stand)
Decision: a bundle's slug is its name, never its position — `comics/the-long-monsoon/the-flood/`, not
`.../02-the-flood/`. Position comes from a single declared source per type (`order` in the type
declaration: date, sequence, or manual), sparse by convention (10, 20, 30) so inserting between two
@@ -384,3 +384,21 @@ caller is what earned `Query.Tag` rather than a guess. Expensive — tag hygiene
since nothing scopes terms, so `check` owes a near-duplicate report; and `tags` is now reserved at the top
level and inside every section.
Revisit if: the pool becomes unusable in practice — and then the answer is curation, not namespacing.
## ADR-0033 — Series membership is structural; `order` is optional
Date: 2026-07-30 · Status: accepted (supersedes ADR-0016's membership clause, not its position rules)
Decision: a bundle is a member of a series because it is nested under the series' landing bundle —
`comics/the-long-monsoon/first-rain` under `comics/the-long-monsoon` — so the engine reads no `series`
field. Reading order is `order` ascending where it is set, then by key; a member without `order` sorts
after every member that has one. A bundle with bundles nested under it is a series landing page, and one
nested inside another series reports its own members rather than its siblings.
Why: the directory already states membership unambiguously, and a second statement of it in frontmatter
can only agree or be a bug — a typo in `series` silently orphans a chapter, which is precisely the class
of error a single source of truth removes. Making `order` optional keeps the cheap case cheap: a series
whose filenames already sort correctly needs no frontmatter at all, and `order` is for when they do not.
Consequence: cheap — nothing to declare, nothing to keep in sync, and moving a series moves its
membership with it. Expensive — a series can never span directories, so a cross-directory collection
needs a Query over some other field, not this; and membership now depends on the bundle key, which
ADR-0008 makes permanent, so re-parenting a chapter is a permalink event with an alias.
Revisit if: a real collection must span sections. Then it is a declared taxonomy (ADR-0032's second
half), not a change to how a series is joined.