Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
70ddf74
chore: add textrefs/.github as submodule at github-profile/
maehr Jun 7, 2026
5f63ebe
docs: revise get-started prose and document staging deploy flow
maehr Jun 7, 2026
30a12a0
fix(ci): repair URL extraction in link-check workflow
maehr Jun 7, 2026
6dd6e0d
chore(deps): bump astro 6.4.4 and migrate to zod 4
maehr Jun 7, 2026
74bce51
docs(association): sync statutes board size and review tracks with do…
maehr Jun 9, 2026
6b0f0e8
docs(spec): tighten dereferenceable-location guidance to should (#7)
maehr Jun 9, 2026
da48c31
docs(spec): self-contained §13 example with @context (#8)
maehr Jun 9, 2026
56eb064
chore(data): bump submodule with second resolvers on single-resolver …
maehr Jun 9, 2026
e9b09d4
feat(spec)!: replace target_kind with dcterms:conformsTo (#6)
maehr Jun 9, 2026
e54b883
chore(data): bump submodule to registry main (36cae56)
maehr Jun 9, 2026
666dc78
fix(404): mark docs/404.mdx as draft to drop catch-all route conflict
maehr Jun 9, 2026
d3ae0d7
fix(ci): repair link-check workflow + bump deps to zod 4 (#5)
maehr Jun 9, 2026
24b2e36
docs: add ORCID for Luz Christopher Seiberth (#19)
maehr Jun 26, 2026
9c9f2b5
feat(spec)!: seed CanonicalReference UUIDs from the semantic identity…
maehr Jul 5, 2026
82bc899
feat(spec): draft lifecycle with retractable pre-promotion identity (…
maehr Jul 5, 2026
1952650
chore(data): bump submodule to registry main (40af385)
maehr Jul 5, 2026
a765770
feat(spec): require explicit canonical ASCII digit and case forms in …
maehr Jul 5, 2026
37d1481
fix(spec): erratum batch and spec-consistency fixes (#10, #11, #12, #…
maehr Jul 5, 2026
29c15e4
feat(site): flag draft records and exclude them from search indexing …
maehr Jul 5, 2026
59a1c54
chore(deps): astro 6.4.8, dompurify 3.4.11, actions/checkout v7
maehr Jul 5, 2026
3455674
chore(release): v0.1.0 — version bump, changelog, roadmap (#28)
maehr Jul 5, 2026
dd1038d
feat(deps)!: upgrade to Astro 7 / Starlight 0.41, all dependencies to…
maehr Jul 6, 2026
238490e
feat(site)!: minimal static templates for reference pages (#30)
maehr Jul 6, 2026
c4b623a
chore(release): regenerate changelog with Astro 7 and slim ref pages
maehr Jul 6, 2026
3dcff6f
chore(data): bump submodule to registry main (c0a3275, ORCID docs)
maehr Jul 6, 2026
fbe8196
chore(deps): Astro 7.1 + dependency refresh (#39) (#43)
maehr Jul 26, 2026
e68c8f7
fix(spec): resolve normative contradictions before the v0.1.0 tag (#44)
maehr Jul 26, 2026
e0b6ef1
fix(site): add explicit whitespace between inline elements (#53) (#54)
maehr Jul 31, 2026
03cee88
fix(site): list works instead of references on CitationSystem pages (…
maehr Jul 31, 2026
b365cfc
feat(standard)!: collapse record lifecycle to draft → active (ADR-000…
maehr Aug 4, 2026
5c2a6f3
feat(standard)!: preferred citation system and qualified /cite/ alias…
maehr Aug 12, 2026
7a94c0e
feat(standard)!: replace SKOS mapping relations with alternateOf and …
maehr Aug 12, 2026
0e9c824
chore(data): bump registry pin to the ADR-0006 reclassification
maehr Aug 12, 2026
aba818d
feat(compile): map locator variables into a provider's own vocabulary…
maehr Aug 12, 2026
a958928
chore(data): bump registry pin to the resolver review
maehr Aug 12, 2026
d2390c9
chore(deps): refresh all dependencies before v0.1.0 (#73)
maehr Aug 12, 2026
71dd92a
fix: release hardening before v0.1.0 (#46, #47, #49, #50) (#75)
maehr Aug 12, 2026
0df2b27
chore(release): v0.1.0 metadata — CITATION.cff, changelog, checklist …
maehr Aug 12, 2026
fa78eb9
ci: bump actions/setup-node to v7 (#32) (#77)
maehr Aug 12, 2026
37faf37
ci(deps): point Dependabot version updates at staging (#78)
maehr Aug 12, 2026
3f6670e
docs: resolve the consistency audit before v0.1.0 (#79) (#80)
maehr Aug 13, 2026
f5a037f
fix(compile): stop projecting retired mapping assertions onto Work (#…
maehr Aug 24, 2026
a4a3b85
feat(api): add works and systems collection endpoints (#83) (#87)
maehr Aug 24, 2026
8bcfdca
feat(api): resolve a reference by work and locator without its UUID (…
maehr Aug 24, 2026
cd9aae3
feat(standard): name works by abbreviation and translated title (#85)…
maehr Aug 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/conformance_failure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ body:
id: failing-cases
attributes:
label: Failing test cases
description: List the conformance test IDs that fail and what your implementation produces instead.
description: Describe the failing case and what your implementation produces instead. Include conformance test IDs if the conformance suite is available.
validations:
required: true
required: false
- type: textarea
id: analysis
attributes:
Expand Down
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
Re-minting changes a record's IRI. The old IRI must continue to resolve as a tombstone. See the [tombstones section in versioning.md](https://textrefs.org/standard/versioning/#tombstones-and-re-minted-records).

- [ ] Old record retained with `status: withdrawn`
- [ ] A new `MappingAssertion` with `relation: exactMatch`, `subject: <old IRI>`, `target: <new IRI>` links the old record to its successor (omit if there is no successor)
- [ ] The old record's `superseded_by` field (`dcterms:isReplacedBy`) links it to its successor's IRI (omit if there is no successor)
- [ ] All other records that reference the old IRI have been audited (re-targeted to the new IRI, or themselves marked `withdrawn`)
- [ ] Commit message uses `feat!:` / `fix!:` or `feat(scope)!:` / `fix(scope)!:` to signal the breaking IRI change

Expand Down
30 changes: 30 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,40 @@
# Version updates target `staging`, not the default branch.
#
# `main` only moves at release time, by squash-merging `staging`. A bump landed
# on `main` alone is therefore reverted by the next release: the squash applies
# staging's tree against a merge base that predates the bump. Everything that
# should survive a release has to reach `main` through `staging`.
#
# Note that `target-branch` governs version updates only — Dependabot security
# updates are always raised against the default branch, so advisory-driven PRs
# will still appear against `main` and still need folding into `staging` by
# hand.
version: 2
updates:
- package-ecosystem: github-actions
directory: /
target-branch: staging
schedule:
interval: weekly
groups:
github-actions:
patterns:
- '*'

- package-ecosystem: npm
directory: /
target-branch: staging
schedule:
interval: weekly
groups:
# Astro, Starlight and their plugins move in lockstep and are upgraded
# together or not at all; a lone bump here usually fails to resolve.
astro:
patterns:
- 'astro'
- '@astrojs/*'
- 'starlight*'
# First match wins, so this picks up everything else in one PR.
npm:
patterns:
- '*'
11 changes: 9 additions & 2 deletions .github/workflows/links.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'textrefs/textrefs.org'
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
submodules: recursive

Expand All @@ -28,7 +28,14 @@ jobs:
- name: Collect external URLs from sources
run: |
mkdir -p lychee
grep -rhoE 'https?://[^"'\''<>) ]+' data/ src/content/docs/ \
# Allow `)` inside URLs (Wikipedia disambiguation titles), then strip
# a single trailing `)` only when unbalanced (handles markdown
# `[text](url)`). Drop resolver templates containing `{placeholder}`.
# Restrict to YAML/MD so lockfiles inside data/ are not scanned.
grep -rhoE --include='*.yaml' --include='*.yml' --include='*.md' --include='*.mdx' \
'https?://[^]["'\''<>[:space:]]+' data/ src/content/docs/ \
| awk '{ n=gsub(/\(/,"&"); m=gsub(/\)/,"&"); if (m>n) sub(/\)$/,""); print }' \
| grep -v '[{}]' \
| sed -E 's/[.,;:]+$//' \
| sort -u > lychee/urls.txt
echo "Collected $(wc -l < lychee/urls.txt) unique URLs"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
submodules: recursive

- uses: actions/setup-node@v6
- uses: actions/setup-node@v7
with:
node-version: 24
cache: npm
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ jobs:
publish-dump:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
submodules: recursive

- uses: actions/setup-node@v6
- uses: actions/setup-node@v7
with:
node-version: 24
cache: npm
Expand All @@ -34,6 +34,7 @@ jobs:
with:
files: |
dist/dump/*.jsonl
dist/dump/aliases.json
dist/dump/datapackage.json
fail_on_unmatched_files: true
generate_release_notes: true
4 changes: 2 additions & 2 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'textrefs/textrefs.org'
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
submodules: recursive
- name: Verify data/ pin is on registry main
Expand All @@ -25,7 +25,7 @@ jobs:
echo "::error::data/ pointer $(git rev-parse HEAD) is not an ancestor of registry/main"
exit 1
fi
- uses: actions/setup-node@v6
- uses: actions/setup-node@v7
with:
node-version: 24
cache: npm
Expand Down
3 changes: 2 additions & 1 deletion .zenodo.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
},
{
"name": "Seiberth, Luz Christopher",
"affiliation": "TextRefs"
"affiliation": "TextRefs",
"orcid": "0000-0002-5606-0964"
}
],
"keywords": [
Expand Down
13 changes: 7 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ Astro + Starlight site for textrefs.org. See [`README.md`](./README.md) for the
- `npm run build:fast` — site build against a tiny fixture registry, without compiling full data
- `npm run format` — Prettier (with `prettier-plugin-astro`)
- `npm run check` — `astro check`
- `npm run verify:fast` — fast local verification: format:check + fixture-backed check + fixture-backed build
- `npm run verify` — format:check + check + build (the CI gate)
- `npm run verify:fast` — fast local verification: format:check + fixture-backed check + tests + fixture-backed build
- `npm run verify` — format:check + check + tests + build (the CI gate)
- `npm run validate:data` / `compile:data` / `build:data` — registry-data gates; see [`data/AGENTS.md`](./data/AGENTS.md)

Use `npm run verify:fast` by default for local validation and agent work. Only use the full `npm run verify` and/or `npm run validate:data` when changes affect registry data, release artifacts, production build behavior, or CI parity.
Expand All @@ -24,12 +24,13 @@ Husky installs on `npm install`: Prettier runs on staged files, `commitlint` enf
- `src/content/docs/{association,standard,api,community,get-started}/` — site sections (autogenerated sidebar)
- `src/content/docs/de/` — German mirror (see Localization)
- `src/pages/id/{work,system,ref,mapping}/` — canonical record pages (`/id/.../` HTML and `.json` JSON-LD siblings)
- `src/pages/reg/` — registry browser (index + paginated reference lists); does not host individual records
- `src/pages/cite/` — short-alias redirects (`/cite/{work}/{locator}` → canonical `/id/` URL)
- `src/pages/reg/` — registry browser (index + paginated reference lists), the registry-wide JSON-LD collections, and the per-work locator index (`/reg/work/{key}/aliases.json`); does not host individual records
- `src/pages/cite/` — short-alias redirects (`/cite/{work}/{system}/{locator}` always; bare `/cite/{work}/{locator}` for a work's preferred citation system, and retargetable if that preference changes) → canonical `/id/` URL
- `src/styles/brand.css` — brand tokens
- `public/{logo.svg,favicon.svg,fonts/}` — brand assets
- `data/` — git submodule pointing at [`textrefs/registry`](https://github.com/textrefs/registry); hand-authored YAML lives there. See [`data/AGENTS.md`](./data/AGENTS.md) for authoring rules and [`CONTRIBUTING.md`](./CONTRIBUTING.md) for the submodule workflow.
- `standard/`, `api/` — scaffolds reserved for future repo splits
- `standard/` — draft standard workspace: canonical Zod schemas (`standard/schema/`)
- `api/` — the OpenAPI contract (`api/openapi.yaml`)

## Conventions

Expand All @@ -47,7 +48,7 @@ Husky installs on `npm install`: Prettier runs on staged files, `commitlint` enf

## Mirrored community files

`CODE_OF_CONDUCT.md`, `CONTRIBUTING.md`, and `SECURITY.md` live at the repo root (for GitHub's Community profile) and are mirrored at `src/content/docs/community/` with Starlight frontmatter. Edit both in the same commit.
`CODE_OF_CONDUCT.md`, `CONTRIBUTING.md`, and `SECURITY.md` live at the repo root for GitHub's Community profile; `ROADMAP.md` lives there as the canonical roadmap text. All four are mirrored at `src/content/docs/community/` with Starlight frontmatter. Edit both halves of a pair in the same commit.

## Pointers

Expand Down
49 changes: 48 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,51 @@

All notable changes to this project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Changelog tracking begins at `v0.1.0`. Pre-release history lives in the git log.
## [0.1.0] - 2026-08-12

### Added

- Replace target_kind with dcterms:conformsTo (#6)
- Seed CanonicalReference UUIDs from the semantic identity tuple (ADR-0002) (#21)
- Draft lifecycle with retractable pre-promotion identity (ADR-0003) (#23)
- Require explicit canonical ASCII digit and case forms in profiles (#24)
- Flag draft records and exclude them from search indexing (#26)
- Upgrade to Astro 7 / Starlight 0.41, all dependencies to latest (#29)
- Minimal static templates for reference pages (#30)
- Collapse record lifecycle to draft → active (ADR-0004) (#62)
- Preferred citation system and qualified /cite/ aliases (ADR-0005) (#63)
- Replace SKOS mapping relations with alternateOf and isReferencedBy (ADR-0006) (#67)
- Map locator variables into a provider's own vocabulary (#71) (#72)

### Documentation

- Revise get-started prose and document staging deploy flow
- Sync statutes board size and review tracks with dossier
- Tighten dereferenceable-location guidance to should (#7)
- Self-contained §13 example with @context (#8)
- Add ORCID for Luz Christopher Seiberth (#19)

### Fixed

- Repair URL extraction in link-check workflow
- Mark docs/404.mdx as draft to drop catch-all route conflict
- Repair link-check workflow + bump deps to zod 4 (#5)
- Erratum batch and spec-consistency fixes (#10, #11, #12, #14) (#25)
- Resolve normative contradictions before the v0.1.0 tag (#44)
- Add explicit whitespace between inline elements (#53) (#54)
- List works instead of references on CitationSystem pages (#55) (#56)
- Release hardening before v0.1.0 (#46, #47, #49, #50) (#75)

### Misc

- Add textrefs/.github as submodule at github-profile/
- Bump astro 6.4.4 and migrate to zod 4
- Bump submodule with second resolvers on single-resolver works
- Bump submodule to registry main (36cae56)
- Bump submodule to registry main (40af385)
- Astro 6.4.8, dompurify 3.4.11, actions/checkout v7
- Bump submodule to registry main (c0a3275, ORCID docs)
- Astro 7.1 + dependency refresh (#39) (#43)
- Bump registry pin to the ADR-0006 reclassification
- Bump registry pin to the resolver review
- Refresh all dependencies before v0.1.0 (#73)
4 changes: 3 additions & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
cff-version: 1.2.0
message: 'If you cite TextRefs, please cite it as below.'
title: TextRefs
version: 0.1.0
date-released: '2026-08-12'
abstract: An open, persistent, machine-readable registry for canonical text references.
type: software
authors:
Expand All @@ -13,8 +15,8 @@ authors:
- family-names: Seiberth
given-names: Luz Christopher
email: luz@seiberth.de
orcid: 'https://orcid.org/0000-0002-5606-0964'
affiliation: TextRefs
# ORCID: TBD
repository-code: 'https://github.com/textrefs/textrefs.org'
url: 'https://textrefs.org'
license:
Expand Down
49 changes: 32 additions & 17 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,30 @@ A contribution does not create a claim to acceptance, prioritization, publicatio

## Review tracks

Changes are routed to one of two tracks:
Changes are routed to one of three tracks:

- **Technical review** — typos, formatting, broken links, minor metadata, `last_checked` updates, uncontested aliases, build / tooling fixes. Needs automated validation and one technical reviewer.
- **Expert review** — new works, new citation systems, new corpora, contested mappings, changes to deterministic ID inputs, status changes (`active` / `deprecated` / `withdrawn` / `blocked`). Needs technical validation, a documented rationale with sources, and at least one expert reviewer.

The Board reserves decisions on legal or policy-sensitive matters (takedowns, blocking, licence policy).
- **Technical review** — typos, formatting, broken links, minor metadata, `last_checked` updates, uncontested aliases, build / tooling fixes, and merging new registry data as `draft`. Needs automated validation and one technical reviewer.
- **Expert review** — new works, new citation systems, new corpora, contested mappings, changes to deterministic ID inputs, status changes (promotion `draft` → `active`, and `deprecated` / `withdrawn` / `blocked`). Needs technical validation, a documented rationale with sources, and at least one expert reviewer.
- **Board reservation** — takedowns, blocking, licence policy, and other legal or policy-sensitive matters. Decided by the Association Board.

```mermaid
flowchart TD
S["Contribution<br/>(issue or PR)"] --> T{Triage}
T -->|"typos, formatting, links, metadata, tooling"| TR[Technical review]
T -->|"new work / system / corpus, contested mapping, ID inputs, status change"| ER[Expert review]
T -->|"new work / system / corpus, contested mapping, ID inputs, status change / promotion"| ER[Expert review]
T -->|"takedown, blocking, licence / policy"| BR[Board reservation]
TR --> V{"Automated validation<br/>+ 1 technical reviewer"}
ER --> V2{"Validation + rationale and sources<br/>+ 1 expert reviewer"}
V -->|pass| A([Accepted / merged])
V -->|pass| A(["Accepted / merged<br/>(new data lands as draft)"])
V -->|fail| R([Rejected, with reason])
V2 -->|pass| A
V2 -->|fail| R
BR -->|decision| A
BR -->|decision| R
```

New registry records enter at `status: draft` after technical review; they stay retractable until an expert review promotes them to `active`, which permanently freezes their identifier (see the [versioning rules](https://textrefs.org/standard/versioning/) and governance §5).

## Local development

Prerequisites: Node 24 and npm.
Expand All @@ -65,7 +66,7 @@ Registry data lives in [`textrefs/registry`](https://github.com/textrefs/registr
Before pushing routine documentation, styling, or route work, run the fast local gate:

```sh
npm run verify:fast # Prettier check + fixture-backed astro check + fixture-backed build
npm run verify:fast # Prettier check + fixture-backed astro check + tests + fixture-backed build
```

Run the full `npm run verify` before PRs that touch registry data, release output, production build behaviour, or CI behaviour. Run `npm run validate:data` as well for registry-data and standard PRs.
Expand All @@ -91,13 +92,25 @@ The commit-msg hook (commitlint) rejects non-conforming messages, so a plain `gi

The changelog is generated from this history via `npm run changelog` (git-cliff).

## Branching model

The production site (`textrefs.org`) is built and deployed from `main`. To keep `main`'s history low-noise while still allowing many small content edits, day-to-day docs/blog/copy work batches on a long-lived `staging` branch and is squash-merged into `main` to publish.
Comment thread
maehr marked this conversation as resolved.

- `main` — production source. Pushes here auto-deploy via `.github/workflows/pages.yml`. Release tags (`vX.Y.Z`) are cut from `main`; the registry's `vYYYY.MM.N` tags are cut in [`textrefs/registry`](https://github.com/textrefs/registry).
- `staging` — long-lived batching branch for docs, blog posts, copy, registry-pointer bumps, and other content edits. Does **not** auto-deploy. Edits accumulate here as many small commits.
- To publish: open a PR `staging → main` and squash-merge. The squash-commit lands on `main` as one conventional commit (so `git-cliff` stays clean) and triggers the production deploy.
- Manual preview / ad-hoc deploy: from the GitHub Actions UI, run the **Pages** workflow via `workflow_dispatch` and pick `staging` (or any branch) as the ref. This deploys that ref to production until the next push to `main`. There is no separate preview URL — GitHub Pages serves a single site per repo, so manual staging deploys temporarily replace production. Use sparingly.
- Infrastructure changes (CI, release workflow, build tooling, deploy config) target `main` directly so they are not gated on the next staging-to-main snapshot.

Squash merging is the only enabled merge style on the canonical repo, so `staging`'s noisy history is collapsed into a single conventional-commit message on `main` and `git-cliff` still produces a clean `CHANGELOG.md`.

## Submitting a pull request

1. Branch from `main`.
1. Branch from `staging` for content/docs/blog; branch from `main` for infra, CI, or release-workflow changes.
2. Keep PRs focused — one logical change per PR.
3. Link related issues in the PR description.
4. Include local verification results: `npm run verify:fast` for routine work, or `npm run verify` plus `npm run validate:data` for registry-data, standard, release, production-build, or CI changes.
5. Open the PR against `main`. GitHub requests `@textrefs/maintainers` by default via `.github/CODEOWNERS`; maintainers may add technical or expert reviewers based on the track.
5. Open the PR against the branch you started from (`staging` or `main`). GitHub requests `@textrefs/maintainers` by default via `.github/CODEOWNERS`; maintainers may add technical or expert reviewers based on the track.

## Project layout

Expand All @@ -109,13 +122,15 @@ Two release trains. The Zenodo–GitHub webhook MUST be enabled once per reposit

**Standard + site** (this repo):

1. Bump `version` in `package.json` to match the new tag.
2. `npm run changelog` to regenerate `CHANGELOG.md`.
3. Update spec page frontmatter `maturity:` if the release transitions the ladder.
4. Commit, open PR, merge to `main`.
5. Tag `vX.Y.Z[-pre]` on `main`; push the tag.
6. Verify the GitHub Release fires and Zenodo mints the version DOI.
7. Fill the concept DOI into `CITATION.cff` `identifiers:` and the badge in `README.md` (once, after the first release).
1. Bump `version` in `package.json` to match the new tag. The compiler reads it, so it also becomes the `datapackage.json` version of the published dump.
2. Set `version` and `date-released` in `CITATION.cff` to the same tag and its release date. Without them the file cannot say which release it describes.
3. `npx git-cliff --tag vX.Y.Z -o CHANGELOG.md` to regenerate `CHANGELOG.md`. Pass `--tag` explicitly: the tag does not exist yet at this point, and bare `npm run changelog` would file the commits under `## [Unreleased]`.
4. Update spec page frontmatter `maturity:` if the release transitions the ladder.
5. Dispatch the **Pages** workflow on `staging`. `main`'s ruleset requires a successful `github-pages` deployment for the exact SHA being merged, so the release PR stays blocked until the branch tip has one.
6. Open a PR `staging → main` and squash-merge it. The squash message should be a conventional commit (`docs(release): vX.Y.Z` or similar) so the changelog stays clean.
7. Tag `vX.Y.Z[-pre]` on `main`; push the tag.
8. Verify the GitHub Release fires and Zenodo mints the version DOI.
9. Fill the concept DOI into `CITATION.cff` `identifiers:` and the badge in `README.md` (once, after the first release).

**Registry** ([`textrefs/registry`](https://github.com/textrefs/registry)):

Expand Down
Loading
Loading