Skip to content

feat(control-plane): add indexed cursor-paginated request history - #1004

Draft
Wibias wants to merge 3 commits into
lidge-jun:devfrom
Wibias:feat/ri-02-request-history-index
Draft

feat(control-plane): add indexed cursor-paginated request history#1004
Wibias wants to merge 3 commits into
lidge-jun:devfrom
Wibias:feat/ri-02-request-history-index

Conversation

@Wibias

@Wibias Wibias commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

RI-02 of the Router Intelligence / Routing Control Plane programme
(devlog/_plan/260804_router_intelligence/000_master_plan.md). Adds a
rebuildable SQLite projection of the canonical usage.jsonl ledger plus a
cursor-paginated request-history API.

usage.jsonl remains the canonical, append-only request evidence. The index
(routing-history.sqlite in the config dir, Bun's built-in bun:sqlite) is a
derived query index that can be deleted, corrupted, or stale at any time and
is automatically rebuilt from the ledger without losing history (ADR-1/ADR-8).

Scope

  • src/routing/history/schema.ts - versioned schema (schema_meta +
    requests with filter indexes), HISTORY_SCHEMA_VERSION = 1.
  • src/routing/history/cursor.ts - opaque base64url keyset cursor
    (timestamp DESC, request_id DESC), InvalidCursorError.
  • src/routing/history/indexer.ts - open/append/rebuild/repair:
    • schema-version check, PRAGMA quick_check, source file identity
      (size/mtime), byte-offset incremental append;
    • handles: missing DB, corrupt DB (auto rebuild), old schema, partial final
      JSONL line (skipped until it completes), file replacement/truncation
      (identity change -> rebuild), duplicate replay (INSERT OR IGNORE),
      crash during indexing (transactional 500-row batches, WAL);
    • single-flight refresh; prepared statements finalized (Windows lock fix);
    • queryRequestHistory, requestHistoryRowById, rebuildRequestHistoryIndex.
  • src/server/management/request-history-routes.ts -
    • GET /api/request-history - filters: provider, model,
      requestedModel, status, conversationId, surface,
      inboundProtocol, apiKeyId, profileId, fallback, from, to;
      limit (1..100), cursor; response carries entries, nextCursor,
      hasMore, and an index status block (schemaVersion, indexedRows,
      sourceSize, sourceMtimeMs, builtAtMs, lastError).
    • GET /api/request-history/:requestId - one canonical row (404 unknown).
  • CLI: ocx logs rebuild-index, ocx logs index-status (run directly
    against the ledger; no running server needed).

Compatibility

  • usage.jsonl untouched; /api/logs contract unchanged.
  • The index is disposable: deleting it costs nothing beyond a rebuild.
  • Index rebuild is automatic on the next query; ocx logs rebuild-index
    forces one explicitly.

Privacy / security

  • The index only stores data already present in the canonical ledger; no new
    secret surface (same config dir, 0o600 semantics, local file).
  • Row payloads are the normalized persisted entries (already privacy-bounded
    by RI-01 and the usage-log normalizer); no prompts or credentials.
  • Invalid cursors and invalid filters return 400 with stable error codes.
  • bun run privacy:scan passes.

Dependency

Non-goals

  • No analytics endpoints (RI-03).
  • No policy profiles or scoring (RI-04..08).
  • No explainability API/CLI (RI-09), no GUI (RI-10).
  • No changes to /api/logs or the in-memory ring buffer.

Local verification (exact)

  • bun x tsc --noEmit -> PASSED (0 errors)
  • bun run test tests/request-history-index.test.ts -> 16/16 pass
    (1574 assertions) covering: empty/missing/corrupt/old-schema/partial-line/
    replacement/truncation/duplicate-replay/cursor-stability/invalid-cursor/
    page-bounds/rebuild-equivalence/filters/row-by-id
  • Focused regression suites (RI-01 tests, request-log, usage-log, combos,
    combo-management-api, codex-routing, codex-account-namespaces) -> 269/269
  • bun run privacy:scan -> passed
  • Full-suite baseline on clean upstream/dev runs out-of-band; result
    recorded in the stack ledger.

Notes for reviewers

  • Bun 1.3.14 quirks handled and regression-tested: named parameters in
    LIMIT/INSERT silently mis-bind (positional parameters used everywhere);
    unfinalized prepared statements keep the DB locked on Windows after close.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 997d8157-1dff-42fa-99aa-ab62dd620020

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant