tools tier

tools-migration-ledger

The migration ledger: every applied migration as a row keyed by a time-ordered id, with its label, its bytes and the work item that asked for it

The migration ledger: every applied migration as a row keyed by a time-ordered id, with its label, its bytes and the work item that asked for it

Tier—
Roleunclassified (baselined)
Pathcrates/tools/migration-ledger
Edition2021
Targetstools-migration-ledger, tools_migration_ledger
Public items9 across 0 modules
Tests11

What it is for

The migration ledger: what ran, in the order it ran, as rows.

# Why this is not itself a migration

A ledger cannot be repaired by the mechanism it records. If the table that says which migrations ran is created by a numbered migration, then a ledger that is wrong or missing cannot be fixed without the very sequence it is blocking. So the table is created by this tool, idempotently, and stands outside the numbered set on purpose.

# Why the identity is time-ordered rather than a number

The number is a filename convention, and two sessions took the same one within minutes of each other on 2026-09-10 (the second 0124). A number can collide; a time-ordered identifier cannot, and it sorts in the order the rows were written without a second column to sort by. The generator is foundation_uuid7, which knows nothing about migrations.

The number still matters — it is the order the sequence runs in — so it stays as its own field. What changes is that it is no longer the identity.

# Three sources of order, in the order they are trusted

1. The database's own record. When the old ledger recorded a time, that is when the migration actually ran on this database. Nothing beats it. 2. Git. When the file was first committed. Weaker — a file can be committed long before it runs — but it is real evidence, and for everything past 0111 here it is the only evidence there is. 3. The sequence number. Always available, never wrong about ORDER, and silent about when.

Each source only fills what the one above it left empty, and the ordering rule refuses to let any of them reverse the sequence.

Capabilities

crate root

The migration ledger: what ran, in the order it ran, as rows.

Item
fn number_of(filename : & str) -> Option <u32>
fn label_of(filename : & str) -> String
fn title_of(filename : & str, keep_number : bool) -> String
fn digest_of(content : & str) -> String
fn assign_ids(registered : & (& str, & str), known : & (Option <i64>, OrderSource), floor : i64, keep_number_in_label : bool,) -> Vec <Entry>

Entry

The migration ledger: what ran, in the order it ran, as rows.

Item
pub struct Entry

OrderSource

The migration ledger: what ran, in the order it ran, as rows.

Item
pub enum OrderSource
OrderSource :: fn as_str(self) -> & 'static str
fn best_known(database : & Option <i64>, git : & Option <i64>,) -> Vec <(Option <i64>, OrderSource)>

How to use it

No examples/ target and no doctest in this crate's rustdoc. The tests listed under Verification are the closest executable usage.

Module structure

No public modules: the crate root is its whole surface.

Public surface

`crate root`

ItemWhat it is
pub struct EntryOne migration, as the ledger holds it.
pub enum OrderSourceWhere a row's position came from, recorded because "we do not know when this ran" and "this ran at 09:41" are different facts and a ledger that blurs them is the thing being repaired.
OrderSource :: fn as_str(self) -> & 'static str—
fn number_of(filename : & str) -> Option <u32>The sequence number a migration filename carries, if any
fn label_of(filename : & str) -> StringThe words in a migration's filename, as a label a person reads
fn title_of(filename : & str, keep_number : bool) -> StringThe title a row carries, with or without its sequence number
fn digest_of(content : & str) -> Stringsha256 of the bytes that ran, as lowercase hex
fn best_known(database : & Option <i64>, git : & Option <i64>,) -> Vec <(Option <i64>, OrderSource)>Combine the database's record with git's, per position
fn assign_ids(registered : & (& str, & str), known : & (Option <i64>, OrderSource), floor : i64, keep_number_in_label : bool,) -> Vec <Entry>Build the ledger rows for a registered migration set

No pub use re-exports: every item above is declared in this crate.

Boundary

Reaches into foundation, operations.

No other crate shares its tier.

_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._

Where it sits

Tier (ontology)—
Architectural role (taxonomy)unclassified (baselined)
Locationcrates/tools/migration-ledger
Vocabulary in force (lexicon)current

Dependencies

Runtime, in this workspace.

CrateTierOptionalOnly on
`foundation-audit-log`foundationnoalways
`foundation-uuid7`—noalways
`operations-control-plane`operationsnoalways

Runtime, from outside the workspace.

CrateRequirementFeaturesOptionalOnly on
chrono^0.4serdenoalways
sqlx^0.8runtime-tokio, postgres, chrono, uuid, json, runtime-tokio, … (10 total)noalways
tokio^1full, macros, rt-multi-threadnoalways
uuid^1v4, v7, serde, js, v7noalways

Development. None.

Build. None.

Depended on by. Nothing in this workspace.

Signal flow — what reaches this crate, and what it reaches.

flowchart LR
  SELF["tools-migration-ledger"]
  SELF -->|runtime| n_foundation_audit_log["foundation-audit-log"]
  SELF -->|runtime| n_foundation_uuid7["foundation-uuid7"]
  SELF -->|runtime| n_operations_control_plane["operations-control-plane"]
  classDef self fill:#1f883d,stroke:#1f883d,color:#fff;
  class SELF self;

Feature flags

No Cargo features are defined: every capability is unconditional, so no consumer can receive a half-wired crate.

Targets

KindNameSource
bintools-migration-ledger`src/main.rs`
libtools_migration_ledger`src/lib.rs`

Error model

No public error type was detected: no public item declares a type named *Error, and no public signature returns one.

Operational characteristics

PropertyEvidence
async public surfacenone detected
async runtimeyes
database accessyes
network I/Onone detected
unsafe codenone detected
environment variablesyes

No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.

Configuration

VariableRead in
CORPUS_SOURCECODE_APP_DBsrc/main.rs

No workspace crate depends on this one.

Verification

KindCount
Unit tests11
Integration tests0
Examples0
Doctests0

Evidence by module. How often each public module is named by something executable.

ModuleTestsExamplesConsumers
crate root800

What the tests establish, by name:

Documentation coverage

MeasureDocumentedTotal
Public items with rustdoc89
Public modules with a //! block00
pie showData
    title Public items with rustdoc
    "Documented" : 8
    "No rustdoc detected" : 1

Metrics

MetricValue
Rust source files2
Source lines644
Code lines416
Public API items9
Public modules0
Tests11
Examples0
Cargo features0
Direct runtime dependencies7
Workspace reverse dependencies0
pie showData
    title Public API by kind
    "enum" : 1
    "function" : 6
    "method" : 1
    "struct" : 1
pie showData
    title Rust source composition
    "Code" : 416
    "Blank or comment" : 228

Generation

Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.

All tools · Manual