From log files to signed dossiers: how my threat-intel pages began
Lesson from:
One honeypot, one HTML page, then 810 signed reports, a public retraction, and readers who turned out to be machines
On 26 April 2026 my threat-intelligence page was one long HTML file holding two reports. By the end of that day it held seven, it had been rebuilt to look like a book, and it had grown from 896 lines to 3,233. Every one of those reports came from the same place: the log files of a single honeypot running on a single machine in my apartment in Iași.
Today, 5 November 2026, a job in my cluster re-signed and resealed 810 dossiers with an Ed25519 key and committed the result to Git. It does this every six hours. Nobody asked it to. I did not watch.
Between those two days is the story of how a hobby page became a small public archive that machines read more than people do, and that has, at least once, publicly corrected itself.
Contents · 12 sections
In one minute #
- My honeypot recorded its first session on 21 March 2026. By late April I was publishing what it saw.
- The reports, which I call dossiers, began as sections of one HTML page: 2 on the morning of 26 April, 7 by the end of it, 11 by 8 May, 43 by mid-June.
- In June the 1.5 MB page was split into one page per dossier, and a small publishing service took over: 48 dossiers imported on day one.
- In July every dossier was signed, given a Merkle root and anchored in Bitcoin, so anyone can check that it has not changed.
- On 29 July I published a retraction of one of my own dossiers, as a new dossier, and left the wrong one standing.
- By August, AI crawlers had fetched the verification pages 2,216 times.
The before: a log nobody reads #
A honeypot is a decoy server. It pretends to be an ordinary, slightly neglected machine on the internet, and it records whoever tries to get in. Mine went live on 21 March 2026. That is the whole origin, and I will not dwell on the attackers here; they have their own post, and they are not the point of this one.
The point is what a honeypot produces: logs. Sessions, timestamps, addresses, counts. A month in, the stats banner I wrote on 26 April said 347,000 events from 3,282 addresses over 37 days, and 210 MB of logs.
If you have ever kept a diary nobody reads, you know the feeling of a log. It is true, it is complete, and it is silent. A row in a database does not warn anybody. It does not teach anybody. It sits there.
I wanted the opposite. I wanted the work to be readable by a stranger, checkable by a sceptic, and useful to someone running a server like mine. That meant publishing. And publishing meant I had to be right in public.
The trigger: one page, one Sunday #
The record for 26 April is a list of tasks that keeps getting longer.
First, three new dossiers went onto the existing page, bringing it to five, with an updated stats banner. Then the same three were rewritten from scratch into what the notes call “deep investigative-quality” reports, which pushed the page to about 1,800 lines. Then I decided it was unreadable as one endless scroll, and rebuilt it into a book: a fixed table of contents on the left, a progress bar at the top, a print button on every dossier that prints only that dossier, a menu for phones. The page went to 2,440 lines. The note is careful to say that all five dossiers were “preserved byte-for-byte”.
Then a sixth dossier. Then a seventh, which was the biggest yet. For that one, six investigation agents ran in parallel and produced 4,202 lines of raw reports, which I condensed into a 488-line article. The day ended with a 237 KB page and seven dossiers, live, returning HTTP 200.
Reading that record now, I notice two things. One is the speed: a single person, working with AI agents, turned five weeks of logs into a readable archive in one day. The other is that every single task ends with a check. “HTTP 200 confirmed.” “7 article elements balanced.” That habit of proving the page was really there turned out to matter more than anything else on the list.
The build: from one file to a service #
Eleven #
On 8 May the eleventh dossier went live. It was the most careful one yet: the public version had personal data redacted before it was published. The same day, cross-checking that investigation, I found that every address in it had already been flagged by a community blocklist before it reached me. That humbling moment belongs to another story. For the archive it meant something simple: what I publish is one voice among many, and it had better be an accurate one.
The 1.5 MB page #
By June the “one long page” idea had collapsed under its own success. On 17 June the threat-intel page was 1.5 MB of HTML holding 43 dossiers. Every visitor downloaded all of it to read one. To a search engine it was one giant document instead of 43 distinct ones. A link to a dossier was a link to a hash fragment inside a monster.
So I split it. A small script pulled each article out of a backup of the monolith and rebuilt it as its own page, with a top bar, previous and next links, and a cleaner visual style. Old links kept working through a small redirect that read the old fragment and sent the reader to the new address. The sitemap went to 55 URLs. It was not glamorous work. It was the work that made everything after it possible.
The publisher #
The next day, 18 June, the dossiers stopped being hand-edited HTML. A small web service, built on FastAPI with a single page template, took over: dossiers became database records, and pages became renderings of those records. The project note records the starting point: “48 dossiers imported”.
This changed what a dossier was. Before, it was prose I had written into a file. After, it was a structured investigation with parts: a hypothesis, evidence, actors, findings, infrastructure and the connections between them. The publisher refuses to publish an investigation that is missing any of them. I hit that wall myself more than once; one of my recorded mistakes is simply that the publish call failed because I had forgotten to write a hypothesis. A machine that says “no” to its own author is a useful machine to have.
Sealing: making it checkable #
By July there were hundreds of dossiers, and a new worry. The task that started the next phase states it plainly: the articles “lacked visible evidence”, so their credibility was “moderate”. I wanted provable depth without handing out the raw intelligence, and I wanted copies to be visibly derived from the original.
On 19 July that became real. Each dossier got:
- a manifest: the structured parts of the investigation, in a fixed order;
- a Merkle root: every part is hashed, the hashes are hashed in pairs up to a single root, so changing any part changes the root;
- an Ed25519 signature over that root, from a key held by a small signing service;
- an OpenTimestamps proof, which commits the hash into a Bitcoin transaction and later proves it existed by that block’s time;
- a public verify page that checks all of this in the reader’s browser, without asking my server anything.
The first run backfilled the archive: 636 entries in the signed log, the seal live on 630 articles and 630 verify pages. The same day the Bitcoin anchoring was switched on for every root, along with a job that re-signs and reseals the archive every six hours.
The mechanics, and the two bugs that taught me what “verifiable” really requires, are in the signing post. I will not repeat them. What I want to say here is what it changed: the archive stopped being something you had to take my word for. My word was no longer the product. The data was.
The retraction: “The Fleet That Wasn’t” #
Ten days after the seals went live, the archive had to be checkable about me.
One dossier in a series about impostors, TI-2026-089I, had named 23 addresses as a fleet pretending to be ClaudeBot, the crawler of the AI company Anthropic. The reasoning looked sound. Real crawlers from Google and OpenAI do not crawl from rented cloud machines, so a “Googlebot” coming from a rented cloud machine is almost certainly fake. I had applied the same logic to this crawler.
It was wrong. The addresses sat inside a range that Anthropic publishes in its own official list of crawler addresses. For this company, crawling from that cloud is normal. The visitors I had called impostors were the real thing.
Amending the original would have taken minutes: one table row, one sentence, one total. My notes from that day say why I did not:
“A body of work whose value rests on being checkable has to be checkable about itself.”
So on 29 July I published the correction as its own dossier, TI-2026-089J, titled “The Fleet That Wasn’t”. It went into the same series, right after the dossier it corrects, and the two link to each other in both directions. The original is still there, unedited, so anyone can see what I claimed and when. The archive went from 784 published dossiers to 785, and the newest one says, in effect, “one of the others was wrong”.
The hardest part was not admitting the error. It was bounding it. A retraction that just says “this was wrong” makes readers doubt everything around it, which destroys more than the error did. So the correction states exactly what falls and what stands: of the six impostor fleets in that dossier, one fell. The other five stood, because those companies’ own published lists genuinely exclude the clouds the traffic came from. The total went from about 160 impostor addresses to about 137. And it includes the sharpest check I could find against myself: the same company’s list also contains 19 single addresses in a second cloud, so that cloud is not disqualifying either; one address I had flagged there is simply not on the list, and stays flagged.
If you have ever had to say “I was wrong” in public, you know the oddly light feeling afterwards. The worst thing has already happened, and you wrote it yourself.
It was not the last correction. In October I found that copy written by agents for my site had invented facts with total confidence, including a dossier count of 8,969. The real number was 817. Every number on the public pages is now bound to live data, and agent-written copy is reviewed line by line. The machines that help me write are fluent. Fluency is not evidence.
The fear that did not come true #
Publishing names of infrastructure has a quiet fear attached to it. What if they read it? What if they come for the site?
On 30 July, after a sudden burst of activity, I tested exactly that question: was the burst retaliation for the dossiers? I wrote seven criteria down before looking, so the answer could not be bent to fit them. Did the activity start after the publications? Did it follow the articles in time? Did any named actor ever visit the site? And so on.
The hypothesis failed six of the seven. The seventh could not be tested at all, because I had no control sensor, and the dossier says so instead of pretending. The activity predated the publications by three months. The tightest timing ran backwards: an article had been written two days after the burst it described. No named actor had ever touched the website.
If you have ever worried about being noticed by the wrong people, you know what a result like that is worth. It is also a lesson in modesty. Whoever is behind the addresses in my dossiers, not one of them had ever visited the site. They do not read me.
Who does read it #
Something else reads it, though.
On 8 August I counted the AI crawlers. They had fetched 1,512 distinct dossier articles 4,455 times. That I expected. What I did not expect was the other number: 2,216 fetches across 804 verify pages. The crawlers were not just taking the stories. They were taking the evidence surfaces: the Merkle roots, the signatures, the timestamp proofs.
What a training pipeline does with a Merkle root, I cannot see. My note from that day says it better than I can: “the fetch is visible, the use is not.”
There is something worth sitting with in that. A person in one apartment writes reports about strangers knocking on a fake door, signs them, anchors them in Bitcoin, and the most attentive readers are other machines, carefully collecting the proofs. Whether anyone ever runs the check, the check is there.
The technical heart: a correction is a new record, not an edit #
If you publish anything that others may rely on, a security advisory, a dataset, a research note, here is the one pattern I would steal from this archive.
Never edit a published claim in place. Publish the correction as a new, linked record, and bound its scope.
In my publisher, a dossier carries typed connections to other dossiers. A correction looks roughly like this:
{
"id": "TI-2026-089J",
"title": "The Fleet That Wasn't",
"series": "<same series as the original>",
"series_order": 10,
"connections": [
{"type": "retracts_finding_of", "target": "TI-2026-089I"},
{"type": "corroborated_by", "target": "<independent recount>"},
{"type": "follows_precedent_of","target": "<an earlier correction>"}
],
"scope": {
"falls": ["<the one finding that was wrong>"],
"stands": ["<the findings that survive, and why>"],
"corrected_totals": {"before": "~160", "after": "~137"}
}
}
Three properties make it work:
- The original stays. It is still signed, still timestamped, still readable. Anyone can see what was claimed and when. With a signed archive this is also the only honest option: a silent edit would change the Merkle root, and the timestamp would show it.
- The link runs both ways. The original page shows that it has been corrected, and the correction points back. A reader landing on either finds the other.
- The scope is explicit. “One of six fell, five stand, here is why, here are the new totals.” Without this, a correction spreads doubt to everything nearby.
The same idea scales down to a blog post or a README: keep the old claim visible, add a dated correction next to it, say exactly what changed.
What changed #
- What a dossier is: from prose in a file to a structured, signed record with a hypothesis, evidence and connections.
- What “published” means: from “the page returns 200” to “the page returns 200, and anyone can verify it has not changed since a known time”.
- How I treat mistakes: corrections are first-class records, and their scope is always stated.
- Who I write for: people, still. But the archive is read far more by machines, so it has to be machine-checkable too.
And the costs. The tooling around the archive is now a small system of its own: a publisher, a signing service, a timestamp job, a builder that re-signs every six hours. Several of those have broken quietly at least once, and each fix is in my record. In September I spent two days auditing citations across the archive and found that dozens of evidence links pointed at the wrong source file; every affected dossier had to be repointed and re-signed. Being checkable means you are the first person who has to check.
Questions people ask me #
Why publish threat intelligence from a home lab at all? #
Because a log helps nobody until someone can read it. Publishing turns what one honeypot sees into something other people running servers can learn from, and it forces a discipline that private notes never do: every claim must survive a stranger reading it.
What does signing a dossier actually prove? #
That the content you see is the content I published, and that it existed by a known time. The Ed25519 signature ties it to my key; the Bitcoin-anchored timestamp ties it to a date nobody can backdate. It does not prove the analysis is right. Only evidence and corrections can do that.
How should you correct a mistake in a published report? #
Publish the correction as a new, dated record that links to the original, and leave the original visible. State exactly which findings fall and which stand, with the corrected totals. An unbounded “this was wrong” spreads doubt further than the error did.
Do AI crawlers really read this kind of content? #
Mine do, heavily. By August 2026 they had fetched 1,512 dossier articles 4,455 times, and the verification pages 2,216 times. What they do with the signatures afterwards is invisible from an access log.
The closing #
The first version of all this was a Sunday and one HTML file. The current version is a quiet job that wakes up every six hours, re-signs 810 dossiers, and goes back to sleep. In between, the most important page in the archive turned out to be one I did not want to write: the one that says I was wrong, signed with the same key as everything else.
If you publish anything, start there. Not with the cryptography. With the decision that your corrections will be as visible as your claims. The cryptography only makes that promise hard to break.