Database backup as a framework capability: content-deduplicated, verified-before-promote, and attestable. Lifted out of three divergent consumer shell scripts (Gate 4.5).
| Tier | infrastructure |
| Role | unclassified (baselined) |
| Path | crates/infrastructure/backup |
| Edition | 2021 |
| Targets | infrastructure_backup, dedup, plan |
| Public items | 20 across 4 modules |
| Tests | 15 |
What it is for
This crate does not document itself. No //! block on its entry point. The facts below are complete; the reason this crate exists is not written down anywhere, and belongs in src/lib.rs rather than here.
Capabilities
dedup (other)
Content-addressed change detection for pg_dump output (US-3.1.8).
| Item |
|---|
fn content_hash(dump : & str) -> String |
fn has_changed(previous : Option <& str>, current : & str) -> bool |
BackupState
What to back up, and whether a backup is current (US-3.1.8).
| Item |
|---|
pub struct BackupState |
fn is_current(state : & BackupState, window_hours : u64) -> bool |
fn stale(states : & BackupState, window_hours : u64) -> Vec <& BackupState> |
PlanError
What to back up, and whether a backup is current (US-3.1.8).
| Item |
|---|
pub enum PlanError |
PlanError :: fn fmt(& self, f : & mut std::fmt::Formatter <'_>) -> std::fmt::Result |
fn plan(discovered : & String) -> Result <Vec <String>, PlanError> |
RetentionError
Retention policy (US-3.1.8).
| Item |
|---|
pub enum RetentionError |
RetentionError :: fn fmt(& self, f : & mut std::fmt::Formatter <'_>) -> std::fmt::Result |
fn prune_plan <S : AsRef <str>>(newest_first : & S, keep : usize,) -> Result <Vec <& str>, RetentionError> |
runner (other)
The pg_dump shell (US-3.1.8).
| Item |
|---|
fn back_up_one(cfg : & Config, database : & str, dsn : & str, stamp : & str,) -> Result <Outcome, RunError> |
Config
The pg_dump shell (US-3.1.8).
| Item |
|---|
pub struct Config |
Config :: fn default() -> Self |
Manifest
The pg_dump shell (US-3.1.8).
| Item |
|---|
pub struct Manifest |
Manifest :: fn to_json(& self) -> String |
Outcome
The pg_dump shell (US-3.1.8).
| Item |
|---|
pub enum Outcome |
RunError
The pg_dump shell (US-3.1.8).
| Item |
|---|
pub enum RunError |
RunError :: fn fmt(& self, f : & mut std::fmt::Formatter <'_>) -> std::fmt::Result |
RunError :: fn from(e : std::io::Error) -> Self |
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
infrastructure_backup
dedupplanretentionrunner
flowchart TD n_infrastructure_backup["infrastructure_backup"] n_infrastructure_backup --> n_dedup["dedup"] n_infrastructure_backup --> n_plan["plan"] n_infrastructure_backup --> n_retention["retention"] n_infrastructure_backup --> n_runner["runner"]
Public surface
`dedup`
| Item | What it is |
|---|---|
fn content_hash(dump : & str) -> String | Hash a dump's content, ignoring pg_dump's per-run session token |
fn has_changed(previous : Option <& str>, current : & str) -> bool | Has the content changed since the recorded hash? None for the previous hash means "no prior backup", which is always a change — a first run must never be deduplicated away. |
`plan`
| Item | What it is |
|---|---|
pub enum PlanError | Why a backup plan could not be built. |
PlanError :: fn fmt(& self, f : & mut std::fmt::Formatter <'_>) -> std::fmt::Result | — |
pub struct BackupState | One database's backup state, as known to the runner. |
fn is_current(state : & BackupState, window_hours : u64) -> bool | Is this database's backup current, given a policy window? None (no archive at all) is never current — a database that has never been backed up must not read the same as one backed up recently. |
fn plan(discovered : & String) -> Result <Vec <String>, PlanError> | Build the list of databases to back up |
fn stale(states : & BackupState, window_hours : u64) -> Vec <& BackupState> | Databases whose backup is outside the policy window, for the attestation check |
`retention`
| Item | What it is |
|---|---|
pub enum RetentionError | Why a retention plan could not be produced. |
RetentionError :: fn fmt(& self, f : & mut std::fmt::Formatter <'_>) -> std::fmt::Result | — |
fn prune_plan <S : AsRef <str>>(newest_first : & S, keep : usize,) -> Result <Vec <& str>, RetentionError> | Which archives to delete, given the existing set newest-first and how many to keep |
`runner`
| Item | What it is |
|---|---|
pub struct Manifest | What a completed backup recorded about itself |
Manifest :: fn to_json(& self) -> String | Render as JSON without pulling in a serialiser. |
pub enum RunError | Why a backup run failed for one database. |
RunError :: fn fmt(& self, f : & mut std::fmt::Formatter <'_>) -> std::fmt::Result | — |
RunError :: fn from(e : std::io::Error) -> Self | — |
pub enum Outcome | The outcome for one database. |
pub struct Config | How to run a backup. |
Config :: fn default() -> Self | — |
fn back_up_one(cfg : & Config, database : & str, dsn : & str, stamp : & str,) -> Result <Outcome, RunError> | Back up one database |
No pub use re-exports: every item above is declared in this crate.
Boundary
Depends on no other workspace tier.
Shares tier infrastructure with 82 other crates: infrastructure-acquire, infrastructure-adapters-google-calendar, infrastructure-adapters-google-gmail, infrastructure-adapters-google-places, infrastructure-adapters-google-trends, infrastructure-adapters-shodan, infrastructure-adapters-yelp, infrastructure-agent, … (82 total).
_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) | infrastructure |
| Architectural role (taxonomy) | unclassified (baselined) |
| Location | crates/infrastructure/backup |
| Vocabulary in force (lexicon) | current |
Dependencies
Runtime, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
sha2 | ^0.10 | — | no | always |
Development. None.
Build. None.
Depended on by. 1 workspace crate.
Signal flow — what reaches this crate, and what it reaches.
flowchart LR n_tools_fleet_db["tools-fleet-db"] -->|uses| SELF SELF["infrastructure-backup"] 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
| Kind | Name | Source |
|---|---|---|
| lib | infrastructure_backup | `src/lib.rs` |
| test | dedup | `tests/dedup.rs` |
| test | plan | `tests/plan.rs` |
Error model
| Error type | Named by |
|---|---|
PlanError | plan |
RetentionError | prune_plan |
RunError | back_up_one |
Operational characteristics
| Property | Evidence |
|---|---|
| async public surface | none detected |
| async runtime | none detected |
| database access | none detected |
| network I/O | none detected |
| unsafe code | none detected |
| environment variables | none detected |
No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.
Configuration
No environment variable is read with a literal name anywhere in this crate. A variable whose key is computed at run time cannot be listed here, and is not claimed to be absent.
Related capabilities
1 workspace crate depends on this one: tools-fleet-db.
Verification
| Kind | Count |
|---|---|
| Unit tests | 0 |
| Integration tests | 15 |
| Examples | 0 |
| Doctests | 0 |
Evidence by module. How often each public module is named by something executable.
| Module | Tests | Examples | Consumers |
|---|---|---|---|
dedup | 2 | 0 | 0 |
plan | 5 | 0 | 2 |
retention | 2 | 0 | 0 |
runner | 5 | 0 | 3 |
What the tests establish, by name:
a_keep_count_of_zero_is_rejected—tests/dedup.rsa_real_content_change_does_change_the_hash—tests/dedup.rsa_schema_change_changes_the_hash—tests/dedup.rsan_empty_dump_hashes_without_panicking—tests/dedup.rsonly_the_directive_lines_are_excluded_not_the_word—tests/dedup.rsretention_keeps_everything_when_under_the_limit—tests/dedup.rsretention_keeps_the_newest_n—tests/dedup.rsretention_on_an_empty_set_is_not_an_error—tests/dedup.rsthe_per_dump_session_token_does_not_change_the_hash—tests/dedup.rsdiscovering_zero_databases_is_a_failure_not_an_empty_success—tests/plan.rsinside_the_window_is_current_and_the_boundary_is_inclusive—tests/plan.rsnever_backed_up_is_never_current—tests/plan.rsnothing_is_stale_when_everything_is_fresh—tests/plan.rsstale_names_every_offender_in_a_stable_order—tests/plan.rsthe_plan_is_sorted_and_deduplicated—tests/plan.rs
Documentation coverage
| Measure | Documented | Total |
|---|---|---|
| Public items with rustdoc | 15 | 20 |
Public modules with a //! block | 4 | 4 |
pie showData
title Public items with rustdoc
"Documented" : 15
"No rustdoc detected" : 5
Metrics
| Metric | Value |
|---|---|
| Rust source files | 5 |
| Source lines | 479 |
| Code lines | 272 |
| Public API items | 20 |
| Public modules | 4 |
| Tests | 15 |
| Examples | 0 |
| Cargo features | 0 |
| Direct runtime dependencies | 1 |
| Workspace reverse dependencies | 1 |
pie showData
title Public API by kind
"enum" : 4
"function" : 7
"method" : 6
"struct" : 3
pie showData
title Rust source composition
"Code" : 272
"Blank or comment" : 207
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.