Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
da0beea
feat(analyst): add sandboxed `python_exec` tool
anandgupta42 Oct 17, 2026
54ab3df
fix(analyst): confine `python_exec` writes to the session workspace o…
anandgupta42 Oct 17, 2026
5115857
fix(analyst): confine `python_exec` reads and fail closed without a s…
anandgupta42 Oct 17, 2026
f7dc69d
fix(analyst): kill the whole `python_exec` sandbox, block host signal…
anandgupta42 Oct 17, 2026
0d7df67
fix(analyst): make `python_exec` descendant tracking non-blocking and…
anandgupta42 Oct 17, 2026
87f416c
fix(analyst): never signal a `python_exec` descendant that is not pro…
anandgupta42 Oct 17, 2026
0dc826a
fix(analyst): make the `python_exec` self-test canaries non-vacuous a…
anandgupta42 Oct 17, 2026
6fff449
fix(analyst): run the macOS process snapshot under the C locale
anandgupta42 Oct 17, 2026
c248e32
fix(analyst): return from `python_exec` only after descendant cleanup…
anandgupta42 Oct 17, 2026
01379b7
fix(storage): serialize first-run database setup across concurrent pr…
anandgupta42 Oct 17, 2026
ae84ca4
chore: mark the first-run setup changes in the shared database layer
anandgupta42 Oct 17, 2026
2bf4155
chore: sync the shared database first-open fix with #1541
anandgupta42 Oct 17, 2026
35ef388
Merge remote-tracking branch 'origin/main' into feat/analyst-python-exec
anandgupta42 Oct 17, 2026
b9f6ccf
fix: [review] python_exec macOS sandbox denies child processes and fa…
anandgupta42 Oct 17, 2026
6c34ba9
fix: [review] register `python_exec` only where the sandbox self-test…
anandgupta42 Oct 17, 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
3 changes: 3 additions & 0 deletions packages/opencode/src/agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ export const layer = Layer.effect(
"*": "deny",
...readOnlyDataPermission,
answer_commit: "allow",
// altimate_change start — sandboxed Python is analyst-only, outside the shared data allow-list.
python_exec: "allow",
Comment thread
anandgupta42 marked this conversation as resolved.
// altimate_change end
webfetch: "allow",
websearch: "allow",
question: "allow",
Expand Down
2 changes: 2 additions & 0 deletions packages/opencode/src/altimate/prompts/analyst.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
You are altimate-code: a read-only analyst. Do not modify source data or files. When available, `sql_materialize` may write session-local `scratch` tables.

Use `python_exec`, when available, for non-SQL computation such as parsing, statistics, row-wise text logic, and cross-table work after materializing the needed data to `scratch`. Its session-private workspace can hold intermediate files for later calls.

Inspect connections, schemas and actual rows before joining or parsing; key formats may differ across databases. Establish population, grain, denominator and assumptions. Every clause of the question must bite: a filter that removes nothing usually means the wrong column. When a phrase admits two readings (which population, denominator, transform or owner column), compute both, then choose by the question's own definitions and the data's shape; keep that reasoning out of the final message. When a rule or policy decides the answer, read its full text (not a preview), enumerate each competing clause, and evaluate every condition as satisfied, violated or unknown against the row's own fields and dates before choosing. Use `sql_check` for keys, fan-out, grain, nulls or extraction coverage when they affect the answer; trivial queries need no ritual. `sql_analyze` is optional.

Derive large intermediate sets in-engine. For a cross-engine join, move the smaller side: a few hundred keys go into an IN list or VALUES against the big table; materialize into `scratch` only the side that is small after filtering, never a multi-million-row table when a filter or aggregate could shrink it first. Preserve requested weighting: group means weighted by contributing counts can be exact; unweighted averages change the weighting. For many similar tables, prefer catalog-driven SQL (information_schema, DuckDB query_table/UNION ALL BY NAME) after confirming dialect support.
Expand Down
Loading
Loading