Skip to content

Land the compaction-loop fix, last_turn counters, and UI cleanup on whip-rlm - #149

Merged
samheutmaker merged 109 commits into
whip-rlmfrom
compaction-loop-and-ui-cleanup
Sep 20, 2026
Merged

samheutmaker merged 109 commits into
whip-rlmfrom
compaction-loop-and-ui-cleanup

Conversation

@samheutmaker

@samheutmaker samheutmaker commented Sep 14, 2026

Copy link
Copy Markdown

Summary

Four commits from the local whip-rlm branch, routed through a PR because whip-rlm requires the go, govulncheck, and codeql checks and rejects direct pushes.

  • Compaction loop fix (internal/agent/agent.go): a fold may now cut inside an oversized turn on an assistant/tool-pair boundary, pinning the turn's opening user message verbatim after the summary. A fold with nothing left to fold makes no model call; a fold that cannot get back under the threshold stalls further proactive folds for the turn; a provider context-limit rejection with nothing left to fold fails the turn with ErrCompactionExhausted. The reactive one-retry is decoupled from proactive folds. Background and evidence: .ai-docs/plans/compaction-loop/.
  • Reload parity (internal/session/session.go): applyCompaction re-derives the pinned message when the fold point is not a user message.
  • Visible child health (internal/session/turn_outcome.go, guide fragment, web agent list): last_turn carries model_calls, compactions, and last_activity_at for the running turn; protocol types regenerated.
  • Compaction-model fallback log (cmd/whip/daemon.go): one compaction.fallback line in whip.log when summaries fall back to the conversation model.
  • Docs: compaction note in docs/agent-loop.md; Loupe SDK-ergonomics records; distribution test fix.
  • UI cleanup across packages/app, apps/web, apps/desktop, and packages/ui.

Merging into whip-rlm triggers release-whipcode.yml.

Test plan

  • go test ./internal/... ./cmd/... green (one daemon acceptance test flaked once under full-suite load with database is locked, passed on every isolated rerun).
  • npm run check in packages/protocol (tsc, interop, drift), tsc -p packages/app/tsconfig.json --noEmit, npm run test:web (602 tests) green.
  • Replay of the incident's real 64-message turn through the new tail selection: 136,638 estimated tokens fold to 18,805 with the opening message pinned and no orphaned tool result.

🤖 Generated with Claude Code


Note

Low Risk
Documentation-only changes under .ai-docs/plans/ with no runtime, protocol, or security surface modified in this diff.

Overview
Adds internal planning and validation ledgers under .ai-docs/plans/ for desktop Browser work—no application or daemon code appears in this diff.

Browser Design Mode (browser-design-mode/): documents the end-to-end Design Mode product contract (hover/select, floating composer, capture/send via existing chat paths, native overlay architecture), implementation slice checklist with automated gate results, and a narrow hover-outline motion follow-up (100ms ease-out, reduced-motion behavior, native/renderer contracts).

Browser tabs & agent attachment (browser-tabs/): a large phased plan for workspace Browser tabs, SSH previews, permissions, and agent control; frozen integration contracts; agent-initiated tabs and list_tabs-style discovery (marked implemented in the working tree); and evidence notes for SDK/WebSocket, native SSH, and packaged acceptance/release gates.

These files record decisions, ownership boundaries, and test status for reviewers—they are not canonical shipped docs (docs/* links to some of them).

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

Sam Hogan and others added 8 commits September 11, 2026 09:34
…s it surfaced

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…he late-ACK fix

Move whip-eval campaigns onto Modal VM Sandboxes without changing the native
Harbor/Pier workers, task bytes, model settings, deadlines, or grading: one
Docker-capable VM per attempt, a detached coordinator function, immutable
allowlisted bundles, and a CLI (whip-eval modal submit/status/logs/fetch/
cancel/reconcile) that survives client exit. Reports label cloud runs as a
separately qualified environment; nothing promotes the native baseline.

Qualification results recorded under evals/reports/modal-*: infrastructure,
90-way credential-free lifecycle (90/90), and the two-task real-model smoke
(2/2 passed, $5.32 estimated). That smoke exposed the one production defect,
a controller export acknowledgement racing a worker that had already exited;
modal_cloud.py now skips the obsolete ACK on an exact-owned integer exit and
only suppresses a typed NotFoundError after ownership re-proof. 102 tests pass.

Plan and resume plan live in .ai-docs/plans/modal-evals.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Inference.net now lists the pinned route as moonshotai/kimi-k3 while the bare
kimi-k3 id still serves completions at high effort. prepare.catalog falls
back to a listing whose last path segment equals the pin, keeps kimi-k3 as
the id whip calls and caches so routing and pricing lookups stay aligned,
and records the listed id as listed_id. Exact listings still win; ambiguous
or near-miss listings still fail closed. 103 tests pass.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…-size limit

Inference.net now rejects prompt + max_tokens above the 1,048,576-token
context, and the pinned whip binary sends max_tokens equal to the catalog's
max_completion_tokens when the config leaves maxOut at 0, so every smoke
trial died with a 403 before its first model call. The frozen eval
configuration now sets maxOut to 262,144: it cannot realistically bind and
leaves about 786K tokens for prompts. Documented as a deviation from the
native cohort, which ran effectively unbounded.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Comment thread internal/session/session.go Outdated
@github-actions

github-actions Bot commented Sep 14, 2026

Copy link
Copy Markdown

🔍 loupe · go-review

✅ no issues · 2 files

PR-wide Go/web changes were previously reviewed; this pass reassesses only the two files changed since: the desktop-check workflow now installs the Playwright ffmpeg build (required by smoke.mjs's new recordVideo) and points the smoke at the already-uploaded evidence directory, and smoke.mjs gains drag-geometry diagnostics plus sidebar drag-to-split assertions. Callers verified: smoke.mjs is invoked only by this workflow (env paths are safe — the script mkdirs the artifacts dir, and the upload step at desktop-check.yml:58 already globbed that path); the 'Connect' and 'General' locator updates match the current host-connection-dialog and settings navigation in this PR; the new assertions match the WorkspaceTabs/WorkspaceLayout drag contract (fresh view per sidebar drop, existing tab order preserved, window bounds unchanged, draft preserved). No correctness, concurrency, or security defects found in the reassessed files.

Run details
  • review: agentic
  • verification: skipped
  • scope: delta
  • dropped: 0 malformed finding(s), 0 malformed concern(s), 0 out of scope, 0 below profile, 0 rejected by verification
  • off-diff notes published: 0

Last reviewed commit: 46b6a00

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread internal/agent/agent.go
Sam Hogan and others added 19 commits September 13, 2026 19:56
…ion log

Runs -a and -b are local preparation failures (key absent, provider model
rename); -c ran end to end with the reviewed controller (complete, proven
cleanup) but every trial died on the provider's new total-token limit; -d
passed all six terminal tasks after the maxOut cap, with both repository
tasks lost to a provider-side 30-second no-token stall. The plan's log
carries the diagnosis and the pending decision.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Brings the detached Modal eval workflow, its qualification record, the
late-ACK controller fix, and the 2026-09-13 smoke reruns onto the branch
the whip fixes are landing on.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Inference.net's kimi-k3 route now stalls on long calls (a 30-second
no-token cutoff killed both repository tasks in today's smoke), so the
pinned route moves to kimi-k3-fast. The model id was spread across the
protocol file, whip's config writer, the observer's CLI arguments, the
native runner's model label, and an adapter guard; it now lives in
whip_evals.common.MODEL, the observer takes it from the contract's
configuration, and a test asserts frontier/protocol.json agrees. The
track name changes with it, so cloud reports form a separate environment
from the native kimi-k3 cohort.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…no defaultModel

The runtime-ab tests drive observe.run with a stub configuration; canonical
trials still take the model from the contract.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Supersedes the 2026-09-11 MCP review with recorded decisions: repairs plus
a truthfulness pass, definition server list as a boundary, eager connect
with a separate project import source, project-over-user-import
precedence, import confers trust, ACP-only additive attach, structured
content and image handles, and a five-server acceptance matrix.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The suite no longer reads the developer's ~/.codex/config.toml by default,
and the opt-in run logs header counts instead of header values.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The daemon-managed stdio path copied cfg.Env into the process manager
verbatim, so a documented "$VAR" reference reached the child as the literal
string while the fallback path resolved it. Both transports now call one
connectSecrets step. "!cmd" helpers run under the connect's own context via
ResolveSecretContext, so a cancelled connect no longer leaves a helper
running.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
headerTransport re-adds configured headers after Go's redirect logic has
already stripped Authorization for a cross-origin hop, so a redirecting
endpoint handed the bearer token to another host. The remote client now
refuses redirects that leave the endpoint's scheme and host; same-origin
redirects keep the headers.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The daemon reads null as every host server and [] as none, but the SDK's
generic list helper collapsed both undefined and [] to null, so an agent
computed with an empty allowlist requested all servers. Only the MCP field
changes; other list fields keep nil-equals-empty semantics.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Connect and catalog refresh read only the first page, so anything past it
did not exist to the model. listAllTools follows cursors under the startup
deadline, bounded to 64 pages, rejects a repeated cursor, and returns the
whole catalog so callers publish it atomically.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
kickAutoReconnect only ran from the disconnect watcher, so one failed
redial ended the chain at a single attempt despite the three-attempt
budget. A failed automatic attempt now schedules the next one; a startup
or manual attempt still stays failed for a human, and a manual reconnect
resets the automatic budget. The give-up test asserts the exact count.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The Codex TOML reader parsed the whole file, so one [[array]] table or an
unsupported top-level value anywhere in ~/.codex/config.toml failed all
MCP discovery, and the daemon showed "no servers" for "failed to parse".
Only [mcp_servers...] tables are parsed now; foreign sections are skipped
and malformed server tables still error. Discovery errors become failed
status rows named by source, are logged at daemon startup, and are printed
by whip mcp import.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…er imports

The repository's .mcp.json shared the claude gate with the user's global
~/.claude.json, and a user-global Codex entry silently overrode a project
file of the same name. The project file is now a third import source,
project, off unless enabled because a repository author wrote it, and the
merge order is native, project, codex, claude-global. Blocked rows name
their source. The daemon, TUI, web panel, and protocol status carry the
new source; schemas and generated TypeScript are regenerated.

Also adds SourceErrors to the client-control test fake so it satisfies the
interface extended in the previous commit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Materialized imports dropped their Origin and Source, so an imported server
copied into whip's own config is now trusted like a hand-written entry, no
per-call consent. This is the one path from imported-and-prompting to
native-and-trusted; the command says so on both dry-run and apply. Closes
mcp-polish item 8 (overlay entries): a materialized import is native, not a
patch over its source.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…itive

Startup filtered discovery by the definition's server list while mcp.attach
rebuilt the manager from every native server, so one authorized attach
widened a restricted agent. mcp.Select is now the single selection step for
the factory and for attachment. Attach no longer replaces the running
manager or re-reads native configuration: attachments are untrusted and
additive across names, names outside the definition's list or belonging to
a native server are recorded as blocked rows, and re-attaching a
non-native name replaces that entry.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
flattenResult dropped structuredContent whenever any text existed and
reduced images to placeholders. A call's text now keeps every text part and
appends structured content as JSON; image, audio and binary resource parts
travel as attachments that the calling agent's services store as content
handles named in the text. Image parts also reach the root's next turn
through the existing screenshot sink; children get the handle only.
CallChecked returns a result struct so nothing is lost between the manager
and the dispatcher handler.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Policy-filtered and attach-refused servers showed as "disabled" and
unreadable discovery sources as "failed", so clients could not tell a row
the daemon can act on from one it cannot. Blocked rows now carry status
"blocked" and source rows "unreadable"; both are never live servers.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Removes the private JSON attach box: it duplicated whip mcp add with a
sensitive one-shot input, and attach is an ACP-facing operation now.
Renames "Available tools" to "Built-in tools" since it lists whip's own
schemas, not MCP tools. Each server row offers only the controls the
daemon can honor for its state (none for blocked or unreadable rows),
every control names its subject and scope ("Reconnect docs", "Disable docs
for this session"), and import toggles live under "Host import defaults"
with the project source.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The palette derived its server rows from local config, so imported,
attached and remote-daemon servers appeared in status but not in the
palette, and a stale local name offered controls the daemon could not
honor. The model now keeps the last mcp.status rows and the palette offers
each server only the actions its state supports, with blocked and
unreadable rows pointing at the status view that explains them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
samheutmaker and others added 7 commits September 17, 2026 17:50
Integrate Browser tabs while preserving the target branch's newer UI and MCP changes over the feature branch's earlier checkpoint. Retain both SDK fixture runner controls and tool-host handling, and regenerate guide digests from the combined source.

Validated with the full Go suite, protocol generation/check, 368 SDK tests, 720 frontend tests, 118 desktop tests (10 opt-in SSH skips), 92 distribution tests, frontend build/typechecks, desktop typecheck, 49 live-daemon SDK acceptance tests, and the selected-holder Browser WebSocket regression (synthetic native bridge).
The shell guide line said shell.start "returns a job id" and listed
shell.read(handle=...) with no source for the handle. In the Starlark run
modal-full-20260917-starlark-b the model passed the whole start result as
id (host saw "" and said no such job), indexed ["output"] on a wait view
before the job had ended, and handed job ids to shell.read (rejected as
an unauthorized content reference). The line now names the start result
shape, says to pass job["id"], states the 25 s wait cap and timed_out,
that tail's text is under "tail", that poll/wait carry output only after
the job ends (inline or as a handle), and that shell.read takes that
handle, never a job id. The result-shape rule points at the same source.
Golden prompts regenerated for both dialects.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…, Starlark strings

Three fixes chosen from the r2 and Starlark HALO analyses: keep "output"
on large bounded results (the model followed the result-shape rule and
the host withheld the key), make a wrong-typed or job-id shell argument
answer with the fix or the job itself instead of "no such job \"\"" and
"not authorized", and give the Starlark guide its multi-line and raw
string sentence. Records Sam's decision not to touch QuickJS const
redeclaration semantics.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Combine the upstream shell-job and content-handle guidance with the existing
Browser instructions, and regenerate definition prompts and engine digests.
Preserve the earlier Browser/chat integration and all subsequent UI work.

Validation: go test ./internal/rlm ./internal/agentdef; race-enabled definition
prompt and runtime-guide tests; app and SDK trees unchanged from 6ae8d5d.
@github-actions

Copy link
Copy Markdown

⚠️ loupe · go-review could not complete this review — whip error: "403 Forbidden: {"error":{"message":"Prompt token size exceeds maximum supported size (1048576). Please contact us if you need a larger context size.","type":"ForbiddenError"}}"

See the Actions run logs for details.

Comment thread internal/agent/agent.go Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread packages/app/src/session-tabs.ts
Comment thread packages/app/src/conversation.tsx Outdated
Comment thread packages/app/src/trace-view.tsx
Comment thread packages/app/src/trace-view.tsx

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread packages/app/src/agent-dock.tsx
Record explicit compaction pin state in schema v21, normalize legacy timestamps transactionally, and recheck compaction after history growth. Use checked integer parsing for MCP settings, align browser probes with current presentation and stream readiness, and add boundary regression tests raising portable race coverage to 90.1%.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread internal/agent/agent.go
Comment thread internal/session/migrations.go
Enable the existing whipcode CodeQL configuration on PRs targeting whip-rlm so GitHub can compare against the branch baseline. Keep publishing branch-only, preserve its concurrency lock and permissions, and test the security and release dependency contracts.
Emit compaction start callbacks only after shared foldability preflight while preserving all three eventful paths and callback-free callers. Accept valid peer-completed v20 migrations in v19 and older compatible upgrade helpers without weakening schema identity checks. Cover no-op callback ordering and stale-opener migration idempotence with race-tested regressions.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

There are 6 total unresolved issues (including 5 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ad81db0. Configure here.

Comment thread internal/session/migrations.go
@samheutmaker

Copy link
Copy Markdown
Author

Review follow-ups and final validation

Review follow-ups are complete in 46b6a00209: 20 fixed, 2 already satisfied/obsolete across the 22 open threads. The latest no-op notice, concurrent v19→v20, and V11 peer-v20 findings are included. The latest scan found 32 total threads / 22 open, with no additional findings beyond these.

Review comment(s) Resolution and regression evidence
#4001849634 Persist explicit compaction Pinned; replay no longer infers it from a non-user tail. internal/session/session.go:336–384, internal/agent/agent.go:1078; reopen/fork + legacy-no-inferred-pin tests in internal/session/compaction_migration_test.go:85,146.
#4010705115 Subscription preserves typed deadline cause before ctx.Err: internal/llm/subscription.go:84–95; TestSubscriptionRetriesAttemptCeilingBeforeHeaders in internal/llm/review_deadline_test.go:12.
#4010705119 Model catalogs have a bounded context covering headers and body in both auth paths: internal/llm/openai.go:734–750; TestModelsBoundsHeadersAndBody, internal/llm/review_deadline_test.go:37.
#4011288116 Legacy whole-second SQL timestamps normalize transactionally with schema 21, preserving precise/empty values: internal/session/compaction_migration.go:15–44, timestamp_migration.go:9–113; ordering and rollback tests in timestamp_migration_test.go:11,115.
#4011667865 Obsolete: regeneration emits stream.discard and consumers rewind: internal/daemon/agent_session.go:178–186, packages/app/src/conversation-rows.ts:224–232, packages/sdk/src/turn.ts:230–232. The raw callback/discard contract is explicit in internal/llm/stall_test.go:112–132; discard boundary test in packages/sdk/test/state.test.ts:175.
#4011702426 Canonical copied SQLite calls/root must match report input: evals/whip_evals/report.py:202–220; tamper/root/corruption regression in evals/tests/test_reports.py:168.
#4011702431 Provider classification uses structured errors or specific provider phrases, not ordinary task output: evals/whip_evals/report.py:65–74; regressions in evals/tests/test_reports.py:195,296.
#4017406215 incomplete exits 2: evals/whip_evals/cli.py:100; run/report status matrix in evals/tests/test_contract.py:265.
#4017702125 No-history checks stay unstalled so later rounds can fold: internal/agent/agent.go:860–869; growth regression in internal/agent/compaction_split_test.go:207.
#4017702132, #4032491604, #4052111031 All per-turn compaction guards reset on every exit via deferred finishTurn: internal/agent/agent.go:493,714–721; reactive/proactive failed-turn regressions in internal/agent/agent_test.go:492,539.
#4033037161 Exact OTLP envelope/span/comma budgeting; oversized singleton fails explicitly: internal/session/otlp_export.go:136–178; TestSplitOTLPByteBounds in internal/session/otlp_split_bounds_test.go:9.
#4042306453 Obsolete: each attempt already uses typed ceiling context around invocation: internal/llm/accounting.go:484–494; ceiling retry regressions in internal/llm/stall_test.go:145 and review_deadline_test.go:12.
#4054315900 Inspector toggles do not change companion identity: packages/app/src/session-tabs.ts:508–514; source/child/both regression in packages/app/test/session-tabs.test.ts:43.
#4054315901 In-place REPL/Trace round trips keep the companion and highlight: packages/app/src/conversation.tsx:164–167; regression in packages/app/test/conversation-agent-dock.test.tsx:111.
#4054372274 Evicted trace selection falls back to retained newest, preserving Whole session: packages/app/src/trace-view.tsx:48–51; tests in packages/app/test/trace-view.test.tsx:102,118.
#4054372278 Native non-passive wheel listener with cleanup: packages/app/src/trace-view.tsx:118–135; cancellation/mount/toggle/unmount regression in packages/app/test/trace-view.test.tsx:133.
#4054883339 Expansion refreshes the clock in the same action: packages/app/src/agent-dock.tsx:124; first-commit duration regression in packages/app/test/agent-dock.test.tsx:175.
#4055037807 Shared compactWithStart sends the notice only after foldability checks: internal/agent/agent.go:983–985,1027–1034 (callers at 549/862/1219). Repeated no-op checks are silent, real-fold callback order is verified in compaction_split_test.go:207–270; all three paths retain start-before-summary/exactly-once coverage in agent_test.go:1070–1140.
#4055037813 Exact v20 identity is treated as peer-completed by v19 and earlier applicable helpers, then migration continues to v21: internal/session/inbox_queue_migration.go:14–33, migrations.go:442–449,471–477,510–514, filesystem_access_migration.go:28–33. No repeated backfill/provenance loss; unsupported identities remain rejected: internal/session/inbox_queue_migration_test.go:10,74,123.
#4055115276 V11 now accepts exact peer-v20 identity: internal/session/turn_outcome_migration.go:28–36. The real production chain is shared through migrations.go:376–449; all 22 stale-snapshot paths (v10..v20 × peer20/21) preserve provenance and prohibit repeated backfill in inbox_queue_migration_test.go:74–121, plus all11 helper progression at :10–72 and rejection coverage at :123.

Independent hardening (not another thread): upgradeV20 now validates exact source20/target21 identity and rejects foreign/mismatched/future schemas before mutation (internal/session/compaction_migration.go:19–44). TestV20UpgradeRejectsUnsupportedSchemaWithoutMutation at internal/session/compaction_migration_test.go:14–83 covers 14 direct/stale20 cases and compares schema version, identity, and change counters. Existing legacy v14–v18 helper guards were not broadened.

Compatibility note: old v20 compactions cannot reveal whether a pin was intentional, so the migration conservatively defaults legacy pins to false; raw messages and summaries are unchanged.

Final validation: All checks passed on 46b6a002096f007ac205671f2c800c6f839196a4 (CI run): Go tests, SDK/browser/performance gates, desktop package/lifecycle (6m15s), mobile, four builds, both runtime platforms, lint, CodeQL, and vulnerability scans. Fresh full portable go test -race -shuffle=on passed at 90.2% statement coverage, above the unchanged 90% floor. Focused/full-session race regressions and independent static/source reviews also passed; no check bypasses, alert dismissals, or threshold reductions were used.

Desktop diagnostic caveat: The preceding a4a9c35986 desktop run failed the drag-preview pointer-alignment assertion once (10px versus the unchanged <2px bound). Controlled font-delay, viewport/scroll, and CPU-throttling tests did not reproduce it. This head adds run-specific geometry, screenshots/video, and the CI FFmpeg prerequisite—not a production drag-logic fix. The fresh hosted diagnostic-enabled lifecycle run passed, but capture affects timing, so the original failure's cause remains unconfirmed.

@samheutmaker
samheutmaker merged commit 1075516 into whip-rlm Sep 20, 2026
24 checks passed
@samheutmaker
samheutmaker deleted the compaction-loop-and-ui-cleanup branch September 20, 2026 00:16
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