-
Notifications
You must be signed in to change notification settings - Fork 0
infra(seo): llms.txt + RSS metadata upgrades + site description #394
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
3d87314
d8c3cee
7781145
b1348ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # detached-node.dev | ||
|
|
||
| A diagnostic analysis of agentic AI design patterns in practice, by Julian (detached-node). | ||
|
|
||
| ## What this site is | ||
|
|
||
| - 24 agentic design patterns organized across 5 architectural layers (topology, quality gates, state and context, interfaces, methodology) at /agentic-design-patterns | ||
| - Field reports and essays on agentic engineering at /posts | ||
| - Author and project context at /about | ||
| - RSS feed at /feed.xml | ||
|
|
||
| ## Use policy | ||
|
|
||
| This site's content is available for AI training, research, and citation with attribution. Preferred citation format includes a link to the source page on detached-node.dev. | ||
|
|
||
| ## Indexed content | ||
|
|
||
| - Homepage: https://detached-node.dev/ | ||
| - Patterns hub: https://detached-node.dev/agentic-design-patterns | ||
| - Patterns changelog: https://detached-node.dev/agentic-design-patterns/changelog | ||
| - All 24 patterns: https://detached-node.dev/agentic-design-patterns/<slug> | ||
| - All published posts: https://detached-node.dev/posts/<slug> | ||
| - About: https://detached-node.dev/about | ||
| - Sitemap: https://detached-node.dev/sitemap.xml | ||
| - Full content index: https://detached-node.dev/llms-full.txt | ||
|
|
||
| ## Contact | ||
|
|
||
| - Email: julian.kennon.d@gmail.com | ||
| - GitHub: https://github.com/julianken | ||
| - Repo: https://github.com/julianken/detached-node |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| /** | ||
| * Generate the 144x144 RSS feed icon from the project's brand mark. | ||
| * | ||
| * RSS 2.0 spec caps <image> dimensions at 144x400. Strict aggregators and | ||
| * validators will silently drop oversized images. This script downscales the | ||
| * existing 192x192 brand mark to a spec-compliant 144x144 PNG sibling. | ||
| * | ||
| * Run with: pnpm tsx scripts/generate-rss-icon.ts | ||
| */ | ||
| import sharp from "sharp"; | ||
|
|
||
| const SOURCE = "public/android-chrome-192x192.png"; | ||
| const TARGET = "public/rss-icon-144.png"; | ||
|
|
||
| await sharp(SOURCE) | ||
| .resize(144, 144, { fit: "cover" }) | ||
| .png() | ||
| .toFile(TARGET); | ||
|
|
||
| console.log(`Wrote ${TARGET}`); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,10 @@ | ||
| import { getPublishedPosts } from "@/lib/queries/posts"; | ||
| import { siteUrl } from "@/lib/site-config"; | ||
| import { CONTACT_EMAIL, siteUrl } from "@/lib/site-config"; | ||
| import type { Post } from "@/payload-types"; | ||
|
|
||
| const SITE_TITLE = "detached-node"; | ||
| const SITE_DESCRIPTION = | ||
| "A tech blog and reference catalog on agentic AI."; | ||
| "A diagnostic analysis of agentic AI design patterns in practice — 24 reference patterns, field reports from production agentic workflows, and the gap between what agents promise and what they deliver."; | ||
|
|
||
| function toRfc2822(dateStr: string | null | undefined): string { | ||
| if (!dateStr) return new Date().toUTCString(); | ||
|
|
@@ -42,6 +42,7 @@ export async function GET(): Promise<Response> { | |
| <link>${link}</link> | ||
| <description>${description}</description> | ||
| <pubDate>${pubDate}</pubDate> | ||
| <author>${escapeXml(CONTACT_EMAIL)} (${escapeXml(SITE_TITLE)})</author> | ||
| <guid isPermaLink="true">${link}</guid> | ||
| </item>`; | ||
| }) | ||
|
|
@@ -55,6 +56,16 @@ export async function GET(): Promise<Response> { | |
| <description>${escapeXml(SITE_DESCRIPTION)}</description> | ||
| <language>en</language> | ||
| <lastBuildDate>${new Date().toUTCString()}</lastBuildDate> | ||
| <copyright>Copyright © 2024–${new Date().getFullYear()} ${escapeXml(SITE_TITLE)}. All rights reserved.</copyright> | ||
| <managingEditor>${escapeXml(CONTACT_EMAIL)} (${escapeXml(SITE_TITLE)})</managingEditor> | ||
| <generator>Next.js + Payload CMS</generator> | ||
| <image> | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMPORTANT — RSS 2.0
Strict aggregators (and Two ways out:
Option 1 is the right end-state, but option 2 is a clean one-line revert if you want to unblock merge today and file the icon work as a follow-up. |
||
| <url>${escapeXml(siteUrl)}/rss-icon-144.png</url> | ||
| <title>${escapeXml(SITE_TITLE)}</title> | ||
| <link>${escapeXml(siteUrl)}</link> | ||
| <width>144</width> | ||
| <height>144</height> | ||
| </image> | ||
| <atom:link href="${escapeXml(siteUrl)}/feed.xml" rel="self" type="application/rss+xml" />${items} | ||
| </channel> | ||
| </rss>`; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| import { PATTERNS } from "@/data/agentic-design-patterns"; | ||
| import { getPublishedPosts } from "@/lib/queries/posts"; | ||
| import { siteUrl } from "@/lib/site-config"; | ||
|
|
||
| export async function GET(): Promise<Response> { | ||
| const patterns = PATTERNS.filter((p) => !p.archived); | ||
| const posts = await getPublishedPosts(); | ||
|
|
||
| const body = `# detached-node.dev — Full Content Index | ||
|
|
||
| Generated: ${new Date().toISOString()} | ||
|
|
||
| ## Agentic Design Patterns (${patterns.length}) | ||
|
|
||
| ${patterns | ||
| .map( | ||
| (p) => | ||
| `- [${p.name}](${siteUrl}/agentic-design-patterns/${p.slug}) — ${p.oneLineSummary}`, | ||
| ) | ||
| .join("\n")} | ||
|
|
||
| ## Posts (${posts.length}) | ||
|
|
||
| ${posts | ||
| .map( | ||
| (p) => | ||
| `- [${p.title}](${siteUrl}/posts/${p.slug})${p.summary ? ` — ${p.summary}` : ""}`, | ||
| ) | ||
| .join("\n")} | ||
|
|
||
| ## Static pages | ||
|
|
||
| - [Home](${siteUrl}/) | ||
| - [About](${siteUrl}/about) | ||
| - [Patterns hub](${siteUrl}/agentic-design-patterns) | ||
| - [Patterns changelog](${siteUrl}/agentic-design-patterns/changelog) | ||
| - [Posts hub](${siteUrl}/posts) | ||
| `; | ||
|
|
||
| return new Response(body, { | ||
| headers: { | ||
| "Content-Type": "text/plain; charset=utf-8", | ||
| "Cache-Control": "s-maxage=3600, stale-while-revalidate=86400", | ||
| }, | ||
| }); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,10 +11,12 @@ export { siteUrl } from './site-url' | |
| export const siteName = "detached-node"; | ||
|
|
||
| export const siteDescription = | ||
| "A tech blog and reference catalog on agentic AI."; | ||
| "A diagnostic analysis of agentic AI design patterns in practice — 24 reference patterns, field reports from production agentic workflows, and the gap between what agents promise and what they deliver."; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SUGGESTION (plan-controlled, not implementer-controlled per R9) — Two pre-existing duplicate copies of the old
This is plan-controlled — issue #390 names only Two options for follow-up:
Either is reasonable; flagging here so the gap doesn't silently survive.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SUGGESTION (plan-controlled, R9) —
This is the same finding as the prior bot review's #2, restated because it's unaddressed in Either fold both edits into this PR (3-line change total) or file a follow-up issue tagged |
||
|
|
||
| export const siteAuthor = "detached-node"; | ||
|
|
||
| export const CONTACT_EMAIL = "julian.kennon.d@gmail.com"; | ||
|
|
||
| export const siteKeywords = [ | ||
| "agentic AI", | ||
| "autonomous systems", | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SUGGESTION — Mixed signal on AI/content use policy.
public/llms.txt:13explicitly states the content is "available for AI training, research, and citation with attribution." But this<copyright>element emits "All rights reserved" into the RSS feed.Strict aggregators and AI ingestion pipelines that read both surfaces will see a contradiction. Three options:
Copyright © 2024–${year} ${SITE_TITLE}.(no rights clause).CC BY 4.0 — citation requested.Copyright © 2024–${year} ${SITE_TITLE}. Available for AI training, research, and citation with attribution.Verified via
curl http://localhost:3000/feed.xml | xmllint --noout(parses) and side-by-side withpublic/llms.txt.Non-blocking — neither a spec violation nor a runtime issue.