provenance: convert from enum to freeform string

The Provenance enum couldn't represent agents defined outside the
source code. Replace it with a Text field in the capnp schema so any
agent can write its own provenance label (e.g. "extractor:write",
"rename:tombstone") without a code change.

Schema: rename old enum fields to provenanceOld, add new Text
provenance fields. Old enum kept for reading legacy records.
Migration: from_capnp_migrate() falls back to old enum when the
new text field is empty.

Also adds `poc-memory tail` command for viewing recent store writes.

Co-Authored-By: ProofOfConcept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-03-11 01:19:52 -04:00
parent de204e3075
commit d76b14dfcd
14 changed files with 160 additions and 67 deletions

View file

@ -38,7 +38,7 @@
// Stages are parsed from strings and composed via the -p flag or
// pipe-separated in agent definitions.
use crate::store::{Store, StoreView, NodeType, Provenance};
use crate::store::{Store, StoreView, NodeType};
use crate::graph::Graph;
use crate::spectral;
@ -147,7 +147,7 @@ pub enum Filter {
Weight(Cmp),
Age(Cmp), // vs now - timestamp (seconds)
ContentLen(Cmp),
Provenance(Provenance),
Provenance(String),
NotVisited { agent: String, duration: i64 }, // seconds
Visited { agent: String },
Negated(Box<Filter>),
@ -280,9 +280,7 @@ impl Stage {
"age" => Stage::Filter(Filter::Age(parse_cmp(value)?)),
"content-len" => Stage::Filter(Filter::ContentLen(parse_cmp(value)?)),
"provenance" => {
let prov = Provenance::from_label(value)
.ok_or_else(|| format!("unknown provenance: {}", value))?;
Stage::Filter(Filter::Provenance(prov))
Stage::Filter(Filter::Provenance(value.to_string()))
}
"not-visited" => {
let (agent, dur) = value.split_once(',')
@ -363,7 +361,7 @@ impl fmt::Display for Filter {
Filter::Weight(c) => write!(f, "weight:{}", c),
Filter::Age(c) => write!(f, "age:{}", c),
Filter::ContentLen(c) => write!(f, "content-len:{}", c),
Filter::Provenance(p) => write!(f, "provenance:{}", p.label()),
Filter::Provenance(p) => write!(f, "provenance:{}", p),
Filter::NotVisited { agent, duration } => write!(f, "not-visited:{},{}s", agent, duration),
Filter::Visited { agent } => write!(f, "visited:{}", agent),
Filter::Negated(inner) => write!(f, "!{}", inner),