v1.13.15-codecontext-synth: forced second-inference synthesis for codecontext overview tools
After a codecontext overview-class tool call lands (get_codebase_overview, get_framework_analysis, get_semantic_neighborhoods), the pipeline runs a second inference pass that replaces the recursive runAssistantTurn. The synth pass auto-fetches the top-N source files referenced in the codecontext output plus project docs (BOOCHAT.md, AGENTS.md, *roadmap*.md, CONTEXT.md), applies a 32k-token budget with explicit drop-priority, and streams a structured response that grounds the model in real load-bearing code rather than relying on the codecontext summary alone. Smoke #1 (default) and #2 (Architect) both cite the correct inference/turn.ts + tool-phase.ts + stream-phase.ts files; smoke #6 (fault injection) verifies the fall-through path marks the synth message status='failed' and yields cleanly to the recursive turn. ## Truncation-aware extraction codecontext's wrapper inline-truncates results at 32k chars. Without the expansion step, the top-N file selection only saw the alphabetical head of the codebase (apps/booterm/dist/*) and auto-fetched the wrong sources. The pipeline now calls in-process readTruncation(outputPath) before extracting referenced files, so top-N selection sees the full 80k+ char output. The 32k truncated head still ships to the synth model — the expansion is reference-extraction-only, preserving the token-budget contract. Graceful degradation on readTruncation null/throw: log warn, fall back to the truncated head. ## Schema deviation from dispatch The dispatch claimed no schema migration was needed for the new 'synthesis' part kind. Reality: message_parts.kind has an explicit CHECK constraint (schema.sql:54) that would reject the new value. Added a DROP CONSTRAINT IF EXISTS + DO $$ pg_constraint idempotency-guarded re-add matching the CLAUDE.md migration pattern. The inline CREATE TABLE constraint also updated so fresh installs land with the extended enum. ## User-abort marks synth-message failed Deviation from review-time spec ("user-abort path does NOT mark the message failed"). The outer abort handler in error-handler.ts operates on the parent turn's assistantMessageId, not the new synth row that runSynthesisPass created. Without explicit marking, the synth row would sit in status='streaming' until the 5-min stale-streaming sweeper (v1.13.1-cleanup-bundle), tripping the frontend's 60s no-token-activity banner in the meantime — exactly the UX bug class the v1.13.1 sweeper was added to handle. Marking failed on every catch path (including user-abort) closes the gap. Cost: one extra DB write + one publish on the rare user-abort-during-synth path. ## Race-safe synth-tool capture tool-phase.ts uses synthEntries: Array<{tc, output, error?}> with per-callback push under Promise.all. find() picks the first non-error entry by call-order (toolCalls array index). Multiple synth-tools in one batch are uncommon but handled deterministically. ## Roadmap rebase Updated boocode_roadmap.md retrospective section + cleanup-order tracker + schema-changes summary to use the new vMAJOR.MINOR.PATCH-slug tag names per the 2026-05-22 retag (CHANGELOG.md is the canonical record). v1.13.15 listed as "this batch, tag pending"; a one-line follow-up commit will remove that qualifier after the tag lands. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -72,6 +72,29 @@ External code lifted from / referenced in: see `boocode_code_review.md` for full
|
||||
|
||||
-----
|
||||
|
||||
### Shipped (v1.13.x — written 2026-05-22, retagged same day)
|
||||
|
||||
All v1.13.x batches were retagged to the `vMAJOR.MINOR.PATCH-slug` scheme on 2026-05-22. `CHANGELOG.md` is the canonical per-tag record (slug describes what shipped; tag name alone recalls the batch). Tip is `v1.13.14-skills-audit` (`0fa46cd`); the next batch is `v1.13.15-codecontext-synth` (this batch, tag pending). Tags in chronological order:
|
||||
|
||||
- `v1.13.0-ai-sdk-v6` — AI SDK v6 migration; `streamCompletion` adapter; `messages_with_parts` view; reasoning_parts end-to-end
|
||||
- `v1.13.1-cleanup-bundle` — `statement_timeout='30s'`, alpha-sorted tool registry, 60s stuck-row sweeper, `experimental_repairToolCall` pass-through
|
||||
- `v1.13.2-compaction-prune` — two-tier prune; `message_parts.hidden_at` column + partial index; `messages_with_parts` view CASE refinement
|
||||
- `v1.13.3-truncate` — opencode `truncate.ts` port; opaque `tr_<…>` id, `view_truncated_output(id)` tool, tmpfs storage
|
||||
- `v1.13.4-reasoning-fix` — `<reasoning>` prose-prefix in compaction head-assembly for tool-bearing turns
|
||||
- `v1.13.5-stability-bundle` — `includeUsage: true` on provider, `hasText` trim guard, `BUDGET_NO_AGENT` 15→30, trailing-empty-assistant filter
|
||||
- `v1.13.6-prefix-stability` — `buildSystemPromptWithFingerprint` SHA-256 + per-session drift observer
|
||||
- `v1.13.7-compaction-trigger` — overflow trigger lowered to `floor(0.85 × ctx_max)`
|
||||
- `v1.13.8-tool-cost` — `tool_cost_stats` SQL view + per-tool rolling 100-call mean in AgentPicker
|
||||
- `v1.13.9-agentlint` — instruction-file AgentLint pass; identity-openers removed; `CLAUDE.local.md` to .gitignore
|
||||
- `v1.13.10-openspec` — `openspec/changes/<slug>/{proposal,tasks,design}.md` shape; archived batch docs preserved via `git mv`
|
||||
- `v1.13.11-tools` — tiered tool loading via `BOOCODE_TOOLS` env (`core | standard | all`)
|
||||
- `v1.13.12-ws-schemas` — Zod schemas for all 27 wire-format frames; `publishFrame` / `publishUserFrame` wrappers; parity test
|
||||
- `v1.13.13-ws-publish` — all ~80 publish sites converted to the typed wrappers; every WS frame now Zod-validated at boundary
|
||||
- `v1.13.14-skills-audit` — 26 skills vendored + audited via 5 parallel agent teams; 14 kept, 11 dropped, 1 migrated to BOOCHAT.md/BOOCODER.md
|
||||
- `v1.13.15-codecontext-synth` — **this batch, tag pending** — forced second-inference synthesis pass for codecontext overview tools
|
||||
|
||||
The remaining strangler-fig final step (drop `messages.tool_calls` + `tool_results` columns) is still pending under its old `v1.13.2` working name; will get a new tag slug when scoped.
|
||||
|
||||
## In flight / next (v1.13.x cleanup line)
|
||||
|
||||
Five more single-dispatch batches before the strangler-fig closes. Each ships independently with its own smoke and rollback surface. **Do not fold.** Order is locked:
|
||||
@@ -462,17 +485,23 @@ term.indifferentketchup.com → booterm :9501 (or routed under code.
|
||||
- **v1.11.7:** none (pathGuard logic, no DB)
|
||||
- **v1.12.0:** none (codecontext stateless; truncation in-memory id-map with TTL cleanup)
|
||||
- **v1.12.1:** `sessions.workspace_panes jsonb` (workspace sync); drop deprecated `session_panes` table; drop stale `messages_status_check` constraint
|
||||
- **v1.13.0:** `message_parts (id, message_id, sequence, kind, payload jsonb, created_at)` + unique `(message_id, sequence)` + `kind` CHECK; `ToolDef.category` field (TS type, not DB)
|
||||
- **v1.13.1-B:** `messages_with_parts` view with COALESCE fallbacks
|
||||
- **v1.13.3:** `ALTER DATABASE boocode SET statement_timeout = '30s'` (op step, documented in schema.sql; doesn't survive volume reset)
|
||||
- **v1.13.4:** `message_parts.hidden_at TIMESTAMPTZ` column + partial index `(message_id) WHERE hidden_at IS NULL`; `messages_with_parts` view filters hidden parts
|
||||
- **v1.13.5:** none (tmpfs id-map stored on disk under `BOOCODE_TRUNCATION_DIR`; no schema)
|
||||
- **v1.13.6:** none (compaction read-side change; `CompactionMessage` extended in TS, not DB)
|
||||
- **v1.13.7:** none (provider config + 4 frontend/payload guards + budget constant, no schema change)
|
||||
- **v1.13.8 (planned):** none — verify-and-measure batch, instrumentation only; drops the originally-planned `system_prompt_cache` table since recon proved input-layer mtime caches already achieve prefix stability
|
||||
- **v1.13.9 (planned):** none (compaction overflow trigger is a constant change in `services/compaction.ts`, no DB)
|
||||
- **v1.13.10 (planned):** `tool_cost_stats (tool_name, prompt_tokens_sum, completion_tokens_sum, n_calls, updated_at)` — rolling 100-call window
|
||||
- **v1.13.2 (planned):** drop `messages.tool_calls`, `messages.tool_results`; simplify `messages_with_parts` view
|
||||
- **v1.13.0-ai-sdk-v6:** `message_parts (id, message_id, sequence, kind, payload jsonb, created_at)` + unique `(message_id, sequence)` + `kind` CHECK; `messages_with_parts` view with COALESCE fallbacks; `ToolDef.category` field (TS type, not DB)
|
||||
- **v1.13.1-cleanup-bundle:** `ALTER DATABASE boocode SET statement_timeout = '30s'` (op step, documented in schema.sql; doesn't survive volume reset)
|
||||
- **v1.13.2-compaction-prune:** `message_parts.hidden_at TIMESTAMPTZ` column + partial index `(message_id) WHERE hidden_at IS NULL`; `messages_with_parts` view filters hidden parts
|
||||
- **v1.13.3-truncate:** none (tmpfs id-map stored on disk under `BOOCODE_TRUNCATION_DIR`; no schema)
|
||||
- **v1.13.4-reasoning-fix:** none (compaction read-side change; `CompactionMessage` extended in TS, not DB)
|
||||
- **v1.13.5-stability-bundle:** none (provider config + 4 frontend/payload guards + budget constant, no schema change)
|
||||
- **v1.13.6-prefix-stability:** none — verify-and-measure batch, instrumentation only; drops the originally-planned `system_prompt_cache` table since recon proved input-layer mtime caches already achieve prefix stability
|
||||
- **v1.13.7-compaction-trigger:** none (compaction overflow trigger is a constant change in `services/compaction.ts`, no DB)
|
||||
- **v1.13.8-tool-cost:** `tool_cost_stats` SQL view over `messages_with_parts` (no new table — view + LATERAL `jsonb_array_elements` on `tool_calls`); rolling 100-call window
|
||||
- **v1.13.9-agentlint:** none (instruction-file audit + `.gitignore` add of `CLAUDE.local.md`, no DB)
|
||||
- **v1.13.10-openspec:** none (docs reorganization, `git mv` only)
|
||||
- **v1.13.11-tools:** none (env-var tier filter at request time, no DB)
|
||||
- **v1.13.12-ws-schemas:** none (Zod schemas + wrappers in TS, no DB)
|
||||
- **v1.13.13-ws-publish:** none (publish-site conversion + protocol-drift fix in `compaction.ts`, no DB)
|
||||
- **v1.13.14-skills-audit:** none (skills + AGENTS.md migration into git via `.gitignore` negation patterns; no DB)
|
||||
- **v1.13.15-codecontext-synth (this batch, tag pending):** `message_parts.kind` CHECK constraint extended with `'synthesis'` value (DROP + DO $$ pg_constraint idempotency-guarded re-add)
|
||||
- **(column drop, pending — old working name v1.13.2):** drop `messages.tool_calls`, `messages.tool_results`; simplify `messages_with_parts` view
|
||||
- **v1.14:** `agents.steps` column (or AGENTS.md parser extension; no DB if file-only)
|
||||
- **v1.14.x-mcp (NEW):** none — single-server MCP-client PoC is config-only at first, no schema change
|
||||
- **v1.14.x-html (NEW):** `message_parts.kind` CHECK constraint extended with `'html_artifact'` value
|
||||
@@ -582,7 +611,7 @@ Earlier May 18 chat recommended Option A (thin orchestration shell over OpenCode
|
||||
|
||||
### v1.13.x cleanup line locked (2026-05-22)
|
||||
|
||||
After v1.13.1-C shipped clean, the cleanup order is **v1.13.3 ✅ → v1.13.4 ✅ → v1.13.5 ✅ → v1.13.6 ✅ → v1.13.7 ✅ → v1.13.8 (verify) → v1.13.9 (overflow) → v1.13.10 → v1.13.11 → v1.13.12 → v1.13.2** (column drop last as rollback insurance). **Do not fold.** Smoke isolation matters: each batch has a distinct rollback surface, and bisecting a 750-LoC merge across four unrelated changes is worse than four separate dispatches.
|
||||
After the 2026-05-22 retag, the v1.13.x cleanup line in `vMAJOR.MINOR.PATCH-slug` form is **v1.13.0-ai-sdk-v6 ✅ → v1.13.1-cleanup-bundle ✅ → v1.13.2-compaction-prune ✅ → v1.13.3-truncate ✅ → v1.13.4-reasoning-fix ✅ → v1.13.5-stability-bundle ✅ → v1.13.6-prefix-stability ✅ → v1.13.7-compaction-trigger ✅ → v1.13.8-tool-cost ✅ → v1.13.9-agentlint ✅ → v1.13.10-openspec ✅ → v1.13.11-tools ✅ → v1.13.12-ws-schemas ✅ → v1.13.13-ws-publish ✅ → v1.13.14-skills-audit ✅ → v1.13.15-codecontext-synth (this batch, tag pending) → column drop (final, pending — old working name v1.13.2)**. **Do not fold.** Smoke isolation matters: each batch has a distinct rollback surface, and bisecting a 750-LoC merge across four unrelated changes is worse than four separate dispatches.
|
||||
|
||||
### v1.13 retrospective (what shipped)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user