tools capa

tools-githooks

Rust implementation of the repo's enforcement hooks (ported from .githooks/{pre-commit,commit-msg} via the script-scan pipeline). pre-commit: Gate 0.5 workspace-first compliance + custom-crypto/raw-identity-SQL warnings + AI-attribution file-body block + secure-media /static content-image block, over the staged diff. commit-msg: strips AI-attribution trailers and stamps CONTRACT-STATUS: UNVERIFIED on completion-claiming messages that declare none. The .githooks files are exec shims into these bins; behavior is pinned by githooks-verify's 36 integration tests.

Rust implementation of the repo's enforcement hooks (ported from .githooks/{pre-commit,commit-msg} via the script-scan pipeline). pre-commit: Gate 0.5 workspace-first compliance + custom-crypto/raw-identity-SQL warnings + AI-attribution file-body block + secure-media /static content-image block, over the staged diff. commit-msg: strips AI-attribution trailers and stamps CONTRACT-STATUS: UNVERIFIED on completion-claiming messages that declare none. The .githooks files are exec shims into these bins; behavior is pinned by githooks-verify's 36 integration tests.

Tiertools
Roleunclassified (baselined)
Pathcrates/tools/githooks
Edition2021
Targetsgithook-commit-msg, githook-fix, githook-pre-commit, lexicon-audit, verify-pins, tools_githooks
Public items65 across 7 modules
Tests122

What it is for

Pure logic for the repo's enforcement hooks, ported line-for-line from .githooks/pre-commit and .githooks/commit-msg (bash). The bash files remain as exec shims so git (and tools-githooks-verify's harness, which runs bash <hook>) keeps working unchanged — those 36 integration tests are the port's behavioral oracle and pin every message substring and exit code asserted below.

Everything here is pure (staged file contents in, messages + violation count out); the bins do the git subprocess I/O with strict argument vectors.

Capabilities

crate root

Pure logic for the repo's enforcement hooks, ported line-for-line from

Item
fn capability_candidates(index_tsv : & str, matched_line : & str) -> Vec <String>
fn pre_commit_report(files : & StagedFile) -> PreCommitReport
fn pre_commit_report_with_index(files : & StagedFile, capability_index : & str,) -> PreCommitReport
fn pre_commit_report_full(files : & StagedFile, capability_index : & str, lexicon_tsv : & str,) -> PreCommitReport
fn pre_commit_report_full_with_clap_facts(files : & StagedFile, capability_index : & str, lexicon_tsv : & str, clap_facts : & ToolCrateClapFacts,) -> PreCommitReport
fn migration_path(path : & str) -> bool
fn parse_ledger(stdout : & str) -> Vec <String>
fn applied_migration(path : & str, staged_digest : & str, ledger : & String) -> bool
fn pre_commit_report_full_with_ledger(files : & StagedFile, capability_index : & str, lexicon_tsv : & str, clap_facts : & ToolCrateClapFacts, immutable_paths : & String,) -> PreCommitReport
fn commit_msg_lexicon_findings(message : & str, lexicon_tsv : & str) -> Vec <vocabulary::Finding>

CommitMsgResult

Pure logic for the repo's enforcement hooks, ported line-for-line from

Item
pub struct CommitMsgResult
fn rewrite_commit_message(input : & str) -> CommitMsgResult

PreCommitReport

Pure logic for the repo's enforcement hooks, ported line-for-line from

Item
pub struct PreCommitReport

StagedFile

Pure logic for the repo's enforcement hooks, ported line-for-line from

Item
pub struct StagedFile
fn touched_tool_crate_names(files : & StagedFile) -> Vec <String>
fn migrations_staged(files : & StagedFile) -> bool

ToolCrateClapFacts

Pure logic for the repo's enforcement hooks, ported line-for-line from

Item
pub struct ToolCrateClapFacts

artifact_path (other)

T3a — where a gate artifact is written, and why the branch name cannot be

Item
fn branch_slug(branch : & str) -> String
fn artifact_path(branch : & str, gate_id : & str) -> String

authz (other)

Write authorization — the state transition the agent cannot silently skip.

Item
fn authorize_write(auth : Option <& Authorization>, path : & str, surfaced : & SurfacedCandidate, observed : & ObservedDigests,) -> WriteVerdict

Authorization

Write authorization — the state transition the agent cannot silently skip.

Item
pub struct Authorization
Authorization :: fn substrate_verdict(& self) -> CheckStatus

CandidateObligation

Write authorization — the state transition the agent cannot silently skip.

Item
pub struct CandidateObligation
CandidateObligation :: fn is_open(& self, declaring_file : & str, observed : Option <& str>) -> bool

Disposition

Write authorization — the state transition the agent cannot silently skip.

Item
pub enum Disposition

Inspection

Write authorization — the state transition the agent cannot silently skip.

Item
pub struct Inspection

ObservedDigests

Write authorization — the state transition the agent cannot silently skip.

Item
pub type ObservedDigests: std::collections::BTreeMap <String, String>

ResolvedDisposition

Write authorization — the state transition the agent cannot silently skip.

Item
pub struct ResolvedDisposition
ResolvedDisposition :: fn discharges(& self, candidate_file : & str, observed_digest : & str) -> bool

SubstrateEntry

Write authorization — the state transition the agent cannot silently skip.

Item
pub struct SubstrateEntry
SubstrateEntry :: fn status(& self) -> CheckStatus

SubstrateState

Write authorization — the state transition the agent cannot silently skip.

Item
pub enum SubstrateState

SurfacedCandidate

Write authorization — the state transition the agent cannot silently skip.

Item
pub struct SurfacedCandidate

WriteVerdict

Write authorization — the state transition the agent cannot silently skip.

Item
pub enum WriteVerdict
WriteVerdict :: fn is_allowed(& self) -> bool

Enforcement

Gate contracts — the hand-written half of the split.

Item
pub enum Enforcement
Enforcement :: fn as_str(self) -> & 'static str

GateContract

Gate contracts — the hand-written half of the split.

Item
pub struct GateContract
fn parse_contract(markdown : & str) -> Result <GateContract, String>
fn parse_catalogue(docs : & (String, String),) -> Result <BTreeMap <String, GateContract>, String>

NextStep

Gate contracts — the hand-written half of the split.

Item
pub struct NextStep

Recipe

Gate contracts — the hand-written half of the split.

Item
pub struct Recipe

evidence (other)

T4 — evidence that can be re-executed, from a fixed allowlist.

Item
pub const ALLOWED_RECIPES: & str; 4
fn audit(record : & EvidenceRecord, observed : Option <& str>) -> AuditOutcome
fn select_sample(n : usize, seed : & str, k : usize) -> Vec <usize>

AuditOutcome

T4 — evidence that can be re-executed, from a fixed allowlist.

Item
pub enum AuditOutcome
AuditOutcome :: fn is_ok(& self) -> bool

EvidenceRecord

T4 — evidence that can be re-executed, from a fixed allowlist.

Item
pub struct EvidenceRecord

ArtifactIdentity

T3 — what a gate artifact was computed against, and when it goes stale.

Item
pub struct ArtifactIdentity

Freshness

T3 — what a gate artifact was computed against, and when it goes stale.

Item
pub enum Freshness
Freshness :: fn is_fresh(& self) -> bool
fn freshness(recorded : & ArtifactIdentity, current : & ArtifactIdentity) -> Freshness

Scope

T3 — what a gate artifact was computed against, and when it goes stale.

Item
pub struct Scope

partial_stage (other)

Refuse a commit whose staged set contains a file that also has unstaged edits.

Item
pub const OPT_OUT: & str
fn opted_out(env_value : Option <& str>) -> bool

PartiallyStaged

Refuse a commit whose staged set contains a file that also has unstaged edits.

Item
pub struct PartiallyStaged
fn partially_staged(staged : & str, unstaged : & str) -> Vec <PartiallyStaged>
fn refusal(found : & PartiallyStaged) -> String

pin (other)

T11 — pin the enforcement surface so the constrained party cannot quietly

Item
fn verify(manifest : & PinManifest, observed : & BTreeMap <String, String>) -> PinReport

PinManifest

T11 — pin the enforcement surface so the constrained party cannot quietly

Item
pub struct PinManifest
fn parse_manifest(text : & str) -> Result <PinManifest, String>

PinReport

T11 — pin the enforcement surface so the constrained party cannot quietly

Item
pub struct PinReport
PinReport :: fn is_clean(& self) -> bool
PinReport :: fn lines(& self) -> Vec <String>

ProtectedPrefix

T11 — pin the enforcement surface so the constrained party cannot quietly

Item
pub struct ProtectedPrefix

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

tools_githooks

flowchart TD
  n_tools_githooks["tools_githooks"]
  n_tools_githooks --> n_artifact_path["artifact_path"]
  n_tools_githooks --> n_authz["authz"]
  n_tools_githooks --> n_contract["contract"]
  n_tools_githooks --> n_evidence["evidence"]
  n_tools_githooks --> n_identity["identity"]
  n_tools_githooks --> n_partial_stage["partial_stage"]
  n_tools_githooks --> n_pin["pin"]

Public surface

`crate root`

ItemWhat it is
pub struct StagedFileOne staged file: its repo-relative path and the ADDED lines of its staged diff
pub struct PreCommitReportOutcome of the pre-commit scan: everything to print, and the violation count that decides the exit code.
fn capability_candidates(index_tsv : & str, matched_line : & str) -> Vec <String>Look up existing implementations of whatever matched_line appears to be reimplementing, from the generated capability index
fn pre_commit_report(files : & StagedFile) -> PreCommitReportThe whole pre-commit scan, pure
fn pre_commit_report_with_index(files : & StagedFile, capability_index : & str,) -> PreCommitReportAs pre_commit_report, but consults the generated capability index so a suspected reimplementation is reported with the existing implementations.
fn pre_commit_report_full(files : & StagedFile, capability_index : & str, lexicon_tsv : & str,) -> PreCommitReportpre_commit_report_with_index, plus the Gate 1.3 lexicon (docs/reference/lexicon-policy.tsv)
pub struct ToolCrateClapFactsPer-crates/tools/<name> facts the bin gathers by reading the crate's Cargo.toml and source tree: whether it declares a clap dependency, and whether any file in the crate contains the string assert_conforms
fn touched_tool_crate_names(files : & StagedFile) -> Vec <String>The distinct crates/tools/<name> crates with a staged file under their own src/, sorted and deduplicated
fn pre_commit_report_full_with_clap_facts(files : & StagedFile, capability_index : & str, lexicon_tsv : & str, clap_facts : & ToolCrateClapFacts,) -> PreCommitReportpre_commit_report_full, plus the crates/tools/* clap-conformance gate: a touched crate whose Cargo.toml depends on clap must have some file that calls assert_conforms, or the commit is blocked
fn migration_path(path : & str) -> boolIs path a migration file: a .sql directly under a migrations/ directory
fn migrations_staged(files : & StagedFile) -> boolDoes this commit stage a migration? Only then is the ledger worth a database round trip (B-111).
fn parse_ledger(stdout : & str) -> Vec <String>corpus applied-migrations output: one source digest per line, blanks dropped.
fn applied_migration(path : & str, staged_digest : & str, ledger : & String) -> boolAre these staged bytes the ones the ledger applied? Keyed on the source digest — B-017's own key — so a filename shared across modules cannot collide, and an edited applied migration (digest changed) is NOT immutable-equal and blocks like any other file
fn pre_commit_report_full_with_ledger(files : & StagedFile, capability_index : & str, lexicon_tsv : & str, clap_facts : & ToolCrateClapFacts, immutable_paths : & String,) -> PreCommitReportpre_commit_report_full_with_clap_facts, plus the set of staged paths whose bytes the migration ledger holds (decided by the bin through applied_migration): a Gate 1.3 finding in one of them is reported, not counted, because the only compliant edit is one B-017 forbids (B-111)
pub struct CommitMsgResultOutcome of the commit-msg rewrite.
fn commit_msg_lexicon_findings(message : & str, lexicon_tsv : & str) -> Vec <vocabulary::Finding>Gate 1.3 lexicon check for a commit message — the author's own prose, at a gate that already fires
fn rewrite_commit_message(input : & str) -> CommitMsgResultThe whole commit-msg rewrite, pure: strip attribution lines, trim trailing blanks, then stamp CONTRACT-STATUS: UNVERIFIED on a completion-claiming message that declares no status

`artifact_path`

ItemWhat it is
fn branch_slug(branch : & str) -> StringA filesystem-safe directory name for branch
fn artifact_path(branch : & str, gate_id : & str) -> StringRepo-relative path of one gate's artifact

`authz`

ItemWhat it is
pub struct InspectionProof that a file was read: its path, and the digest the reader observed.
pub enum DispositionWhat a reuse candidate resolved to.
pub struct ResolvedDispositionA discharged obligation.
ResolvedDisposition :: fn discharges(& self, candidate_file : & str, observed_digest : & str) -> boolWhether this discharges an obligation on candidate_file
pub struct CandidateObligationA reuse candidate surfaced by the capability index, and its resolution.
pub struct SurfacedCandidateA candidate as the runner issued it: identity bound to declaring file
CandidateObligation :: fn is_open(& self, declaring_file : & str, observed : Option <& str>) -> boolWhether this still blocks
pub enum SubstrateStateThe outcome of searching for an existing implementation of one capability.
pub struct SubstrateEntryOne capability the task needs, and what was found.
SubstrateEntry :: fn status(& self) -> CheckStatusCollapse to a verdict
pub struct AuthorizationAn open authorization to write source, scoped to paths.
Authorization :: fn substrate_verdict(& self) -> CheckStatusRoll the substrate inventory up to one verdict
pub enum WriteVerdictWhether a write may proceed.
WriteVerdict :: fn is_allowed(& self) -> boolWhether the write may proceed.
pub type ObservedDigests: std::collections::BTreeMap <String, String>Current digest of each declaring file, as the runner sees it.
fn authorize_write(auth : Option <& Authorization>, path : & str, surfaced : & SurfacedCandidate, observed : & ObservedDigests,) -> WriteVerdictDecide whether a source write to path is authorized

`contract`

ItemWhat it is
pub enum EnforcementWhether a gate can refuse a write
Enforcement :: fn as_str(self) -> & 'static strStable name for the runner's per-gate table.
pub struct RecipeAn allowlisted evidence recipe
pub struct NextStepWhat the runner emits when a gate is unsatisfied.
pub struct GateContractOne gate's requirements.
fn parse_contract(markdown : & str) -> Result <GateContract, String>Parse one gate contract from its markdown document
fn parse_catalogue(docs : & (String, String),) -> Result <BTreeMap <String, GateContract>, String>Parse a whole catalogue: gate id → contract

`evidence`

ItemWhat it is
pub const ALLOWED_RECIPES: & str; 4Every recipe the runner knows how to execute
pub struct EvidenceRecordOne executed piece of evidence, as recorded in an artifact.
pub enum AuditOutcomeWhat an audit of one record concluded.
AuditOutcome :: fn is_ok(& self) -> boolWhether the record survived the audit.
fn audit(record : & EvidenceRecord, observed : Option <& str>) -> AuditOutcomeAudit one record against a freshly observed digest
fn select_sample(n : usize, seed : & str, k : usize) -> Vec <usize>Deterministically choose up to k of n records to re-execute

`identity`

ItemWhat it is
pub struct ScopeWhat a gate declared it examines
pub struct ArtifactIdentityThe repository state an artifact was computed against.
pub enum FreshnessWhether an artifact still describes the current state.
Freshness :: fn is_fresh(& self) -> boolWhether the artifact may still be relied on.
fn freshness(recorded : & ArtifactIdentity, current : & ArtifactIdentity) -> FreshnessCompare a recorded identity against the current one

`partial_stage`

ItemWhat it is
pub struct PartiallyStagedA path that is staged and also carries unstaged modifications.
pub const OPT_OUT: & strEnv var that permits partially-staged files for one commit.
fn partially_staged(staged : & str, unstaged : & str) -> Vec <PartiallyStaged>Intersect the staged and unstaged path sets
fn refusal(found : & PartiallyStaged) -> StringThe blocking message
fn opted_out(env_value : Option <& str>) -> boolTrue when the operator has opted out for this commit.

`pin`

ItemWhat it is
pub struct ProtectedPrefixA path prefix whose every file must be pinned
pub struct PinManifestThe manifest: protected prefixes, and the expected digest of every file.
pub struct PinReportWhat a verification found.
PinReport :: fn is_clean(& self) -> boolWhether the enforcement surface is intact.
PinReport :: fn lines(& self) -> Vec <String>Human-readable lines, each naming what to do.
fn parse_manifest(text : & str) -> Result <PinManifest, String>Parse the manifest
fn verify(manifest : & PinManifest, observed : & BTreeMap <String, String>) -> PinReportCompare the manifest against the observed state of the tree

Re-exports. Exported here, defined elsewhere.

ExportDefined in
foundation_lexiconasvocabularyfoundation_lexiconasvocabulary

Boundary

Reaches into foundation.

Shares tier tools with 84 other crates: tools-advisory-reach, tools-archive-guard, tools-artifact-scaffold, tools-ask-ai-core, tools-ask-ais, tools-ask-gemini, tools-book, tools-book-report, … (84 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)tools
Architectural role (taxonomy)unclassified (baselined)
Locationcrates/tools/githooks
Vocabulary in force (lexicon)current

Tier flow. Which tiers this crate's own edges cross.

flowchart LR
  n_tools["tools"] --> n_foundation["foundation"]

Dependencies

Runtime, in this workspace.

CrateTierOptionalOnly on
`foundation-audit-log`foundationnoalways
`foundation-bounded-io`foundationnoalways
`foundation-lexicon`foundationnoalways

Runtime, from outside the workspace.

CrateRequirementFeaturesOptionalOnly on
anyhow^1noalways
regex^1noalways
sha2^0.10noalways
toml^0.8noalways

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-githooks"]
  SELF -->|runtime| n_foundation_audit_log["foundation-audit-log"]
  SELF -->|runtime| n_foundation_bounded_io["foundation-bounded-io"]
  SELF -->|runtime| n_foundation_lexicon["foundation-lexicon"]
  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
bingithook-commit-msg`src/bin/commit_msg.rs`
bingithook-fix`src/bin/fix.rs`
bingithook-pre-commit`src/bin/pre_commit.rs`
binlexicon-audit`src/bin/lexicon_audit.rs`
binverify-pins`src/bin/verify_pins.rs`
libtools_githooks`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 runtimenone detected
database accessnone detected
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
CARGO_MANIFEST_DIRsrc/contract.rs
GITHOOKS_WORKSPACE_ROOTsrc/bin/pre_commit.rs

No workspace crate depends on this one.

Verification

KindCount
Unit tests122
Integration tests0
Examples0
Doctests0

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

ModuleTestsExamplesConsumers
crate root1700
artifact_path200
authz1100
contract600
evidence500
identity400
partial_stage500
pin500

What the tests establish, by name:

Documentation coverage

MeasureDocumentedTotal
Public items with rustdoc6565
Public modules with a //! block77
pie showData
    title Public items with rustdoc
    "Documented" : 65
    "No rustdoc detected" : 0

Metrics

MetricValue
Rust source files13
Source lines4392
Code lines3124
Public API items65
Public modules7
Tests122
Examples0
Cargo features0
Direct runtime dependencies7
Workspace reverse dependencies0
pie showData
    title Public API by kind
    "constant" : 2
    "enum" : 6
    "function" : 26
    "method" : 10
    "struct" : 20
    "type alias" : 1
pie showData
    title Rust source composition
    "Code" : 3124
    "Blank or comment" : 1268

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.

Todas las tools · Manual