Skip to content

feat(blog): import the owner-approved backfill articles - #78

Draft
axsaucedo wants to merge 8 commits into
feat/blog-pilotfrom
feat/blog-imports
Draft

feat(blog): import the owner-approved backfill articles#78
axsaucedo wants to merge 8 commits into
feat/blog-pilotfrom
feat/blog-imports

Conversation

@axsaucedo

Copy link
Copy Markdown
Collaborator

Summary

  • import eight recoverable owner-approved long-form articles with their canonical URLs and 64 colocated article images
  • add two body-less LinkedIn feature cards whose publication dates are decoded from their activity IDs
  • add newsletter-compatible syndication records and render an “Also published on” row below blog post bodies

Imported pieces

  • Beyond CUDA: GPU Accelerated C++ for Machine Learning on Cross-Vendor Graphics Cards Made Simple
  • Supercharging Game Development with GPU Accelerated Machine Learning
  • Supercharging your Mobile Apps: GPU Accelerated Machine Learning using Android NDK & Vulkan Kompute
  • Parallelizing GPU-intensive Workloads via Multi-Queue Operations
  • Beyond CUDA: GPU Accelerated Python for Machine Learning on Cross-Vendor Graphics Cards Made Simple
  • Claude Code: It's not replacing devs. It's moving them to a higher altitude.
  • Autonomous Agentic Systems: A Practical Guide to Always-On Agents
  • Production Observability for Multi-Agent AI (with KAOS + OTel + SigNoz)
  • ACM US & Europe AI Principles announcement (external card)
  • UK AI Policy Adoption Proposals announcement (external card)

The manifest entry “Why Agents Belong in Your Software Architecture (Not Just Your Chatbot)” is intentionally skipped because its canonical URL currently serves an April 2026 HackerNoon article by Filip Mareš. No matching owner-authored source could be recovered, and importing that page would incorrectly attribute it to the blog's default author.

Canonical and syndication scheme

Republished posts retain the manifest source and canonical original URL, so their local pages emit an off-site canonical and stay out of the sitemap through the pilot's existing rule. Additional known copies use the optional syndication list of { name, url } records and render below the body as external links. Body-less LinkedIn entries link directly out from the archive and generate no local page.

Source recovery

Medium returned HTTP 403, so its live article content was recovered through the Jina text rendering service. The available Wayback capture for the game-development article was also checked. Medium's embedded code figures were not exposed by either route and could not be reconstructed verbatim. The Android article mirror exposed no content image URLs, so it includes the full exposed prose without dead image references. HackerNoon article prose and code were recovered from the live pages.

Verification

  • rm -rf .astro node_modules/.astro && npm run build
  • npm run check:ratchet
  • npm run lint
  • Prettier check for all changed source and content files
  • DOM checks at 1440x1000 and 420x900 for /blog/ and three image-rich imported post routes

Two additional, exceptionally long article routes exceed the DOM harness's fixed 20,000px page-height ceiling, with no other DOM findings. They remain full length to preserve the verbatim source requirement.

Import eight recoverable owner-approved long-form articles with canonical source metadata, locally stored article imagery, mechanically normalized heading levels, and language-tagged HackerNoon code fences. Add two body-less LinkedIn feature cards using dates decoded from their activity IDs.

Extend the blog schema with newsletter-compatible syndication records and render an Also published on row below article bodies using blog-owned metadata styles. Record the new style ownership and refresh the style-document ratchet.

Skip the manifest entry whose canonical URL currently serves an article by another author, avoiding an incorrect republication under the site's default byline.
@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown

Visual parity — dark theme 🌙

1440x1000 — 37 of 37 routes moved.

Route Differing pixels Peak channel delta
404.html.png 12,604 210/255
about.png 12,604 210/255
contact.png 12,604 210/255
frameworks--agentic-maturity-model.png 41,874 210/255
frameworks--agentic-rfx.png 12,604 210/255
frameworks--ai-rfx.png 12,604 210/255
frameworks--maturity-model.png 12,604 210/255
frameworks--security.png 41,874 210/255
frameworks.png 12,604 210/255
home.png 12,605 210/255
membership.png 41,874 210/255
network.png 41,875 210/255
newsletter--396.png 41,875 210/255
newsletter.png 41,875 210/255
open-source--ai-guidelines.png 41,874 210/255
open-source--kaos.png 12,604 210/255
open-source--kompute.png 12,604 210/255
open-source--production-ml-list.png 41,874 210/255
open-source--xai.png 12,604 210/255
open-source.png 12,604 210/255
partners.png 12,604 210/255
policy.png 12,604 210/255
principles--01.png 12,604 210/255
principles--02.png 12,604 210/255
principles--03.png 12,604 210/255
principles--04.png 12,604 210/255
principles--05.png 12,604 210/255
principles--06.png 41,874 210/255
principles--07.png 12,604 210/255
principles--08.png 41,874 210/255
principles--09.png 41,874 210/255
principles.png 12,604 210/255
privacy.png 12,604 210/255
reports--state-of-ml-2024.png 12,604 210/255
reports--state-of-ml-2025.png 42,160 210/255
reports.png 12,604 210/255
talks-and-events.png 45,203 210/255

420x900 — 37 of 37 routes moved.

Route Differing pixels Peak channel delta
404.html.png 15,210 147/255
about.png 15,210 147/255
contact.png 15,210 147/255
frameworks--agentic-maturity-model.png 15,210 147/255
frameworks--agentic-rfx.png 15,210 147/255
frameworks--ai-rfx.png 15,210 147/255
frameworks--maturity-model.png 15,210 147/255
frameworks--security.png 15,210 147/255
frameworks.png 15,210 147/255
home.png 23,735 147/255
membership.png 15,210 147/255
network.png 15,210 147/255
newsletter--396.png 15,211 147/255
newsletter.png 15,211 147/255
open-source--ai-guidelines.png 15,210 147/255
open-source--kaos.png 15,210 147/255
open-source--kompute.png 23,734 147/255
open-source--production-ml-list.png 15,210 147/255
open-source--xai.png 15,210 147/255
open-source.png 15,210 147/255
partners.png 15,210 147/255
policy.png 23,734 147/255
principles--01.png 23,734 147/255
principles--02.png 23,734 147/255
principles--03.png 15,210 147/255
principles--04.png 23,734 147/255
principles--05.png 15,210 147/255
principles--06.png 23,734 147/255
principles--07.png 15,210 147/255
principles--08.png 15,210 147/255
principles--09.png 15,210 147/255
principles.png 15,210 147/255
privacy.png 23,734 147/255
reports--state-of-ml-2024.png 15,210 147/255
reports--state-of-ml-2025.png 15,210 147/255
reports.png 15,210 147/255
talks-and-events.png 15,210 147/255

Differing pixels locate a change; the peak channel delta sizes it. A large count with a
delta of 1–2/255 is a sub-perceptual shift, a small count at 200/255 is something a reader
would see.

Informational: label the PR visual-change to state that pixels are meant to move, or dependencies to require zero.

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown

Visual parity — light theme ☀️

1440x1000 — 37 of 37 routes moved.

Route Differing pixels Peak channel delta
404.html.png 12,478 241/255
about.png 12,478 241/255
contact.png 12,478 241/255
frameworks--agentic-maturity-model.png 12,478 241/255
frameworks--agentic-rfx.png 12,478 241/255
frameworks--ai-rfx.png 12,478 241/255
frameworks--maturity-model.png 12,478 241/255
frameworks--security.png 12,478 241/255
frameworks.png 12,478 241/255
home.png 12,479 241/255
membership.png 12,478 241/255
network.png 12,479 241/255
newsletter--396.png 12,479 241/255
newsletter.png 12,479 241/255
open-source--ai-guidelines.png 12,478 241/255
open-source--kaos.png 12,478 241/255
open-source--kompute.png 12,478 241/255
open-source--production-ml-list.png 12,478 241/255
open-source--xai.png 12,478 241/255
open-source.png 12,478 241/255
partners.png 12,478 241/255
policy.png 12,478 241/255
principles--01.png 12,478 241/255
principles--02.png 12,478 241/255
principles--03.png 12,478 241/255
principles--04.png 12,478 241/255
principles--05.png 12,478 241/255
principles--06.png 12,478 241/255
principles--07.png 12,478 241/255
principles--08.png 12,478 241/255
principles--09.png 12,478 241/255
principles.png 12,478 241/255
privacy.png 12,478 241/255
reports--state-of-ml-2024.png 12,478 241/255
reports--state-of-ml-2025.png 12,478 241/255
reports.png 12,478 241/255
talks-and-events.png 65,133 248/255

420x900 — 37 of 37 routes moved.

Route Differing pixels Peak channel delta
404.html.png 15,050 167/255
about.png 15,050 167/255
contact.png 15,050 167/255
frameworks--agentic-maturity-model.png 15,050 167/255
frameworks--agentic-rfx.png 15,050 167/255
frameworks--ai-rfx.png 15,050 167/255
frameworks--maturity-model.png 15,050 167/255
frameworks--security.png 15,050 167/255
frameworks.png 15,050 167/255
home.png 15,051 167/255
membership.png 15,050 167/255
network.png 15,050 167/255
newsletter--396.png 15,051 167/255
newsletter.png 15,051 167/255
open-source--ai-guidelines.png 15,050 167/255
open-source--kaos.png 15,050 167/255
open-source--kompute.png 15,050 167/255
open-source--production-ml-list.png 15,050 167/255
open-source--xai.png 15,050 167/255
open-source.png 15,050 167/255
partners.png 15,050 167/255
policy.png 15,050 167/255
principles--01.png 15,050 167/255
principles--02.png 15,050 167/255
principles--03.png 15,050 167/255
principles--04.png 15,050 167/255
principles--05.png 15,050 167/255
principles--06.png 15,050 167/255
principles--07.png 15,050 167/255
principles--08.png 15,050 167/255
principles--09.png 15,050 167/255
principles.png 15,050 167/255
privacy.png 15,050 167/255
reports--state-of-ml-2024.png 15,050 167/255
reports--state-of-ml-2025.png 15,050 167/255
reports.png 15,050 167/255
talks-and-events.png 15,050 167/255

Differing pixels locate a change; the peak channel delta sizes it. A large count with a
delta of 1–2/255 is a sub-perceptual shift, a small count at 200/255 is something a reader
would see.

Informational: label the PR visual-change to state that pixels are meant to move, or dependencies to require zero.

Seven review items from the owner's pass over the stacked imports:

- Light theme: code windows and the committed dark diagrams keep their dark
  chrome (the Shiki palette has no light rendition; background and chrome are
  pinned under :root[data-theme='light']).
- Related posts render as bordered cards in a responsive grid instead of bare
  accent links.
- The italic standfirst that duplicated the summary (typed in the hero) is
  removed from all nine posts that carried one.
- Images centre at their natural size: Astro's pipeline stamps width/height,
  which exempted optimised images from the full-width rule and left them
  left-aligned inside the centred measure.
- Captions (italic-only paragraph after an image) read Medium-style: small,
  centred, muted; the 21 '(Image by ...)' caption lines are italicised.
- The external-link card capability is removed entirely per owner call: the
  two LinkedIn announcement cards are deleted, every blog entry now has a
  body, and the hasBlogBody/external plumbing is gone from the utils, the
  archive and the post page. A queued post in TODO.md will discuss the ACM
  and UK policy engagements properly instead.

Verified: parity vs master zero on homepage, issue 396 and the archive (399
only the intended separator fix); DOM gates green on the reworked routes
except the pre-known 20,000px harness height ceiling on the C++ post
(20,366px, content-complete); build, lint, format, ratchet green; light-theme
code window verified by screenshot.
Owner calls on surfacing the blog:

- The Network menu's JOIN column gains a Blog item beside the newsletter, so
  the drawer, mega menu and llms.txt all pick it up; llms.txt drops the
  /blog/ exclusion and derives the archive entry (title, post count and date
  span) the same way as the newsletter archive.
- The footnote band's hardcoded two-talk list becomes a publications list:
  blog, newsletter, talks and open source rows in the same kind/title/arrow
  format, replacing the single-surface talks column; the all-talks mono link
  is retired and the DOM gate's footnote assertion updated to the remaining
  legal link.
- The blog archive opens with the flagship Hero (classic mode, cycling the
  blog's subject areas) instead of the bare ProseLayout header the owner
  called boring; a fuller landing redesign is proposed separately.

Verified: build, lint, format, ratchet green; DOM gates pass on the archive,
a post, the homepage at desktop and issue 399 at both viewports. The mobile
homepage gate fails identically on a master build (drawer accordion
visibility timeout in the harness), so that failure is pre-existing and
recorded, not introduced here. Nav and footer changes are deliberate visual
changes on every route, so pixel parity vs master no longer applies to this
branch's chrome.
…orphs

Owner direction on the landing:

- Every post now carries a featured image, enforced by the schema through
  Astro's image() helper (typed metadata, optimised rendering, og:image from
  the built asset). Missing covers were recovered: the HackerNoon covers for
  the memory series, the Kompute Android artwork for the 2020 Android post
  and the talk's YouTube frame for the pilot. On the post page the body's own
  first image remains the opening visual, per owner preference; the featured
  image powers the archive and social cards.
- The archive body is rebuilt: a featured latest-post card (image and copy in
  a split card) followed by a ScrollStage showcase, reusing the existing
  scroll-driven component the talks reel already consumes: the sticky stage
  crossfades each post's featured image while the post cards scroll past the
  activation line. On small screens the stage hides and the cards carry the
  page.
- Clicking any archive title morphs into the post's hero title via shared
  view-transition names (the Hero gains a title_transition prop).
- New hero copy: 'Blogs, Tutorials / & Thought Leadership / from The
  Institute' with a rewritten subtitle, alternatives proposed to the owner.

Verified: build, lint, format, ratchet green; DOM gates pass on the archive
and two post routes at both viewports.
…olumn

Owner-directed iteration on the archive showcase, landed as the interim
design after exploring and rejecting a boxed split layout, a mid-screen
gradient with backdrop blur, and per-card floating fade boxes:

- Each post's featured image fills the showcase container edge to edge
  behind the cards, with only a light uniform wash; the scroll column sits
  flush against the container's right edge at 450px.
- The card column carries a 70% translucent backdrop so the artwork ghosts
  through behind readable text, and the only transition is a fixed 80px fade
  strip off the column's left edge; no hard boundary anywhere.
- Cards follow the talks-reel rhythm: the first enters around the lower
  third (52vh runway) and each gets a 46vh beat with the hairline dividers
  removed.
- Scoping note: ScrollStage's rendered elements do not carry the page's
  style scope, so every override anchors on the page-owned section wrapper
  with :global; the same applies to the Image component's img output.

TODO.md records the follow-up blog landing redesign with the rejected
explorations, per owner verdict: acceptable to ship, not yet good.

Verified: build green; DOM gates pass on the archive at both viewports;
lint, format and ratchet green.
'& Thought Leadership' becomes '& Thoughts' per owner, so the middle line no
longer risks wrapping at the classic display scale.
Owner call: Blog sits under CONNECT beside talks and partners rather than in
the JOIN column, and replaces the Policy & standards item there, which was
redundant with the top-level Policy & Frameworks menu. llms.txt keeps
deriving the blog's section from the menus, now under CONNECT.
The daily 05:43 UTC cron exists only to publish future-dated blog posts, but
deployed a byte-identical site on every quiet day. A decision script now
gates scheduled runs: deploy only when a post's publish date falls within a
three-day lookback window ending today. Push and manual runs never consult
it and always deploy.

The window is three days rather than one so missed cron runs self-heal:
GitHub delays or drops scheduled runs under load, and a post that became due
on a skipped day must still publish on the next run instead of waiting for
an unrelated push. The script tolerates the empty-match case explicitly
(grep -c exits nonzero on zero matches, which would otherwise kill the set
-e shell and fail the run on exactly the days it should skip), always exits
zero, and takes a date override so the decision table is testable offline.

Tested offline across the corner cases: no due posts (skip, exit 0), due
same day, due one and two days earlier (all deploy), three days after the
last post (skip), month boundary arithmetic, and the zero-match exit-code
path. Workflow YAML parse-validated; the guard's skip path leaves every
build step and the deploy job unscheduled.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant