| Age | Commit message (Collapse) | Author | Files | Lines |
|
init.build() can now write [misp], [abusedb] and [urlhaus], the three
sections report reads, so a user no longer has to hand-edit the config
for them. Follows the [reporter] pattern: a section is emitted only
when something was answered for it, never with an empty api_key.
A half-answered pair (misp_url given, misp_api_key skipped, or vice
versa) is rejected rather than silently written: config.load() would
classify it "incomplete" and report would refuse, but only after the
user believed setup succeeded. Task 8's prompts are the normal route
in, but build() is pure and a caller can hand-build a dict, so this is
enforced here too.
Also fixes FOOTER, which still promised a single [vendors] table; the
spec settled three separate sections and [misp] is no longer "a later
part" since this plan builds it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176FYdVfpzUq8S9jecqQqL6
|
|
The "Later parts add further sections here" block was emitted by build(),
so preserved sections were appended below it and it became a comment about
nothing, pointing at a table already underneath it.
It is now a FOOTER constant that build() still appends, so a lone build()
reads as a complete file, and write() strips before adding preserved text
and puts back at the end.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LByBnw83xr9YP85nskzkyE
|
|
The previous commit removed this guard after a mutation check said it was
redundant. The check was wrong: it only exercised runs that skipped the
identity from the start, where [reporter] is never written and the footer
always trails a rendered table.
The sequence that breaks is answering the identity and then re-running and
skipping it. [reporter] is then PRESERVED rather than rendered, so the
footer that trailed it in the old file rides across while this run emits
its own, and the file grows a second copy per run.
Covered by a test naming that sequence, and both guards now fail when
removed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LByBnw83xr9YP85nskzkyE
|
|
The carry-across preserved every line before the first [table], but that
text is build()'s own header, not the user's. A second init emitted it
twice and a third three times, with [general] missing from the tail half,
so the file grew a copy per run. It still parsed, which is why the suite
stayed green and only a hand test found it.
Preserving from the first table onward fixes the trailing "Later parts"
block too: it trails whichever table came last, so it is already inside a
skipped section. A separate guard for it passed its own mutation check
and was removed as redundant.
Required prompts now say so. The relay question and the hop picker cannot
be skipped, because with no trust boundary parse refuses and init is the
route out, but they read like the reporter questions that do offer a skip.
The cases prompt says "Enter for <default>" rather than showing the
default in brackets, which was the same ambiguity in the other direction.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LByBnw83xr9YP85nskzkyE
|
|
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
|
|
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
|