Skip to content

v1.3.211

Choose a tag to compare

@topcheer topcheer released this 18 Aug 11:23
· 983 commits to main since this release

ggcode v1.3.211

Highlights

  • See the changelog below for the user-facing updates included in this release.

Compare

Changelog

  • release: v1.3.211
  • 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(#602): provider — string-fallback retry excludes 402/413 (billing errors stop retried 20x/~7min), failover goroutine chain ctx-gated end to end, JSON status anchors digit-piercing closed, window-limit exclusion vendor-gated, unreachable fallback removed, mixed-prefix rate-limit merge fixed
  • fix(#604): tool execution core — multi_edit_file resolves relative paths via resolveToolPath before SandboxCheck (wrong-file + basis mismatch closed), whitespace-tolerant fallback re-counted under lenient semantics at BOTH uniqueness gates (sim side mirrors via exported tool.LenientRecount), RunCommand.Clone preserves JobManager
  • fix(#605): fix-batch regressions — mid-stream ErrTooLong outranks count message, completion event keyed to run_done (dead complete case removed), uncovered-script samples frozen instead of ASCII-misattributed, delta gate distinguishes worsening writes from untouched ones
  • fix(#601): session render window anchors on last user/assistant message
  • fix(#600): desktop notifications — approval dedup keys carry request identity (2nd banner no longer swallowed), dedup branch bumps badge (#427 symmetry), mount focus probed not hardcoded, toast queue-full rolls back counters, error/complete wording carries session dimension
  • fix(#601): write_integrity — computeFileChange simulation mirrors real edit_file semantics (replace_all + line-anchored resolution, dual-side diff locked), secret check single-sourced, severity-ordered capping, zero-delta gating, blast-radius denominator fixed
  • 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(#599): OAuth+LSP bridges — error callback requires state (single-packet flow-abort closed), refreshable tokens count as connected, empty workingDir refuses LSP install
  • fix(#594): text-path persistence — sendMessageData/SendHiddenText bind the per-run persist snapshot, InitAgent gains the #269 mismatch guard, dead saveSession removed
  • test(#599): add test documentation for OAuth security fixes
  • fix(#596): security fixes for command rules and MCP plan mode
  • fix(#593): 6 defects in 3 text detectors - phantom_verify, premature_success, false_premise
  • fix(#595): premature success detector - background verify channels & guard words
  • 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(#589): criteria drift detector — cross-turn repetition counts again; auth exemption N1/N2/F1-B/C/N3
  • fix(#588): spec gaming detector — recognize escaped skip markers in awk gsub remediation, Makefile tampering helper distinguishes commented-out from deleted test target
  • refactor(#585): extract mergeExistingIntoUpdate from SaveIMAdapter (complexity 18 → under threshold)
  • fix(#587): ListIMAdapters keeps all bindings per adapter — IsCurrent true when any binding matches the current workspace
  • fix(#586): fix 8 defects in criteria drift detector authorization exemption
  • fix(#585): SaveIMAdapter platform switch discards old-platform credentials; TestIMConnection validates required fields
  • fix(#584): add config.PatchMCPServerConfig merge helper with type-switch field cleanup
  • fix(#582): criteria_drift — threshold counts indicators not categories (single-category progressive drift fires), user-authorized descoping exempted, seenCategories documented as legacy; .bak leftovers untracked
  • 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
  • fix(#576): interface compliance method promotion + export guard interface fingerprints
  • fix(#574): daemon+checkpoint batch — flock daemon slots, cmdline-empty identity self-healing, Revert records Correction, log-rotation limitation documented
  • fix(#573): permission batch — bypass redirect-target gating, deny rules in all modes, case-insensitive sensitive paths, command-anchored rm, prefix patterns, env-quote stripping, sandbox fail-closed
  • fix(#575): config-syntax dead code + YAML dup keys + OAuth token validation
  • fix(#572): reward-hacking detector FP hardening — bare/scoped suppression split, content-keyed placeholder delta, data-table + single-quote hardcoded_output, Skip/gomega assertion exemptions
  • fix(#568): de-flake TestGUIProcessSurvivesExecuteReturn — sync on marker before kill-window
  • fix(#571): write_integrity registry reconciliation — mount race-verify-hint, 4 reward-hacking detectors, 8 silent-wrong-behavior detectors
  • fix(#566): hook env cap 128KB→64KB — Linux MAX_ARG_STRLEN caps whole NAME=value string
  • fix(#570): false_premise go-test success supersede, retry_quality unexported methods + ForStmt, wire content-growth/blast-radius
  • fix(#568): tool batch — GUI ctx outlives Execute, explicit-empty required params, ~ expansion, MCP rune-safe truncation, nested coercion
  • fix(#566): hooks+extract batch — shell-quote hook templates, truncate env vars, streaming zip, RTF destination/surrogates, empty-book errors, ODT pages
  • fix(#565): a2a batch — skill allowlist enforced on agent path, SSE 8MB buffer, card lock, stream artifacts, id:null, messageId idempotency
  • fix(#569): IM daemon race conditions and error handling
  • fix(#567): taint fingerprint prefix noise, typosquat registration, package.json minified support
  • fix(#564): export full-load (no 24h truncation), _test.go secret exemption, err-counter/zero-float comparison FPs
  • fix(#563): RemoveMCPServer single-snapshot — Disconnect no longer lands on wrong workspace after switch
  • fix(#562): mcp batch — WS single-writer lock, elicitation off read loop, cursor pagination, capability gate, caps race, id:null routing, notify downgrade
  • fix(#561): provider batch — OpenAI sends effective MaxTokens, 401 terminator anchoring, Gemini stream usage fallback
  • fix(#560): OAuth status expiry check + callback code single-consumption
  • fix(#559): config+cost batch — vendor field-level merge, ${VAR:-default} interpolation, one-way prefix pricing, Knight false persistence
  • fix(#558): session batch — post-migration cutoff recompute, top-level timestamp extraction, cross-process rewrite lock, MsgCount max, Windows session ID
  • fix(#557): fulfillment_gate word-boundary verbs + read_validity path-form convergence
  • fix(#556): hardcoded_path URL-route/comment exemptions, exit_call tombstone, repetition key convergence, ghost-IM-bind validation