Skip to content

Add a query API to TraceStore (filter by principal, capability, time, outcome) #177

Description

@dgenio

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 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

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

  1. Define TraceQuery (dataclass of optional filters: principal_id, capability_id,
    since/until, outcome, reason_code, limit/offset or cursor).
  2. Implement TraceStore.query(q: TraceQuery) -> list[ActionTrace] with deterministic
    ordering (timestamp, then action_id).
  3. Keep the interface a Protocol so [Feature] Pluggable persistence for TraceStore, HandleStore, and token revocation (SQLite + JSONL backends) #126 backends implement the same contract.
  4. Wire Kernel.explain-adjacent helper or document direct store access.

AI-agent execution notes

  • Inspect first: trace.py, kernel/__init__.py (trace accessors), tests/test_trace.py.
  • 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.

Suggested labels

product, architecture, developer-experience

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions