**adamastor.blog is frozen, hashed and registered — the first source about the Portuguese startup
ecosystem itself rather than one event's website.** Before this, 83% of the register was
`startupsummit.io`, and only 4 of the 67 organisations in the graph appear anywhere in
Adamastor's digest. Now: **104 frozen files** — robots.txt, the publisher's own `llms.txt`, the
home and about pages, the sitemap, the digest's RSS archive, the events feed and one feed per
category, and **92 posts**, January 2025 to last week, by 11 named authors. From them,
`dados/adamastor.json`: every post's title, date, byline, outbound links and lexicon tags; **45
upcoming events** with when, where and category; and **406 domains** the digest pointed at. It is
served at `/api/v1/adamastor.json`, with one file per post.

**Rule 3 held by construction.** Not a sentence of the digest's prose is in a data file: the
longest value outside the notes is a source id. Event descriptions are the organisers' writing and
are not read at all. **The 406 domains are not 406 companies** — they include YouTube, Spotify,
Google Forms and a newsletter's click tracker — and turning any of them into a company record is
task #7, which needs a source of its own.

## Five things went wrong on the way, and each is fixed

**1. Re-running the register would have wiped the event off the site — before Adamastor was
touched.** `build/extract.py` read the event from the *newest dated folder*. Two research
deliveries had frozen their sources into folders of their own (15 and 23 September), so the newest
folder held no speakers page: re-running it wrote **0 people, 0 organisations and 0 sessions**, and
the core gate went red. It had stayed hidden only because the build runs that step with `--fetch`
alone. Now the event is read from the newest folder that *contains the event*; every folder is
still registered file by file — which also registers, for the first time, **24 delivery sources
that had been frozen and never entered the register**.

**2. The graph pointed 128 edges at nodes that did not exist.** Every frozen file gets a
*captured-in* edge to its folder's date, but capture nodes were made only for the event's captures.

**3. The publisher's sitemap is incomplete.** It lists 78 posts; the RSS feed lists the newest
50; **14 September-2026 posts appear in no sitemap at all.** The first capture trusted the sitemap
and froze an archive with its newest fortnight missing — noticed only because it reported *0
tracking redirects* when a post read earlier plainly had some. They were all in the missing posts.
The capture now reads both lists; the gap is recorded as an observation about the publisher's
file, not papered over.

**4. The robots.txt check could not say no.** Python's `urllib.robotparser` applies the *first*
matching rule; Adamastor's file opens with `Allow: /`, so under it **every `Disallow` was
shadowed** — tested against the frozen file, it called `/api/`, `/dashboard/` and `/login` all
fetchable. The capture's docstring said every URL was checked. It was, by a check that always
answered yes. Replaced with RFC 9309 matching — longest rule wins, Allow wins a tie — and tested
against the real file on eight paths. **Every page actually fetched is allowed under the correct
reading**: nothing disallowed was taken, but only because nothing disallowed was on the list, which
is luck and not a control.

**5. Nothing checked a data file for contact details.** Rule 4 was enforced where data is *read*
(`extract.sem_contactos`), and that works — an email planted in a post link was dropped. But an
email planted in `dados/adamastor.json` itself **passed both gate files green**. **Gate 46** now
scans every JSON file the site builds from or serves, with two exemptions read from the repository
rather than typed: the data controller's contact as the notice declares it, and the internal mail
protocol's `.local` addresses. It catches an email and a Portuguese phone number on injection.

*Not in the daily run, on purpose: a capture is about 14 MB, mostly each post page's framework
payload, and re-freezing 92 unchanged posts every day is not worth what it costs the repository.
Joining the scheduled run is the editor's decision. And for the question that started this: the
digest mentions **Web Summit 45 times** — including Startup Portugal's *Road 2 Web Summit*
programme for up to 125 Portuguese startups — and **Estonia not once**.*
