Development record
plugin surface parity: commands/abcd/ahoy.md drives only the bare read-only detect while the CLI registers install, uninstall, doctor, and dry-run — doctor and dry-run are read-only so a keep-mutation-away-from-agents policy cannot explain their absence, and the landing commit claimed the sub-verbs were wired through the plugin command; every plugin command remedy for abcd not on PATH says make build, which cannot produce an on-PATH abcd; plain-CLI abcd memory ask output is headed as a plugin slash command. Detector: a surface-parity check — every CLI sub-verb is reachable from the plugin markdown or carries an explicit scoping note, and remedy text is exercised by a test. Acceptance corpus: the three instances above.
plugin surface parity: commands/abcd/ahoy.md drives only the bare read-only detect while the CLI registers install, uninstall, doctor, and dry-run — doctor and dry-run are read-only so a keep-mutation-away-from-agents policy cannot explain their absence, and the landing commit claimed the sub-verbs were wired through the plugin command; every plugin command remedy for abcd not on PATH says make build, which cannot produce an on-PATH abcd; plain-CLI abcd memory ask output is headed as a plugin slash command. Detector: a surface-parity check — every CLI sub-verb is reachable from the plugin markdown or carries an explicit scoping note, and remedy text is exercised by a test. Acceptance corpus: the three instances above.
Frontmatter
| id | iss-44 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | major |
.abcd/work/issues/resolved/iss-44-plugin-surface-parity.md
open on GitHub ↗ · commit history ↗
mentions4
- dcn-26080500000000022026-08-05 — iss-44 + iss-160 + iss-161 + iss-162 (v0.5.0 item D, one work item): the plugin surface is reconciled with every document describing it, and the reconciliation is a MOVE rather than a rename, because the harness's namespace rule leaves no other answer. Verb files under `commands/abcd/` registered as `/abcd:abcd:<verb>` — a `commands/` subdirectory IS a namespace segment, and this one was named after the plugin, so the prefix appeared twice and every documented `/abcd:<verb>` was an unknown command (iss-161). Flattening into `commands/` is what makes the printed guidance runnable, which is why iss-162 needed no rewrite at all: all eighteen verb files already spelled `/abcd:<verb>` in their self- and cross-references — verified by grep across every one rather than assumed — so the guidance was correct prose about a name nothing registered. On iss-160 the fix direction was settled by evidence, not preference: the loader registers every markdown file under `commands/`, requiring no frontmatter and exempting no name (this repo's own iss-110 records `agents/README.md` registering as an agent; the published plugin reference describes commands purely as flat `.md` files with no ignore list), so NO in-place form keeps a readme unregistered and the only reliable home is outside the auto-discovery root. It goes to the brief's surface registry, which already enumerates the same surface and is already machine-checked against it — folding the doc into the gate that guards it rather than leaving a second enumeration to drift. The cost is one repointed link in a 2026-07-12 plan, paid because `links_resolve` is a blocker and a dangling pointer is not history. iss-44's three instances close with them: `ahoy` gains a section per sub-verb (with `identity-check` carrying an explicit CLI-only note, because its exit code is the point of wiring it into a hook — an absence recorded as a decision is not a gap), every `make build` remedy is replaced by the `go run ./cmd/abcd …` fallback the same paragraphs already carried, and `memory`'s renders stop naming a front door from `internal/core`, which is transport-agnostic by boundary rule: the heading a plain-CLI reader sees must not claim they invoked a plugin command they may not have installed. Detectors first, both watched failing: a surface-parity test over the real command tree and the real directory (flat-and-commands-only, every sub-verb reachable or scoped, no unrunnable remedy), and a string-literal check over `internal/core/memory` — literals, not comments, because prose explaining a surface may name it. `surface_coverage` gains a `bare_command` field so the flat directory's top-level board file is excluded the way README already is, rather than demanding a registry row that cannot exist; hardcoding the name would have been wrong in a lint engine that ships to repos whose plugin is not called abcd. Left alone deliberately: the historical citations of `commands/abcd/` across decisions, shipped intents, closed specs, research and resolved issues — they describe the tree as it was, and rewriting them would trade a true record for a tidy one. Not fixed here, and reported instead: the release-gate manifest's `promptHash` pins prompt text this change edits, by an algorithm nothing in the tree computes or verifies, so it is left untouched rather than guessed at.
- iss-183The blanket `.abcd/` exclusion claim that iss-43 corrected in the README survives across the record. Recorded rather than fixed there, because the disposition scoped iss-43 to one README line.
- iss-387the release-gate manifest pins 17 briefDocs while four shipped surface chapters (guard, ideate, identity, banlist) are outside the pin, so every full-tier crosscheck attests coverage it never ran
- iss-392bughunt round-3 confirmed nitpick batch — zero-padded record-id filenames evade the id-uniqueness lint in all three families; the go-version lockstep test skips .yaml workflows; scripts/*.sh lack the eol=lf pin the repo's own policy states; agents/CHANGELOG announces lifeboat-reviewer 0.1.1 while the prompt carries 0.1.0; five live records still route to the pre-flattening commands/abcd/ and retired docs/reference pages