| Age | Commit message (Collapse) | Author | Files | Lines |
|
The author keeps ideas in an Obsidian note outside this repository. Nothing
in the repo pointed at it, so a fresh session would never find it and the
backlog would look complete while ideas sat unread. AGENTS.md now names the
path and the rule: the note is the inbox, the backlog is the tracked list,
and they are reconciled in both directions.
Item 3 is that note's one open idea, an API letting qtmaildir tag incoming
mail by resemblance to a kept case. It is recorded unsized and explicitly
marked as having no verified cause, because unlike items 1 and 2 there is
nothing built to verify. The entry records the real tension rather than just
the request: this tool has been deliberately mechanical, reporting what a
message declared and refusing rather than guessing, and a resemblance score
would be its first opinion. It also notes that source.eml is unredacted, so
matching must not become a route by which a stored recipient identifier
reaches a comparison.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wrfqr2xqQfhtXCscU7zrdz
|
|
An RDAP query discloses what the user is looking at, and property 1
covers only what is published, so the query rule needed stating in its
own right beside the other three. The section records the three leaks it
came from, because each one was the same shape: validation applied per
branch, forgotten on the next.
Also moves rdap.py's imports into one block at the top. Pure move, the
suite is 192 either side of it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wrfqr2xqQfhtXCscU7zrdz
|
|
Twelve tasks, TDD throughout, building bottom up: transport, bootstrap
cache, server selection, jCard extraction, querying with the label walk,
the worklist, resolution, the subcommand, an offline proof, two sweeps
and the documentation.
The code in the plan was assembled and run before committing it, against
the plan's own tests, 44 of which pass. That found two defects in the
plan itself: a parameter that shadowed the cache_dir function and forced
a globals() lookup, now renamed to cache_root, and a hand-rolled fake
request in the redirect test that lacked the attributes
HTTPRedirectHandler reads, now a real urllib Request.
Also drops the em dashes from the Documents list in AGENTS.md, which the
no-em-dash writing rule covers and which the contacts entry had matched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wrfqr2xqQfhtXCscU7zrdz
|
|
Settles what the umbrella design left open for this part: RDAP bootstrap,
caching policy, and what happens for a netblock that publishes no abuse
contact.
Scope is IPs and domains, with a URL contributing only its host. The
bootstrap files are fetched from IANA and cached with a long TTL, while
responses are cached in memory for one run only: a stale bootstrap merely
misses, but a stale abuse address sends a report into a dead mailbox
silently. The registrable domain is found by walking up the labels and
asking the registry rather than by bundling a Public Suffix List, which
would be a transcribed table that goes stale weekly.
Address extraction is a strict abuse-role match with no fallback. In
particular it never constructs abuse@<domain>, because for a phishing
domain that mailbox belongs to the attacker and mailing it would confirm
both the catch and that the address is live.
Adds a fourth non-negotiable property: a query carries a bare host or IP
and never a URL. Property 1 governs what is published, and a query is a
disclosure that appears in no report, so a path segment that parse
deliberately flags rather than redacts would otherwise leak.
Transport is urllib with an injected fetch, so requirements.txt stays
empty and the suite keeps passing with sockets raising, for the whole
suite rather than for everything except contacts.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wrfqr2xqQfhtXCscU7zrdz
|
|
A synthetic fixture only ever holds the shapes someone thought of, and
the shapes nobody thought of are the ones that leak. Sweeping the user's
own tag:spam is the only source of those, and it earned its place: the
first message found a header the parser did not read, and the corpus
exercised a spoofed Reply-To display name no fixture had.
AGENTS.md records it under Testing, beside the fixture rule it is the
deliberate exception to: ask first, work from the scratchpad, compare
every address in the raw source against the whole ioc output, and let
only counts and stripped domains out. A finding becomes a synthetic
fixture; the real message never enters the repository.
BACKLOG.md opens with the one thing the sweep found that was not worth
fixing blind: boilerplate namespace urls (w3.org doctypes) reported as
indicators. Noise rather than a defect, and the argument for leaving it
alone is real, so it is written down with both sides rather than built.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019NHaqA1Rz5ybed7wFUeQbK
|
|
Same arrangement as qtmaildir: one source of truth, and a thin pointer
beside it so every agent tool reads the same file.
It leads with the three properties that are not negotiable, because each
has a concrete victim and each is a thing a later change could quietly
break. Recipient identifiers must never reach a report, and the guarantee
is structural rather than a step someone remembers. Nothing is fetched or
resolved, which the suite verifies by running with sockets disabled. The
trust boundary is configured rather than guessed, and its test is
mutation-checked because walking one hop too far reports an innocent party
the attacker named.
It also records the traps that were found the hard way rather than
reasoned about: ipaddress.ip_network(42) returning 0.0.0.42/32 instead of
raising, a string trusted_relays iterating characters, goog.json looking
like the right SPF source while listing all of Google, and the provider
table having been wrong in every entry when it was first written from
memory.
The hand-testing rule is stated with its evidence: the prompts are the
user's to test, and one pass over them found five defects, four being the
same mistake of validating an answer somewhere other than where it was
given.
Every factual claim in it was checked against the code before committing.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
|