• v1.13.15-codecontext-synth: forced second-inference synthesis for codecontext overview tools

    indifferentketchup released this 2026-05-22 20:08:47 +00:00

    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

    Downloads