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
53 changes: 53 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,59 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.12.8] - 2026-10-23

**Claude Code can work through your Altimate workspace.** With the Altimate Code plugin installed and the project linked, tasks Claude hands to altimate-code run with the workspace's skills, knowledge and shared memory, and a headless `run` no longer hangs waiting on a stdin nobody writes to. Also in this release: the curl and PowerShell installers add an `altimate-code` command, the analyst can read workspace memory, `learn status` shows whether a lesson keeps being corrected, `schema_inspect` shows what column values look like, and SQL policy checks fail closed on statements they cannot analyze.

**Heads-up for support:**
- **`run` waits at most 3 s on a socket stdin.** When `run` already has a message or `--command` and stdin is a socket (an agent's shell tool, a Node `spawn`), it waits 3 s for the first byte, then continues without stdin and prints one line on stderr; input sent later is ignored. Files and shell pipelines (`dbt build | altimate-code run …`) are still read to the end. `ALTIMATE_RUN_STDIN_WAIT_MS` changes the wait (`0` waits for EOF), and `< /dev/null` (`< NUL` in cmd.exe) skips it. On Windows a pipe is not a socket, so a caller that never closes stdin should redirect it (#1577).
- **`run` may end with a line about unsent memory**, giving the count and `altimate-code workspace sync`. It goes to stderr; scripts that parse stderr will see it.
- **Plain `run` prompts are no longer quoted.** Arguments containing spaces used to reach the model wrapped in quotes; they now arrive as typed. `--command` keeps its quoting.
- **`check` policy and semantic checks fail closed.** altimate-core 0.9.0 accepts table-valued functions (`TABLE(fn())`, Snowflake `LATERAL FLATTEN`, DuckDB `read_csv(...)`) that 0.8.0 rejected as invalid, but cannot plan them. Policy now reports `policy_not_evaluated` and treats the statement as blocked; semantics reports it as skipped instead of clean.
- **`schema_inspect` sends sampled column values to the model provider** by default (see Added). `values: false` turns it off per call, and `ALTIMATE_DISABLE_SCHEMA_VALUES=1` turns it off for every call.
- **`error_fingerprint` telemetry carries a masked `error_message`**: the first line of the error with every word outside a fixed list of common error terms replaced by `<x>`, at most 200 characters. No identifiers, paths, values or SQL.
- **Read and bash deny rules match equivalent path spellings** (relative, absolute, after `cd`, through a symlink). A deny rule can now stop a command that used to slip past it; allow rules are unchanged.
- **Warehouse connections are kept per project directory.** A `serve` process serving two projects no longer shares one project's connections with the other. Global and project connection files load as before; a running server still does not re-read an edited `connections.json`.
- **`datamate_manager` is not offered in projects linked to a workspace**; integrations there come from the workspace's engine. Existing `datamate-*` entries still load, with a one-time notice naming their file.

### Added

- **Claude Code plugin path to workspaces.** The plugin hands work to `altimate-code run` in the linked workspace; the first run in a project pulls the workspace's skills; `workspace list [--json]` lists the workspaces an account can link to. See the Claude Code guide. (#1552)
- **`altimate-code` from the standalone installers.** curl installs link `altimate-code` to `altimate`; PowerShell installs add `altimate-code.cmd` and a Git Bash shim. Re-running the installer adds it to an existing install. Scripts on Windows should call `altimate`, since the `.cmd` shim passes arguments through cmd.exe. (#1562)
- **Column value profiles in `schema_inspect`.** On SQLite, DuckDB, PostgreSQL and MongoDB it adds, per column, distinct count, null share, the most frequent values with counts, uniqueness in the sample and common value shapes, from a bounded sample, so filters match the stored format. MongoDB nested fields are listed by path. (#1542)
- **`ALTIMATE_DISABLE_SCHEMA_VALUES`** turns those value profiles off for every call, whatever the model asks for. (#1578)
- **Lesson recurrence in `learn status`.** It shows whether a lesson that was shown still drew a correction on the same topic, and flags recurring lessons to reflection. (#1556)
- **`/integrations` in the TUI** opens the workspace's integration status directly, or offers the link or the engine install when those are missing. (#1464)
- **Workspace sync state for every client.** When skills and memory were last checked and what changed is recorded and published, so the IDE extension can show it as the TUI sidebar does. (#1429)
- **Analyst data analysis** gets query deadlines, result envelopes, a scratch bridge (`sql_execute` `query_from`) and verification checks. (#1441)
- **`answer_commit` asks once for a missed item.** A commit with fewer fields than the request asked for ("the X and its Y") is rejected once, naming the clause; an unchanged recommit is accepted. (#1553)
- **`client_connected` telemetry** marks the first client to attach to a running server. (#1528)

### Changed

- **The analyst can read workspace memory** (read, refresh and audit) and is steered to workspace skills. Saving memory blocks stays with builder; `training_save` still works. (#1570)
- **altimate-core 0.9.0**, with policy and semantic checks failing closed as described above. The messages now say to review such statements by hand. (#1555, #1585)
- **`datamate_manager` is off in linked projects.** (#1431)
- **Plain `run` prompt arguments are no longer quoted.** (#1561)

### Fixed

- **Headless `run` no longer hangs under an agent's shell.** (#1552)
- **"database is locked" when several CLI processes start on a fresh data directory.** Setup is serialized with a lock that the OS releases if its holder dies; after 5 s of waiting, CLI commands such as `run` and `serve` print the lock they are waiting on to stderr; the TUI writes it to the log. (#1541, #1580)
- **Warehouse connections no longer leak between projects in one server**, including SSH tunnels, which are now owned by the connect attempt that opened them. (#1567)
- **`warehouse_list` with no connections points at the real config locations** and the `ALTIMATE_CODE_CONN_*` variables. (#1559)
- **Workspace memory and link checks match a repo's remote across its URL forms**, using the same comparison as the workspace service. (#1462)
- **A message sent while the assistant is busy attaches the workspace engine.** (#1461)
- **Prompt caching works across working directories.** The environment section moved after the cached instructions, and tool schemas no longer embed the directory. (#1517)
- **Gemini:** tool schemas no longer contain empty-string enum values, which Gemini rejected with a 400 on every request; small calls on Gemini 4 use thinking levels instead of a budget it rejects. (#1532, #1534)
- **Large MongoDB reads are fast again.** Byte-bounded cursors read in 1,000-document batches instead of one document per round trip. (#1480)
- **DuckDB schema indexing** stays in the current catalog, no longer duplicates schemas from attached catalogs, and stops at a 30 s default deadline with partial results. (#1514)
- **The analyst reports tool failures as failures**, accepts valid read-only syntax and retrieves long text in full. (#1448)
- **`run --model` reports a failed provider list as itself**, with the HTTP status, not "Model not found". (#1472)
- **A failed background file scan is handled** instead of surfacing as an unhandled rejection. (#1471)
- **The read-only SQL check blocks PostgreSQL replication-slot copy and sync functions.** `pg_copy_logical_replication_slot`, `pg_copy_physical_replication_slot` and `pg_sync_replication_slots` were not on the side-effect list, so a top-level call passed as read-only; the create and drop slot functions were already blocked. Found in this release's review.
- **`uninstall` on Windows gives PowerShell commands, and says so**, and now also offers to remove the empty `~/.altimate/bin` directory (previously only a legacy `~/.opencode/bin`, with a POSIX `rmdir … 2>/dev/null` line even on Windows). Found in this release's review.

## [0.12.7] - 2026-10-13

**Workspace skills and knowledge come first.** In a linked project the agent prefers the workspace's own skills over lookalikes in the repo or your home folder, and checks the workspace's knowledge base for best practices without being asked. Linking now ends with a starter that says what the workspace provides and suggests prompts. Also in this release: opt-in automatic promotion for `learn`, session traces for the IDE extension, and Snowflake reconnects written to `opencode.log`.
Expand Down
5 changes: 5 additions & 0 deletions docs/docs/data-engineering/tools/schema-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ Table: ANALYTICS.PUBLIC.ORDERS
- `table` (required): Table name (schema-qualified: `schema.table` or just `table`)
- `schema_name` (optional): Schema to search in
- `warehouse` (optional): Connection name
- `values` (optional, default `true`): Append a value profile per column

On SQLite, DuckDB and PostgreSQL connections, and for MongoDB collections, `schema_inspect` also profiles each column's values from a bounded sample (10,000 rows, or 100 documents for MongoDB; at most 40 columns): distinct count, null share and whether the values are unique in the sample. A column with at most 20 distinct values lists all of them with their counts; a text column with more shows its most frequent values with their counts and, for short text, the common value shapes; other columns with more, such as numbers and dates, show only the distinct count and null share. MongoDB nested fields are listed by their dotted paths. The profile shows the stored format, such as case, prefixes or padding, so filters match real data.

The profile contains real cell values, which are sent to your model provider with the rest of the tool output. For tables that hold personal or sensitive data, ask for `values: false` to get the column list only. Set `ALTIMATE_DISABLE_SCHEMA_VALUES=1` to turn value profiles off for every call, whatever the model asks for: no value-profile query runs, and the output says profiles are turned off so the model does not ask again. Only an empty value, `0` or `false` leaves them on.

---

Expand Down
1 change: 1 addition & 0 deletions docs/docs/reference/telemetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ We collect the following categories of events:
| `core_failure` | An internal tool error occurs (tool name, category, error class, truncated error message, PII-safe input signature, and optionally masked arguments — no raw values or credentials) |
| `first_launch` | Fired once on the first CLI run after an install or upgrade, triggered by a marker file the installer wrote — the installers themselves send nothing and contact no telemetry endpoint. Contains the installed version, `is_upgrade`, and `install_method` (`curl`, `powershell`, `npm`, `vscode-extension`, `local` for `install --binary`, or `unknown` for markers written before the field existed). `vscode-extension` starts appearing only once an extension build containing the marker write ships, so a zero share for it means the extension has not rolled out yet rather than no extension installs. No PII. **Reading `is_upgrade`:** it means "this machine had run altimate-code before", probed as whether `~/.altimate/machine-id` already existed — *not* "a binary was already present". A reinstall onto a machine that ever ran the CLI reports `is_upgrade: true`, and `altimate uninstall` leaves `machine-id` in place, so a metric excluding upgrades counts installs **per previously-unseen machine** and undercounts reinstalls onto known ones. (`is_upgrade` is a boolean in the event schema; it arrives in Application Insights `customDimensions` as a string, so KQL filters read `tostring(customDimensions.is_upgrade) != "true"`.) Delivery is at-most-once: the marker is deleted before the event flushes, so a process that dies first loses that install rather than re-firing it every launch. Local `--binary` installs report `version: "local"`. |
| `startup_ready` | Fired once per process when the top-level command can serve its first request or frame (`serve` listening, TUI transport resolved, `run` about to send its first prompt). Contains the command name, `duration_ms` since process start, and `fresh_install` (true when this process also emitted a non-upgrade `first_launch`). No PII. |
| `client_connected` | Fired once per process when the first client attaches to a running server, which separates "the backend started but no client connected" from "connected but never sent a message". Contains `surface` (the launching command: `serve`, `run` or `tui`, also sent on `startup_ready`) and `since_start_ms`. No PII. |
| `event_loop_stall` | A 250 ms monitor tick fired more than 1 s late, meaning the event loop was blocked for that long (for example an in-process dependency install). Contains the command name, `thread` (`main` or `worker`), `blocked_ms`, and `since_start_ms`. Capped at 20 per thread (the main thread and the TUI server worker each keep their own counter). No PII. |
| `altimate_base_registration` | Timing and outcome of each Altimate Base registration, whether triggered automatically at startup, by an explicit picker selection, or through the `POST /altimate/base/register` route an IDE calls (`origin: "server"`) (concurrent calls share one result, and a still-valid cached credential reports `success` without a network round trip): `result` (`success`, `network`, `http`, `response`, `cancelled`, `configuration`, or `error`), `duration_ms`, and the HTTP `status` when the result is `http`. Distinct from `altimate_base_register_result`, which records the onboarding-flow outcome. No gateway URL, response body, credential, or error text is included. |
| `task_outcome_signal` | Behavioral quality signal at session end — accepted, error, abandoned, or cancelled. Includes tool count, step count, duration, and last tool category. No user content. |
Expand Down
4 changes: 3 additions & 1 deletion docs/docs/reference/windows-wsl.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ directory to your user PATH (open a new terminal afterwards). It also writes an
`altimate-code` alias there: `altimate-code.cmd` for cmd.exe and PowerShell, and
an extensionless shim for Git Bash. Inside WSL, install the Linux build with
`curl -fsSL https://www.altimate.sh/install | bash`; the Windows shim refuses to
run there. The installer
run there. The `.cmd` alias passes its arguments through cmd.exe, which expands
`%VAR%` and interprets unquoted `&`, `|` and `^`, so scripts should call
`altimate` directly. The installer
auto-detects AVX2 support and falls back to the baseline build on older CPUs.

Options (pass via a script block):
Expand Down
2 changes: 2 additions & 0 deletions docs/docs/usage/check.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ altimate-code check --fail-on warning
| `semantic` | Semantic validation (cartesian products, wrong JOINs) | Optional | No |
| `grade` | SQL quality grading with recommendations | Optional | No |

`policy` and `semantic` never report a statement the engine cannot plan as clean. Such statements include table-valued functions (`TABLE(fn())`, Snowflake `LATERAL FLATTEN`, DuckDB `read_csv(...)`). `policy` fails closed: it reports a `policy_not_evaluated` error and treats the statement as blocked. `semantic` reports the skip as a finding: an error when `--schema` is given, and a warning without it, which does not fail a run with `--fail-on error`. Earlier versions rejected these statements as invalid SQL.

Findings usually carry a machine-readable `rule` field (e.g. `unbalanced_quote`, `sql_injection`, `L003`) visible in `--format json` output — see the [Finding Object](#finding-object) schema below. `safety` and `policy` findings always include one; `lint` findings may omit both `rule` and `code` if the engine didn't attach them, so switch on presence rather than assuming.

By default, `lint` and `safety` are enabled. Override with `--checks`:
Expand Down
Loading
Loading