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
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ jobs:
env:
OPENCODE_VERSION: 0.0.0-sanity-${{ github.sha }}
OPENCODE_RELEASE: "1"
ALTIMATE_BASE_GATEWAY_URL: https://gateway.test
MODELS_DEV_API_JSON: test/tool/fixtures/models-api.json

- name: Build dbt-tools
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ jobs:
# a plain tag (v0.9.0) goes to `latest`. Prevents a beta tag from bricking the whole user base.
OPENCODE_CHANNEL: ${{ contains(github.ref_name, '-') && 'beta' || 'latest' }}
OPENCODE_RELEASE: "1"
# altimate_change — embed the operator-controlled Base endpoint without publishing it in source
ALTIMATE_BASE_GATEWAY_URL: ${{ vars.ALTIMATE_BASE_GATEWAY_URL }}
GH_REPO: ${{ env.GH_REPO }}
# altimate_change — MODELS_DEV_API_JSON is deliberately NOT set here.
# Pointing it at test/tool/fixtures/models-api.json (as ci.yml does, where
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,16 @@ installing it in your own repository.

Then — in order:

**Step 1: Configure your LLM provider** (required before anything works):
**Step 1: Choose an LLM provider** (required before anything works):
```bash
altimate # Launch the TUI
/connect # Interactive setup — choose your provider and enter your API key
/connect # Interactive setup — choose Altimate Base, sign in, or bring an API key
```

Altimate Base is the free, no-signup option. It is rate limited, and its requests and responses
are logged and may be used to improve Altimate products and services; do not send secrets or
confidential code. The setup dialog shows this disclosure and defaults to **No** before registering.

Or set an environment variable directly:
```bash
export ANTHROPIC_API_KEY=your_key # Anthropic Claude
Expand Down
48 changes: 48 additions & 0 deletions docs/docs/configure/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,54 @@ For pricing, security, and data handling details, see the [Altimate LLM Gateway
!!! tip "Automatic model selection"
When Altimate credentials are configured and no model is explicitly chosen, the Altimate LLM Gateway is selected automatically. You can override this by setting `model` in your config or by restricting the `provider` section to specific providers only.

## Altimate Base

Altimate Base is Altimate's own hosted free model. It requires no signup or user-managed API key
and is subject to rate limits and abuse protection.

**Data handling:** Requests and responses are logged and may be used to improve Altimate's products,
including the model. Secrets are automatically masked before storage, but don't rely on it — avoid
sending secrets or confidential code. Altimate Base is pseudonymous, not anonymous: a stable
per-installation identifier links your requests across launches and `altimate providers logout
altimate-base` does not reset it (see the [security FAQ](../reference/security-faq.md)). Usage is
rate limited.

If you need stronger guarantees — no training on your data, metadata-only retention — use the
[Altimate LLM Gateway](https://help.altimate.ai/datamates/user-guide/components/llm-gateway/)
instead.

Choose **Altimate Base** from the first-run picker or `/connect`. A disclosure is shown before any
registration request; **No** is selected by default. After registration, the model is available as
`altimate-free/altimate-base` and becomes the free fallback when no paid Altimate Gateway or
explicit model is selected. Big Pickle is retired as a new selection — it no longer appears in the
picker or the full model catalog for users choosing a model for the first time. Users already on
Big Pickle are still detected on launch and offered Altimate Base through the same consent gate.

Official release binaries embed the current gateway endpoint at build time. Operators and local
development can override it without changing code:

```bash
export ALTIMATE_BASE_GATEWAY_URL=https://your-gateway.example
altimate
```

The URL must use HTTPS. Credentials,
query strings, and fragments in the URL are rejected. `ALTIMATE_FREE_GATEWAY_URL` is retained as a
legacy fallback, but `ALTIMATE_BASE_GATEWAY_URL` takes precedence. If the configured gateway host
changes, credentials issued by the previous host are not loaded and the consented registration
flow must run again.

Altimate Base credentials are stored separately from the shared provider-auth file and are never
returned to the TUI. The installation secret is hashed before registration; the gateway receives
the hash, not the local secret.

That hash is stable across launches, so it links this installation's logged requests together —
it is what enforces the free allowance. Running `altimate providers logout altimate-base` clears
the credential but keeps the installation identity on purpose, so logging out is not a way to
reset the allowance. Each inference request additionally carries a session identifier used for
rate limiting. See the security FAQ for what this means for privacy and how to reset the local
identity.

## Anthropic

```json
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/getting-started/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ On a fresh install, a welcome panel appears with a curated 6-provider picker:

- **Altimate LLM Gateway** *(recommended)* — 10M tokens free, no API keys. Routes to the best model per task across Sonnet, Opus, GPT-5, and more. Sign-in opens a browser tab; complete Google or email signup and you're back in the TUI. If your terminal can't open a browser (SSH / tmux / WSL), the CLI prints the URL — paste it into a browser on your desktop.
- **Anthropic** / **OpenAI** / **Google** — paste an API key or OAuth in.
- **Big Pickle** — free tier, chats work but many data tasks fail; useful for kicking tires.
- **Altimate Base** — a hosted open model, free and rate limited, with no signup or API key. Requests and responses may be logged and used to improve Altimate's products, so do not send secrets or confidential code. Registration happens only after an explicit confirmation that defaults to **No**.
- **Search all providers…** — full picker if you need Bedrock, Databricks AI Gateway, Cloudflare AI Gateway, Snowflake Cortex, DigitalOcean Inference, etc.

Or set an environment variable and skip the picker:
Expand All @@ -36,7 +36,7 @@ altimate
```

!!! tip "Don't want to manage API keys?"
The [Altimate LLM Gateway](https://help.altimate.ai/datamates/user-guide/components/llm-gateway/) is the top row of the picker — 10M free tokens, and altimate-code auto-selects the right model per task. First-run sign-in uses a loopback OAuth on `127.0.0.1:7317-7325` (falls back if the preferred port is taken).
Choose **Altimate Base** for the no-signup, rate-limited model. Choose the [Altimate LLM Gateway](https://help.altimate.ai/datamates/user-guide/components/llm-gateway/) for 10M free tokens and automatic model routing. Gateway sign-in uses a loopback OAuth on `127.0.0.1:7317-7325` (falls back if the preferred port is taken).

---

Expand Down
1 change: 1 addition & 0 deletions docs/docs/reference/network.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ altimate needs outbound HTTPS access to:
| Destination | Purpose |
|-------------|---------|
| Your LLM provider API | Model inference (Anthropic, OpenAI, etc.) |
| Official Altimate Base gateway (embedded in release), or the host set by `ALTIMATE_BASE_GATEWAY_URL` | Altimate Base registration and inference when you explicitly enable Altimate Base |
| `registry.npmjs.org` | Package updates |
| `models.dev` | Model catalog (can be disabled) |
| Your warehouse endpoints | Database connections |
Expand Down
21 changes: 21 additions & 0 deletions docs/docs/reference/security-faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,26 @@ Answers to the most common security questions about running Altimate Code in you

Altimate Code sends prompts and context to the LLM provider you configure (Anthropic, OpenAI, Azure OpenAI, AWS Bedrock, etc.). **You choose the provider.** No data is sent anywhere else except optional [telemetry](#what-telemetry-is-collected), which contains no code, queries, or credentials.

Altimate Base is an optional hosted provider. Its confirmation dialog explains that requests and
responses are logged and may be used to improve Altimate products and services; do not send
secrets or confidential code. The dialog defaults to **No**, and no registration request is made
unless you explicitly accept. This request logging is part of the Altimate Base service and is
separate from anonymous product telemetry.

**What identifies you to Altimate Base.** Registration sends a SHA-256 hash of a locally generated
installation secret — the secret itself never leaves your machine. That hash is stable, so logged
requests from this installation are linked to one another. This is deliberate: it is how the free
allowance is enforced. Running `altimate providers logout altimate-base` disconnects the provider
but **keeps** the installation identity, by design, so that logging out and back in cannot mint a
fresh allowance. Each inference request also carries a session identifier used for rate limiting
and abuse control.

Altimate Base is therefore pseudonymous, not anonymous. To reset the local identity completely,
delete `altimate-base.json` from the application data directory — `$XDG_DATA_HOME/altimate-code/`,
which defaults to `~/.local/share/altimate-code/` on both macOS and Linux — while the app is
closed. This is outside the supported flow, and the gateway applies its own network-level rate
limits.

If you use a self-hosted or VPC-deployed model (e.g., AWS Bedrock, Azure OpenAI), your data never leaves your cloud account.

## Can the AI read my database credentials?
Expand Down Expand Up @@ -90,6 +110,7 @@ You can also configure per-agent permissions. For example, restrict the `analyst
| Destination | Purpose |
|-------------|---------|
| Your configured LLM provider | Model inference |
| Altimate Base gateway | Registration and inference only after you explicitly enable Altimate Base |
| Your warehouse endpoints | Database queries |
| `registry.npmjs.org` | Package updates |
| `models.dev` | Model catalog (can be disabled) |
Expand Down
9 changes: 5 additions & 4 deletions docs/docs/reference/telemetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ We collect the following categories of events:
| `validator_check` | A completion-gate validator ran on session end — validator name, `ok` boolean, step, retry count, `enforced` flag (false in shadow mode), and structured `details` (model counts, elapsed time, concurrency limit — no SQL or model content). Only emitted when `ALTIMATE_VALIDATORS_ENABLED=1` or `ALTIMATE_VALIDATORS_SHADOW=1`. See [Validators](../data-engineering/validators.md). |
| `validator_retries_exhausted` | A session terminated with unresolved validator failures after exhausting the synthetic-retry budget — names of the failing validators (no failure body content). |
| `onboarding_started` | The first-run setup gate opened (fresh launch with no usable model). |
| `model_picker_shown` | The provider picker was displayed. `trigger` distinguishes the first run from `/connect`, from declining Big Pickle, and from the prompt gate. |
| `provider_selected` | A provider row was chosen — `altimate_gateway`, `anthropic`, `openai`, `google`, `big_pickle`, `search_all`, or `other` for anything outside the curated five. `provider_id` carries the raw id only for publicly-known providers, so a provider you named yourself in config is reported as `other` with no name attached. `via_search` marks a pick made inside the full catalogue after choosing "Search all providers…". **Choosing search emits this event twice for one user** — once as `search_all`, then again with the provider actually chosen — so count distinct users or filter on `via_search`, not raw event count. Recorded at the moment of choice, so a sign-in that is then cancelled still counts. |
| `big_pickle_confirm_shown` / `big_pickle_choice` | The Big Pickle interstitial was shown, and what the user decided (`accept`/`cancel`). |
| `model_picker_shown` | The provider picker was displayed. `trigger` distinguishes the first run from `/connect`, from declining Altimate Base, and from the prompt gate. |
| `provider_selected` | A provider row was chosen — `altimate_gateway`, `altimate_base`, `anthropic`, `openai`, `google`, `search_all`, or `other` for anything outside the curated five. `provider_id` carries the raw id only for publicly-known providers, so a provider you named yourself in config is reported as `other` with no name attached. `via_search` marks a pick made inside the full catalogue after choosing "Search all providers…". **Choosing search emits this event twice for one user** — once as `search_all`, then again with the provider actually chosen — so count distinct users or filter on `via_search`, not raw event count. Recorded at the moment of choice, so a sign-in that is then cancelled still counts. |
| `altimate_base_confirm_shown` / `altimate_base_choice` | The Altimate Base disclosure was shown (`welcome` or `model` origin), and what the user decided (`accept`/`cancel`). |
| `altimate_base_register_result` | The consented registration outcome: `success`, `rate_limited`, `unavailable`, `network`, or `error`. No credential or gateway response body is included. |
| `gateway_device_code_issued` | The Altimate Gateway authorize URL was built and the browser open attempted. **Name note:** the flow is a browser loopback OAuth — there is no device code. The name follows the original event spec. |
| `gateway_auth_completed` / `gateway_auth_failed` | Gateway sign-in outcome. `reason` is `timeout`, `denied`, or `error` — never the underlying message, which can contain the instance name. An unrecognised callback state does not reject the pending attempt, so a CSRF mismatch surfaces as `timeout`. |
| `instance_connected` | Credentials received and saved. `time_to_connect_ms` runs from the start of the authorize call, so it includes the browser launch. No instance or tenant name is sent. |
Expand All @@ -65,7 +66,7 @@ We collect the following categories of events:
| `activation_menu_shown` | The activation menu was (very likely) rendered. `variant` is `warehouse` or `no_data`. **Derived** — see the note below. |
| `activation_job_selected` / `first_job_completed` | Which activation job the user started and, where observable, finished. Completion is reported only for the job that was actually selected, so the two form a coherent pair. **Derived** — see the note below. |
| `first_prompt_sent` | The user's first typed message in an onboarding session. Slash commands are excluded, so the hidden `/onboard-connect` submission does not count. |
| `onboarding_abandoned` | The CLI exited during a first run without connecting. `last_stage` is the furthest point reached: `started`, `model_picker`, `provider_setup`, `big_pickle_confirm`, or `gateway_auth`. (`connected` is a funnel position but never a `last_stage` — reaching it means the run completed, which is not an abandonment.) Only emitted for a genuine first run — opening `/connect` as an existing user does not enter the funnel, and abandonment after setup completes is out of scope by definition. Emitted on the exit path under a bounded flush, so the measured rate is a lower bound — see [Delivery & Reliability](#delivery--reliability). |
| `onboarding_abandoned` | The CLI exited during a first run without connecting. `last_stage` is the furthest point reached: `started`, `model_picker`, `provider_setup`, `altimate_base_confirm`, or `gateway_auth`. (`connected` is a funnel position but never a `last_stage` — reaching it means the run completed, which is not an abandonment.) Only emitted for a genuine first run — opening `/connect` as an existing user does not enter the funnel, and abandonment after setup completes is out of scope by definition. Emitted on the exit path under a bounded flush, so the measured rate is a lower bound — see [Delivery & Reliability](#delivery--reliability). |
| `review_run` | A dbt/SQL review completed or failed — `invocation` (`cli` for `altimate-code review`, `tool` for the `dbt_pr_review` tool), status, duration, and on success the verdict, the pre-gating verdict, mode, risk tier, and finding counts by severity and by category. No file paths, model or column names, finding titles or bodies, SQL, diff content, or repository/branch/PR names. |
| `review_post_outcome` | Whether a review was published to GitHub — `not_requested`, `not_attempted`, `target_unresolved`, `full`, `partial`, or `summary_failed`, plus duration. Emitted on the **CLI path only** — the `dbt_pr_review` tool completes reviews but never publishes, so a `review_run` with `invocation: tool` has no post event and that is not a failure. Within the CLI path there is exactly one per **completed** review: a review that failed emits `review_run: failed` and no post event, so absence there means the review failed rather than that an event was lost. `not_attempted` is publication requested but never reached (a bad `--output` path, a stdout write error). No repository, PR, or comment content. |

Expand Down
Loading
Loading