diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 8d19aaa..cce1e82 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -32,6 +32,8 @@ Optional extras (telemetry, SDK helpers): e.g. **`uv sync --extra dev --extra te FlightDeck's core package (`flightdeck-ai`) does not import OpenAI, Anthropic, or OpenTelemetry at runtime. These extras exist so your project can declare a single dependency (`flightdeck-ai[openai]`) and get a compatible version of both without resolving conflicts manually. +**Note on listed core dependencies:** `pyproject.toml` currently lists `sqlalchemy`, `aiosqlite`, and `rich` as direct (non-optional) dependencies, but `src/flightdeck/` does not import any of them — the package uses the standard-library `sqlite3` module and plain `click` output. These entries are carried over from earlier prototypes and are scheduled for removal in a future cleanup release. + ## Setup (pip — fallback) ```bash diff --git a/docs/cli.md b/docs/cli.md index 6f2deb7..ed15fa6 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -320,6 +320,10 @@ below each action line. 2026-05-01T13:00:00+00:00 promote PASS rel_abc123 baseline=rel_prev789 actor=ci-bot reason=passed staging ``` +**No record limit:** `release history` returns all matching rows from `release_actions` +(newest first). For scripted access to a bounded window, use `GET /v1/actions` which +accepts a `limit` query parameter (1–500, default 50). + --- ## `flightdeck pricing` diff --git a/docs/http-api.md b/docs/http-api.md index c05b438..82f362e 100644 --- a/docs/http-api.md +++ b/docs/http-api.md @@ -242,7 +242,7 @@ Full field reference: [`schemas/v1/run_event.schema.json`](../schemas/v1/run_eve | `api_version` | `"v1"` | no (defaults to `"v1"`) | Must be `"v1"` or omitted. Any other value returns HTTP 400. | | `type` | `"run_start"` \| `"run_end"` | no (defaults to `"run_end"`) | Event type. Only `"run_end"` events carry cost/latency data; `"run_start"` is accepted but contributes no usage. | | `timestamp` | ISO-8601 string | **yes** | Event timestamp. Used for time-window filtering in diff queries. | -| `workspace_id` | string | no (defaults to `"ws_local"`) | Workspace identifier for multi-workspace setups. | +| `workspace_id` | string | no (defaults to `"ws_local"`) | Workspace identifier. Stored with the event but **not used as a query filter** — diff queries filter on `release_id`, `tenant_id`, `task_id`, and `environment` only. | | `agent_id` | string | **yes** | Stable agent identifier (must match the `spec.agent.agent_id` in the registered release). | | `release_id` | string | **yes** | The `release_id` returned by `flightdeck release register`. Links the event to a release record. | | `run_id` | string | **yes** | Unique run identifier per workspace. Duplicate `run_id` values are silently skipped. | diff --git a/docs/operations-and-policy.md b/docs/operations-and-policy.md index eda5583..b0e59ad 100644 --- a/docs/operations-and-policy.md +++ b/docs/operations-and-policy.md @@ -479,6 +479,26 @@ The operations layer reads and writes seven tables (via `src/flightdeck/storage. that migrations are applied through `LATEST_SCHEMA_MIGRATION_VERSION` and that `audit_seq` has no gaps. +### `run_events` column layout + +The `run_events` table stores six indexed columns extracted from each `RunEvent` (used for +filtering in diff and promote/rollback queries) plus the full serialized event: + +| Column | Source | Notes | +|--------|--------|-------| +| `run_id` | `RunEvent.run_id` | PRIMARY KEY; duplicate inserts are silently skipped (idempotent ingestion) | +| `release_id` | `RunEvent.release_id` | Covered by the `(release_id, timestamp)` index added in migration v2 | +| `agent_id` | `RunEvent.agent_id` | Stored for direct inspection; not used as a WHERE clause in current query paths | +| `tenant_id` | `RunEvent.tenant_id` | Used as a filter in `query_runs` (optional `--tenant` flag on `release diff`) | +| `task_id` | `RunEvent.task_id` | Used as a filter in `query_runs` (optional `--task` flag on `release diff`) | +| `environment` | `RunEvent.environment` | Used as a filter in all diff and promote/rollback queries | +| `timestamp` | `RunEvent.timestamp` | ISO-8601 string; used for time-window filtering (`since ≤ timestamp < until`) | +| `event_json` | Full `RunEvent` serialized to JSON | Deserialized into `RunEvent` objects by `query_runs` before returning | + +Fields that are stored inside `event_json` but **not** in top-level columns — and therefore +not filterable in diff queries — include `workspace_id`, `labels`, `request`, and all +`usage.*` fields. The `usage` data is read from `event_json` during cost computation in `compute_rollup`. + ### Storage connection settings Every connection is configured with four pragmas before any statement runs: diff --git a/docs/release-artifact.md b/docs/release-artifact.md index 1f42b15..66a7dc9 100644 --- a/docs/release-artifact.md +++ b/docs/release-artifact.md @@ -196,14 +196,32 @@ flightdeck pricing show --provider openai --version 2024-05 ``` Every import — including `--replace` — writes a record to the `pricing_import_audit` -SQLite table with fields: `import_id`, `provider`, `pricing_version`, `action` -(`"insert"` or `"replace"`), `actor` (OS `$USER`), `reason`, `old_pricing_json` (on -replace), `new_pricing_json`, `new_checksum`, and `created_at`. This record is retained -even if the table is later replaced again. +SQLite table. This record is retained even if the table is later replaced again. + +| Column | Type | Description | +|--------|------|-------------| +| `import_id` | TEXT | `pim_` + 12 random hex chars | +| `provider` | TEXT | Matches the table's `provider` field | +| `pricing_version` | TEXT | Matches the table's `pricing_version` field | +| `action` | TEXT | `"insert"` (first import) or `"replace"` (with `--replace`) | +| `actor` | TEXT | Value of `$USER` / `$USERNAME` at import time | +| `reason` | TEXT | Rationale (required for `"replace"`, `null` for first imports) | +| `old_pricing_json` | TEXT | Serialized previous table contents; `null` for first imports | +| `new_pricing_json` | TEXT | Serialized new table contents | +| `new_checksum` | TEXT | SHA-256 hex of `new_pricing_json` (deterministic serialization) | +| `created_at` | TEXT | ISO-8601 timestamp of this audit event | `--replace` requires `--reason` to be non-empty. Importing without `--replace` when a table already exists returns an error. +To inspect the audit trail directly: + +```bash +sqlite3 .flightdeck/flightdeck.db \ + "SELECT import_id, provider, pricing_version, action, actor, reason, created_at + FROM pricing_import_audit ORDER BY created_at;" +``` + ### Pricing and diff accuracy The diff compares each release using **its own `pricing_reference`** — a baseline and