| Age | Commit message (Collapse) | Author | Files | Lines |
|
Thirteen tasks, TDD throughout. Task 1 changes parse.py to store a whitelist
of publishable headers, which is what lets report never open source.eml, and
Task 13 re-runs both sweeps with a third assertion covering generated bodies.
Two spec items deliberately have no task and are recorded as gaps: api
destination bodies belong to the submit spec, and writing the frozen marker
is submit's work.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xj1ayFRSUQ2u7cwb3S4axE
|
|
The spec named a strict Accept: application/rdap+json while the plan, and
so the code, sends application/rdap+json with application/json at q=0.9.
A spec review caught the disagreement. The wider header is the right
behaviour, since some registries serve plain application/json and a
strict header would lose a contact that was published, so the spec moves
to match the code and now records why.
Both documents also claimed requirements.txt stays empty. There is no
requirements.txt in this repository and there never has been, so the
claim was true only vacuously. They now say the tool declares no
dependencies, which is the thing actually being promised.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wrfqr2xqQfhtXCscU7zrdz
|
|
Two corrections found while executing it.
The offline proof in task 9 patched socket.socket itself, which breaks
the ssl module at import time and produces false failures unrelated to
network use. It now patches socket.socket.connect, which is the right
target.
Task 12 gains a step moving the imports in rdap.py to the top of the
file. The module was built one task at a time, so several imports landed
mid-file after function definitions. Doing it in the documentation pass
keeps it out of the diff that contacts.py builds on.
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
|
|
Its SPF is a tree of includes rather than a flat list: spf.privateemail.com
carries no addresses at all, only includes, and one branch nests a further
level. Two of the branches live on jellyfish.systems. The entry here is the
flattened union of the five leaf records, deduplicated, 18 networks.
The re-verification command lists the leaves rather than the top-level
name, and a note says why: querying spf.privateemail.com and finding no
ip4 entries looks like a stale record and is not one.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
|
|
Every range in the first draft was wrong. They had been written from
memory, and the correct source is each provider's own SPF record, which
is the list of addresses it declares it sends from.
Gmail is the clearest case: the table claimed eleven IPv4 ranges and
_spf.google.com publishes two. Fastmail, Proton and the rest were wrong
in the same way. Outlook and Zoho are added since they were queried
anyway, and the transcription commands are recorded in a comment so the
next check is a copy-paste rather than a search.
Google's goog.json is deliberately NOT the source, though it looks like
one: it lists all Google infrastructure, over a hundred ranges, and using
it would trust every Google-hosted service as part of the user's own mail
path. _spf.google.com is the mail-sending answer.
The table is IPv4 only. An IPv6 hop from one of these providers does not
match and the user is asked instead, which is the safe direction: a hop
wrongly trusted means the real sender is never reported.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
|
|
Thirteen tasks, TDD throughout, stdlib only. parse is pure and offline:
the trusted-relay boundary arrives as an argument rather than a config
read, so the whole extractor is testable against fixtures with no setup.
The plan carries three checks that are not ordinary unit tests. The
Received-chain task has a mutation step, because walking one hop too far
reports an innocent third party named in a header the attacker wrote, and
a test that cannot fail would not protect against it. The URL task runs
the suite with sockets refused, so the never-fetch rule is verified
rather than read. And every fixture is asserted to leave no recipient
address anywhere in the manifest.
init exists because parse refuses to guess the trust boundary. It asks
for CIDRs, offers a static table of known provider ranges, or reads the
chain of a known-good sample and lets the user pick their own hops. A
pure builder with the prompts and the flags as two front ends over it, so
--non-interactive covers agent-driven setup and the config writing is
tested without a terminal. Re-running shows what is already configured
and asks; either route backs the old file up first and preserves sections
this run does not set, so a later init cannot silently drop a MISP key.
The prompts themselves are hand-tested rather than driven from stdin: a
test there would assert the wording it was written against and break on a
rewording that improved it. Task 12 is the checklist, weighted towards
wrong answers.
Redirect chains were missing from the first draft of the plan and are now
specified: a parameter whose value is itself a URL is recovered as an
indicator while every other value stays redacted, which resolves the
conflict between reporting the destination and never publishing a
tracking token.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
|