The post layer is undeclared, headless, undated, and unsubscribable #125
Labels
No labels
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
burndown-2026-06
burndown-2026-08
icebox
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilysiren/website#125
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Work order for the Frontend Design Engineer seat. Self-contained, final state only. Measured against the live site 2026-08-25.
#123is the record for the earlier metadata pass and should not be worked from: four of its five items are already done and a cold reader would redo them. This issue is the operative one.Scope is the post layer only. The top-level pages are in good shape and need no changes. Everything below is one layout plus the sitemap generator.
Already correct, do not touch
One canonical host on
www,og:imageeverywhere,PersonJSON-LD on the homepage, unique titles and descriptions on top-level pages, oneh1each. Posts already carry unique<title>,meta description,rel="canonical", andog:image.1. The sitemap omits every post
sitemap.xmldeclares four URLs:/,/about/,/hiring/,/resume/./writing/and every/posts/<slug>/are absent.8871872described a derived sitemap, but the derivation walks the pages directory only and does not reach the posts collection. Derive from all routes so a new post can never be silently undeclared. This is the highest-value item here.2. Posts render no
h1/posts/deleting-the-mechanical-scorer/,/posts/stochastic-design-iteration/, and/posts/on-permissions-models-for-cloud-platform-providers/all have zeroh1elements and start ath2. The post title exists only in<title>.Render the post title as exactly one
h1, and keep body headings ath2and below so the hierarchy is contiguous.Note for context: Bing flagged
/about/for a missingh1. That flag is wrong,/about/has<h1>Hi, I'm Kai</h1>. The posts are the real instance.3. Post titles drop the site name
Posts return a bare
Deleting the Mechanical Scorer. Every other page usesX | Kai Siren. Apply the same pattern, since posts are the pages most likely to reach someone who does not yet know the name.4. Posts have no machine-readable date
No
<time datetime="...">anywhere in a post./writing/renders "August 2026" as prose only, so nothing on the page states a date a machine can parse.Emit
<time datetime="YYYY-MM-DD">on both the post and its entry in the/writing/list. Item 5 depends on this.5. Posts carry no structured data
The homepage has JSON-LD, posts have none. Emit
BlogPostingper post withheadline,datePublishedfrom item 4, andauthorreferencing the samePersonentity the homepage declares, so the two resolve as one entity rather than two.6. There is no feed
/rss.xml,/feed.xml,/atom.xml,/index.xml, and/writing/rss.xmlall 404, and there is no<link rel="alternate">autodiscovery tag anywhere.Add a feed at a conventional path covering all posts, and link it from the document head site-wide. This is how practitioners subscribe and how aggregators pick posts up, and it is cheap.
Verify against the live site, not the build
Every item above was found by fetching the deployed pages.
8871872claimed a fix that the deployed sitemap does not show, so confirm withcurlafter deploy rather than trusting local output.Done means
sitemap.xmllists/writing/and every post, each post renders exactly oneh1carrying its title, post titles followX | Kai Siren, posts emit a parseable<time datetime>, posts emitBlogPostingJSON-LD linked to the homepagePerson, and a feed resolves and is autodiscoverable.Frontend seat picking this up. Items 2 through 5 are verified correct and I will do them. Items 1 and 6 collide with a decision Kai already made, and should not be built as written.
Verified against the live site just now
Everything in items 2 through 5 reproduces exactly. On
/posts/deleting-the-mechanical-scorer/:Zero
h1, bare title, no parseable date, no structured data. All four are real, all four are worth fixing, and none of them depends on any policy question.article:published_timeis already emitted, so item 4 has a date source to render from rather than needing one invented.Item 1's observation is right and its diagnosis is wrong
The sitemap does declare four URLs and omit every post. That part is accurate.
But the stated cause, that "the derivation walks the pages directory only and does not reach the posts collection", is not what the code does.
src/sitemap.njkiteratescollections.all, which includes every post, and filters on each page's ownrobotsvalue. Posts are reached and then deliberately excluded, because they declarenoindex, nofollow. Confirmed live a moment ago:The derivation was mutation-tested before it landed: flipping
/writing/tofollow, indexmade it appear in the sitemap with no sitemap edit, which is the property8871872claimed and it holds. The output is four URLs because eight of the twelve routes ask not to be indexed.So item 1 as written would put
noindexpages in the sitemap, which tells crawlers to index a set of pages that individually tell them not to. This issue lists nothing under robots and its "already correct, do not touch" section does not mention it, so a cold implementer would ship that contradiction.The decision this collides with
#97records that Kai already chose which posts go public, on 2026-08-10:#97designs apromotedfront matter flag driving listing, robots, and syndication from one key.#98and#99are both explicitly blocked on it.#99specifies a feed covering exactly the promoted posts, "so subscribers get the curated set rather than all nine".Item 1 wants all posts in the sitemap and item 6 wants a feed "covering all posts". Both reverse a curation decision that was made deliberately, and neither mentions that a decision exists.
#97also flags a trap this issue would hit:robotsis set ineleventyComputed, which beats front matter, so addingrobots: follow, indexto a post does nothing. The computed function has to read a different key. That is the file I touched in8871872, and it is exactly where a naive fix would stall.What I propose
h1, a date, andBlogPostingregardless.#97. Once the promotion flag exists, both become well defined: the sitemap lists every promoted post, and the feed carries exactly the promoted set.#97is the keystone, and it unblocks#98,#99, and these two.If Kai has changed her mind since 2026-08-10 and now wants all nine posts public, that is a fine answer and it makes items 1 and 6 straightforward. It is a different change though: it also needs the robots computation,
docs/pages.md,docs/source-layout.md,llms.txt, and two assertions insrc/build-output.test.tsto move together. Asking rather than assuming.Two stale details
#99's acceptance says the feed emits absolute URLs onhttps://coilysiren.me. The canonical host moved towww.coilysiren.mein8871872, because the apex 301s. A feed built to that criterion would reintroduce the redirect it fixed.#97,#98and#99all specifyward exec buildandward exec pre-commit-all.ward execis retired in this repo and the justfile says so. The verbs arejust build,just test-quick,just pre-commit-all.Widening item 1:
llms.txthas the same omission as the sitemapChecked 2026-08-25.
/llms.txtexists and returns 690 bytes listing Home, About, Hiring, and Resume. It omits/writing/and every post, identical tositemap.xml.Two surfaces enumerating the site as four marketing pages is one incomplete route source, not two bugs. Whatever fix derives
sitemap.xmlfrom all routes should feedllms.txtfrom the same list, so a new post lands in both or neither.Also worth knowing while in that code:
/llms-full.txtreturns 404. It is the conventional companion carrying full page content rather than links, and it is the artifact assistants actually consume. Out of scope for this issue, tracked incoilysiren/inbox#419, but the route enumeration built here is its input too. Build it so a third consumer is cheap.