Skip to content

Tranches 9–12: chat/build stability, hardening, and perf — by Ox Alpha - #1

Merged
RasputinKaiser merged 17 commits into
mainfrom
tranche-9-through-12
Aug 25, 2026
Merged

RasputinKaiser merged 17 commits into
mainfrom
tranche-9-through-12

Conversation

@RasputinKaiser

Copy link
Copy Markdown
Owner

Tranches 9–12: Hemlock chat/build stability, hardening, and performance

Author: Ox Alpha

Summary

Sixteen commits spanning four tranches of iterative work on the Hemlock local-AI chat surface, plus a critical MLX upgrade that fixes a class of uncatchable Metal GPU crashes. The through-line across every tranche: make the chat→build loop trustworthy — no wedged composers, no silently dropped streams, honest error surfaces, and deterministic verification at every gate.

Highlights

🔧 Root-cause fix: MLX 0.32.1 (75a3795)

Upgrades MLX from <0.32.0 to 0.32.1, where Metal CommandBuffer errors became catchable exceptions instead of process-killing SIGABRTs. This was the root cause of the GPU-timeout crashes that motivated the watchdog work in Tranche 8.

🛡️ Tranche 9 — Hardening (93a24d1, 14e30d3)

  • Readiness probe for server startup (launch script guarded behind defaulted env vars)
  • Error taxonomy: user-visible failures classified instead of raw dumps
  • Artifact flow tests, stop button, renderer hygiene pass

⚡ Tranche 10 — Stability + perf (e707da7)

  • Coalesced stream updates: createFrameCoalescer buffers stream frames, drains on rAF or a 50 ms cap (fixes background-tab stalls); terminal frames drain synchronously; shared scheduler fixes a prior rAF leak
  • Composer untrap guards: pre-flight failures in startDream and sendMessage no longer strand isDreaming/isThinking true — composer can never wedge disabled again
  • Plan approval guards: approvePlan rejects non-waiting_for_approval states without mutation; budget overrides clamped via existing pure clampBudgetOverrides
  • Queue duplicate rejection: identical pending objectives are rejected as duplicates; active-task steering and FIFO order untouched

✨ Tranche 11 — Polish + hardening (125d36b)

  • Host stream performance, taxonomy gaps closed
  • Transcript memoization
  • Streaming prose improvements

🩹 Tranche 12 hotfix (e1fbefe)

Build-mode loop dead, artifacts reach viewer, chat reads top-down.

Earlier reliability work (tranches 6–8, included)

  • Cache telemetry, stall watchdog, Metal error surfacing, dead-flag cleanup (694a813)
  • Partial output preserved on cancel; fresh-context reset for poisoned history (46ad96d)
  • Honest tok/s accounting via include_usage + approx fallback; artifact-id sanitization (a1ad5ba)
  • Provider escalation removed — Hemlock runs only the selected model lane (2b96689)
  • Crash-loop policy with visible recovery + re-run button under server death (1e457d3)
  • Terminated SSE connections recognized as transport errors; honest empty-reply copy (76756e7)
  • Seamless loop: answer-in-place, grantable budgets, eval lane (19dbd09)
  • Grounded harness: memory injection, thread digests, verification card (dfe2c1e)
  • Understory night mode + Maple runtime hardening (b165526)

Scope

70 files changed, ~7,900 insertions / ~465 deletions across the host (Electron main), renderer, Maple runtime, launch scripts, MLX patches, and state ledger.

Verification

Per-tranche deterministic gates recorded in state.yaml:

  • Electron: 241/241 tests passing (236 baseline + new coverage)
  • Renderer: 30/30 tests passing (26 baseline + new coverage)
  • vite build, node --check on main/orchestrator/maple_runtime, esbuild — all green

Claim boundary: verification is deterministic-only; coalescing latency gains, untrap guards, duplicate rejection, and stop-button behavior have not yet been exercised against a live wedged/streaming server session.

…ssible glossary hints, launcher reap, onboarding polish
… verification card, fitness loop, comparison lane)
…tes, composer untrap guards, plan-approval guards, queue duplicate rejection)

Renderer: ordered frame coalescer (rAF or 50ms cap, sync terminal drain),
pre-flight failure guards keep isDreaming/isThinking from stranding the
composer. Host: approvePlan rejects non-waiting states and clamps budget
overrides; intent queue rejects duplicate pending objectives.

Gates: electron 241/241, renderer 30/30, esbuild ok, node --check ok,
vite build ok.
…axonomy gaps, transcript memoization, streaming prose)

Host: checkpoint throttle no longer JSON.stringify's all channels per SSE
chunk (O(n²) over stream length — pure shouldCheckpointStream predicate +
incremental byte accounting); streamRing leak fixed on finishStream;
agentEventIds dedup set bounded to 4096; taxonomy gains endpoint-not-found,
server-error, action-envelope-invalid, unreachable-host kinds.
Renderer: memoized TranscriptMessageRow (only the streaming row re-renders
per coalesced flush); honest waiting state instead of flashing terminal
empty-copy mid-stream; 72ch prose measure; caret pulse w/ reduced-motion
fallback; contrast fixes (reasoning 4.32→5.56:1, skipped-card 4.09→5.13:1);
plan card reads objective → steps → usage → actions.

Gates: electron 249/249, renderer 33/33, esbuild ok, node --check ok,
vite build ok.
…, chat reads top-down

Root cause of the loop (from durable receipts): adaptPlanForCommand inserted
a NEW plan step for every adaptive re-proposal of an already-completed
command, growing the plan forever and pushing the real step out of reach.
Anti-repeat progress guard now redirects repeat proposals to the plan's next
incomplete step with an action.redirected host note; plan no longer mutates.

artifact.author: create-if-missing ensure step before authoring; registry
throws degrade to the host scaffold instead of failing the action; taskId is
now injected at executeCommand so authoring never resolves under a foreign
task. Next-action prompt states 'Completed already (do NOT repeat)' + plan
progress explicitly.

Renderer: live-stream panel renders BELOW the transcript (was above sent
messages); plan card owns its own grid row in the transcript column (no more
overlap with the work rail).

Gates: electron 257/257 (+8), renderer 34/34 (+1), esbuild ok,
node --check ok, vite build ok.
@RasputinKaiser
RasputinKaiser merged commit d5f50d7 into main Aug 25, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant