Skip to content

chore(release): v0.1.0 — first citable baseline - #4

Open
maehr wants to merge 57 commits into
mainfrom
staging
Open

chore(release): v0.1.0 — first citable baseline#4
maehr wants to merge 57 commits into
mainfrom
staging

Conversation

@maehr

@maehr maehr commented Jun 7, 2026

Copy link
Copy Markdown
Member

Release v0.1.0 — first citable baseline

Publishes stagingmain as v0.1.0 (0.0.1 → 0.1.0: pre-1.0 breaking spec changes). This is the first tagged release; after merge, main is tagged v0.1.0, release.yml builds the dump and creates the GitHub Release, and Zenodo mints the concept DOI. Community announcement with the full story: discussion #31.

Tracked in #68, which carries the merge sequence and the pre-tag checklist.

Not mergeable yet. This PR is stagingmain, so it picks up whatever
staging holds at merge time. Every bullet below has landed; none carries a
pending marker. staging is now 56cab1b (#121, the review follow-ups —
see the section below), and Pages is dispatched on that SHA. One item from
#68 §0 is still outstanding: the association's founding record is not
published. After the founding record lands, dispatch Pages again on the final
staging SHA, then approve and merge.

What it ships

86,397 references across 23 works and 13 citation systems, all at status: draft — 86,477 records in total, plus 172,838 aliases.

That is up from ~39,200 when this PR was opened, in two steps. The resolver review completed the New Testament (John only → 27 books) and the Tanakh (Genesis only → 39 books), taking it to 67,959 across 12 works, so the baseline covers two complete biblical corpora rather than one book of each. The second-wave works (#96) then added Dante's Divina Commedia (14,233 lines, the canonical count), Hume's Treatise and first Enquiry, and eight Nietzsche works — 23 works and 86,397 references.

references.jsonl is 69 MB (72,591,804 bytes) and the alias table is 17 MB (17,521,319 bytes); the built site is 259,811 pages. Both are far inside GitHub's 2 GB asset limit, but neither is a trivial upload — see Verification.

Standard — seven ADRs adopted (decisions/)

Their follow-up checklists were refreshed before the tag (#110): twelve boxes were unchecked for work that had shipped, ADR-0006 still read Proposed although it is implemented, and seven deferred items existed only inside decisions/ — each now carries an issue (#103#109). ADR-0006's last substantive follow-up also landed: specification §10 now states that an isReferencedBy target stays a lookup alias rather than leaving it to a code comment. All eight remaining unchecked boxes carry a tracker.

ADR-0007 is purely additive and re-mints nothing: the field is optional, and no label has ever been an identity input. ADR-0005 and ADR-0006 both re-mint IRIs. Landing them before the first tag costs nothing — every record is draft under ADR-0004 and no identifier has ever been published. After the tag the same change would cost a documented migration against a baseline people may already cite. That timing argument is why they are in v0.1.0 rather than v0.2.0 (#68 §2).

Registry

The data/ submodule is pinned to textrefs/registry@7d10919, carrying:

Compiler and site

API audit follow-ups (#111)

An audit of the live site against the ReSed API-design criteria found ten items (#111). Five
landed on staging on 2026-08-31, in three PRs. Two were published claims the site did not
meet
, which is why they are in this release rather than after it: a tagged baseline should not
name a URL that returns 404.

Four routes are added: /api/openapi.yaml, /dump/, /robots.txt, and
/schemas/v1/textrefs.schema.json. No registry data changes, and no record IRI moves.

The five findings that stay open are tracked in #111: G2 (/cite/ and /find/ absent from the
contract), G6 (no stated HTTP versioning policy), G7 (the no-query-parameter choice is unstated),
G9 (the German hreflang alternate on record pages 404s), and G10 (the production 404 page
carries a draft banner). None is a false published claim, and each needs a decision before code.

Two checks belong after the deploy, because a static host decides them: curl -sI https://textrefs.org/api/openapi.yaml must return 200 with text/yaml — the value the contract
records, confirmed against two live GitHub Pages deployments rather than assumed — and
curl -sI https://textrefs.org/id/work/does-not-exist.json must return 404 with text/html.

Review follow-ups (#120, #121)

A review of this PR found six defects across the finder, the contract, the docs, the build and the
minimal pages. #121 fixed them and landed on staging as
56cab1b, which closes #120. Every finding was reproduced
before it was fixed.

  • /find/ matched a fragment of a name — tier 6 compared the query against one joined string,
    so includes accepted any fragment of any name: ant sits inside Dante, and interpret
    carried that fragment through to locator resolution. The haystack is now a set of normalized
    tokens, and membership is exact.
  • /find/ resolved a typo straight to a passageinterpret treated every tier alike, so a
    single fuzzy hit returned resolvable. The page tells the reader "Nothing is guessed", so that
    claim was false. A fuzzy leading tier now returns work-matches, which already meant "never
    resolved further", and the page renders it as "Did you mean …?". Republik still finds the
    Republic; it asks first.
  • The contract rejected data the site publishesIri declared format: uri, and RFC 3986
    forbids the non-ASCII characters that registered resolver targets carry. iri is a defined
    format in the JSON Schema 2020-12 vocabulary that OpenAPI 3.1 uses, and
    standard/schema/json-schema.ts already applied this exact correction to the generated schema;
    the OpenAPI document was the last place still saying uri. New api/openapi.test.ts validates
    real non-ASCII targets against the parsed contract, because nothing else in the build checked
    data against it.
  • Permanence was promised for draft records — every record in this release is draft, which
    carries no persistence promise under ADR-0004, and the get-started pages promised permanence
    anyway. finding-references.md, how-it-works.md, url-layout.md, get-started/index.md and
    the /reg/ front page now reserve "permanent" for an active record. The normative pages
    already did.
  • /dump/ recomputed the whole dump on every build — see the corrected bullet above. The new
    DUMP_MANIFEST carries the file list with no body, and a test locks it to what dumpResources
    produces, so the page and the descriptor still cannot disagree about which files exist. The
    verify snippet on the same page printed no hash: grep -A2 stops five lines short of the field
    in the descriptor order. It uses jq now.
  • The minimal record pages ran a second visual systemrecord.css invented a palette and
    used system-ui, against AGENTS.md. Colours already flowed through custom properties, so only
    the token block changed. The file is served unbundled from public/ and cannot import
    brand.css, so both files now carry a comment naming the other.

Fuzzy matching is kept, but stripped of authority: a near miss offers, and never applies.
#120 asked whether the tier earns its place; cutting it is a small follow-up. The STE rewrite of
the get-started introduction is the one acceptance criterion #121 does not meet; it is a style
question, not a false published claim, so it is deferred to #122 and does not block the tag. #120
is closed.

Documentation

  • Consistency audit (docs: resolve the consistency audit before v0.1.0 (#79) #80, resolves 40 of the 41 findings in docs: consistency audit — 41 findings across the standard, get-started, and mirrored root docs #79) — every documentation file checked against the schemas, the compiler, the published context, the OpenAPI contract and the compiled registry output. Four findings would otherwise have frozen wrong statements into a citable baseline: §13's flagship Work example was invalid against Work.safeParse for want of preferred_citation_system_key, the OpenAPI document described the advertised <link rel="alternate"> type as application/json where the HTML emits application/ld+json and omitted Work.creators, and §14 required BCP 47 validation that all three schema layers implemented as minLength: 2. That last one is now a shared LanguageTag (RFC 5646 langtag + privateuse), mirrored as an OpenAPI pattern.

    The audit's media-type finding touched only that prose. The response media types stayed application/json, and feat(api): add works and systems collection endpoints (#83) #87 confirmed that this is the correct declaration rather than an oversight: the site is static, so GitHub Pages derives every Content-Type from the file extension and discards the header the Astro APIRoute sets. On the live site /id/work/plato.republic.json returns application/json; charset=utf-8 and /dump/works.jsonl returns application/octet-stream. Declaring application/ld+json would have described a response no client receives. The contract now states the rule and tells clients to parse by documented shape rather than by response header.

  • The published contributing page described the wrong branching model (docs: resolve the consistency audit before v0.1.0 (#79) #80) — it told contributors to branch from and PR against main, and omitted the branching section entirely, while the infrastructure integrates on staging. Fixed in both halves of the mirrored pair, and the release checklist is resynced to the canonical 9 steps.

  • Related standards and systems (docs: resolve the consistency audit before v0.1.0 (#79) #80, closes docs: add more systems like IIIF #81) — the related-systems page framed every neighbouring standard as an identifier scheme. It is now grouped by the layer each system addresses, and adds IIIF Presentation API, W3C Web Annotation, BIBFRAME, IFLA LRM, RAMEN, and URN:NBN — the last of which Appendix B already listed and the page did not.

  • F36 is deliberately not in this release branch yet — the legal-reservation notice missing from the English association pages ships with the statutes batch, alongside the association's founding record.

Release plumbing

Spec version vs tag

The tag is v0.1.0; the specification stays at 0.1.0-draft with maturity: working-draft. These are deliberately different things — ADR-0004 and ADR-0006 both declined a spec bump under the working-draft clause, and 0.x releases stay working-draft by the maturity ladder. All registry data is draft and carries no persistence promise until expert review promotes it.

Verification

maehr and others added 2 commits June 7, 2026 16:05
Rewrite the Get Started body around the single-identity narrative
("a passage has one identity, the editions that carry it are many"),
keeping the Keep reading and Live examples lists as deep-link entry
points.

Document the branching model in CONTRIBUTING.md: main is the
production source and auto-deploys; staging is a long-lived batching
branch for content edits; publish by squash-merging staging into main.
Manual workflow_dispatch from staging is available as an escape-hatch
preview that temporarily replaces production.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 7, 2026 14:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the onboarding and contribution/deploy documentation to support a new long-lived staging branch workflow, while also adding an org-level .github repository as a git submodule.

Changes:

  • Rewrites the Get Started page copy around the “single passage identity, many editions” narrative.
  • Documents a main (production) + staging (batching) branching/publishing model in CONTRIBUTING.md.
  • Adds a github-profile submodule pointing at textrefs/.github.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/content/docs/get-started/index.md Reframes the Get Started explanation and adjusts link placement.
CONTRIBUTING.md Adds branching/deploy workflow guidance for main/staging and PR targeting.
.gitmodules Registers the new github-profile submodule for the org .github repo.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread CONTRIBUTING.md Outdated
Comment thread CONTRIBUTING.md
Fixes #3. Three buckets of false-positive errors:

- grep regex truncated URLs at `)`, mangling Wikipedia disambiguation
  titles. Allow `)` in URLs and strip only unbalanced trailing `)`.
- resolver templates with `{placeholder}` reached lychee verbatim.
  Filter them out.
- `data/package-lock.json` contributed bot-blocked opencollective URLs.
  Restrict grep to YAML/MD and add opencollective to lychee excludes.

Also bump the registry submodule for the Perseus license_url fix, and
mirror that URL change in the how-it-works example.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
maehr and others added 9 commits June 7, 2026 16:29
- npm update: astro 6.4.3 → 6.4.4 (patch)
- zod 3.25.76 → 4.4.3 (was already pulled in by astro/starlight as
  transitive at v4; align top-level so there's one resolved copy)

Zod 4 migration in schema + validator:
- z.string().url() → z.url() (Iri)
- z.ZodIssueCode.custom → 'custom' string literal (superRefine calls)
- validate-data reportIssue path type widened to PropertyKey[] to match
  zod 4's $ZodIssue['path']

GH Actions are already on current majors; no bumps needed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ssier

Vorstand minimum reduced from three to two persons (Statuten Art. 11)
in DE and EN; align contributing guides to frame all three review
tracks (technical, expert, board reservation) as first-class, matching
the governance regulation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
§1 previously said a conforming registry MAY record dereferenceable
locations. A bare identifier with no resolution path is of limited
practical use, so tighten to SHOULD to nudge implementers toward
providing a resolvable URL per reference.

Closes #7.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace §13's compound JSON-shaped wrapper with a single JSON-LD
document under @context + @graph. Each record carries full id, type,
and administrative metadata so a reader can copy the example out and
validate it directly against the published context and Zod schemas.

The CanonicalReference id is the deterministic UUID v5 produced by the
seed for `new-testament / bible-book-chapter-verse / John.3.16 / 1.0.0`,
verified locally against standard/schema/.

Closes #8.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…works

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
target_kind was an OPTIONAL human-readable scheme hint with no
normative weight; maintaining Appendix B's enumerated label list was
upkeep without payoff. Replace it with optional target.conforms_to —
an IRI (or array of IRIs) typed as dcterms:conformsTo in the v1
JSON-LD context — mirroring Linked Art's conforms_to pattern.

Spec, Appendix B, JSON-LD context, Zod schema, compile pipeline,
in-tree fixture, registry detail pages, and get-started prose all
migrated. The Astro mapping/work pages drop the scheme-label badge:
the identifier IRI is authoritative and self-describing.

The data/ submodule pointer moves to the matching textrefs/registry
commit (target_kind→conforms_to in every data/works/*.yaml).

See decisions/ADR-0001 for the rationale and alternatives considered.

BREAKING CHANGE: target.target_kind is removed; downstream consumers
that read it MUST migrate to target.conforms_to. Acceptable pre-v1.0.0.

Closes #6.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
textrefs/registry#1 merged via squash; advance data/ pointer from the
feature branch tip to the merge commit on main so the Validate
workflow's "pin is on registry main" guard passes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Starlight reads docs/404 via getEntry() for its dedicated /404 route
AND enumerates the same entry through the [...slug] catch-all,
producing a benign but noisy build warning ("Could not render /404
from route /[...slug] as it conflicts with higher priority route
/404"). draft: true excludes the entry from the catch-all in
production builds while leaving Starlight's direct-by-id lookup
intact, so dist/404.html still ships our custom hero.

The localised dist/de/404/index.html is dropped (the fallback-route
pass uses the same draft-filtered docs list); Cloudflare Pages serves
/404.html for missing pages across all locales anyway.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(ci): repair URL extraction in link-check workflow

Fixes #3. Three buckets of false-positive errors:

- grep regex truncated URLs at `)`, mangling Wikipedia disambiguation
  titles. Allow `)` in URLs and strip only unbalanced trailing `)`.
- resolver templates with `{placeholder}` reached lychee verbatim.
  Filter them out.
- `data/package-lock.json` contributed bot-blocked opencollective URLs.
  Restrict grep to YAML/MD and add opencollective to lychee excludes.

Also bump the registry submodule for the Perseus license_url fix, and
mirror that URL change in the how-it-works example.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore(deps): bump astro 6.4.4 and migrate to zod 4

- npm update: astro 6.4.3 → 6.4.4 (patch)
- zod 3.25.76 → 4.4.3 (was already pulled in by astro/starlight as
  transitive at v4; align top-level so there's one resolved copy)

Zod 4 migration in schema + validator:
- z.string().url() → z.url() (Iri)
- z.ZodIssueCode.custom → 'custom' string literal (superRefine calls)
- validate-data reportIssue path type widened to PropertyKey[] to match
  zod 4's $ZodIssue['path']

GH Actions are already on current majors; no bumps needed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(association): sync statutes board size and review tracks with dossier

Vorstand minimum reduced from three to two persons (Statuten Art. 11)
in DE and EN; align contributing guides to frame all three review
tracks (technical, expert, board reservation) as first-class, matching
the governance regulation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(spec): tighten dereferenceable-location guidance to should (#7)

§1 previously said a conforming registry MAY record dereferenceable
locations. A bare identifier with no resolution path is of limited
practical use, so tighten to SHOULD to nudge implementers toward
providing a resolvable URL per reference.

Closes #7.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(spec): self-contained §13 example with @context (#8)

Replace §13's compound JSON-shaped wrapper with a single JSON-LD
document under @context + @graph. Each record carries full id, type,
and administrative metadata so a reader can copy the example out and
validate it directly against the published context and Zod schemas.

The CanonicalReference id is the deterministic UUID v5 produced by the
seed for `new-testament / bible-book-chapter-verse / John.3.16 / 1.0.0`,
verified locally against standard/schema/.

Closes #8.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore(data): bump submodule with second resolvers on single-resolver works

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(spec)!: replace target_kind with dcterms:conformsTo (#6)

target_kind was an OPTIONAL human-readable scheme hint with no
normative weight; maintaining Appendix B's enumerated label list was
upkeep without payoff. Replace it with optional target.conforms_to —
an IRI (or array of IRIs) typed as dcterms:conformsTo in the v1
JSON-LD context — mirroring Linked Art's conforms_to pattern.

Spec, Appendix B, JSON-LD context, Zod schema, compile pipeline,
in-tree fixture, registry detail pages, and get-started prose all
migrated. The Astro mapping/work pages drop the scheme-label badge:
the identifier IRI is authoritative and self-describing.

The data/ submodule pointer moves to the matching textrefs/registry
commit (target_kind→conforms_to in every data/works/*.yaml).

See decisions/ADR-0001 for the rationale and alternatives considered.

BREAKING CHANGE: target.target_kind is removed; downstream consumers
that read it MUST migrate to target.conforms_to. Acceptable pre-v1.0.0.

Closes #6.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore(data): bump submodule to registry main (36cae56)

textrefs/registry#1 merged via squash; advance data/ pointer from the
feature branch tip to the merge commit on main so the Validate
workflow's "pin is on registry main" guard passes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(404): mark docs/404.mdx as draft to drop catch-all route conflict

Starlight reads docs/404 via getEntry() for its dedicated /404 route
AND enumerates the same entry through the [...slug] catch-all,
producing a benign but noisy build warning ("Could not render /404
from route /[...slug] as it conflicts with higher priority route
/404"). draft: true excludes the entry from the catch-all in
production builds while leaving Starlight's direct-by-id lookup
intact, so dist/404.html still ships our custom hero.

The localised dist/de/404/index.html is dropped (the fallback-route
pass uses the same draft-filtered docs list); Cloudflare Pages serves
/404.html for missing pages across all locales anyway.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Moritz Mähr <14755525+maehr@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
@maehr maehr changed the title Bootstrap staging branch: revise Get Started + deploy flow Publish staging → main: spec fixes #6/#7/#8, CI/deps, governance, get-started rewrite Jun 9, 2026
@maehr
maehr temporarily deployed to github-pages June 9, 2026 22:15 — with GitHub Actions Inactive
* chore(profile): bump github-profile submodule

Refresh org profile README and add a top-level README in
textrefs/.github.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs: add ORCID for Luz Christopher Seiberth

Record ORCID 0000-0002-5606-0964 for the second author/creator in
CITATION.cff and the project's Zenodo metadata, matching the existing
ORCID entry for the first author. Checksum-verified valid.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Moritz Mähr <14755525+maehr@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@maehr
maehr temporarily deployed to github-pages June 26, 2026 08:26 — with GitHub Actions Inactive
maehr and others added 8 commits July 5, 2026 21:13
… tuple (ADR-0002) (#21)

* feat(spec)!: seed CanonicalReference UUIDs from the semantic identity tuple

Adopt ADR-0002 (fixes #15): reference UUIDs are computable offline from
(work_key, citation_system_key, locator); normalization_version is
removed from the data model entirely. Citation-system profiles now
define canonical locator forms — non-canonical spellings are rejected at
validation time, never folded — and a profile change that alters an
accepted locator is a compatibility event (migration, breaking release,
or new citation_system_key), not a version bump.

- Zod schemas: drop normalization_version (reference + system), drop
  examples, add required CitationSystem.description; drop unused SemVer
- compile/validate: 3-field LF-joined seed on both sides; systems emit
  description instead of normalization_version/examples
- JSON-LD context + OpenAPI: same shape change
  (description = dcterms:description)
- spec docs: identifier-syntax gains a purpose-of-determinism section
  and the canonicalization-change compatibility rule; system-profiles
  gains the canonical-locator-form section (relates to #13)
- doc example UUIDs recomputed for the 3-field seed
- data submodule → textrefs/registry#5 (systems gain description, lose
  normalization_version/examples)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(spec): align conformance item 6 and get-started checklist with examples removal

The CitationSystem contract no longer carries examples.valid/invalid;
conformance now requires description + a valid ECMAScript locator_regex.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore(data): bump submodule to registry review fixes (5337e71)

modified bumped on all systems for the shape change; bible description
aligned with its locator_regex (Copilot review on registry#5).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(spec): align quoted bible description with updated registry text

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Moritz Mähr <14755525+maehr@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…ADR-0003) (#23)

* feat(spec): add draft lifecycle with retractable pre-promotion identity

Adopt ADR-0003 (fixes #22): new draft status is an ephemeral tier below
candidate. The identifier-persistence promise attaches at the promotion
event (draft -> candidate, expert review), not at publication. Draft
records may be corrected (identity change mints a different id) or
retracted (deleted, no tombstone); a re-proposed tuple regains the same
UUID by construction. All records keep deterministic v5 ids at every
stage - governance §6.3/6.4 no longer prescribes generated ids for
provisional objects.

- specification §11/§12: promotion semantics + draft status definition
- identifier-syntax: immutability scoped to candidate-or-higher
- versioning: ladder, draft-retraction section, promoted-must-not-cite-
  draft invariant (enforcement is an ADR follow-up)
- governance EN/DE §4-§6: entry via technical review, promotion via
  expert review, tombstones scoped to promoted records
- CONTRIBUTING: review tracks + flowchart
- Status enum: draft added (Zod + OpenAPI)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore(data): bump submodule to draft-demoted registry (3f6c9f2)

All records enter the ADR-0003 ladder at draft; see textrefs/registry#7.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Moritz Mähr <14755525+maehr@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
All records demoted to draft per ADR-0003 (textrefs/registry#7); pin
returns to a registry main ancestor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…profiles (#24)

Fixes the spec side of #13: system profiles MUST state their
leading-zero policy (default forbidden) and canonical letter case
(default case-sensitive declared casing). Seed-profile examples and the
worked example follow the registry: Bekker pages from 1 without leading
zeros, Stephanus likewise, Bible vocabulary pinned to case-sensitive
OSIS book abbreviations. Submodule bumped to registry main d31ed0b
(registry#8).

Co-authored-by: Moritz Mähr <14755525+maehr@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…) (#25)

- #14: RFC 9562 replaces obsoleted RFC 4122; JSON-LD siblings advertised
  and served as application/ld+json; alias mechanism described without
  the undefined aliases.json filename; undefined tombstone rationale
  fields dropped; UUID namespace derivation notes clarify NAMESPACE_DNS
  is an opaque salt.
- #10 (option B): succession is provenance, not equivalence — tombstoned
  records carry superseded_by (dcterms:isReplacedBy); MappingAssertion
  stays reserved for work-level equivalence with a Work-IRI subject. New
  compiler invariant: superseded_by only on withdrawn/blocked records.
- #11: published Work records now carry direct exactMatch/closeMatch
  arrays derived from accepted mappings, so skos:exactMatch/closeMatch
  edges exist in the JSON-LD graph alongside the reified assertions.
- #12 (option 1): authored SPDX ids are emitted as canonical SPDX IRIs
  (https://spdx.org/licenses/{id}); dcterms:license is now IRI-typed for
  both license and license_url. Non-SPDX values are omitted with a
  compile warning (registry data already cleaned in registry#9).
- data/ submodule -> registry main 2c548b3 (SPDX license cleanup).

Co-authored-by: Moritz Mähr <14755525+maehr@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…26)

ADR-0003 render follow-up: /id/ record pages show a draft notice and
emit robots noindex while status is draft; /reg/ listing pages inherit
the flag from their work/system. The tombstone banner now follows the
superseded_by successor link (was: exactMatch mapping prose) and covers
blocked records.

Co-authored-by: Moritz Mähr <14755525+maehr@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Catches staging up with dependabot PRs #16/#17/#18, which target main
and will close automatically at release.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Moritz Mähr <14755525+maehr@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@maehr maehr changed the title Publish staging → main: spec fixes #6/#7/#8, CI/deps, governance, get-started rewrite Release v0.1.0: ADR-0002/0003, all data draft, spec fixes #6–#15, canonical ASCII forms Jul 5, 2026
maehr added 3 commits August 31, 2026 16:32
…112) (#117)

Two findings from the API audit (#111).

#113 (G3): the shared `NotFound` response declared `application/json` against
the `Error` schema, but a static host serves the site's HTML 404 page. All 12
record paths reach that response through `$ref`, so one edit corrects them.
`Error` and `RegistryObject` stay, each with a comment that says why it is
published without a reference.

#112 (G1): the site advertised `/api/openapi.yaml`, which returned 404. A
static endpoint now serves the file. `?raw` inlines the source at build time,
so the body is byte-identical and cannot drift. GitHub Pages sends `text/yaml`
for the extension, which the contract now records.

Closes #113
Closes #112
Two findings from the API audit (#111), both about bulk access.

#116 (G8): `/dump/` returned 404, so `/dump/datapackage.json` could not be
guessed. The index lists all six artifacts with the size and sha256 hash of
each, and says what each holds and how to parse it. `astro build` runs before
`scripts/compile.ts`, so the page cannot read the descriptor from `dist/`; it
calls the same pure functions the compiler calls, over the same registry, so
the table and `datapackage.json` cannot drift. The sidebar gains a Bulk
downloads entry.

#114 (G4): `/robots.txt` returned 404. It now names the sitemap and points a
bulk consumer at `/dump/`. Nothing is disallowed: draft record pages already
carry `noindex` and stay out of the sitemap. An endpoint rather than a static
file, so the `Sitemap:` line follows `SITE_DOMAIN`. The `Bulk` tag in the
contract states the hosting limits.

Closes #116
Closes #114
…) (#118)

Finding G5 from the API audit (#111).

`specification.md` §14 stated that a normative JSON Schema is published at
`/schemas/v1/textrefs.schema.json`, and the URL returned 404. The document is
now generated from the canonical Zod schemas with `z.toJSONSchema()` on every
build. The four record types sit in `$defs`, and the document is their union,
discriminated by the `type` const.

Three corrections to the raw Zod output, each documented in the generator:
`additionalProperties: false` is dropped, because a served body carries a
JSON-LD `@context` and §15 allows extensions; `format: "iri"` replaces `"uri"`,
because RFC 3986 rejects the non-ASCII resolver targets that 1219 references
carry; and `alternative_labels` keeps its §6 `uniqueItems` rule, with the
cross-field half of that rule stated in the field description.

All 86477 records of the current registry validate against the document.
`ROADMAP.md` and its site mirror move the item to done.

Closes #115
Closes #120.

- fix(find): match whole tokens, and ask instead of guessing
- fix(api): declare Iri as an IRI, and test the contract
- docs(get-started): reserve "permanent" for active records
- perf(dump): serialize and hash the dump once per build
- fix(brand): use the brand tokens and Inter on minimal pages
- docs: qualify persistence with `active` on the last three pages
- docs(dump): print the hash with jq, not grep
maehr and others added 3 commits September 2, 2026 19:42
Clear the form-data advisory with an override.

Refresh every compatible dependency before the first tag.

Upgrade Astro to 7.2.10 and Starlight to 0.42.0 with current plugins.

Refresh all in-range transitive dependencies.

Keep TypeScript 6.0.3 because @astrojs/check does not accept TypeScript 7.

All Actions already use current major pins, so workflows need no edits.

Verified under Node 24 with npm audit, 118 tests, links, full build, and registry dump.

Co-authored-by: Moritz Mähr <14755525+maehr@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Every 404 page showed a yellow aside that read "This content is a draft and
will not be included in production builds". The page is in production, so the
statement contradicted itself.

`src/content/docs/404.mdx` carries `draft: true`, and Starlight renders
`DraftContentNotice` from that flag. The production filter that drops a draft
page never applies to the 404 route, so the page shipped and kept the banner.

Keep the flag and override the component instead. The flag is load-bearing: the
sitemap, the Pagefind index, and the `llms*.txt` corpus all exclude the page by
reading `data.draft`, not by matching the route. Removing it would have added
the page to the sitemap as `/de/404/` and to both `llms-full.txt` and
`llms-small.txt`. The `exclude` option of `starlight-llms-txt` does not cover
that, because only `llms-small.txt` passes it to the generator.

The override suppresses the notice for the `404` entry alone. Every other draft
page keeps it.

Verified against a fixture build: the banner is gone, the hero content is
intact, the page carries no `data-pagefind-body`, and `dist/llms-full.txt` and
`dist/sitemap-0.xml` are byte-identical to the build without this change.

Addresses finding G10 of #111. The other open findings there (G2, G6, G7, G9)
are unaffected.


Claude-Session: https://claude.ai/code/session_01NGYwkXwkDwd2a3b7B4CJDK

Co-authored-by: Moritz Mähr <14755525+maehr@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…mbers to expense reimbursement (#123) (#124)

* docs(association): limit Board members to expense reimbursement (#123)

The Cantonal Tax Office of Zürich objected that Art. 15 was broader than
the governance model presented in the tax-exemption application. Amend
Art. 15 so that Board members serve in an honorary capacity, claim only
effective expenses and cash outlays, and receive no compensation for
special or operational services.

Art. 20 requires that regulations do not contradict the statutes.
Therefore align the expense regulation and the governance regulation in
both languages with the amended article.

Closes #123

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JjkvMC8utk7nEWYNGe4azL

* docs(association): date the working versions to the signing day

The founding documents are signed on 2 September 2026. Move the
Arbeitsfassung date in the three German documents to that date.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JjkvMC8utk7nEWYNGe4azL

* docs(association): publish the founding documents as final, not drafts

The founding documents are signed on 2 September 2026. Remove the
Arbeitsentwurf aside from the four German documents, because the texts
are no longer working versions under legal reservation.

Set the adoption date and the place-and-date line in Art. 22 of the
statutes, and name the president above the signature line. ZGB Art. 60
requires the statutes in written form, and the cantonal tax office asked
for the signed statutes.

Drop "in Gründung befindlich" and "in formation" from the association
index and the mission, in both languages.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JjkvMC8utk7nEWYNGe4azL

* docs(association): name both signatories in Art. 22

Name the president and the recording officer above the signature lines
of the statutes, in both languages. The cantonal tax office asked for
the signed statutes and the signed founding minutes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JjkvMC8utk7nEWYNGe4azL

* docs(association): state the assured tax exemption

The Cantonal Tax Office of Zürich assured the association of tax
exemption on 27 August 2026. State the assurance and its condition on
both association index pages.

Keep the note that donations become deductible only after the legally
binding decision. An assurance is not a rechtskräftige Verfügung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JjkvMC8utk7nEWYNGe4azL

* docs(association): record the founding and the submission as done

The founding assembly meets on 2 September 2026, and the association
submits the signed statutes and the founding minutes on the same day.
State both in the simple past on the two index pages.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JjkvMC8utk7nEWYNGe4azL

---------

Co-authored-by: Moritz Mähr <14755525+maehr@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants