You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Introduce a small, stable query interface on TraceStore — filtering by principal,
capability, time window, success/failure, and reason code, with pagination — instead
of only per-action lookup.
Why this matters
The audit trail is the product's flagship artifact, but today consumers can only
fetch a trace by action_id. Operators answering "what did principal X do in the
last hour?" or "which capabilities failed today?" must iterate internals. A query
API is also the natural substrate for the proposed audit CLI (#147), pluggable
persistence (#126), and OTel export (#125): defining it first keeps those layered.
Current evidence
trace.py: TraceStore is an in-memory dict keyed by action id with get/record-style access only; no filtered listing or pagination.
Determinism: ordering must be stable for identical inputs (AGENTS.md).
Edge cases: empty store, overlapping time bounds, limit=0.
Coordinate field names with ISSUE 7's event records if both land.
Acceptance criteria
Queries filter correctly by each field and combinations, with deterministic ordering.
Pagination returns disjoint, complete slices.
The query interface is exported in the public API (__init__.py) and covered by tests/test_public_api.py.
Test plan
Unit tests in tests/test_trace.py covering each filter, combination filters, ordering,
and pagination. Run make ci.
Documentation plan
Add a "Querying the audit trail" section to docs/architecture.md or docs/tutorial.md;
CHANGELOG Added.
Migration and compatibility notes
Additive API; not expected to require migration.
Risks and tradeoffs
Query semantics become a compatibility surface for #126 backends — design the Protocol
deliberately small. In-memory filtering is O(n); acceptable until persistence lands.
Summary
Introduce a small, stable query interface on
TraceStore— filtering by principal,capability, time window, success/failure, and reason code, with pagination — instead
of only per-action lookup.
Why this matters
The audit trail is the product's flagship artifact, but today consumers can only
fetch a trace by
action_id. Operators answering "what did principal X do in thelast hour?" or "which capabilities failed today?" must iterate internals. A query
API is also the natural substrate for the proposed audit CLI (#147), pluggable
persistence (#126), and OTel export (#125): defining it first keeps those layered.
Current evidence
trace.py:TraceStoreis an in-memory dict keyed by action id with get/record-style access only; no filtered listing or pagination.External context
Audit stores in comparable systems expose time-range and principal filters as the
baseline query surface (e.g., OCSF-aligned event stores).
Proposed implementation
TraceQuery(dataclass of optional filters: principal_id, capability_id,since/until, outcome, reason_code, limit/offset or cursor).
TraceStore.query(q: TraceQuery) -> list[ActionTrace]with deterministicordering (timestamp, then action_id).
Kernel.explain-adjacent helper or document direct store access.AI-agent execution notes
trace.py,kernel/__init__.py(trace accessors),tests/test_trace.py.Acceptance criteria
__init__.py) and covered bytests/test_public_api.py.Test plan
Unit tests in
tests/test_trace.pycovering each filter, combination filters, ordering,and pagination. Run
make ci.Documentation plan
Add a "Querying the audit trail" section to
docs/architecture.mdordocs/tutorial.md;CHANGELOG
Added.Migration and compatibility notes
Additive API; not expected to require migration.
Risks and tradeoffs
Query semantics become a compatibility surface for #126 backends — design the Protocol
deliberately small. In-memory filtering is O(n); acceptable until persistence lands.
Suggested labels
product, architecture, developer-experience