Added
- Subagent work now survives into committed checkpoints, for every agent that reports subagent completion: Claude Code, Codex, Cursor, Copilot CLI, and Factory AI Droid. 0.10.2 shipped the in-session half and noted that committed checkpoints still carried no per-subagent data for any agent — this is the durable half. A subagent's work becomes a
task_recordsledger on the parent session, and condensation materializes each record's transcript intotasks/<tool-use-id>/inside the parent session's checkpoint, so every checkpoint is self-contained; the ledger, the materializer, and the commit linkage are all agent-agnostic. Commits a subagent makes between the parent's turns link to their session too, instead of shipping with noEntire-Checkpointtrailer at all — six of seven commits on a real subagent-driven branch had gone unlinked. The one agent-specific piece is Claude Code'sSubagentStophook, now registered: a backgroundedTaskfiresPostToolUseat the launch acknowledgment, before the subagent has done anything, so a session that dispatched 29 background agents running 5–18 minutes each had captured nothing but a launch stub per agent. Gemini CLI, OpenCode, and Pi expose no subagent hook and are unchanged (#2032, #2034) - An agent's commit links to its session by who made it, not by worktree path: the owner fingerprint already recorded at every turn start is matched against the commit hook's own process ancestry, so a commit made in a sibling worktree links automatically with no
entire session adopt. Nearest ancestor wins for nested agents, host/boot/start-time guards defeat PID reuse, and a human commit typed in the same terminal still never matches. Identity is unioned with worktree matching, never a replacement; on Windows, where the process walk is unavailable, linking is unchanged (#2013) - Zombie sessions self-heal instead of waiting for someone to run
entire doctor. The session-start hook cheaply detects sessions whose agent died without a stop hook, or that have been sitting on uncondensed checkpoint data for over 24h, and fires a detached__sweep_sessionsthat finalizes and condenses them — one real session had been stuck for 4 days with 60 checkpoints, slowing every commit in the meantime. The hook's own timeout budget is untouched regardless of backlog (#2029) - Teams can choose which secret-scanner engines feed redaction, via
redaction.betterleaks.enabledandredaction.goredact.enabledin committed.entire/settings.json. Defaults are unchanged (betterleaks on, goredact off), the keys are deliberately ignored insettings.local.json— the choice affects everyone who reads the repo's checkpoints — and disabling both fails settings load rather than shipping unscanned content. If the sole enabled engine fails at runtime, transcript writes fail closed instead of persisting under-scanned data (#2081) entire doctor trace --summaryaggregates hook traces into per-hook p50/p90/max with the dominant step, and--slownarrows to the slow ones — the question with slow traces accumulating is "what is slow in general", which previously meant hand-rolling a grep over.entire/logs. The command's help no longer claims traces need DEBUG to be enabled; they have been emitted at WARN by default since 0.10.1 (#2092)- Redaction diagnostics reach
.entire/logsandentire doctorreports a log directory Entire cannot write to. Pack load failures, rule compile errors and sample mismatches went to the process-default logger — bare stderr, which hook contexts swallow — so a user debugging custom rules could grep forcomponent=redaction, find nothing, and reasonably conclude the rules never ran. There is now also one INFO summary per process naming pack/rule/inline counts and PII/OPF state, and an unwritable.entire/logsis called out by name instead of presenting as a silent exit 0 (#1973, #2082) entire trail update --bodysends the description's ETag asIf-Match, so a body write is rejected rather than silently clobbering a description that changed since it was read.--overwritewrites unconditionally, and a server or trail without an etag degrades to the previous behavior (#2079)- Telemetry gained three content-free signals, all gated on the same opt-in setting and
ENTIRE_TELEMETRY_OPTOUT:cli_skill_invokedfor skill invocations (skill name from a closed vocabulary — no prompt text or arguments),cli_commit_condensedfor whether a commit landed files already carrying AI checkpoint history without the session ever consulting search, andcli_search_completedfor whether a search actually returned a usable response rather than just that it ran (#2023, #2024, #2100, #2130)
Changed
- The search TUI scrolls continuously instead of paging 10 results at a time — commit search reads like a pruned
git log, and the next API page loads automatically as you approach the end. Type tabs move on ←/→ (or tab/shift+tab) with wraparound; the1-3number keys are gone, and the status row reportsN of M resultsinstead ofpage X/Y(#2138) - CLI search results match the web's. Per-cell responses were always identical — only the client-side merges diverged: the CLI cut the merged list globally at 100 where the web windows per type, reported summed corpus counts up to 13× larger, deduped every type where the web dedupes sessions only, and dropped every completeness flag. Counts now describe exactly what you can see (with a
+when lower-bounded), incomplete results are labeled rather than silent, and the retired ANN fallback tail no longer renders (#2090) - A logged-out
git pullagainst a cluster now names one login server —entire login— instead of printing a list of seven hosts and leaving you to pick, three of which were not login servers at all. Staging still names--serverwhere the flag is genuinely required (#2128)
Security
task.json'stask_description— the free text an agent writes when dispatching a subagent — was copied verbatim into the pushed checkpoint while the subagent transcript beside it went through the full sanitize → externalize → redact pipeline. The checkpoint writer now redacts it, covering both persistent backends (#2129)- betterleaks moves to 1.8.0, which closes a real under-redaction gap: a bare
password=<secret>assignment previously escaped every layer. Validated with an A/B diff over 22 real checkpoint transcripts (64MB) — 21 byte-identical, one file with five safe-direction over-redactions of test-fixture passwords, zero under-redactions. The upstream dependency swap also makes the transcript redaction path 1.36× faster and shrinks the binary (#2042)
Fixed
- Every
git statusEntire runs now passes--no-optional-locks.git statusis a write: it refreshes the index's stat cache, holds.git/index.lockfor the whole worktree walk, and renames a fresh index over.git/index. Entire read the porcelain output once and discarded it, so that write bought nothing — but on a filesystem where rename-over-existing is not atomic against a concurrent lookup (virtiofs / gRPC-FUSE bind mounts, i.e. Docker Desktop devcontainers — measured at 9.9% ENOENT across 29,596 opens, versus 0 on ext4) a reader can observe.git/indexmissing, and git treats ENOENT, and only ENOENT, as an empty index: agit commitlanding in that window records the empty tree with exit 0 and no warning. Output is byte-identical with the flag. This removes Entire's contribution rather than the hazard — any concurrentgit statuson an affected mount opens the same window, including several agents working one repo, and the environment-wide mitigation isGIT_OPTIONAL_LOCKS=0(#2143) - A Stop hook on a large transcript no longer re-redacts the whole thing. Redaction was 99.7% of the blob write, and because
full.jsonlis append-only but was re-redacted in full at every checkpoint, a session with N checkpoints re-redacted O(N²) bytes — a 70MB Codex transcript took ~67s. The line pass is now sharded across goroutines (byte-balanced, output byte-identical) and the previous checkpoint's redacted prefix is reused, so only appended lines are redacted: ~66s → 2.0s on a simulated 14-checkpoint session. The same reuse now covers post-commit condensation and the Stop finalize rewrite, which had been left out — a coworker was hitting Codex's 30s Stop-hook timeout on a 65MB rollout and losing the checkpoint's final transcript rewrite to the kill (#2002, #2107) - A pathological repo can no longer leave orphaned hook processes grinding for hours. A stray
git initin a user's$HOMEmeant every Stop hook walked the entire home directory: the agent stopped waiting at its ~60s hook timeout but theentireprocess survived, and two were found hours later at ~1.8GB RSS each, one with 25 CPU-minutes, still writing loose objects — silently, with no session state, no checkpoint, and no log line. Agent-hook status walks are now bounded by a 20s wall-clock budget with a process-local latch, the unboundedgit statussubprocess on the first-checkpoint path is bounded the same way, capture degrades to transcript-derived data instead of failing the turn, andentire statusreports the degradation instead of showing a healthy session with new-file detection silently off (#1977) - Session-end condensation could write a checkpoint durably before saving its updated session state, so a hook killed in that window left recovery thinking the transcript was unfinished — and
entire doctorwould write it again under a different checkpoint ID. Condensation now reserves its checkpoint ID write-ahead and reuses it on retry, anddoctorreconciles interrupted writes from older CLI versions by session identity and transcript bounds rather than minting a new ID. Existing duplicate pairs are deliberately left in place (#2038) entire disable --uninstallreported success while leaving an external agent's hooks on disk — the uninstall reached agents only through the registry and never ran external-agent discovery, so the plugin was absent from the confirmation summary and itsUninstallHooksnever ran, leaving agent hooks calling into an Entire that was no longer installed. Discovery is now ungated (the setting that would gate it lives in the.entire/this command deletes),AreHooksInstalleddistinguishes "no hooks" from "cannot tell" instead of collapsing both into "none", and any step that fails exits non-zero with a per-agent remedy rather than claiming a success it could not verify (#2010)- Cursor's file attribution used the transcript. Six places in the Cursor agent asserted as fact that Cursor transcripts contain no
tool_useblocks — a real session has 26 of them — soExtractModifiedFilesFromOffsetreturned nothing and every session fell back to git status while realWrite/StrReplaceblocks sat unread.Shellstays excluded, since the transcript records only the command string (#2120) - Imported Cursor session titles no longer read
<timestamp>Tuesday, Aug 18, 2026, 2:37 PM…</timestamp>; Cursor's injected block is stripped by the single shared prompt cleaner, fixing live and imported prompts at once (#2045) - Codex 0.149.0 can load project hooks from a different checkout than the one it runs in, so a linked worktree's own
.codex/hooks.jsonwas silently not the file Codex used.entire doctorandentire statusnow report the discovered path alongside the current worktree's, while installs, removals and cleanup still touch only the checkout the command was invoked from (#2052) - OpenCode hooks fire under OpenCode Desktop: the plugin spawned via
Bun.spawn, which does not exist in the Electron sidecar's Node runtime, and now usesnode:child_processso both the Bun CLI/TUI and Desktop work (#2018) entire session attach <id> --agent opencodeworks for sessions Entire never tracked. Preparation was only attempted when a transcript file already existed, but OpenCode produces its transcript on demand viaopencode exportfor any session in its store — so a session spawned outside a hooked terminal could not be attached at all. A new optional agent capability materializes the transcript on demand; file-based agents are unaffected (#1877)- Search routed each repo to every placement it has, home and mirrors alike, so a multi-region repo returned the union of all its namespaces — 100 rows against the web's 6 on one measured query, 94 of them duplicate or stale mirror rows. Each repo now routes to exactly one home placement, and a home placement that is not ready is reported as skipped rather than substituted with a mirror (#2044)
entire search --json --compactno longer emits a repodescription; its only source was the legacy MySQL repos table, which is gone server-side, so the field could never be populated again.checkpointCountstays, re-sourced from core (#2125)entire trail createdelivered the trail's branch to a hardcodedoriginin four places with nothing warning, so a fork workflow,remote.pushDefault, orbranch.<name>.pushRemoteall sent it to the wrong remote. Delivery now resolves through git's own precedence, once, so push and cleanup cannot disagree (#2086)entire enableshowed only six of its eight agents, hiding OpenCode and Pi below the initial viewport even on a tall terminal — ahuhheight-sizing bug, worked around here for single-line multi-select fields while the library fix is handled upstream (#2132)entire doctorwithout a TTY crashed on a stuck session instead of reporting it: the fix prompt went straight to an interactive select, bubbletea failed withcould not open TTY, and the whole scan aborted mid-report with exit 1. It now prints the diagnosis with a--forcehint and completes the scan (#2015)- Checkpoint reads on a partial clone no longer hammer the remote one blob at a time.
entire checkpoint explaincould trigger a Git lazy fetch per missing blob per promisor remote before reaching its own batched prefetch, so blob-existence probes and fallback reads now setGIT_NO_LAZY_FETCH=1, and the probe settles a whole candidate set with onegit cat-file --batch-checkrather than one subprocess per blob. Two hook paths — post-commit attribution and the stop hook's turn finalize — opened the checkpoint store with a ref fetcher and no blob fetcher, so with lazy fetch off a filtered-outmetadata.jsonread as "checkpoint not found": attribution was skipped, the finalized transcript never reached its checkpoints, and nothing above DEBUG said why. Both now carry a blob fetcher bounded by a 15s whole-call budget with non-interactive SSH, memoized so a dead network costs one budget per store instead of one per checkpoint (#2141, #2145, #2146) - Telemetry payload building no longer shells out once per event. The machine ID is resolved via
ioregon macOS (p50 11.8ms), the registry on Windows, and nothing cached it — so a hook draining a 20-event skill backlog paid 217ms of blocking subprocesses in the parent. It is now resolved once per process, dropping ~11.6ms from every command that builds an event (#2101) - The committed
SessionStarthook in.claude/settings.jsonleft${CLAUDE_PROJECT_DIR}unquoted, so any checkout whose path contains a space failed on every session start (#2139) - Every control-plane request went out as
Go-http-client/2.0, notentire-cli/<version>— soentire org|project|repo|grant|search|api|authtraffic was invisible to server-side CLI version gating, along with cluster discovery, the cluster catalog GET, and plugin release-asset downloads. The User-Agent is now stamped at the client constructors, innermost in each transport chain so the token-exchange and federation hops carry it too (#2096)
Housekeeping
mise run lintno longer rewrites source. The local path passed--fix, which made the documented pre-commit sequence a mutating command — it could strip a//nolintdirective, report 0 issues, and fail on the next run with the deprecation the directive was suppressing. Rewriting stays withmise run fmt(#2117)- This repo's committed dogfood hook configs are now checked against their templates on the CI path, using the same drift check
entire doctoralready runs. The committed Pi extension had sat two commits behind its template for three weeks, silently forwarding a subagent's lifecycle as the user's session (#2084) - A Cloud Agent development environment boots with the pinned toolchain, the CLI built, and
entireon PATH so this repo's committed hooks fire (#2114) - Two CI flakes removed at the mechanism rather than the probability: a
Text file busy(ETXTBSY) fork race on test-written fake binaries, now linked instead of written, and the Factory Droid E2E tests, which had polled shadow branches for task data that #2032 stopped writing and had failed on every push to main since (#2094, #2095) - The logger is closed in one place (
main.go, which covers the error paths cobra's post-run loop skips), the security-review runner prompt is reframed around an engineer who owns the codebase rather than a checklist auditor, and three docs corrections landed: the ref-backend doc no longer lists pre-push OPF among the paths the primary backend drives, the log-flush comments point atmain.go, andphonePII redaction is qualified as North American (NANP) formats only (#1914, #2083, #2093, #2097, #2110) - The
gemini-cliE2E leg is dropped from the automatic agent fan-out, where it had been reddeningmainon every push; it stays in everyworkflow_dispatchchoice list so it can be run by hand against a newer release. This turns off the alarm, not the bug — since Gemini CLI 0.57.0 the agent forcescore.hooksPath=''on every shell command it runs, so a commit the agent makes records no checkpoint, and no change on Entire's side can win that back (#2147) - Go dependencies bumped as a group: bubbles 2.2.0, bubbletea 2.0.9, betterleaks 1.8.1, posthog-go 1.23.1, testify 1.12.1,
x/mod0.40.0,x/net0.58.0 (#2118)
Thanks
Thanks to @Legonaftik for making entire session attach work for OpenCode sessions Entire never tracked, @sdshah09 for fixing OpenCode hooks under OpenCode Desktop's Node sidecar and qualifying the phone PII pattern as NANP-only in the docs, and @MuskanPaliwal for preventing duplicate session-end checkpoints, making Codex hook discovery honest in linked worktrees, and unhiding OpenCode and Pi in the agent picker!