Skip to main content

EventLog

Struct EventLog 

Source
pub struct EventLog { /* private fields */ }

Implementations§

Source§

impl EventLog

Source

pub fn open(path: impl AsRef<Path>) -> Result<Self, EventLogError>

Opens (creating if needed) the event log and applies pending migration steps in order, idempotently.

§Errors

Returns EventLogError::Storage on any SQLite failure.

Source

pub fn begin_session(&self) -> Result<SessionId, EventLogError>

Starts a new session (fresh UUID; seq restarts at 1 within it).

§Errors

Currently infallible in practice; Result for API stability.

Source

pub fn append( &self, session: &SessionId, result: &CheckResult, ) -> Result<GateEvent, EventLogError>

Appends one gate decision as an event and returns its envelope.

§Errors

Returns EventLogError on storage or serialization failure.

Source

pub fn append_failopen( &self, session: &SessionId, detail: &str, ) -> Result<GateEvent, EventLogError>

Records a fail-open occurrence (review directive: visible, queryable).

§Errors

Returns EventLogError on storage failure.

Source

pub fn append_escalation( &self, session: &SessionId, detail: &str, ) -> Result<GateEvent, EventLogError>

Records a ladder escalation (attempt cap reached — addendum §7/§8).

§Errors

Returns EventLogError on storage failure.

Source

pub fn append_telemetry( &self, session: &SessionId, telemetry: Telemetry<'_>, ) -> Result<GateEvent, EventLogError>

Records a non-decision telemetry event (spec §14: delivery, nudge arms, and compression tiers ride the same stream as gate decisions, distinguished by decision = "telemetry").

§Errors

Returns EventLogError on storage failure.

Source

pub fn attempts( &self, session: &SessionId, rule: &str, file: &str, ) -> Result<u64, EventLogError>

Session-scoped rule-hit counter — the Phase 2 escalation-ladder substrate (attempt N derives from this).

§Errors

Returns EventLogError::Storage on query failure.

Source

pub fn denied_since( &self, rule: &str, file: &str, since: &str, ) -> Result<bool, EventLogError>

Has an agent write to file ever been denied under rule? The evidence half of the amended charter option B: a recorded deny plus a staged change means the write happened through a surface PreToolUse never saw.

Deliberately CROSS-SESSION, unlike Self::attempts. The ladder counts within one agent conversation; this answers “did any agent get told no about this path”, and the shell running git commit is never the session that was denied.

since is the commit time of the last commit that TOUCHED file, not HEAD’s. That difference is the whole design: the question is not “when was the deny” but “is the denied change still uncommitted”, and only a per-path boundary answers it. Once a human commits the file, the boundary moves past the deny and later edits pass — resolution is committing the change, which is what a human owning the edit actually does.

Comparison is on WHOLE SECONDS, because a git commit time resolves to the second while ts carries microseconds. substr(x, 1, 19) is exactly YYYY-MM-DDTHH:MM:SS — the whole second and nothing after it — so both sides normalize to the one shape they share, however each spells what follows: the time crate writes a fraction only when it is nonzero and renders UTC as a literal Z, while git may render the offset as Z or as +00:00.

The earlier 20-character form is what made this fragile. At that length the deciding character was whichever of . (0x2e), Z (0x5a), or + (0x2b) the two formatters happened to emit, so the verdict rode a formatting accident rather than time. Executed evidence: with git rendering Z, a deny in the same second as the commit compared as OLDER and was silently dropped.

Both sides must therefore be UTC before they arrive: comparing a local-time since against a UTC ts would be wrong by the offset. last_commit_touching pins TZ=UTC on its git log for exactly this reason, and that pin is load-bearing here.

>= counts a deny in the same second as the boundary commit. That direction is deliberate: git’s second resolution cannot tell before from after within a second, and the tie must fall toward blocking, because a false block is visible and recoverable (commit the file, or --no-verify) while a false pass silently defeats the gate. A deny in a strictly earlier second is resolved history and does not count.

§Errors

Returns EventLogError::Storage on query failure.

Source

pub fn block_count(&self, session: &SessionId) -> Result<u64, EventLogError>

Count of block decisions in a session (any rule, any file).

§Errors

Returns EventLogError::Storage on query failure.

Source

pub fn rule_count( &self, session: &SessionId, rule: &str, ) -> Result<u64, EventLogError>

Count of events in a session filed under rule (telemetry included).

§Errors

Returns EventLogError::Storage on query failure.

Source

pub fn failopen_count(&self, session: &SessionId) -> Result<u64, EventLogError>

Count of fail-open events in a session.

§Errors

Returns EventLogError::Storage on query failure.

Source

pub fn stats(&self) -> Result<StatsSummary, EventLogError>

Aggregates for pushkin stats (spec §14): blocks by rule, compression savings, nudge arms, fail-opens — across all sessions in this repo’s log. Historical rows keep their legacy-prefixed ids (append-only); aggregation normalizes so the mixed population groups as one rule (remediation pass 3, PART B2).

§Errors

Returns EventLogError::Storage on query failure.

Source

pub fn decision_counts(&self) -> Result<(u64, u64), EventLogError>

Decision counts for the compact statusline segment: (checks, denials) — real gate decisions only, escalation marker rows excluded so three denials read as three, not four.

§Errors

Returns EventLogError::Storage on query failure.

Source

pub fn latest_session_escalated(&self) -> Result<bool, EventLogError>

Whether the most recent session has hit the escalation ladder cap.

§Errors

Returns EventLogError::Storage on query failure.

Source

pub fn mean_attempts_to_compliance(&self) -> Result<Option<f64>, EventLogError>

Mean-time-to-compliance (integration doc §8): across sessions that recovered (a block followed by an allow), the average number of attempts — denials before the allow, plus the complying write. None when no session has recovered yet.

§Errors

Returns EventLogError::Storage on query failure.

Source

pub fn schema_version(&self) -> Result<u32, EventLogError>

Current schema version.

§Errors

Returns EventLogError::Storage on query failure.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.