pub struct AttributionCensus { /* private fields */ }Expand description
Attribution census over every transaction row read.
Counted over all rows, not only the ones that verified, so a chain that
breaks at row 5 still reports what the remaining rows claim about who
acted. Those claims are only as good as the chain verdict beside them: unless
it is Intact, treat every count here as unproven, and note that
Self::rows can then exceed the verdict’s rows_checked. A row past the
break may be perfectly authentic – a deleted or reordered row breaks the link
while leaving every later signature valid – so the surplus is the part of the
trail this command cannot vouch for, not proof of forgery. Self::rows
exists so a reader can see that gap instead of inferring it.
One counter is not enough, because a row can name no account for reasons with
different remedies. none:unattributed says the daemon tried and failed on a
host that could have attributed the call, which is a configuration problem to
chase in the daemon log. A v1 or v2 row says the encoding had no principal
field when the row was signed, which is history and cannot be repaired:
backfilling it would rewrite the bytes the signature covers. An unattested
value says something wrote to the column that should not have.
Splitting them keeps the report honest on an upgraded database. A single
“unattributed” count of 0 over a chain of pre-v3 rows reads as “every
action is attributed” when in fact none of them is.
Fields are private and Self::of is the only constructor that reads rows, so
a census cannot state totals that contradict the rows it describes.
from_counts_for_tests is the one other way to build one, and it is
not for production. That is not hypothetical tidiness: in 0.3.0 the MCP report
built its own all-zero attribution count on the cannot_verify path, where a
real count had already been computed, and the MCP tool and audit verify --json then published different numbers for one database.
Implementations§
Source§impl AttributionCensus
impl AttributionCensus
Sourcepub fn of(tx_rows: &[ChainRow]) -> Self
pub fn of(tx_rows: &[ChainRow]) -> Self
Count the rows. The only way to obtain a census of real data.
Sourcepub fn named(&self) -> u64
pub fn named(&self) -> u64
Rows whose signed principal names an account (uid: or token:).
Names an account, which is not a person: see SECURITY.md on shared
logins, su, uid reuse, and on token:vsock proving possession of a
file.
Sourcepub fn attribution_failed(&self) -> u64
pub fn attribution_failed(&self) -> u64
Rows signing none:unattributed, the daemon’s admission that it could
not name the caller.
Sourcepub fn not_recorded(&self) -> u64
pub fn not_recorded(&self) -> u64
Rows with no principal the signature covers, normally written before the column existed.
Sourcepub fn unattested(&self) -> u64
pub fn unattested(&self) -> u64
Rows carrying a principal no signature vouches for. Non-zero means investigate: nothing in SysKnife writes such a value.
Sourcepub fn rows(&self) -> u64
pub fn rows(&self) -> u64
Rows censused.
The four row outcomes partition the rows, and Self::of
increments exactly one bucket per row, so this equals their sum. State the
partition rather than the arithmetic: a fifth bucket keeps the partition
true, and any sum written out by hand somewhere else would not survive it.
Sourcepub fn unnamed(&self) -> u64
pub fn unnamed(&self) -> u64
Rows that name no account, for any reason. What an operator asking “can this trail tell me who acted” has to subtract.
Subtraction rather than addition on purpose: a fifth non-naming bucket
cannot make this number stale, whereas summing the reasons would need
editing here too. A future bucket that does name an account would have to
be added to named instead, which is why named is the one counter this
subtracts.
Trait Implementations§
Source§impl Clone for AttributionCensus
impl Clone for AttributionCensus
Source§fn clone(&self) -> AttributionCensus
fn clone(&self) -> AttributionCensus
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for AttributionCensus
Source§impl Debug for AttributionCensus
impl Debug for AttributionCensus
impl Eq for AttributionCensus
Source§impl PartialEq for AttributionCensus
impl PartialEq for AttributionCensus
impl StructuralPartialEq for AttributionCensus
Auto Trait Implementations§
impl Freeze for AttributionCensus
impl RefUnwindSafe for AttributionCensus
impl Send for AttributionCensus
impl Sync for AttributionCensus
impl Unpin for AttributionCensus
impl UnsafeUnpin for AttributionCensus
impl UnwindSafe for AttributionCensus
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more