Concepts
Git-first
Releaseledger is git-first. Git tags and commit ranges define the shipped change
set. The canonical evidence of what shipped is git rev-list --reverse --topo-order <base>..<head>
โ every commit reachable from the release target and absent from the previous release.
Taskledger, issue trackers, and PR descriptions are optional provenance that enrich curated entries, but releaseledger works correctly with only git.
Source refs
A source ref is a coverage identity. Two kinds are accepted:
Global refs (taskledger, GitHub, etc.):
tl:task-0006,github:pr-42. Canonicalized by ledgercore.Git commit refs:
git:<7-to-40 hex sha>. The primary evidence type for git-first workflows.
A git-range:*, git-tag:*, or git-branch:* ref is a non-coverable
range marker โ useful as release metadata but never creating a missing-coverage row.
Pinned release snapshot
Git-backed releases store both symbolic refs and the resolved commit SHAs. The
resolved SHAs are the immutable snapshot used by default for later git-backed
commands (git range, git scaffold, audit init, review, release check,
strict build coverage). This prevents a moving branch head from silently adding
new commits to an in-progress release.
Resolve HEAD once when attaching the range. A new commit belongs to the
release only after an explicit refresh.
Release
A release is a versioned record stored as release.md with YAML front matter
and an optional Markdown body. It tracks status, previous version, release date,
source boundary, source refs, and changelog file metadata.
Release statuses are:
planneddraftcandidatereleasedyankedcanceled
canceled means the release was never shipped: it is excluded from
previous-version inference and not built into public changelogs by default.
Canceled releases may carry cancel_reason and superseded_by metadata
and remain visible in release list as an audit tombstone.
Version correction is a domain operation across the release identity, bundle,
entry ownership, predecessor links, audit sheet, changelog identity, and
indexes. release rename --dry-run previews those surfaces; changelog mutation
remains explicit with --rename-changelog-section.
Entry
An entry is one release-note item stored under
releases/<version>/entries/entry-NNNN.md. Entries are grouped by kind for
changelog rendering.
Entry kinds are:
addedchangedfixedremoveddeprecatedsecuritydocsqualityinternal
documentation and doc are accepted aliases for docs.
Entry statuses are draft, accepted, and rejected. Changelog builds
include accepted entries by default.
Event
Events are append-only operation rows. They do not store wall-clock timestamps or before/after deltas. Releaseledger relies on git history for chronological review and on per-record revisions for validation.
Commit audit sheet
A commit audit sheet is a per-release review artifact that maps every commit in the selected git range to a reviewer decision and, when applicable, to a release entry. It is evidence state, not changelog prose.
The sheet exists to prevent release notes from being generated from commit subjects. Each row records the commit SHA, inspected paths, reviewer-observed behavior, public/internal impact, decision, and target release entry. Public changelog entries are written from reviewed behavior, API/docs impact, changed paths, tests, and diff evidence. Commit subjects are evidence-only and must not be copied or mechanically transformed into release summaries.
Decisions are needs_review, accepted, grouped, internal, and
rejected. public_impact values are public, docs, internal, none,
and unknown.
Audit validation is phase-aware:
evidencevalidates inspection completeness and row evidence quality without requiring entries.completeadditionally validates accepted entry coverage, internal coverage when requested, and the commit-subject summary guard.
This concept keeps Git as the canonical source of shipped changes while making the human or agent review work durable and auditable.
Coverage and audit accounting
Raw entry coverage records whether an entry directly carries a source ref. The release gate additionally accounts for the audit decision on Git commits:
acceptedandgroupedrequire an accepted public entry.internalis satisfied by complete inspected audit evidence in public mode; with--include-internal, it requires an accepted internal entry.rejectedis satisfied by complete inspected rejection evidence.needs_review, missing rows, and incomplete evidence are unresolved and block.
This separation keeps internal commits from being attached to unrelated public
notes merely to satisfy a counter. Coverage JSON retains the raw status and
adds audit_decision, coverage_requirement, gate_satisfied, and
accounted_as.
Release-check phases
release check --phase current evaluates persisted state with the compatible
default behavior. --phase finalize --released-at DATE asks whether a planned,
draft, or candidate release is ready to transition to released and does not
require a tag. --phase published checks post-release consistency, including a
release date, matching Git tag when Git is active, changelog presence, and clean
reconciliation. Human output renders every gate included in the final result;
JSON exposes stable failed_checks and actionable next_actions.
Versioning
Release and entry files contain versioning.schema_version and a positive
versioning.revision. New records start at revision 1, and the revision
increases by exactly one whenever that record file meaningfully changes.
Planned versus released
A dated planned / draft / candidate release is intentionally treated as a
consistency warning or strict failure in review/check flows, because default
public full builds include only released releases. Finalize a shipped release
explicitly before the final public build.
Index
Releaseledger rebuilds indexes/releases.json and indexes/entries.json
after mutations. Indexes are derived state and should remain deterministic.
Global refs
External provenance is recorded as caller-supplied global refs, for example
tl:task-0103. Releaseledger stores these refs but does not resolve or
validate external ledger state.