Development record
Full Removal When You Mean It
Press Release
abcd supports
/abcd:ahoy destroy— a deeper uninstall that goes beyond removing the marker block. When you decide abcd isn't right for a project,destroycleanly removes the marker block, the/usr/local/bin/abcdsymlink, AND the entire.abcd/namespace (including lifeboat, dev artefacts, logbook, and config). Thegitignoreallowlist entries get reverted. abcd offers a final summary of what's about to be deleted with hard confirmation, then walks away. The danger is encoded in the verb itself — same convention asrm -rf,git push --force,terraform destroy."Marker-only
uninstallwas great for 'I'll be back' moments," said Jack, consultant. "But sometimes a project leaves abcd entirely. Now I can/abcd:ahoy destroyand clean up properly withoutrm -rf'ing manually and missing things."
Why This Matters
abcd's uninstall is intentionally lightweight — /abcd:ahoy uninstall removes only the BEGIN/END marker block from CLAUDE.md/AGENTS.md and the symlink. Everything in .abcd/ stays put. This is correct for the common "ahoy then change my mind" case: re-running ahoy resurrects markers from existing config without re-asking.
But for projects that genuinely leave abcd (acquired, deprecated, pivot), the lightweight uninstall leaves lifeboat data, logbook reports, and visibility-driven gitignore entries that no longer make sense. destroy is the nuclear option — explicit, confirmed, complete. Two-tier on the same verb (ahoy) keeps the naming surface small while making the danger gradient legible.
What's In Scope
/abcd:ahoy destroysub-verb (two-tier with theuninstallsub-verb)- Hard confirmation showing exact list of files/directories to delete
- Revert
.gitignoreallowlist entries added by ahoy (back to project's own state) - Removes scheduled
dev-syncjobs if installed (forward-compatible with itd-13) - Final summary report
- Documentation update:
04-surfaces/01-ahoy.mddocuments both sub-verbs side-by-side with the danger gradient explicit (anduninstall's description rewords to "reversible marker-only removal" so the distinction is discoverable from bare/abcd:ahoystatus+help output).
What's Out of Scope
/abcd:purgeas a separate command — explicitly rejected. Two sub-verbs on one command (with adestroythat names its own danger) keeps the surface small. The earlier/abcd:purgeworking name is preserved here for git-blame continuity, but the shipping name is thedestroysub-verb on/abcd:ahoy.- "Soft destroy" (archive
.abcd/to.abcd-archive/instead of delete) — a possible future extension - Cross-project destroy ("remove abcd from all my repos") — requires global state we don't yet have
- Forced destroy without confirmation —
destroyis destructive; always confirm
Acceptance Criteria
Required (per the itd-1 discipline). At least one Given-When-Then bullet describing the verifiable bar for "shipped".
- Given an abcd-installed repo with a populated
.abcd/directory and ahoy-managed marker block inCLAUDE.md, when the user runs/abcd:ahoy destroy, then abcd shows a hard-confirmation prompt enumerating every file/directory queued for deletion (marker block, symlink,.abcd/namespace contents,.gitignoreallowlist entries) before any deletion occurs. - Given the user confirms the
destroyprompt, when the command completes, then the repo no longer contains the abcd marker block inCLAUDE.md/AGENTS.md, the/usr/local/bin/abcdsymlink is removed, the.abcd/directory is fully removed, and.gitignoreahoy-managed allowlist entries are reverted to their pre-ahoy state. - Given the user declines the
destroyconfirmation, when the command exits, then no files or directories are modified and the command's exit code reflects the user's cancellation (non-zero, distinct from error codes). - Given scheduled
dev-syncjobs were installed (per itd-13), when/abcd:ahoy destroyruns successfully, then the scheduled jobs are also removed and the final summary report enumerates the removed schedule entries. - Given a repo with a clean abcd installation, when the user runs
/abcd:ahoy uninstall(marker-only) followed later by/abcd:ahoy destroy, thendestroystill removes the residual.abcd/namespace contents thatuninstallleft behind — the two sub-verbs are composable, not mutually exclusive.
SOTA
Surveyed on 2026-10-23; sources, evidence tiers and the local fit risks are in the install-update-release SOTA note.
- Preview, then tiers, then honesty about what is left is the convention:
mise implode --dry-runpreviews;mise implode"removes the CLI, installed tools, cache and state", keeps "the user config directory unless you pass--config", and tells the person to remove shell activation lines themselves. rustup has one verb (rustup self uninstall); uv has none and documents the steps, including removing the binaries a pre-0.5.0 install left in~/.cargo/bin, which an upgrade does not remove. - "Zap" names the danger and admits collateral: Homebrew's
brew uninstall --zapis to "Remove all files associated with a cask. May remove files which are shared between applications". - Binary and state are removed in separate steps, with a warning on the second: the harness's uninstall page removes the binary per install method and then, under a warning that it "will delete all your settings... and session history", the configuration, noting that other installed clients recreate the directory.
- Destroy-class verbs plan first:
terraform destroyisapply -destroy, andplan -destroyshows "the proposed destroy changes without executing them"; the drafted enumerated confirmation matches. - Two scopes, not one: every tool separates the project's files from the
person's machine-level state. This intent is a repository destroy; the
machine-level counterpart (the user-level home,
path-entry, the plugin data directory the harness keeps across updates) has no verb and is out of this intent's scope.
Path 2 — native, shaped to mise implode: keep the enumerated
confirmation, add --dry-run as a first-class flag, keep the design record by
default behind a flag that names it (the "config" tier every surveyed tool
keeps; proposed answer to the open question below), and have the summary name
what destroy cannot remove (shell-profile lines, commits in git history that
still carry .abcd/, machine-level state) with the one command for each. The
2026-05-07 naming ruling is untouched. The independent fit-challenge runs at
plan time.
Open Questions
- (SOTA 2026-10-23) Does
destroytake--dry-run, and does a misspelt flag refuse rather than run (unrecognized input never writes)? - (SOTA 2026-10-23) Is
.abcd/development/kept by default and removed only when a flag names it, the way mise keeps config unless--config? This is the proposed answer to the design-record question below, for the product thinker to rule on. - (SOTA 2026-10-23) Is a machine-level removal (the user-level home,
path-entry, the plugin data directory) filed as its own intent, since no repository-scoped verb may reach it? - ~~Should
destroyoffer to back up.abcd/lifeboat/somewhere first (since it may be valuable independently)?~~ Moot under adr-35: a lifeboat is written out of tree, to a destinationdisembark packis handed, sodestroyfinds none inside the repository. - Same question for
.abcd/development/(it's design history, not just runtime state)? - Naming — resolved 2026-05-07. Two-tier on
/abcd:ahoy:/abcd:ahoy uninstallis reversible marker-only removal (re-runningahoyre-installs cleanly); the deeper destroy surfaces as/abcd:ahoy destroy— fits the nautical metaphor (scuttling a ship has a name and a weight) and the verb's danger is encoded in the verb itself. Theuninstalldescription ("reversible marker-only removal") makes the distinction discoverable. Plan-review for this intent treats this naming as decided rather than re-opening.
Amendments
Amended by itd-2610030814013772 (2026-10-03, its decisions 4 and 8): the marker block lives in AGENTS.md; a block an earlier setup planted in CLAUDE.md is still found and stripped, so the CLAUDE.md wording here describes projects set up before that change.
Audit Notes
Empty. Populated by intent-fidelity-reviewer when intent moves to shipped/.
Frontmatter
| id | itd-10 |
|---|---|
| type | intent |
| lifecycle | drafts |
| kind | standalone |
| severity | minor |
.abcd/development/intents/drafts/itd-10-purge-uninstall.md
open on GitHub ↗ · commit history ↗
References1
- itd-13Reviews and Memory Stay Fresh, Alwaysbuilds on
Referenced by4
- iss-2610262031329436itd-10's destroy removes an in-tree lifeboat inside .abcd/, but the platform rules say no in-tree lifeboat home existsrelated
- iss-2610262032548523itd-10 lists a lifeboat among the .abcd/ contents destroy deletes; disembark always writes the lifeboat out-of-treerelated
- iss-2610262038521887itd-10's destroy deletes a lifeboat and a logbook inside .abcd/; 03-configuration says neither namespace exists in any treerelated
- iss-2610262040479670itd-10's destroy removes a lifeboat from inside .abcd/; the disembark glossary says there is no in-tree lifeboat directory.related
mentions10
- adr-35The lifeboat is a coverage experiment — read-only, out-of-tree, and proven before it is packed (supersedes adr-4)
- adr-2610030814023326AGENTS.md is the one conventions file abcd writes; it never writes a host-specific copy
- iss-94The intent corpus still specifies the pre-adr-35 lifeboat model: itd-2, itd-8, itd-9, itd-10, itd-13, itd-15, itd-19, itd-22 and itd-24 variously use the retired 'disembark to home' signature, the in-tree .abcd/lifeboat/ home, or the in-tree .abcd/development/voyage/ path (itd-9's acceptance writes voyage provenance in-tree — the exact path that would fail abcd's own privacy-hygiene audit rule). The brief, glossary and roadmap were reconciled to adr-35; the intents were deliberately NOT rewritten, because an intent is a proposal with its own lifecycle and silently rewriting nine of them inside an unrelated change is worse than tracking the drift. Each reconciles when it is next planned.
- iss-2610252214123453The ahoy chapter's 'Not built yet: destroy … (itd-10)' presents a draft intent (intents/drafts/itd-10-purge-uninstall.md, spec_id null) as a staged design, against the 00-meta truth rule that the brief records no undecided option.
- itd-1Every Intent Has Acceptance Criteria; Every Audit Verifies Them
- itd-42Grill Reads an Intent Against the Brief and Its Siblings, Not Just the Glossary
- itd-177An intent's claims are typed and its scope conditions keep their identity across edits — the readiness gate refuses an intent that leaves a context claim unrecorded
- itd-2609091034175565Before an agent starts on an item, it reserves it on the shared remote, and everyone who works on the project sees the reservation
- itd-2610030814013772abcd's projects keep one conventions file, AGENTS.md, and Claude Code reads it directly
- spc-2610031156364295evaluate-whether-claude-md-can-be-removed-safely-now-that