Development record
Every mutating verb's brief surface row carries at least one If/Then unwanted-behaviour clause in the EARS pattern (If <unwanted condition>, then the system shall <refusal or recovery>), making the refusal a first-class, testable spec item before any code exists. The convention serves specification completeness: unwanted-behaviour handling is the dominant omission class in specs, and a row that only describes the happy path leaves the fail-closed behaviour to be invented at implementation time. This feeds the iss-29 fail-closed test convention, which needs a spec-level clause to test against. Detector/acceptance: a surface-row lint flags any mutating verb whose row lacks an If/Then clause, and each clause maps to at least one fail-closed test.
Every mutating verb's brief surface row carries at least one If/Then unwanted-behaviour clause in the EARS pattern (If <unwanted condition>, then the system shall <refusal or recovery>), making the refusal a first-class, testable spec item before any code exists. The convention serves specification completeness: unwanted-behaviour handling is the dominant omission class in specs, and a row that only describes the happy path leaves the fail-closed behaviour to be invented at implementation time. This feeds the iss-29 fail-closed test convention, which needs a spec-level clause to test against. Detector/acceptance: a surface-row lint flags any mutating verb whose row lacks an If/Then clause, and each clause maps to at least one fail-closed test.
Grounds
- declined: the refusal is already a mandatory, generated spec line per verb; this would be wrong if a mutating verb could ship with no refusal stated on its surface
Frontmatter
| id | iss-53 |
|---|---|
| type | issue |
| lifecycle | wontfix |
| severity | minor |
.abcd/work/issues/wontfix/iss-53-ears-unwanted-behaviour-rows.md
open on GitHub ↗ · commit history ↗
mentions1
- iss-29fail-closed capture surface: a misspelled capture subcommand (e.g. capture resovle) is swallowed as capture text and files a NEW issue instead of erroring (internal/surface/cli/cli.go:455) — a typo becomes a ledger mutation; --json errors emit raw Go text, not JSON (internal/surface/cli/cli.go:165), and abcd docs lint without a config surfaces a raw file error. Detector (per unrecognized-input-never-writes): a surface test convention where every mutating verb has a malformed-input case asserting an error, a did-you-mean for near-misses, and no write occurred, plus a --json error-shape contract test. Acceptance corpus: the three instances above — the detector is proven when it flags all three.