#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum VerbGroup {
Core,
Diagnostics,
Analysis,
Ingestion,
Compliance,
Attestation,
Sbom,
Insights,
Engineering,
Tooling,
}
impl VerbGroup {
pub fn label(self) -> &'static str {
match self {
Self::Core => "Core",
Self::Diagnostics => "Diagnostics",
Self::Analysis => "Analysis",
Self::Ingestion => "Ingestion",
Self::Compliance => "Compliance",
Self::Attestation => "Attestation",
Self::Sbom => "SBOM",
Self::Insights => "Insights",
Self::Engineering => "Engineering",
Self::Tooling => "Tooling",
}
}
pub fn description(self) -> &'static str {
match self {
Self::Core => "Core receipt lifecycle operations (emit, assemble, verify, show, inspect, stats)",
Self::Diagnostics => "Diagnostic and forensic operations for troubleshooting receipt failures",
Self::Analysis => "Analysis and mining of receipt chains for quality and coverage insights",
Self::Ingestion => "Event ingestion adapters for CI/CD, cloud, SCM, and monitoring systems",
Self::Compliance => "Framework compliance verification against GDPR, HIPAA, PCI-DSS, SOC 2, SLA, and custom policies",
Self::Attestation => "Signing, notarization, and attestation of receipts for supply-chain assurance",
Self::Sbom => "Software Bill of Materials scanning, verification, and NTIA compliance checks",
Self::Insights => "Predictive and anomaly-detection insights derived from receipt chains",
Self::Engineering => "Engineering health and productivity metrics extracted from receipt history",
Self::Tooling => "Infrastructure tooling: catalog management, search, profiling, and hook installation",
}
}
}
#[derive(Debug, Clone)]
pub struct VerbEntry {
pub verb: &'static str,
pub noun: &'static str,
pub group: VerbGroup,
pub summary: &'static str,
pub keywords: &'static [&'static str],
pub example: Option<&'static str>,
}
impl VerbEntry {
pub const fn new(
verb: &'static str,
noun: &'static str,
group: VerbGroup,
summary: &'static str,
keywords: &'static [&'static str],
) -> Self {
Self {
verb,
noun,
group,
summary,
keywords,
example: None,
}
}
pub const fn with_example(mut self, example: &'static str) -> Self {
self.example = Some(example);
self
}
}
pub static REGISTRY: &[VerbEntry] = &[
VerbEntry::new(
"emit",
"receipt",
VerbGroup::Core,
"Record an operation-event into the working receipt chain",
&["emit", "record", "event", "append", "log"],
),
VerbEntry::new(
"assemble",
"receipt",
VerbGroup::Core,
"Finalize the working receipt into an immutable sealed file",
&["assemble", "finalize", "seal", "build", "commit"],
),
VerbEntry::new(
"verify",
"receipt",
VerbGroup::Core,
"Run the 7-stage certify pipeline against a receipt (exit 0=ACCEPT, 2=REJECT)",
&["verify", "certify", "check", "validate", "audit"],
),
VerbEntry::new(
"show",
"receipt",
VerbGroup::Core,
"Human-readable dump of the receipt chain with event details",
&["show", "display", "print", "dump", "read"],
),
VerbEntry::new(
"inspect",
"receipt",
VerbGroup::Core,
"Detailed inspection of receipt internals (chain hash, commitments, continuity)",
&["inspect", "detail", "internals", "debug", "examine"],
),
VerbEntry::new(
"stats",
"receipt",
VerbGroup::Core,
"Chain metrics: event count, hash distribution, event-type histogram",
&["stats", "metrics", "count", "histogram", "summary"],
),
VerbEntry::new(
"diagnose",
"receipt",
VerbGroup::Diagnostics,
"Troubleshoot verification failures with suggested remediation steps",
&["diagnose", "debug", "troubleshoot", "fix", "repair"],
),
VerbEntry::new(
"diff",
"receipt",
VerbGroup::Diagnostics,
"Compute a structural diff between two receipts showing added, removed, and changed events",
&["diff", "compare", "delta", "changes", "between"],
),
VerbEntry::new(
"graph",
"receipt",
VerbGroup::Diagnostics,
"DAG visualization of event dependencies and object references (dot, mermaid, json)",
&["graph", "dag", "visualize", "dot", "mermaid", "dependencies"],
),
VerbEntry::new(
"replay",
"receipt",
VerbGroup::Diagnostics,
"Re-execute chain from stored events, optionally applying custom handlers",
&["replay", "rerun", "re-execute", "simulate", "playback"],
),
VerbEntry::new(
"timeline",
"receipt",
VerbGroup::Diagnostics,
"Render a temporal timeline of events ordered by sequence number",
&["timeline", "time", "sequence", "order", "chronology"],
),
VerbEntry::new(
"root_cause",
"receipt",
VerbGroup::Diagnostics,
"Trace failure events back to their causal predecessors in the chain",
&["root_cause", "root-cause", "cause", "origin", "trace", "failure"],
),
VerbEntry::new(
"audit",
"receipt",
VerbGroup::Analysis,
"Run a full audit pass over a receipt: chain integrity, commitments, and event completeness",
&["audit", "full-check", "integrity", "scan", "review"],
),
VerbEntry::new(
"query",
"receipt",
VerbGroup::Analysis,
"Query receipt events using a filter expression (event_type, object, seq range)",
&["query", "filter", "search", "find", "select", "jq"],
),
VerbEntry::new(
"model",
"receipt",
VerbGroup::Analysis,
"Extract the type schema from a receipt (event types, object types, qualifiers)",
&["model", "schema", "types", "extract", "ontology"],
),
VerbEntry::new(
"conformance",
"receipt",
VerbGroup::Analysis,
"Check a receipt against custom conformance rules or a named profile",
&["conformance", "profile", "rules", "standard", "check"],
),
VerbEntry::new(
"coverage_analysis",
"receipt",
VerbGroup::Analysis,
"Measure what fraction of defined event types appear in the receipt",
&["coverage", "coverage_analysis", "completeness", "missing", "gaps"],
),
VerbEntry::new(
"tech_debt",
"receipt",
VerbGroup::Analysis,
"Identify stale or low-quality events that signal accumulated technical debt",
&["tech_debt", "debt", "quality", "stale", "maintenance"],
),
VerbEntry::new(
"security_debt",
"receipt",
VerbGroup::Analysis,
"Surface security-relevant events with missing or weak commitments",
&["security_debt", "security", "vulnerability", "weakness", "cve"],
),
VerbEntry::new(
"emit_batch",
"receipt",
VerbGroup::Ingestion,
"Ingest multiple events from a JSONL or CSV file in a single batch operation",
&["emit_batch", "batch", "bulk", "import", "ingest", "jsonl"],
),
VerbEntry::new(
"emit_from_cicd",
"receipt",
VerbGroup::Ingestion,
"Ingest events from a CI/CD pipeline run (GitHub Actions, GitLab CI, Jenkins, etc.)",
&["emit_from_cicd", "cicd", "ci", "cd", "pipeline", "build"],
),
VerbEntry::new(
"emit_from_cloud",
"receipt",
VerbGroup::Ingestion,
"Ingest events from cloud provider audit logs (AWS CloudTrail, GCP Audit, Azure Monitor)",
&["emit_from_cloud", "cloud", "aws", "gcp", "azure", "cloudtrail"],
),
VerbEntry::new(
"emit_from_github",
"receipt",
VerbGroup::Ingestion,
"Ingest events from a GitHub repository (commits, PRs, releases, workflow runs)",
&["emit_from_github", "github", "git", "commits", "prs"],
),
VerbEntry::new(
"emit_from_gitlab",
"receipt",
VerbGroup::Ingestion,
"Ingest events from a GitLab project (pipelines, MRs, tags, deployments)",
&["emit_from_gitlab", "gitlab", "git", "pipelines", "merge-requests"],
),
VerbEntry::new(
"emit_from_monitoring",
"receipt",
VerbGroup::Ingestion,
"Ingest events from monitoring/observability systems (Datadog, Prometheus, PagerDuty)",
&["emit_from_monitoring", "monitoring", "observability", "datadog", "prometheus", "alerts"],
),
VerbEntry::new(
"emit_from_sbom",
"receipt",
VerbGroup::Ingestion,
"Ingest SBOM document events (CycloneDX or SPDX) into the receipt chain",
&["emit_from_sbom", "sbom", "cyclonedx", "spdx", "components"],
),
VerbEntry::new(
"emit_from_security",
"receipt",
VerbGroup::Ingestion,
"Ingest security scan events (Snyk, Trivy, Dependabot, SARIF) into the receipt chain",
&["emit_from_security", "security", "scan", "snyk", "trivy", "sarif"],
),
VerbEntry::new(
"verify_compliance",
"receipt",
VerbGroup::Compliance,
"Check evidence presence for a compliance framework (evidence present/absent — not a legal determination)",
&["verify_compliance", "compliance", "framework", "evidence", "gdpr", "hipaa", "soc2"],
),
VerbEntry::new(
"verify_sla",
"receipt",
VerbGroup::Compliance,
"Verify that receipt events satisfy defined SLA thresholds and time windows",
&["verify_sla", "sla", "service-level", "latency", "uptime", "availability"],
),
VerbEntry::new(
"verify_family",
"receipt",
VerbGroup::Compliance,
"Verify a family of related receipts all satisfy shared constraints",
&["verify_family", "family", "group", "batch-verify", "related"],
),
VerbEntry::new(
"policy_enforce",
"receipt",
VerbGroup::Compliance,
"Evaluate receipt events against a Rego or CEL policy file",
&["policy_enforce", "policy", "rego", "cel", "opa", "enforce"],
),
VerbEntry::new(
"license_compliance",
"receipt",
VerbGroup::Compliance,
"Check that dependency licenses in the receipt satisfy the project's license policy",
&["license_compliance", "license", "oss", "open-source", "spdx", "policy"],
),
VerbEntry::new(
"gdpr_proof",
"receipt",
VerbGroup::Compliance,
"Generate GDPR data-processing evidence from receipt events for auditor review",
&["gdpr_proof", "gdpr", "privacy", "data-protection", "dpa", "evidence"],
),
VerbEntry::new(
"hipaa",
"receipt",
VerbGroup::Compliance,
"Collect HIPAA safeguard evidence from receipt events for auditor review",
&["hipaa", "health", "phi", "safeguard", "audit", "healthcare"],
),
VerbEntry::new(
"pci_dss",
"receipt",
VerbGroup::Compliance,
"Collect PCI-DSS control evidence from receipt events for auditor review",
&["pci_dss", "pci", "dss", "payment", "card", "control"],
),
VerbEntry::new(
"soc2_audit",
"receipt",
VerbGroup::Compliance,
"Collect SOC 2 trust-service-criteria evidence from receipts for auditor review",
&["soc2_audit", "soc2", "soc", "trust", "service-criteria", "audit"],
),
VerbEntry::new(
"sign",
"receipt",
VerbGroup::Attestation,
"Cryptographically sign a sealed receipt with a private key (PEM or PKCS#11)",
&["sign", "signature", "cryptography", "private-key", "pem"],
),
VerbEntry::new(
"notarize",
"receipt",
VerbGroup::Attestation,
"Submit a receipt to a transparency log for timestamped notarization (Sigstore/Rekor)",
&["notarize", "notarization", "transparency", "sigstore", "rekor", "timestamp"],
),
VerbEntry::new(
"attest",
"receipt",
VerbGroup::Attestation,
"Create a signed SLSA attestation document from a sealed receipt",
&["attest", "attestation", "slsa", "provenance", "in-toto"],
),
VerbEntry::new(
"assemble_with_signature",
"receipt",
VerbGroup::Attestation,
"Assemble and immediately sign the receipt in a single atomic operation",
&["assemble_with_signature", "sign", "assemble", "atomic", "seal"],
),
VerbEntry::new(
"assemble_and_notarize",
"receipt",
VerbGroup::Attestation,
"Assemble, seal, and submit to a transparency log in one step",
&["assemble_and_notarize", "notarize", "assemble", "atomic", "rekor"],
),
VerbEntry::new(
"sbom_attest",
"receipt",
VerbGroup::Attestation,
"Attach a SLSA attestation to a previously generated SBOM document",
&["sbom_attest", "sbom", "attestation", "slsa", "supply-chain"],
),
VerbEntry::new(
"sbom_scan",
"receipt",
VerbGroup::Sbom,
"Scan a project and emit an SBOM event capturing all detected components",
&["sbom_scan", "sbom", "scan", "components", "dependencies", "inventory"],
),
VerbEntry::new(
"sbom_blast_radius",
"receipt",
VerbGroup::Sbom,
"Compute the blast radius of a vulnerable component across the SBOM dependency graph",
&["sbom_blast_radius", "blast-radius", "impact", "vulnerability", "transitive"],
),
VerbEntry::new(
"sbom_compliance",
"receipt",
VerbGroup::Sbom,
"Verify that the SBOM satisfies a license or security policy",
&["sbom_compliance", "sbom", "compliance", "license", "security", "policy"],
),
VerbEntry::new(
"sbom_ntia",
"receipt",
VerbGroup::Sbom,
"Check an SBOM document against the NTIA minimum-element requirements",
&["sbom_ntia", "ntia", "minimum-elements", "sbom", "executive-order"],
),
VerbEntry::new(
"anomaly_detect",
"receipt",
VerbGroup::Insights,
"Detect anomalous events in the receipt chain using statistical outlier analysis",
&["anomaly_detect", "anomaly", "outlier", "detect", "unusual", "statistics"],
),
VerbEntry::new(
"predict",
"receipt",
VerbGroup::Insights,
"Forecast future chain state or failure probability based on historical receipt patterns",
&["predict", "forecast", "probability", "failure", "ml", "trend"],
),
VerbEntry::new(
"trend_analysis",
"receipt",
VerbGroup::Insights,
"Compute rolling trends over event frequency, latency, and error rates across receipts",
&["trend_analysis", "trend", "rolling", "frequency", "latency", "error-rate"],
),
VerbEntry::new(
"variance",
"receipt",
VerbGroup::Insights,
"Measure variance in event timing and payload size across a collection of receipts",
&["variance", "spread", "deviation", "timing", "payload-size"],
),
VerbEntry::new(
"find_blast_radius",
"receipt",
VerbGroup::Insights,
"Find all receipt events transitively affected by a given failing event",
&["find_blast_radius", "blast-radius", "impact", "transitive", "cascade"],
),
VerbEntry::new(
"explain_incident",
"receipt",
VerbGroup::Insights,
"Generate a structured incident explanation from events surrounding a failure",
&["explain_incident", "incident", "explain", "postmortem", "rca"],
),
VerbEntry::new(
"causality_chain",
"receipt",
VerbGroup::Insights,
"Build a causality chain graph linking events by causal relationships",
&["causality_chain", "causality", "cause", "effect", "graph", "chain"],
),
VerbEntry::new(
"bus_factor",
"receipt",
VerbGroup::Engineering,
"Compute the bus factor for each object in the chain based on contributor events",
&["bus_factor", "bus-factor", "knowledge", "risk", "contributors", "single-point"],
),
VerbEntry::new(
"dora_metrics",
"receipt",
VerbGroup::Engineering,
"Extract DORA metrics (deployment frequency, lead time, MTTR, change failure rate) from receipts",
&["dora_metrics", "dora", "deployment", "lead-time", "mttr", "change-failure"],
),
VerbEntry::new(
"team_velocity",
"receipt",
VerbGroup::Engineering,
"Measure team throughput and cycle time from emit/assemble event pairs",
&["team_velocity", "velocity", "throughput", "cycle-time", "team"],
),
VerbEntry::new(
"portfolio_health",
"receipt",
VerbGroup::Engineering,
"Aggregate health signals across a portfolio of receipts into a dashboard-ready report",
&["portfolio_health", "portfolio", "health", "dashboard", "aggregate"],
),
VerbEntry::new(
"orphaned_code",
"receipt",
VerbGroup::Engineering,
"Identify object references in the receipt that have no corresponding emit events",
&["orphaned_code", "orphaned", "dead-code", "unreferenced", "objects"],
),
VerbEntry::new(
"dependency_matrix",
"receipt",
VerbGroup::Engineering,
"Build an object-to-object dependency matrix from co-occurrence in receipt events",
&["dependency_matrix", "dependency", "matrix", "coupling", "objects"],
),
VerbEntry::new(
"catalog",
"receipt",
VerbGroup::Tooling,
"Index a directory of receipts into a local catalog for fast search and lookup",
&["catalog", "index", "registry", "store", "database"],
),
VerbEntry::new(
"search",
"receipt",
VerbGroup::Tooling,
"Search the local receipt catalog by event type, object, date range, or keyword",
&["search", "find", "query", "lookup", "catalog"],
),
VerbEntry::new(
"profile",
"receipt",
VerbGroup::Tooling,
"Profile the performance of verify and assemble operations on a receipt",
&["profile", "benchmark", "perf", "performance", "timing"],
),
VerbEntry::new(
"install_git_hook",
"receipt",
VerbGroup::Tooling,
"Install a git hook that auto-emits receipt events on commit, push, or tag",
&["install_git_hook", "git", "hook", "pre-commit", "post-commit", "auto-emit"],
),
VerbEntry::new(
"monitor",
"receipt",
VerbGroup::Tooling,
"Watch a working receipt file and stream events to stdout as they are appended",
&["monitor", "watch", "stream", "tail", "live"],
),
VerbEntry::new(
"receipt_throughput",
"receipt",
VerbGroup::Tooling,
"Measure how many receipts per second the local store can verify under load",
&["receipt_throughput", "throughput", "load", "benchmark", "performance"],
),
VerbEntry::new(
"visualize",
"receipt",
VerbGroup::Tooling,
"Generate an interactive HTML or SVG visualization of the receipt chain",
&["visualize", "html", "svg", "interactive", "chart", "render"],
),
VerbEntry::new(
"test",
"receipt",
VerbGroup::Tooling,
"Run the built-in receipt self-test suite to validate the local installation",
&["test", "self-test", "smoke-test", "sanity", "validate"],
),
];
pub fn lookup(verb: &str, noun: &str) -> Option<&'static VerbEntry> {
REGISTRY.iter().find(|e| e.verb == verb && e.noun == noun)
}
pub fn by_group(group: VerbGroup) -> Vec<&'static VerbEntry> {
REGISTRY.iter().filter(|e| e.group == group).collect()
}
pub fn did_you_mean(input: &str) -> Vec<&'static VerbEntry> {
let input_lower = input.to_lowercase();
let mut matches: Vec<&'static VerbEntry> = REGISTRY
.iter()
.filter(|e| {
e.verb.contains(&*input_lower)
|| e.keywords.iter().any(|k| k.contains(&*input_lower))
})
.collect();
matches.sort_by_key(|e| {
if e.verb.starts_with(&*input_lower) {
0u8
} else {
1u8
}
});
matches.truncate(5);
matches
}
pub fn verb_count() -> usize {
REGISTRY.len()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn registry_has_67_entries() {
assert_eq!(
verb_count(),
67,
"REGISTRY must have exactly 67 entries — update registry.rs when adding/removing verbs"
);
}
#[test]
fn all_entries_have_non_empty_fields() {
for entry in REGISTRY {
assert!(!entry.verb.is_empty(), "verb is empty");
assert!(!entry.noun.is_empty(), "noun is empty for verb {}", entry.verb);
assert!(!entry.summary.is_empty(), "summary is empty for verb {}", entry.verb);
assert!(!entry.keywords.is_empty(), "keywords is empty for verb {}", entry.verb);
}
}
#[test]
fn lookup_core_verbs() {
for verb in &["emit", "assemble", "verify", "show", "inspect", "stats"] {
let entry = lookup(verb, "receipt")
.unwrap_or_else(|| panic!("verb '{}' not found in registry", verb));
assert_eq!(entry.group, VerbGroup::Core);
}
}
#[test]
fn lookup_missing_returns_none() {
assert!(lookup("nonexistent", "receipt").is_none());
assert!(lookup("emit", "nonexistent").is_none());
}
#[test]
fn by_group_returns_correct_group() {
let core = by_group(VerbGroup::Core);
assert!(!core.is_empty());
for entry in &core {
assert_eq!(entry.group, VerbGroup::Core);
}
}
#[test]
fn did_you_mean_returns_suggestions() {
let suggestions = did_you_mean("emit");
assert!(!suggestions.is_empty());
assert_eq!(suggestions[0].verb, "emit");
}
#[test]
fn did_you_mean_max_five_results() {
let suggestions = did_you_mean("e");
assert!(suggestions.len() <= 5);
}
#[test]
fn all_groups_have_at_least_one_entry() {
let groups = [
VerbGroup::Core,
VerbGroup::Diagnostics,
VerbGroup::Analysis,
VerbGroup::Ingestion,
VerbGroup::Compliance,
VerbGroup::Attestation,
VerbGroup::Sbom,
VerbGroup::Insights,
VerbGroup::Engineering,
VerbGroup::Tooling,
];
for group in groups {
let entries = by_group(group);
assert!(
!entries.is_empty(),
"group {:?} has no entries in REGISTRY",
group
);
}
}
}