rlsbl v0.113.0 /rlsbl.changelog.schema
On this page

JSONL changelog entry schema with dataclass definition, JSON parsing, serialization, field validation, type coercion, and entry ID generation.

#rlsbl.changelog.schema

#rlsbl.changelog.schema

JSONL changelog entry schema with dataclass definition, JSON parsing, serialization, field validation, type coercion, and entry ID generation.

The strictspec-generated validator (rlsbl/strictspec_gen/changelog_entry_commit_validator.py) is the DOCUMENT authority for one JSONL line: the per-line format_version gate and the field/enum/conditional-required shape. This module routes shape validation through it and keeps only what strictspec cannot see (hash resolution, tag ranges, coverage vs git, batch limits, cross-file rules) native -- those live in validate.py and files.py.

Transition contract (see docs/changelog.md): every line rlsbl WRITES carries format_version = 1. Reading is EXPLICIT two-mode -- a line carrying format_version is validated via strictspec; a line lacking it is legacy and accepted ONLY when the caller opts into legacy mode (enforce_format_version=False, the transition default). With enforce_format_version=True a missing gate is a hard error. The absence is never silent: a warn-level check surfaces "enforcement not yet enabled" until a repo records its changelog_format_version_enforced decision in its config.

#generate_entry_id

python
def generate_entry_id() -> str

Generate a unique entry ID.

Uses a timestamp-prefixed UUID4 hex for approximate lexicographic sortability without adding external dependencies. Format: <timestamp_hex><uuid4_hex> (48 chars total: 16 timestamp + 32 uuid).

#ChangelogEntry

One line in a .jsonl changelog file.

#_native_message

python
def _native_message(diag, entry: ChangelogEntry) -> str

Render one strictspec diagnostic as an rlsbl-native schema error string.

strictspec is the shape engine; this is a thin presentation adapter that preserves the historical rlsbl wording (which the check layer and tests read) without a second validation implementation.

#validate_schema

python
def validate_schema(entry: ChangelogEntry) -> list[str]

Return a list of schema errors for the entry. Empty list means valid.

commits is required and id is optional. The entry is serialized (stamping format_version = CURRENT_FORMAT_VERSION) and validated through the strictspec-generated validator -- the single shape engine. Diagnostics are rendered back into rlsbl's native wording by :func:_native_message.

#_gate_line

python
def _gate_line(line: str) -> None

Run the strictspec per-line format_version gate on a raw JSONL line.

Uses the validator's compiled program, but checks only the gate, never entry shape. Raises ChangelogError when format_version is present but not accepted (e.g. a future/wrong value). A line with NO format_version passes here silently -- the legacy/enforced decision is the caller's (see :func:parse_entry).

#parse_entry

python
def parse_entry(line: str, *, enforce_format_version: bool=False) -> ChangelogEntry

Parse one JSON line into a ChangelogEntry.

The per-line format_version gate is routed through strictspec:

  • a line carrying format_version is validated via strictspec (a wrong or

unsupported version is a hard error);

  • a line lacking format_version is LEGACY. It is accepted only when

enforce_format_version is False (the transition default). With enforce_format_version=True a missing gate is a hard error telling the operator to stamp the line, re-add the entry, or record a deliberate legacy-mode decision in .rlsbl/config.json.

Raises ChangelogError on malformed JSON or missing required fields. Historical entries without id load fine (id is optional on read). Entries without commits load with an empty commits list; the changelog-schema check is what rejects them.

#serialize_entry

python
def serialize_entry(entry: ChangelogEntry) -> str

Serialize a ChangelogEntry to one JSON line (no trailing newline).

Every line is stamped with format_version = CURRENT_FORMAT_VERSION as the leading key (the per-line gate). Only includes non-None optional fields to keep lines compact. Omits commits when the list is empty.

#parse_jsonl

python
def parse_jsonl(path: str, *, enforce_format_version: bool=False) -> list[ChangelogEntry]

Read a .jsonl file and return a list of ChangelogEntry objects.

Raises ChangelogError with line number on malformed JSON. When enforce_format_version is True, a line lacking format_version is a hard error (the caller threads this from the project's changelog_format_version_enforced config -- see :func:rlsbl.changelog.files.read_changelog_format_version_enforced).

Search