fix(analyst): reduce tool output friction and preserve interrupted traces

Merged
AN
1d ago
+648-53

Issue for this PR

Part of #1497

Remaining from #1497: item 1 reserved-word alias diagnosis, item 3 startup profiling/lazy loading, item 5 duplicate source materialization reuse, item 7 correlated table-function lint (needs a fix in altimate-core). Item 8 was already fixed.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Stacked on feat/analyst-harness-dab-2026-10 (#1441).

Why: analysts hit several small frictions in tool output and diagnosability: misleading error footers, noisy truncation, unqualified schema inspection, startup excluded from the time budget, running tools missing from traces, and cross-warehouse schema search leaks.

Root causes and changes:

  • Error footers told users to start a separate dispatcher although native handlers run in-process. Removed from SQL, schema, lineage and schema-cache errors. Analyst agents skip the progressive-analysis and string-filter hints.
  • Shortened column aliases triggered spilling and an "output truncated" state. Alias-only clipping now keeps the visible marker and schema_truncated metadata without spilling; real omitted data still spills. Row-limit warnings no longer claim a tool cap the connector did not apply.
  • schema_inspect passed dotted names straight to describeTable, and MongoDB inherited the PostgreSQL public fallback. Qualified names are split only when the connector lists that schema; scratch aliases map to main; MongoDB uses its database and lists collections on not-found.
  • The work clock started at prompt dispatch. It is now anchored to process start, and help text says startup is included.
  • Trace.logToolCall only recorded completed/error tools. Running spans are now persisted and updated on completion; unfinished tools are closed as aborted on finalize, shutdown, crash flush and rehydrate.
  • Schema-search OR terms were unparenthesized before the warehouse AND clause, leaking other warehouses. Now grouped.

Deferred: items listed above. Review follow-ups (P2, not fixed): explicit scratch schema is mapped to main even if a real scratch schema exists; completions arriving after trace rehydration create a second span instead of updating the aborted one; alias-only clipping can yield identical headers for long names sharing a prefix.

How did you verify your code works?

  • Touched/related test files (72 files): 2535 pass, 64 skip, 11 fail. All 11 failures are timing-sensitive subprocess tests (--time-budget run flows, budget finalization, trace rename race); the same flows fail intermittently, with varying sets, on a clean checkout of the base (4, 1, 7 failures in repeated runs), so they are pre-existing flakiness.
  • New and updated tests fail before the fix and pass after (formatter/tool 113/7 -> 120/0; schema 50/13 -> 114/0; time budget 6/1 -> pass; running-tool traces 0/8 -> 11/0).
  • bun run typecheck in packages/opencode: pass.
  • Marker check: all changed src/ files except src/cli/cmd/run.ts are absent from the v1.17.9 upstream tag; the run.ts change is inside altimate_change markers. git diff --check clean.

Screenshots / recordings

N/A

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

šŸ¤– Generated with Claude Code


[!NOTE]
Medium Risk
Touches schema routing, MongoDB defaults, trace span lifecycle, and CLI budget timing—behavior changes in production analyst flows and observability, though largely covered by new tests.

Overview
This PR tightens analyst-facing tool output and observability across schema inspection, SQL formatting, tracing, and CLI time budgets.

Schema inspection now resolves MongoDB databases from config or the connection URI (not public), splits schema.table only when the connector lists that schema, maps scratch aliases to main, and returns collection-specific not-found / empty-collection messages. Schema search parenthesizes multi-token OR clauses so warehouse filters apply to every term.

Tool errors drop the misleading ā€œensure the dispatcher is runningā€ footer; the analyst agent also skips progressive SQL hints and small-result filter hints in sql_execute. SQL result formatting treats alias-only clipping as schema metadata (full result saved) instead of ā€œoutput truncated,ā€ and row-limit copy attributes limits to the connector, not the tool limit.

Tracing records tool spans at running, updates the same span on completion, closes unfinished tools as aborted on shutdown/rehydrate, and wires trace-consumer / run-tracing to emit running tool events.

CLI --time-budget anchors elapsed time to process start (including bootstrap), with updated help text.

Reviewed by Cursor Bugbot for commit af4b401b9dddd59db12bb49052b22156f917d9ee. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Reduces analyst-facing tool friction and makes interrupted tool calls visible in traces: misleading error footers are gone, column truncation and schema-inspection edge cases are handled correctly, the time budget includes startup, running tools show up in traces, and schema search no longer leaks across warehouses.

Tool output and schema inspection

  • Removed the "start the dispatcher" footer from SQL, schema, lineage, and schema-cache errors; the analyst agent skips the progressive-analysis and string-filter hints.
  • Alias-only column clipping no longer flags output as truncated, but the full result is now saved so clipped names are not lost; row-limit warnings attribute the cap to the connector.
  • schema_inspect splits qualified table names only when the connector lists that schema, maps scratch aliases to main, and uses the MongoDB database (from config or the connection URI) instead of public; missing collections list the available ones.
  • Parenthesized schema-search OR terms so the warehouse filter applies to every term.

Tracing and time budget

  • The --time-budget clock now starts at process start so startup counts toward the deadline.
  • Tool spans are recorded when running and updated on completion; unfinished tools are closed as aborted on finalize, shutdown, crash flush, and rehydrate, and a completion arriving after rehydration updates the existing span instead of adding a duplicate.