Go CLI built with Cobra and Charmbracelet Huh. AGENTS.md is a symlink to this
file. Keep this entry point short: repo-wide rules and pointers, not command
catalogs, implementation histories, or subsystem specifications.
cmd/entire/: entry point and external-command dispatch.cmd/entire/cli/: Cobra commands, group roots, and CLI helpers. Group/verb files use<noun>_group.goand<noun>_<verb>.go.cmd/entire/cli/agent/: built-in agent integrations and external-agent protocol.cmd/entire/cli/strategy/: manual-commit strategy and lifecycle/git hooks.cmd/entire/cli/checkpoint/: persistent checkpoint storage (written at commit).cmd/entire/cli/session/: session state shared across worktrees.cmd/entire/cli/integration_test/: simulated-hook integration tests.e2e/: real-agent tests and deterministic Vogon canary.internal/entireclient/: API clients, authentication, and user directories.
Use the Go version pinned by go.mod and tools configured in mise.toml.
For installed CLI usage, run entire agent-help, then
entire agent-help <command> for current flags; do not guess from a static list.
Read the applicable reference before changing that area, not every reference at session start. Follow its related links when the task crosses those boundaries.
| Area being changed | Reference |
|---|---|
| Commands, help, experimental visibility, repo refs, prompts | CLI conventions |
| Test harnesses, isolation, TTY behavior, source guards | Testing |
Filesystem I/O, .entire, symlinks, hook configs, root anchors |
Filesystem safety |
| Git operations, executable lookup, subprocesses, Windows launching | Git and subprocess safety |
| Caller identification or session current/tokens/adopt | Caller-session resolution |
| Control-plane auth or data-plane routing | API routing |
| Checkpoint writes, lifecycle, sync, settings trust, redaction | Implementation contracts, domain model, scenarios |
| Ref-based checkpoint backend | Ref backend |
| Agent integrations | Agent guide, integration checklist |
| External commands or agents | External commands, agent protocol |
| Security, privacy, scanners | Security and privacy, implementation contracts |
| Review command | Review architecture |
| Release artifacts, install scripts, version-check origins | Release origins |
| E2E tests | E2E guide |
| Task | Command / requirement |
|---|---|
| Unit tests | mise run test |
| Integration tests | mise run test:integration; required when changing integration test code |
| Deterministic E2E canary | mise run test:e2e:canary; safe without API calls |
| All CI tests | mise run test:ci (unit + integration + canary) |
| Format and lint | mise run fmt && mise run lint |
| Before every commit | mise run check (format, lint, all CI tests) |
| Before any push or remote code update | mise run lint on the current tree, after the latest formatting pass |
| After every push to an open PR | check the trail's findings (entire trail finding list cli/<n> --freshness any; <n> is the PR branch's cli trail number, not the PR number); fix real ones, resolve with -m, and re-check after the fix lands. Not done until findings are clear |
| Duplication checks | mise run dup or mise run dup:staged; normal lint also checks duplication |
| Windows installer | mise run test:ps1; see testing reference for prerequisites |
Do not run real-agent E2E tests unless the user explicitly requests them. They make paid API calls. Vogon is the exception: its canary is deterministic and free. When changing E2E prompt wording, run the canary and update Vogon's regex parsing if needed. Formatting can rewrite files; an earlier lint pass is not sufficient.
Before implementing Go code, search nearby packages and helpers for reusable
patterns. Use /go:discover-related when available, otherwise rg and related
implementations/tests. Check .golangci.yaml; handle errors and avoid duplication.
- Every top-level test and subtest calls
t.Parallel()unless it changes process-global state (t.Chdir,t.Setenv, or theirosequivalents). - Git tests use isolated temporary repositories, preferably
testutil.InitRepo(t, dir)plus its file/add/commit helpers. Redirect CWD before calling CWD-based handlers. Never mutate the real checkout's git/session state. - Tests must not access the developer's real config, cache, or keychain.
In-process fallbacks are shared per process; use per-test overrides and
tokenstore.UseFileBackendForTestingwhen isolation between tests is needed. Tests that can reach the OS keyring needkeyring.MockInit()inTestMain. - Spawned binaries do not inherit Go's test detection. Harnesses must isolate
ENTIRE_CONFIG_DIR,XDG_CACHE_HOME,ENTIRE_TOKEN_STORE=file,ENTIRE_TOKEN_STORE_PATH, andENTIRE_TEST_AUTH_STORE_FILE. - Prefer
execx.NonInteractivefor real CLI/git test subprocesses so a developer's terminal cannot make them prompt or hang. - Caller-resolution tests clear every variable from
agent.CallerSessionEnvVars(); never hand-maintain a partial list or inherit the developer's agent identity. - Source-scanning guards discover files through testutil's guard helpers
(
GitGrepGuard,GuardGoFiles), restrict pathspecs to Go files, and fail on zero matches. Do not weaken guard ledgers to silence failures.
Use the existing anchor for each tree; never assemble a path and perform bare I/O beneath it. Read the filesystem reference before adding or changing I/O.
| Tree | Canonical owner |
|---|---|
.entire |
entiredir |
| Git common directory | gitdir |
| Working tree | worktreedir |
| Agent hook configuration | agent.HookConfigFile |
| Agent session store | agent.SessionStore |
| Active git hooks directory | strategy.hooksRootForInstall / ForRemoval |
| Per-user config/cache | userdirs.ConfigRoot / CacheRoot |
| Managed plugins | pluginRoot |
- Root bases come from trusted resolvers, not
filepath.Dir(target). Confining a file to its own derived parent proves nothing. Prefer an existing anchor. - Roots share the
osroot.Sharedregistry. Open child roots withosroot.SharedChild/OpenChild, not bareparent.OpenRoot. - Use
osrootoperations andjsonutil.WriteFileAtomicIn/CreateTempIn. Directories useMkdirAllNoSymlink; rooted read-only operations must also enforce symlink policy. Atomic writes replace leaf links rather than follow them. .entiremust be a real directory; validate throughpaths.ValidateEntireDirAt/RequireEntireDir. Do not treat an unresolved repository as absent. Settings reads must also refuse symlinks themselves.- Do not broaden symlink exceptions. Developer-vouched agent config directories
are scoped, locally trusted exceptions;
.entireand git hooks are not vouchable. entiredir.OpenForReadmust not create directories. Reset cached roots before deleting/recreating their directories. Useentiredir.Name/MustNameto bridge repo-relative constants and root-relative I/O names.- All settings access goes through
settings; never read or parse settings JSON ad hoc. Per-user config/cache resolution belongs only touserdirs. - Repository-controlled settings must not authorize executable discovery, custom executables, or instructions for permission-bypassed agents. Preserve the existing local-provenance gates and their rejection reporting.
- Existing exceptions (explicit user paths, global git config, transcript-read protocol gaps) are documented in the references; do not generalize them.
- Open repositories only through
gitrepo.OpenCurrent(ctx)orgitrepo.OpenPath(root), never direct go-git opens. This preserves alternates and reftable support. Do not fall back to CWD after failed repo resolution. - Use
gitrepo.Status, neverworktree.Status(). Agent-hook capture paths useStatusWithBudgetand preserve degraded-capture reporting on budget exhaustion. - Every
git statussubprocess passes--no-optional-locks. This does not protect worktree-comparinggit difffrom refreshing the index; use the hook-safe alternatives in the git reference. - Use the git CLI, not go-git v5, for checkout and hard reset; go-git can delete ignored/untracked directories. This is an implementation rule, not permission to run destructive git commands.
- Git-relative paths resolve against
paths.WorktreeRoot, never process CWD. - A git subprocess targeting a repository independently of the current hook must
use
gitrepo.EnvWithoutRepoOverrides();Diror-Calone does not override inherited selectors. Queries inspecting the commit Git is preparing must retain the hook environment, including its temporaryGIT_INDEX_FILE. Hook queries reading only the hook's own refs or reflog may strip selectors and resolve frompaths.WorktreeRoot. User-invoked CWD commands also honor intentionally exported repo selectors. - PATH scanners use
execx.PathScanDirs(); external-agent execution requires absolute binary paths. User-directory overrides use the checkeduserdirsresolvers before any I/O. - When Entire owns execution, pass arguments separately; never interpolate
dynamic values into
cmd.exe. Agent-owned shell execution uses the shared escaping helper. See the reference for the literal-only Unix updater exception.
- Load settings through the
settingspackage, not new helpers in CLI consumers. - Operational/debug messages use
logging.Debug/Info/Warn/Error; user output usescmd.OutOrStdout()/cmd.ErrOrStderr(). Never log prompts, file contents, or commit messages; log operational metadata only. - Cobra suppresses errors globally;
main.goprints returned errors. ReturnNewSilentError(err)only after printing a custom error yourself. - Every read-only workflow must work without a TUI: provide complete text/JSON, stable IDs and detail commands, or direct selection flags. Test that path.
- Use
uiform.New(orNewAccessibleFormincli) for Huh forms; these wire accessibility and theming centrally. Do not hand-rollWithAccessible. - Separately opened prompt terminals use
interactive.OpenPromptTTY()andPromptTTY.Close(), not a bare file close (Windows pending reads can hang). - Register experimental commands with
experimental.Register. Classify new commands inagentHelpClassification; default to unlisted/user-owned and flag the product choice for review. Agent guidance belongs inagentHelpGuidance, not CobraShort/Longor first-turn injection.
*strategy.ManualCommitStrategyis the only strategy; there is no interface or worktree restore path. Turn ends write session state only; checkpoints are metadata refs written at commit, never working-branch commits. Log resume is distinct from restoring worktree files.- Caller identity comes from
strategy.ResolveCallerSession, not newest state. Preserve resolution provenance; do not narrate worktree fallback or ambiguous matches as identified callers.IsCaller()excludes those guesses; consult the caller-resolution reference for current enforcement gaps. - Preserve sanitize → image externalization → redact ordering where all apply, fail-closed scanner behavior, and checkpoint-scoped token accounting. Read the implementation contracts before modifying any transcript/storage pipeline.
- Control-plane precedence belongs to
coreapi; displayclient.CoreOrigin()rather than independently resolving a possibly different target. - Repo-scoped data-plane requests resolve the repo's cell and fail on resolution
failure.
/meuses the home cell; repo-set queries use shared fanout helpers. Multi-cell operations share oneauth.CellClientFactoryper operation.
Update the relevant reference when subsystem behavior changes. Update this file only for repository-wide development rules or routing links. Preserve safety contracts in references and regression tests rather than accumulating incident narratives here. Prefer existing docs over a second account of the same behavior.
The root-file budget is 20 KiB, enforced alongside local documentation links
by go test ./docs/development. Extract specialized material instead of expanding
that budget. Do not require every linked document
to be loaded on every task. Keep AGENTS.md as the symlink to this file.