Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
2 changes: 1 addition & 1 deletion docs/http-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. |
Expand Down
20 changes: 20 additions & 0 deletions docs/operations-and-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
26 changes: 22 additions & 4 deletions docs/release-artifact.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading