From 33feb9c200f9b04dcbac54f483566fed554df6fe Mon Sep 17 00:00:00 2001 From: REPPL <77722411+REPPL@users.noreply.github.com> Date: Fri, 11 Sep 2026 10:46:31 +0100 Subject: [PATCH] chore: close spc-26 and record the ruling that adoption stays nameless MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two maintainer rulings from the v0.8.0 review, landed together because both came out of the same read of what the release had left standing. spc-26 is closed and itd-121 ships. The record-id dispatch form has been live for some time — `abcd itd-20`, `spc-26`, `adr-23` and `iss-110` all render their path, status, links and next moves — while its spec sat in `open/` and its intent in `planned/`. That is the silent half of the definition of done: nothing runs the close for you, and a planned intent is not refused by the release cut, merely unseen. It was deliberately not closed during the v0.8.0 cut. The changelog is composed from the records that reach a terminal folder since the anchor tag, so closing it mid-cut would have written a 0.8.0 line for work that shipped earlier, and broken the completeness bijection the section had already proved. Closing it now moves that line to the next cut instead, which is still not the release that carried the work. `spec close` has no `--shipped-in` escape, unlike `capture resolve`, so there is no way through this verb to close the record and keep it out of the cut. Worth deciding at the next cut whether the line stands or the escape is worth adding. The ahoy ruling is recorded rather than implemented. `ahoy install` defaults `--docs-target` to `both` and plants a block opening "Managed by abcd" into a target repository's committed CLAUDE.md and AGENTS.md, while `prepare-this-repo` promises in its acceptance criteria that no abcd-internal content appears in any committed artefact. The v0.8.0 gate caught the contradiction and the prose was corrected to match the code; the ruling is that the promise was the right end and the behaviour is what should change, so implementing it reverses that correction deliberately. The record carries what the change has to settle rather than just the verdict: the marker is what promotes a folder to managed-repo, so a nameless block must still classify; the rule loader has to keep being discoverable; and the real question is the `both` default rather than the wording of the block. Refs: iss-2609110944498549, iss-110 Assisted-by: Claude:claude-opus-5[1m] --- ...next-move-abcd-id-dispatches-on-a-recor.md | 3 +- ...next-move-abcd-id-dispatches-on-a-recor.md | 0 ...-write-abcd-by-name-into-a-target-repos.md | 77 +++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) rename .abcd/development/intents/{planned => shipped}/itd-121-type-the-id-get-your-next-move-abcd-id-dispatches-on-a-recor.md (97%) rename .abcd/development/specs/{open => closed}/spc-26-type-the-id-get-your-next-move-abcd-id-dispatches-on-a-recor.md (100%) create mode 100644 .abcd/work/issues/open/iss-2609110944498549-ahoy-install-must-not-write-abcd-by-name-into-a-target-repos.md diff --git a/.abcd/development/intents/planned/itd-121-type-the-id-get-your-next-move-abcd-id-dispatches-on-a-recor.md b/.abcd/development/intents/shipped/itd-121-type-the-id-get-your-next-move-abcd-id-dispatches-on-a-recor.md similarity index 97% rename from .abcd/development/intents/planned/itd-121-type-the-id-get-your-next-move-abcd-id-dispatches-on-a-recor.md rename to .abcd/development/intents/shipped/itd-121-type-the-id-get-your-next-move-abcd-id-dispatches-on-a-recor.md index e6ed21df0..736d13116 100644 --- a/.abcd/development/intents/planned/itd-121-type-the-id-get-your-next-move-abcd-id-dispatches-on-a-recor.md +++ b/.abcd/development/intents/shipped/itd-121-type-the-id-get-your-next-move-abcd-id-dispatches-on-a-recor.md @@ -84,4 +84,5 @@ is a future consideration, deliberately not an AC._ ## Audit Notes -_Empty. Populated by intent-fidelity-reviewer when intent moves to shipped/._ + +Fidelity review OWED (receipt rcp-e85e544ece36). diff --git a/.abcd/development/specs/open/spc-26-type-the-id-get-your-next-move-abcd-id-dispatches-on-a-recor.md b/.abcd/development/specs/closed/spc-26-type-the-id-get-your-next-move-abcd-id-dispatches-on-a-recor.md similarity index 100% rename from .abcd/development/specs/open/spc-26-type-the-id-get-your-next-move-abcd-id-dispatches-on-a-recor.md rename to .abcd/development/specs/closed/spc-26-type-the-id-get-your-next-move-abcd-id-dispatches-on-a-recor.md diff --git a/.abcd/work/issues/open/iss-2609110944498549-ahoy-install-must-not-write-abcd-by-name-into-a-target-repos.md b/.abcd/work/issues/open/iss-2609110944498549-ahoy-install-must-not-write-abcd-by-name-into-a-target-repos.md new file mode 100644 index 000000000..a23d42c4b --- /dev/null +++ b/.abcd/work/issues/open/iss-2609110944498549-ahoy-install-must-not-write-abcd-by-name-into-a-target-repos.md @@ -0,0 +1,77 @@ +--- +schema_version: 1 +id: "iss-2609110944498549" +slug: "ahoy-install-must-not-write-abcd-by-name-into-a-target-repos" +severity: "major" +category: "ux" +source: "user-observation" +found_during: "v0.8.0 release review, maintainer ruling" +origin: researcher-authored +production_mode: hand-written +found_at: "internal/core/ahoy/defaults/claude-md-marker-block.md" +--- + +**Maintainer ruling, 2026-09-11: `ahoy install` must not write abcd by name into +a repository it adopts.** This record exists to carry that decision to the change +that implements it. + +## What happens today + +`ahoy install` defaults `--docs-target` to `both` +(`internal/core/ahoy/detect.go:28`), and `stepMarker` +(`internal/core/ahoy/apply.go:866-900`) plants +`internal/core/ahoy/defaults/claude-md-marker-block.md` into the target +repository's committed `CLAUDE.md` **and** `AGENTS.md`. That block opens +"Managed by abcd (Agent-Based Configuration for Development)" and carries a full +"## abcd rule loader" section. + +So a default adoption commits abcd's name and its internals into somebody else's +repository, and does so in files that repository's contributors read first. + +## Why it is wrong rather than merely surprising + +`prepare-this-repo` promises the opposite in its own acceptance criteria: "Given +the adoption completes, then nothing from `private-names.txt` and no +abcd-internal content appears in any committed artefact", reinforced by a +Boundaries claim that the output is nameless and never mentions abcd. + +The v0.8.0 release gate caught the contradiction and the prose was corrected to +describe what the code does +(`.abcd/development/brief/04-surfaces/15-prepare-this-repo.md`). That was the +right move for the record at the time and is now the wrong end to have fixed: +the ruling is that the PROMISE was correct and the BEHAVIOUR should change. +Implementing this therefore reverses that prose correction, deliberately. + +It is the same stance as +[`the-users-directory-is-theirs`](../../development/principles/the-users-directory-is-theirs.md) +and adr-2609091248200336, one level in: a tool does not create directories in +space the user did not hand it, and it does not write its own name into files +the user will commit under their project's history either. + +## What the change has to settle + +- **The marker still has to be findable.** Detection promotes a folder to + managed-repo on a marker block (`internal/core/ahoy/detect.go:139`, + `strong := registered || markerFired`), so whatever replaces the named block + must still be recognisable to `classify` and must not silently downgrade every + adopted repo to unmanaged. +- **The rule loader has to keep working.** The block is not decoration; it is how + a session learns the loader exists. If the committed half goes nameless, the + loader's documentation has to live somewhere the adopting project chose. +- **The default is the question, not just the text.** `--docs-target both` is + what makes this the out-of-the-box behaviour. Options include defaulting to + `skip`, keeping the block but stripping the name and the internals, or moving + the whole thing under `.abcd/` where the adopter already accepted a namespace. +- **Registry-only adoption already exists** as the other strong signal, so a + nameless install is not a new mechanism, only a different default. + +## Acceptance + +- **Given** a repository adopted with default options, **when** the install + completes, **then** no committed file in that repository contains the string + "abcd" as a result of the install. +- **Given** that same repository, **when** `ahoy` classifies it afterwards, + **then** it still reports managed-repo. +- **Given** the `prepare-this-repo` acceptance criterion about nameless output, + **when** the change lands, **then** the criterion is true of the code and the + v0.8.0 prose correction is reversed in the same diff.