diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-10 10:38:10 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-10 10:38:10 +0200 |
| commit | 37d723f2ffd55dcca141831ee2368b5b49618de8 (patch) | |
| tree | 6b1a2c1c126a92a506f29fc9dbdd44f2f041713a /docs/BACKLOG.md | |
| parent | 5f9bbeb509773e5280995b39b44cf9be9c29ece2 (diff) | |
| download | abusectl-37d723f2ffd55dcca141831ee2368b5b49618de8.tar.gz abusectl-37d723f2ffd55dcca141831ee2368b5b49618de8.zip | |
feat: ask for the reporter identity during init
Each answer is validated at the prompt that asked for it, and a skipped
answer is absent from the file rather than an empty string.
Two defects fixed beyond the plan, both in the carry-across rule. Sections
build() does not produce are preserved verbatim, and that rule was written
when [general] was the only section it produced. Emitting [reporter] as well
made preservation emit it TWICE, and tomllib refuses a duplicate table
outright, so the rewritten file became unreadable and took the preserved
[misp] key with it. Dropping [reporter] unconditionally instead would have
been the opposite defect: an init that skips all three questions would
silently delete an identity set by hand. What is dropped is now read back off
the rendered text, so it is what this run actually wrote rather than what it
might have written, and a section added to the builder later cannot be
forgotten here.
The email check is deliberately not an RFC 5322 validator. What a typo costs
is a report whose reply address bounces, and the answers that produce that
are a name with no @ at all, a spelled-out "at", and a stray space from a
copy-paste. Anything stricter starts rejecting addresses that work.
Skipping the address is allowed but warned about at the prompt: it is the one
field a report cannot be built without, since it becomes the From.
report.build() raises a bare KeyError on that identity today, which the three
prompts made reachable from a config file for the first time; logged as
backlog item 5 rather than fixed here, because where the check belongs is the
report subcommand.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LByBnw83xr9YP85nskzkyE
Diffstat (limited to 'docs/BACKLOG.md')
| -rw-r--r-- | docs/BACKLOG.md | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md index 780cbf5..63ea52c 100644 --- a/docs/BACKLOG.md +++ b/docs/BACKLOG.md @@ -134,3 +134,31 @@ to name the field differently, the fix is one string and one test. a field an x-arf parser skips rather than acts on wrongly. Worth doing before the first real report is filed, so a desk running x-arf tooling gets what it expects. + +## 5. `report.build()` raises KeyError on an identity with no email + +**Observed.** `report.build(manifest, destination, identity)` reads +`identity.get("name", "")` defensively but `identity["email"]` directly, so an +identity carrying a name and no address raises `KeyError: 'email'` rather than +saying what is missing. Reproduced through the public API against the real +config reader: `config.load()` on a file whose `[reporter]` sets `name` and +omits `email` returns `{"name": "A Reporter"}`, and that dict raises. + +**Cause.** Every key in `[reporter]` is independently optional, by the same +skipped-answer-is-absent rule the rest of the config follows, but the report +builder treats one of them as required without checking. Task 9 fixed the +config half of this seam; the report half was not reachable from a config file +until `init` grew the three prompts, and now it is: skipping the email +question while answering the name produces exactly this shape. + +**Approach.** Refuse before building, not after: raise a named error saying no +reply address is configured. Filling in an empty addr-spec instead would be +worse, since a `From:` with no address produces a report that is sent and +cannot be replied to, which defeats the reason the identity is disclosed at +all. `init` now warns at the prompt when the address is skipped, so the +remaining gap is a hand-edited config and the error message it deserves. + +**Constraints.** Belongs with the `report` subcommand rather than the builder +alone, since where the check lives decides whether the user sees an exit code +and a sentence or a traceback. Not a leak: the failure is loud and nothing is +sent. |
