You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(#707): agent — expired-read hint stops ordering the re-read it elsewhere punishes
fix(#705,#706): agent/desktop follow-ups — commit hint resolves FilesEdited against workingDir before the intersection (the LLM's literal relative tool arguments no longer produce an empty ∩ with the absolutized dirty tree — the #698 fix works for relative paths too), the UI event channel stops dropping request-class events (ask_user/approval requests ride a lossless path — only regenerable token-stream data may drop; a dropped request can no longer hang the agent on a no-timeout ask, and request/cancel pairs cannot both vanish)
fix(#703,#704): tui/desktop — /cost all consumes HasPricing in the display layer (unpriced rows render "(no pricing data)" instead of fake-precise $0.0000; an all-unpriced grand total prints "(no pricing data for any session)" — the previously dead agg.HasPricing hook is wired; mixed totals keep the #687 partial annotation), JSON session export redacts before truncating (formatMessagesAsJSON runs RedactForDisplay on the full ToolArgs/Content before the 2000-byte cut, matching the Markdown path — boundary-straddling secrets can no longer slip below the regex minimum length into the shared artifact)
fix(#699,#700,#701): desktop — NewSession/RespondAskUser use the chat snapshot taken at the nil check (no more TOCTOU re-read of a.chat across workspace switches; nil path returns an error instead of silent success; initWorkspace propagates NewChatBridge failures to its three callers), lastCloseAttempt converted to atomic.Pointer[time.Time] (the four unsynchronized goroutines — OnBeforeClose, focus tracking, hotkey toggle, tray handlers — now Load/Store; the hotkey window-toggle direction race is gone), the UI event loop survives panics (each event dispatched under a per-event recover; enqueueUIEvent is a non-blocking select with drop accounting — one panicked handler no longer deadlocks every emitter on a full 4096 buffer; the Windows toast drain worker gets the same guard)
fix(#696,#697,#698,#702): agent/context/checkpoint follow-ups — commit hint attributes only the agent's own edits (FilesEdited ∩ dirty tree with porcelain relative-path normalization; pre-existing/untracked dirt disclosed separately with a do-not-touch note; git stash round-trips no longer exempt the hint; porcelain parser's TrimSpace offset bug that ate the status column fixed), context pins its four LOW defects (benign-removal contract extended to both orphan paths, version-diff inference replaced with an explicit lastSummarizeApplied flag ending CheckAndSummarize false positives, script-aware CJK token estimation, pinned items on a consistent rune unit), zz_issue685 regression test rewritten to deterministically pin the #685 promise (order assertion on a forced-random map iteration; disclosure accuracy asserted against the real error text)
fix(#693,#694): im/tui follow-ups — binding unmute gains dead-owner takeover (foreignOwnerPossiblyAlive via instanceDetect liveness: a binding whose owning session is dead is claimed and LastSessionID re-declared in memory and on disk; a live foreign owner is still rejected — UnmuteBinding and UnmuteAll now share the same classifier, UnmuteAll stops bypassing ownership entirely), clearPendingApprovals releases the questionnaire response channel (a non-blocking cancelled answer instead of nil-dropping it — the agent goroutine no longer hangs on an abandoned ask; tunnelPendingAskUserID cleared alongside), and the #688 batch's async safego.Go release sends become synchronous non-blocking selects (a select/default send cannot block; the goroutine wrapper only added nondeterministic timing that made the #688 test flake 3/15 under -race)
fix(#691,#692,#695): regression follow-ups — JSON-aware argv truncation's structural-boundary path actually produces a valid prefix (the scanner never matched, so every >64KB payload collapsed to the 90-byte marker — audit hooks failed open and the payload was destroyed; now boundary cuts succeed and the marker is the true fallback), tar decompress-limit hits get their own marker (a 200MB byte cap is not corruption and not the entry cap — three distinct attributions; header-boundary hits stop truncating silently), monorepo scoper's suppression cap guard matches reality (the unreachable >max branch and the comment describing a nonexistent mechanism are gone)
fix(#689,#690): im/desktop — rebind purges the disabled tombstone (#434's lone violation: dead adapters stop lingering and ghosts stop resurrecting on rebind; missing syncInstanceActiveChannels restored), UnmuteBinding enforces ownership (a binding whose LastSessionID belongs to another session is rejected instead of letting UpdateSessionID hijack the channel), reload keeps in-memory bindings until the nil checks pass (pre-session reload no longer wipes currentBindings/prevMuted), platform-switch guard gates the full transport family (Transport/Command/Args/Env/AllowFrom reset on platform mismatch — the old stdio bridge command with its old-env credentials can no longer resurrect on a new platform; same-platform inheritance unchanged)
fix(#688): tui — /clear new-session branch syncs ConfigPolicy (cp.SetMode(globalMode) alongside m.mode — the policy layer no longer keeps session A's autopilot alive while the UI shows supervised; the resume branch already synced), pending approvals cleared on session switch and both mode-change paths (clearPendingApprovals releases a blocked approval waiter with Deny, resets pendingDiffConfirm/tunnelPendingApprovalID/pendingQuestionnaire — stale approval requests stop leaking across /clear, Shift+Tab, and /mode)
fix(#684,#685,#686,#687): regression closeout round 2 — argv truncation is JSON-aware (structure-boundary cuts with an explicit truncation marker fallback; audit hooks stop receiving illegal JSON and crashing fail-open), non-blocking exit-2/403 violation reasons flow through PolicyNotice into Output (all three consumers read Output only), Revert walks files in deterministic checkpoint-first-touch order with precise disclosure of restored vs pending on partial failure (history stays retryable; no more random map-order mixed states), TUI revert toast lists every restored file, SVG decode errors return flagged partial text (the promised-but-missing #683 path; archive-contained SVGs stop vanishing silently), /cost all discloses sessions without pricing instead of a fake-precise total, tar corruption and entry-cap truncation are distinct markers, monorepo hint retries cap at 3 with per-run reset
test(#667,#673): make persistence-failure injection cross-platform
fix(#681,#682,#683): agent/cost/extract regression closeout — one-shot prompts survive budget rejection (injectGuidance reports delivery; checkpoint/monorepo one-shots retry next turn instead of being silently consumed forever), detector inner quotas only count DELIVERED guidance (a budget rejection no longer burns the detector's per-run warning slots leaving 0 delivered), tar-family truncation is marked like zip (200MB/500-entry caps surface Truncated instead of silently dropping entries; the drain counter is honored), SVG decode errors stop masquerading as success (partial text flagged, script contents excluded), unknown models show "(no pricing data)" instead of fake-precise $0.00 (persisted .cost.json recalculates once pricing becomes known), net-loss rendering drops the double minus
fix(#678,#680): checkpoint/desktop — Revert() restores the target checkpoint's full file set (UndoRun pattern: per-file state at the target moment — last NewContent before idx, or OldContent+Existed for first edits — written back for every unique file in the span before truncation; failure keeps the history retryable; no more mixed disk state, dishonest Correction records, or unre-doable undos), OAuth epoch snapshot and currentOAuthFlow read merged into one oauthMu critical section (the re-login race's stale epoch can no longer make a fresh Complete misreport "no flow in progress") with the joiner re-reading oauthLogoutGen after wakeup (a Logout between done-close and wakeup is no longer missed)
fix(#679): hooks — tail-star matcher anchors on the path segment (a trailing * stopped being a no-op that fell through to whole-document JSON matching and mis-blocked unrelated tools; it now anchors like every other wildcard position), $RAW_INPUT/$PAYLOAD argv injection truncates like the #566-C envp fix (oversized payloads no longer hit Linux E2BIG and silently bypass hook auditing), post_tool_use exit-2 no longer short-circuits the injection (the blocking verdict kept its injection payload instead of dropping it)
fix(#677): agent — iteration-level detector guidance routed through the budget (30 bare contextManager.Add sites in the 1700-2300 cluster — errorCompound/correctionSpiral/errorRush/targetScatter/toolThermal/momentumLoss/verifyDebt/editPropagation/solutionFixation/redundantReverify and the rest — now pass injectGuidance; the documented "hard per-turn limit across ALL detectors combined" is finally true; error storms cap at 5 warnings/turn instead of 3-4 un-budgeted near-duplicates each), solutionFixation/redundantReverify reset() wired into the per-run reset block (per-run-2 semantics restored — the counters were per-Agent-lifetime, going permanently silent after run 2; firedFor/recentCalls/failedByFile no longer leak across runs)
fix(#676): session test infra — drain the store's background maintenance before t.TempDir() cleanup
fix(#674,#675): desktop — OAuth single-flight binds to the flow generation (a re-login's fresh Complete no longer inherits a stale flow's failure; the new flow's waiter stops leaking) and logout gates the exchange's token save (a token completed during the uncancellable 30s exchange is discarded instead of reviving after logout), clipboard text-branch mime whitelist widened to the full textual family (pasted .svg keeps image/svg+xml instead of degrading to sniffed text/plain — the comment's stated intent, now the implementation)
fix(#672,#673): acp/tunnel/cron — device flow classifies transport errors (permanent failures — DNS NXDOMAIN, TLS/cert, non-429 4xx, non-JSON 200 — abort immediately instead of burning the 15-minute poll; 200-with-empty-token is a terminal error, no more fake-success persistence; transient retries cap at 30 with slow_down intervals clamped to 60s), stale-epoch drops become observable (debug.Log with session/type/event/epoch; nil-return semantics unchanged), cron Update rollback skips timer rebuild when the restored NextFire is already past (no spurious AfterFunc(0) fire)
fix(#670,#671): desktop — LogoutAnthropicOAuth gains the #616 symmetric refresh (logout now clears in-memory state AND the persisted token together, so the UI's disconnected state matches what chat actually uses) with single-flight Complete (concurrent finishers share the outcome; the loser stops receiving a misleading "flow already completed" error), clipboard attachments stop mixing extension-based MimeType with content-sniffed Kind/Error (UTF-16 .txt no longer reports text/plain + binary error — rejection-path fields agree)
fix(#666,#667,#668,#669): tunnel/cron/acp/session — ProjectionStore.Append drops stale-epoch events (old-authority latecomers no longer laundered into the new epoch; legacy zero-epoch adopts current), cron Update() preserves the paused zero-NextFire invariant (UI stops showing never-arriving fire times; rollback no longer swallows NextTime errors), acp device flow survives transient network errors (only terminal OAuth errors abort — user_code stays valid) with RFC 8628 slow_down backoff accumulation, session LastTurnIndex survives dropped corrupt lines (turn baseline no longer undercounted) and acp DeliverResponse logs dropped string IDs
fix(#662,#663): regression closeout — loadSession propagates real IO errors instead of masking them as EOF (EIO/EDQUOT no longer silently return a truncated session that Save then permanently trims), compact discard attribution distinguishes user resets from benign internal cleanup (retry truncation / orphan removal keep the cooldown — no more redundant full-context summarization every turn)
fix(#664,#665): im/provider/config — server-controlled durations clamped before the multiply (matrix retry_after_ms overflow no longer bypasses backoff into a request storm; rate-limit headers with negative values rejected at parse), a2a Disabled merge honors instance wins (workspace disabled:false re-enables a globally disabled A2A; explicit true still disables)
fix(#658,#659,#660,#661): tool/cli — sleep clamps seconds BEFORE the duration multiply (int64 overflow wraps no longer pass the d<=0 check as fake 0s success; the 30-minute cap holds, #513 sister), run_command auto-background finish() cancels the derived WithTimeout ctx (fast-terminal commands stop leaking timer/ctx trees for up to 24h), mcp list emits LF like every sibling subcommand (CRLF stripped from all four output sites; pipeline/script consumers stop seeing a stray CR per line), Registry.Clone() carries codeIndex (cloned registries' CodeIndex() no longer silently nil — @ fuzzy search works, #645 Cloner-contract family)
fix(#652,#653,#654,#655): regression closeout — mcp waiters unregister synchronously on ctx cancel (ghost waiters no longer pin a hung connection forever; last cancelled waiter aborts and the transport recovers), error_rush marker table narrowed to framework-level identifiers (timeout/connection-refused substrings stop blinding flaky-test blind-fix-loop detection; real build/test failures feed the streak again), rsync exclude/include/filter bare-value forms tokenized (colon patterns stop corrupting direction analysis), im pendingAsk registered once before send with compare-then-clear on every answer/cancel path (early button answers resolve; stale callbacks can't leak into the next question)
fix(#656,#657): session — loadSession tolerates over-long lines (a >10MB base64 record no longer makes the whole session unrecoverable; #478's fix covered only the search path), appendRecordLines repairs a torn tail before appending (crash residue can no longer fuse with the next record into a silently double-dropped malformed line)
fix(#646,#647,#648): desktop — session:changed handler reads activeSessionIdRef (stale-closure fix: the empty-sid reset branch from #630 now executes; ChatView clears the stale transcript on explicit empty sessionId), window X/Y/W/H merged under the dirtyWindowState flag ((0,0) origin persists instead of restoring old coordinates; no more contradictory WindowPosSet=true-with-dropped-axes state), SaveIMAdapter normalizes the platform to the canonical registry ID after validation (Telegram saves resolve to telegram — runtime exact-match adapters actually start; typos still rejected)
fix(#649,#650,#651): context/agent regression closeout — Vietnamese calibration residual attributed to its own latinExt tier instead of 100% to asciiRatio (3.0 clamp pressure gone, ~17% ASCII overestimate corrected), read-validity write eviction resolves ambiguous same-file keys both ways (self-edit "content changed" false positives gone) with lazy 1MB hash allocation, liveShrunk refund gate reads tokens at SCHEDULE time via pc.startTok (the refund was mock-only: post-shrink live tokens sit far below threshold by construction)
fix(#641,#642): permission/a2a — direction-aware scp/rsync exfiltration analysis (pure downloads and local copies stop forcing Ask in autopilot; remote destinations still exfiltrate) with a shell tokenizer that survives option values and Windows drive letters, curl exfil pattern requires an actual data flag (here-strings with < no longer flagged); a2a Message/Artifact snapshots deep-copy Metadata (protocol extension metadata stops being silently dropped from every tasks API path)
fix(#643,#644,#645): mcp — crash-reconnect Close() runs Abort unconditionally (notification goroutine no longer leaks), single-request ctx timeout keeps the shared stdio/WS connection when other requests are in flight (last waiter still aborts a dead connection), mcpTool clones its mutable ContextFill (teammate truncation semantics no longer cross-contaminate) with sampling/elicitation setters mutex-guarded
fix(#638,#639,#640): agent detectors — momentum_loss stall window actually satisfiable (startIteration no longer pre-appends the empty record that kept the detector dead in production), solution_fixation window slides on the documented 12-tool-call span with consistent edit-tool attribution across detectors (multi_file_edit files all attributed, not just Files[0]), error_rush streak counts only code-failure errors (permission denials and MCP timeouts no longer feed the threshold)
fix(#635,#636,#637): wailskit — per-field dirty flags gate Save()'s bool-field merge (stale snapshots stop rolling back other instances' notification/hotkey/on-top settings), walkDirectoryEntries caps via SkipAll (10k already-collected entries returned instead of discarded — large-directory browsing works), IM form fields get explicit Required flags (dead Label=="" branch killed, stdio Command actually checked, SaveIMAdapter validates platform)
fix(#632,#633,#634): regression closeout — retryTimerIdents is a per-call local map (parallel checkRetryQuality race-closed, -race verified), precompact cooldown refund gated on the liveShrunk discard reason only (summarization failures keep backoff — no more back-to-back full-context re-summarization), latinExt counted as a covered script in the #623 freeze (Vietnamese-class sessions calibrate again; #598 ratio composition unchanged)
fix(#628,#629,#630,#631): desktop — RenameSession syncs the bridge's in-memory title (meta write-backs stop resurrecting the old name), Markdown export redacts tool Content (#583 path completion), DeleteSession emits session:changed so the frontend drops the deleted transcript (empty sessionId = reset), maximized-exit window state preserves normal bounds and WindowPosSet disambiguates the (0,0) origin
fix(#626,#627): agent read guards — partial reads stop seeding the path-level mtime baseline (partial→full no longer mis-flagged "already read"), read-validity suffix scans require unique matches (same-basename ambiguity returns no wrong hash; sibling hashes safe from eviction) and the hash window grows 16KB→1MB (large-file tail edits within sub-second mtimes detected)
fix(#614,#615,#616,#617): desktop — ApplyImpersonation merges custom headers + rejects unknown presets (#67/#69 4th instance closed), hotkey registration failures surface with rollback and the poller stops cleanly (register-then-persist, no leaked 200ms goroutine), CompleteAnthropicOAuth refreshes the running provider (no 401s until restart), UpdateCronJob requires a prompt (empty no longer silently means unchanged)
fix(#612,#613,#618): agent — precompact discard branch refunds the 2-min cooldown when tokens still exceed the threshold (no more degradation to destructive truncation), retry-quality exemptions require whole-word counters + body comparisons + provable timer receivers (attemptLog/countryCode/arbitrary .C no longer exempt unbounded no-backoff loops), foresight empty-result detection structured and multi-tool turns stop misbinding predictions to toolCalls[0]
fix(#619,#620,#621,#622): subagent — watchdog refreshes on tool-arg chunks (giant streaming args survive), success Complete after Cancel backfills its result, unnamed tool calls pair FIFO (no single-slot overwrite), CancelAll force-reclaims leaked semaphore slots with per-agent timeout budgets
fix(#623,#624,#625): context/provider — calibration freeze extended to uncovered-script share (spaces no longer smuggle Cyrillic error into asciiRatio at 1.0), OpenAI rate-limit early-return removed (Anthropic token headers merge, TokenFractionRemaining stops hallucinating 100%), single-group compaction embeds the trigger message verbatim (#324 invariant restored at the len(groups)==minRecentGroups boundary)
fix(#610): config — tombstone mechanism makes string-field clearing expressible in Save() (old values stop resurrecting on reload; #284 concurrent-write and #608 ${VAR} boundaries enforced)
fix(#611): session-timeout exit — dedicated sentinel ErrSessionTimeout replaces the shared post-loop block (maxIter>0 no longer misreports "max iterations reached" with contradictory on-screen messages; maxIter<=0/autopilot/cron no longer return nil masquerading as success)
fix(#608,#609): config — SaveVendors restores ${VAR} references from disk before writing (env-var rotation survives Load's auto-Save), MergeInstance registers knight/a2a/subagents/swarm in instanceFields (instance values stop leaking into the global ggcode.yaml)
fix(#607): guidance post-processing — isCriticalTag normalizes both sides via ToLower (security tag variants regain critical exemption, no longer double-swallowed by cap+budget), applyToolResultGuidance routes through the per-turn guidance budget (8/8-in-one-turn injection closed, hard cap restored), conflict meta-hint counts against the cap with cross-result dedup and self-summary exclusion
fix(#606): wailskit MCP management — List/Remove operate on the runtime's merged server set (.mcp.json migrated servers visible AND removable, dual-side purge stops resurrection), patch nil-sentinel semantics make explicit clearing reachable
fix(#607): MaxContextMessages truncation keeps recent user dialogue in agent context
fix(#603): im adapters — approval pruner's 32-entry threshold removed (#259 Deny fallback works for a single abandoned approval, time-driven pruner added), WhatsApp retries network outages indefinitely (LoggedOut stays terminal) with mutex-scoped Start/Stop (-race clean), Slack terminal auth errors exit the run loop, emitter close() works after enqueue (shared sync.Once split), binding watcher accepts same-mtime size changes
fix(#597): mcp HTTP transport matches JSON-RPC id (concurrent cross-injection closed), scanner.Err surfaced (>1MB lines no longer "no data event"), Windows cross-vet clean
fix(#598): CJK calibration de-contaminated (Cyrillic/Greek out of the ratio bucket), a2a CancelTask fires its terminal callbacks, Bearer rejection falls through to mTLS
fix(#552,#574): daemon Windows test suite green — 8 red tests to 0
fix(#574): restore Windows build - platform-split flock in daemon PID slot
fix(#590): session store — removeFromIndex corrupt-index guard (4/5 sessions no longer vanish), appendRecordLines aborts on flock failure (60/60 silent message loss window closed), retry parity with updateIndex
fix(#591): IM platform registry gains privateclaw + case-insensitive lookup; int Extra values validated via %v; empty-workspace guard restored; first-run Load now merges external im.yaml
fix(#588): wire Makefile tampering analysis and source-existence check into production detector (was test-local)
fix(#584): add config.PatchMCPServerConfig merge helper with type-switch field cleanup
fix(#583): wailskit followup — JSON export redaction+truncation parity, config read-merge across instances, ListSessions fail-closed, LastSession dead field removed
fix(#580): wailskit batch — ListCronJobs fails loudly (nil scheduler no longer reads as "all jobs lost"), recursive walk caps+logging, overflow notice seq repositioned
fix(#579): desktop clipboard+notification batch — FIFO post-read caps close the #459 half-fix, approval storm dedup, focused-session center events, dead file:// branch removed
fix(#581): session export, config backup, and delete lock fixes