How this was made

No framework, no build server, no database. This is plain HTML, CSS and JavaScript on GitHub Pages — the same free static hosting anybody gets with a repository — and a pile of Python that writes the pages before they ship.

Every number below is counted from the repository when this page is built, not typed in. That is the rule the whole site runs on: if a figure is on a page, something measured it.

471posts written
510pages published
194python scripts
86checks before a push
18github workflows
83,330lines behind it
3,587commits

What happens when I publish

A post is a file. Everything a reader sees is built from it, which means the pages can always be thrown away and made again — and are, on every publish. Here is the whole trip a post takes, from the file to your screen.

0:00/2:03 The idea

Everything, in one picture

The same trip, laid out at once: what is written by hand, what Python builds from it, what stands between the two, and what a reader finally opens. Every box names a real file in the repository — a check refuses this page if one of them stops existing.

WRITTEN BY HAND BUILT BY PYTHON WHAT A READER OPENS posts/ one file per post DATA STORES news.json status.json events.json ai.json reinvent2026.json SEC filings cloud-economics.json AWS · Azure · GCP their own feeds: status, releases, and events .github/workflows 12 jobs on a clock re-read, rebuilt, committed sync_blog.py posts, index, feed, archive build_arch_post.py build_news_page.py build_status_page.py build_events_page.py build_ai_page.py build_reinvent_page.py build_reinvent_plan.py build_reinvent_planner.py build_clouds_page.py fetch_cloud_economics.py build_sitemap.py run by sync_blog.py, walks the built site sitemap.xml robots.txt, for crawlers preflight.py on everything just built: 87 checks, a real browser a failure refuses the push Portfolio Blog · 471 posts Intelligence What’s new Live status Cloud events j.AI re:Invent 2026 The three clouds GitHub Pages static files, no server nothing to restart passes site-footer.css · site-footer.js one bar, one theme, one menu on all 510 pages reader
What each part does
posts/
One HTML file per post, front matter and body. This is the source: every page, card, feed entry and search result is derived from it, and nothing is derived from a served page.
news.json
Every cloud announcement, ranked, with the day it was made. Written by the scheduled jobs, never by hand.
status.json
The current health of AWS, Azure and GCP, as each vendor's own status feed reports it.
events.json
Vendor conferences, launches and end-of-life dates, with the source each one came from.
ai.json
What the AI vendors have shipped, and the model catalogue behind the j.AI page — announcements, prices and context windows.
reinvent2026.json
All 1,582 AWS re:Invent 2026 sessions, with the room and the start and end time of each. Fetched from the official catalog by hand rather than on a clock, because the catalog needs a browser to hand out its API credentials.
SEC filings
Each company's own 10-Q or 10-K, from SEC EDGAR. The segment figures are parsed out of the XBRL instance the filing ships, not read from the convenient API: that API strips the dimensions and returns consolidated totals, so asking it for Amazon's revenue gives the whole company, retail included.
AWS · Azure · GCP
The vendors' own feeds. Nothing here is summarised by a model: the raw RSS and sitemaps are parsed, because a summary silently drops items and a parser does not.
.github/workflows
The scheduled jobs. They fetch, rebuild and commit on GitHub's machines, so the data pages stay current whether or not I have opened a laptop.
sync_blog.py
Build the blog: read posts/*.md and posts/*.html → clean → build static pages at blog/.
build_arch_post.py
Build the served page for an Architecture Series post.
build_news_page.py
Build /intelligence/whats-new/ from the announcement store.
build_status_page.py
Render intelligence/status/ from the fetched status data.
build_events_page.py
Build /intelligence/events/ from intelligence/events.json.
build_ai_page.py
Build /intelligence/ai/ — what the AI vendors have shipped, and what runs.
build_reinvent_page.py
Render /reinvent-2026/ from the catalog store.
build_clouds_page.py
Build /intelligence/clouds/ — the three clouds, as they report themselves.
build_sitemap.py
Write sitemap.xml and robots.txt from what is actually published.
sitemap.xml
Every published URL with the date it last changed, plus robots.txt. Regenerated on every sync, so it cannot drift from what is actually published.
preflight.py
Run every check before anything reaches the live site.
Portfolio
The home page. Its figures — post count, latest posts, the service and domain widgets — are read from the same files the blog is built from.
Blog · 471 posts
The index, the paged archive, the filter pills and the RSS feed. All of it is regenerated from posts/ on every sync.
Intelligence
The hub for the data-driven pages below it.
What’s new
Cloud announcements, ranked, from news.json.
Live status
Current vendor health, from status.json.
Cloud events
Conferences and end-of-life dates, from events.json.
j.AI
The AI page: models, prices, context windows and what each vendor shipped, from ai.json.
re:Invent 2026
A planner for the conference: every session searchable by service, grouped into connectivity, platform and compute lanes, and — the part the official catalog will not do — a check on whether two sessions you picked are far enough apart in time to actually get between the venues.
The three clouds
What AWS, Azure and Google Cloud disclose about themselves, from their filings rather than from analyst estimates — and the gap where one of them discloses nothing. Microsoft reports Azure as a growth rate against an undisclosed base, so a like-for-like three-way revenue table cannot be built from public filings. The page says so instead of filling it in.
GitHub Pages
Static hosting. There is no server and no database, so there is nothing to restart and nothing to patch.
site-footer.css · site-footer.js
One stylesheet and one script shared by every page on the site — the nav bar, the theme switch and the menu. A change here reaches all of them.
reader
You. Everything to the left of this exists to put a correct page in front of you without a human remembering a step.

The trip, stop by stop

Four kinds of post, and they do not take the same route. Three of them do work before a word is written that the architecture series never does — a roundup fetches a week of feeds and builds an inventory from them, a daily post ranks everything the cloud announced yesterday, and a lab post has to actually run the thing it is about. Two of them draw a diagram and two never do. From the sync onwards every post is treated identically, which is the last five stops on all four.

  1. 1Writeposts/arch-103-….htmlone hand-written file, with the vendor’s own docs quoted and every figure carrying a source
  2. 2Drawblog/assets/diagrams/arch-103-….svgraw SVG, no tool — all 267 of the 267 architecture posts carry one
  3. 3Build the pagebuild_arch_post.py267 post pages are built from the template and never regenerated; the other 204 come from sync_blog
  4. 4Sync the sitepublish.py → sync_blog.pyrewrites 27 shared files: the index, the paged archive, the feed, the sitemap, the offline worker
  5. 5Check the postprepublish.py8 checks on what was just written, then it prints Ready
  6. 6Commitlocal, reversiblenothing is public yet and nothing is claimed
  7. 7Push, and waitpreflight.py87 checks over all 471 posts, 47 of them driving a real browser. Ten to thirteen minutes, measured. A failure refuses the push
  8. 8LiveGitHub Pages, then the search index12 jobs on a clock keep the rest of the site current afterwards

The last five stops are the same on every path. 204 of the 471 post pages are built by sync_blog rather than by a builder of their own; only the three architecture series have one.

scroll the diagram sideways →

How it stays current

12 of those 18 run on a clock, on GitHub’s machines rather than mine. They fetch, rebuild and commit on their own — the cloud pages are current whether or not I have opened a laptop. The rest run when something is pushed.

JobDoesWhen
deploy-pagesscheduled maintenance25 */4 * * *
doc-freshnessflag documentation going staleTuesdays, 07:00 UTC
healthrebuild the health reportdaily, 13:00 UTC
ingest-newsingest announcements, rebuild What’s newdaily, 05:10 UTC
preflightscheduled maintenance40 */6 * * *
refresh-aischeduled maintenancedaily, 05:40 UTC
refresh-aws-servicesrefresh the AWS service catalogueMondays, 06:00 UTC
refresh-economicsscheduled maintenanceTuesdays, 06:35 UTC
refresh-eventsre-import events from the vendorsdaily, 05:40 UTC
refresh-reinventscheduled maintenanceevery hour
statusfetch every cloud's incidents, rebuild Live statusevery hour
verify-eventsopen every event link, reconcile what is missingdaily, 06:20 UTC

What runs before anything ships

87 checks on every push, 47 of them in a real browser. They do not read the code — they open the pages and look: does the header hold still, does the music button actually play, does a filter filter, does every link still resolve, is each page asking for the current stylesheet. If one fails, the push is refused. It costs about twelve minutes, which is the price of not finding out from a reader.

Ask it anything

The terminal on the portfolio answers questions over these posts rather than from a model’s memory: the question is matched against what is actually written here, and the answer cites the post it came from. If nothing here covers it, it says so instead of inventing something.

Why it is built this way

Static files cannot be hacked through a plugin, cost nothing to serve, and load on a bad connection. Nothing here needs a server to be running, a subscription to be paid or a database to be backed up. In ten years these pages will open the same way, because they are just files.

The whole thing is public: github.com/katta698/katta698.github.io

How was your experience?
Your feedback helps improve this site.
PoorExcellent