Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
b63244b
feat: release Altimate Base model
anandgupta42 Aug 30, 2026
bc01527
Merge remote-tracking branch 'origin/main' into codex/altimate-base-r…
anandgupta42 Aug 30, 2026
38730f1
chore: mark Altimate Base fork seams
anandgupta42 Aug 30, 2026
a4ea16c
chore: complete Base provider markers
anandgupta42 Aug 30, 2026
bb005cc
fix: inject configurable Base gateway at release
anandgupta42 Aug 30, 2026
c616d26
fix: harden Altimate Base release boundary
anandgupta42 Aug 30, 2026
a3658ef
fix: close Altimate Base release gates
anandgupta42 Aug 30, 2026
bcd7c3e
fix: enforce Altimate Base consent and secret boundary
anandgupta42 Aug 30, 2026
b9121aa
fix: close Altimate Base review findings
anandgupta42 Aug 30, 2026
65a7cc3
fix: mark ACP model guard boundaries
anandgupta42 Aug 30, 2026
4f6ea45
test: align ACP event fixture with model guard
anandgupta42 Aug 30, 2026
ac7f404
fix: close Altimate Base release review gaps
anandgupta42 Aug 30, 2026
99826aa
fix: close final Altimate Base release findings
anandgupta42 Aug 30, 2026
335168d
fix: close release CI gaps
anandgupta42 Aug 30, 2026
c63922f
fix: close late Altimate Base review findings
anandgupta42 Aug 30, 2026
04fceaf
docs: add Altimate Base release handoff
anandgupta42 Aug 30, 2026
936c02f
Merge remote-tracking branch 'origin/main' into codex/altimate-base-r…
anandgupta42 Aug 30, 2026
755b410
fix: harden MCP discovery and ClickHouse TLS
anandgupta42 Aug 30, 2026
ddd31f0
fix: finish Altimate Base release review
anandgupta42 Aug 30, 2026
a68f0b0
fix: clear partial Altimate Base registration state
anandgupta42 Aug 30, 2026
bb778f7
fix: preserve Altimate Base abuse identity on logout
anandgupta42 Aug 30, 2026
696c49d
fix: parse serialized ClickHouse TLS flags
anandgupta42 Aug 30, 2026
57f041a
fix: prevent Altimate Base reconnect after logout
anandgupta42 Aug 30, 2026
1727bae
fix: recover malformed Altimate Base logout
anandgupta42 Aug 30, 2026
e07e3ad
fix: close Base logout and ACP fallback gaps
anandgupta42 Aug 30, 2026
a5b3cd7
fix: use Base namespace in consent boundary
anandgupta42 Aug 30, 2026
7d5d9b2
docs: record final Base boundary fix
anandgupta42 Aug 30, 2026
15655e0
docs: record live altimate base release verification
anandgupta42 Aug 30, 2026
3b25146
Merge remote-tracking branch 'origin/main' into codex/altimate-base-r…
anandgupta42 Aug 31, 2026
d087b61
fix: use free tier store namespace type
anandgupta42 Aug 31, 2026
7ccd16d
fix(base): use gateway URL namespace in release build
anandgupta42 Aug 31, 2026
7629650
fix: keep restored ACP model and effort consistent
anandgupta42 Aug 31, 2026
d5acff9
chore: mark restored ACP effort projection
anandgupta42 Aug 31, 2026
73cedcf
Merge main and migrate Big Pickle defaults
anandgupta42 Aug 31, 2026
9a9d9ed
fix: mark Altimate Base migration changes
anandgupta42 Aug 31, 2026
242f2d0
fix: honor provider allowlists during Base migration
anandgupta42 Aug 31, 2026
f873da1
fix: address blocking review findings on Altimate Base release
anandgupta42 Sep 1, 2026
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 @@ -503,6 +503,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
36 changes: 36 additions & 0 deletions docs/docs/configure/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,42 @@ 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 the hosted Qwen 3.8 free model. It requires no signup or user-managed API key and
is subject to rate limits and abuse protection. Requests and responses are logged and may be used
to improve Altimate products and services. Do not send secrets or confidential code.

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 no longer selected implicitly, but remains available in
the full OpenCode model catalog for users who choose it explicitly.

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. `/providers logout` 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** — hosted Qwen 3.8, free and rate limited, with no signup or API key. Requests and responses are logged and may be used to improve Altimate products and services, 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
20 changes: 20 additions & 0 deletions docs/docs/reference/security-faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,25 @@ 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. `/providers logout` 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 +109,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
1 change: 1 addition & 0 deletions packages/core/src/util/glob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export namespace Glob {
"**/vendor/**",
"**/.git/**",
"**/.pnpm/**",
"**/.yarn/unplugged/**",
"**/.venv/**",
"**/.turbo/**",
]
Expand Down
5 changes: 4 additions & 1 deletion packages/core/test/util/glob.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ beforeAll(async () => {
root = await mkdtemp(path.join(tmpdir(), "glob-ignore-"))
await mkdir(path.join(root, "src"), { recursive: true })
await mkdir(path.join(root, "node_modules", "pkg", ".vscode"), { recursive: true })
await mkdir(path.join(root, ".yarn", "unplugged", "pkg"), { recursive: true })
await mkdir(path.join(root, "vendor"), { recursive: true })
await mkdir(path.join(root, "dist"), { recursive: true })
await mkdir(path.join(root, ".vscode"), { recursive: true })
await writeFile(path.join(root, ".vscode", "mcp.json"), "{}")
await writeFile(path.join(root, "src", "mcp.json"), "{}")
await writeFile(path.join(root, "node_modules", "pkg", ".vscode", "mcp.json"), "{}")
await writeFile(path.join(root, ".yarn", "unplugged", "pkg", "mcp.json"), "{}")
await writeFile(path.join(root, "vendor", "mcp.json"), "{}")
await writeFile(path.join(root, "dist", "mcp.json"), "{}")
})
Expand All @@ -37,6 +39,7 @@ describe("Glob.scan ignore", () => {
const found = (await Glob.scan("**/mcp.json", { cwd: root, absolute: true, dot: true })).map(rel).sort()
expect(found).toEqual([
".vscode/mcp.json",
".yarn/unplugged/pkg/mcp.json",
"dist/mcp.json",
"node_modules/pkg/.vscode/mcp.json",
"src/mcp.json",
Expand Down Expand Up @@ -105,7 +108,7 @@ describe("Glob.DEFAULT_IGNORE", () => {
})

test("covers the package-manager, VCS and build output directories", () => {
for (const dir of ["node_modules", ".git", "dist", "build", "target", ".venv"]) {
for (const dir of ["node_modules", ".git", ".yarn/unplugged", "dist", "build", "target", ".venv"]) {
expect(Glob.DEFAULT_IGNORE).toContain(`**/${dir}/**`)
}
})
Expand Down
Loading
Loading