← the Atlas

Whole-codebase correctness review

analysis · seedling ·

A static audit of path authority, terminal lifecycle, channel cancellation, session-restore fidelity, parser failures, and kill confirmation. Not a style review.

A static correctness audit of the codebase, focused on logic errors, false safety boundaries, lifecycle leaks, silent failure handling, and restore fidelity. Date: 2026-06-01 · commit reviewed 1a62eeeb · method: repo map, targeted static scans, source verification against line anchors.

Summary

SeverityFindingPrimary surfaceStatus
HighRepo-root guard is lexical only; symlinks can escape the repo for reads, previews, and local diffs.kolu-git, iframe previewfixed #1128
HighTerminal exit subscriptions leak forever for explicitly killed terminals.client terminal lifecycle, server eventsfixed #1105
MediumPTY channel aborts leak subscribers when the abort fires between pulls.@kolu/pty-hostopen
MediumSession restore drops persisted metadata and active selection for sub-terminals.client session restoreopen
MediumOpenCode message JSON parse failure is silently treated as “no messages yet”.OpenCode integration watcherfixed #1108
MediumTerminal kill unregisters local state even when pty-host kill fails; the client removes the UI anyway.server terminal backend, client terminal CRUDopen

Scope

Reviewed the major correctness-bearing paths across packages/common, packages/server, packages/client, packages/integrations, packages/pty-host, packages/shared, and packages/surface — emphasizing file authority, streaming and event lifetimes, session persistence, terminal lifecycle, integration parsers, SQLite/watchers, and error fallbacks. Not run end-to-end; findings are source-derived and should be paired with focused tests as each fix lands.

Findings

High Explicit terminal kills leak exit subscriptions

Every terminal gets a per-terminal exit subscription rooted with createRoot, but the disposer is discarded. The server stream yields once only when terminalExit is published. Natural exits publish that event; explicit kills intentionally do not. The result is a root and event stream that wait forever after every explicit kill.

Refs:

Risk: terminal churn accumulates client roots and server event subscribers for terminals already gone — memory growth and stale event channels over time.

Fix: make subscribeExit return a disposer stored by terminal id (dispose on natural exit, explicit kill, and list removal), or derive exit subscriptions from the terminal list with keyed cleanup.

Status — fixed in #1105 . Exit subscriptions are now derived from the live terminal list with mapArray in useTerminalExits.ts — the same list-keyed lifecycle useTerminalMetadata uses. Each id owns a reactive owner SolidJS disposes the instant the id leaves the list, so explicit kills, killAll, and natural exits all release with no disposer map. Covered by useTerminalExits.test.ts.

Medium PTY channel abort can leak when no pull is pending

Channel.subscribe cleans up immediately when CLOSE is pushed into a pending next(). But an abort that fires between pulls only queues CLOSE. If the consumer never pulls again after cancellation, the subscriber remains in subs and the abort listener remains attached.

Refs:

Risk: cancelled attach/tap streams can leave dead subscribers behind if cancellation happens while the consumer isn’t actively awaiting.

Fix: introduce a single finish() path for abort/close that removes the subscriber and listener immediately, resolves any pending next() as done, and prevents future buffered delivery.

Medium Sub-terminal restore loses saved metadata and active selection

Top-level terminals are restored with saved metadata and the old id mapped to the new id. Sub-terminals are recreated with only cwd — their saved themeName, canvasLayout, panel state, intent, last activity, and agent command are ignored, and their old id is never mapped. A saved active terminal pointing to a sub-terminal therefore cannot be restored.

Refs:

Risk: restoring a workspace with sub-terminals silently changes saved UI and agent state; if the active terminal was a sub-terminal, restore falls back instead of reselecting it.

Fix: change handleCreateSubTerminal to accept InitialTerminalMetadata and return the new id; during restore pass the same persisted fields used for top-level terminals, seed sub/right-panel state, populate oldToNew, and reselect the mapped active sub-terminal.

Medium OpenCode message parse failures are silently treated as empty state

The OpenCode integration reads OpenCode-owned JSON from SQLite. If the latest message.data is malformed, parseMessageState catches the parse error and returns null. The watcher then logs the same debug message used for a legitimate empty session: “no messages yet”.

Refs:

Risk: upstream schema drift or DB corruption hides behind a normal empty-state log; the terminal badge can disappear or stale out without an actionable error.

Fix: return a discriminated parse result or pass logging context into parseMessageState; treat malformed latest-row JSON as a warn/error distinct from “no row”.

Status — fixed in #1108 . parseMessageState logs malformed JSON as error (tagged with the session); the genuine no-row “no messages yet” debug moved into deriveSessionState’s !row branch. session-watcher.ts no longer flattens both into one ambiguous line. Covered by unit tests in index.test.ts.

Medium Kill failures are hidden while local terminal state is removed

The server comment says kill awaits daemon confirmation so a failed kill cannot orphan the PTY. The implementation catches pty-host kill failure, logs it, and unregisters anyway. killAll drains every terminal after a failed killAll too. The client then swallows kill errors and removes the local UI regardless.

Refs:

Risk: if the pty-host kill RPC or transport fails, kolu can forget a still-running PTY and remove the user’s UI handle to it. The in-process host makes this rare, but the backend is written around a daemon/socket confirmation model.

Fix: do not unregister on kill RPC failure — propagate the error and leave the terminal visible, mark it kill-failed while retrying, or unregister only after a natural exit/tombstone. For killAll, only drain terminals confirmed killed.

Triage order

  1. Path authority is fixed. #1128 split lexical normalization from fs.realpath authority and closed the symlink escape — the only issue crossing from correctness into a workspace boundary violation.
  2. Terminal subscription lifecycle is fixed. #1105 landed the list-keyed cleanup + regression coverage.
  3. Fix channel abort cleanup before daemon work expands — a small primitive with a large downstream blast radius.
  4. Fix sub-terminal restore and kill-confirmation together — both terminal lifecycle fidelity issues, covered by restore/CRUD scenarios.
  5. OpenCode parser errors are hardened. #1108 landed the malformed-JSON error path + the empty-vs-malformed log split.