On this page
The command behind rlsbl transition record: which two kinds it writes, which record file it appends to, and the duplicate-declaration refusal it answers with.
#rlsbl.commands.transition_record_cmd
#rlsbl.commands.transition_record_cmd
rlsbl transition record: the typed door onto the operator-declared facts.
Most transition record events are written by the surgery that produced them -- an extract writes its conversion, a rewrite writes its commit remap, a rename writes its boundary alias. The kinds below are the ones an operator can declare instead: two that no command writes at all, because they are not things a command DID, and one whose command exists but which a hand-performed rename leaves with nothing to have recorded it.
non-version-tag This tag stands outside the version model on purpose -- a nightly marker, an upstream vendor tag imported with a history. Nothing can derive that; a human decides it, and the readers of the tag namespace (:mod:rlsbl.tag_explanation, hence rlsbl release backfill and rlsbl release reconcile) then stop reporting it forever.
release-history-closed This member's or releasable's release history is deliberately over, so the version file, changelog directory and archives it leaves behind are a record rather than residue.
releasable-rename This releasable used to be called something else. rlsbl monorepo rename-releasable records it itself, beside the boundary alias tag it creates; the door is here for a rename performed another way -- edited into workspace.toml by hand, or carried in from a repository converted before the record existed. It is a tag-SPELLING fact and never an identity change, so it does not make rlsbl release reconcile refuse anything.
Until this command existed the only way to write the first two was the Python snippet rlsbl release backfill's own refusal spelled out. A fact worth recording in a committed store is worth a typed door.
WHERE IT WRITES: the repository-scoped record -- <root>/.rlsbl-monorepo/transitions.jsonl in a workspace, and <root>/.rlsbl/transitions.jsonl in a standalone repository, which is :func:rlsbl.transition_record.repository_transition_record_path's answer and therefore exactly the file the backfill's refusal names and reads back. Every kind here goes there rather than into a releasable's own state directory: a tag namespace belongs to the repository, a releasable whose release history just closed may be a releasable whose state directory is about to leave with it, and a renamed releasable's state directory no longer exists under the OLD name -- which is the spelling a reader looking the rename up will have.
The same resolution is what :func:rlsbl.targets.refs.ref_context adds to the records the TAG-NAMESPACE question consults, so a non-version-tag declared here is seen by rlsbl release reconcile in a workspace as well as in a standalone repository.
WHAT IT REFUSES: a second declaration of the same kind about the same subject (the record is append-only, so a duplicate would stand beside the first forever with no way to say which one is meant), a --releasable-rename without the --to naming what it was renamed to, and -- defensively -- a kind outside the declared set. A rename's subject is the PAIR of names, so renaming widget to gadget and later renaming it back are two facts rather than one repeated. A supplied-but-empty subject or reason is refused one step earlier, at the CLI boundary (rlsbl._refuse_empty_flags), which is the one place in rlsbl that decides what an explicitly-empty value means, so this command's message for it is every other command's message for it. The choice flag admits only these kinds, so no argv reaches that last refusal; it exists so that widening the choice without teaching this router is a hard error rather than an event written with a shape nobody checked.
#_subject_of
def _subject_of(event)The one string an event declares its fact about.
A rename is about a PAIR of names, so its subject is both: renaming widget to gadget and later renaming it back are two different facts that both concern widget, and a duplicate refusal keyed on the old name alone would refuse the second as a repeat of the first.
#run_cmd
def run_cmd(flags, *, ctx)Record one operator-declared transition record fact.
Exits non-zero through :func:sys.exit on every refusal, so a failure is the process's rather than a value a caller could ignore.