/* Maintains packages/share/src/semantic/llms.ts as an authored share authored module so agents can evolve it without rediscovering local boundaries. Do not parse raw content or validate input models. Do not manage external data fetching. RFC-1075: emit canonicalUri for organization and offer in llms-full.txt. RFC-1076: add formatClaims section in buildLlmsFull for claim provenance. RFC-1097: step 6 — compass.migrate codemod run Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order. RFC-1097: sweep — werkstatt-engine clean Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics. RFC-1113: add ARD catalog discovery line — /.well-known/ard.json (v0.91 canonical path) joins the agentLinks blockquote set in buildLlmsIndex. RFC-0184, RFC-0372 */ import { toPathname } from "./ids.ts"; import { canonicalizeGeneratedMarkdownText, formatGeneratedMarkdownListItem, normalizeGeneratedMarkdownText, } from "./markdown-hygiene.ts"; import type { SemanticLlmsDepth, SemanticPageModel, SemanticSiteModel } from "./models.ts"; function canonicalStaticUrl(artifactPath: string, opts: { baseUrl: string }): string { const base = opts.baseUrl.replace(/\/+$/, ""); const clean = artifactPath.replace(/^\/+/, ""); return clean === "" ? `${base}/` : `${base}/${clean}`; } /** RFC-0142: effective llms depth for a page. Defaults to `full` when unresolved. */ function pageDepth(page: SemanticPageModel): SemanticLlmsDepth { return page.output?.llms?.depth ?? "full"; } /** RFC-0142: pages that contribute a row to the llms.txt index. */ function inIndex(page: SemanticPageModel): boolean { return pageDepth(page) !== "exclude"; } /** RFC-0142: pages that contribute a body section to llms-full.txt. */ function inFull(page: SemanticPageModel): boolean { const depth = pageDepth(page); return depth === "full" || depth === "summary"; } function pageLabel(page: SemanticPageModel): string { return page.heading ?? page.title; } function pageSummary(page: SemanticPageModel): string { return canonicalizePageText(page, page.lead ?? page.description); } function canonicalizePageText(page: SemanticPageModel, text: string | undefined): string { return canonicalizeGeneratedMarkdownText(text, { baseUrl: page.url ? new URL(page.url).origin : undefined, defaultLanguage: page.defaultLanguage, }); } function formatBlocks(page: SemanticPageModel): string { const excludeIds = new Set(page.output?.llms?.sections?.exclude ?? []); return page.blocks .filter((block) => block.heading && !excludeIds.has(block.id)) .filter((block) => block.summary || block.body || block.facts?.length || block.items?.length) .map((block) => { const parts = [`### ${block.heading}`]; if (block.summary) { parts.push(canonicalizePageText(page, block.summary)); } if (block.body) { parts.push(canonicalizePageText(page, block.body)); } if (block.facts?.length) { parts.push( ...block.facts.flatMap((fact) => formatGeneratedMarkdownListItem(canonicalizePageText(page, fact)), ), ); } if (block.items?.length) { for (const item of block.items) { const desc = item.description ? `: ${item.description}` : ""; parts.push(`- ${item.title}${desc}`); } } return parts.join("\n\n"); }) .join("\n\n"); } function formatPeople(page: SemanticPageModel): string { if (!page.people?.length) { return ""; } return [ "### People", ...page.people.map((person) => { const details = [person.role, person.description].filter(Boolean).join(" — "); return details ? `- ${person.name}: ${details}` : `- ${person.name}`; }), ].join("\n"); } function formatInitiatives(page: SemanticPageModel): string { if (!page.initiatives?.length) { return ""; } return [ "### Initiatives", ...page.initiatives.map((initiative) => { const facts = initiative.facts?.length ? ` (${initiative.facts.join("; ")})` : ""; return `- ${initiative.name}: ${initiative.summary}${facts}`; }), ].join("\n"); } function formatOrganizationFacts(site: SemanticSiteModel): string[] { return [ ...(site.organization.canonicalUri ? [`- Canonical URI: ${site.organization.canonicalUri}`] : []), `- Name: ${site.organization.legalName ?? site.organization.name}`, ...(site.organization.foundingYear ? [`- Founded: ${site.organization.foundingYear}`] : []), ...(site.organization.registration ? [`- Registration: ${site.organization.registration}`] : []), ...(site.organization.representative ? [`- Representative: ${site.organization.representative}`] : []), ...(site.organization.email ? [`- Email: ${site.organization.email}`] : []), ...(site.organization.areaServed?.length ? [`- Areas served: ${site.organization.areaServed.join("; ")}`] : []), ...(site.organization.address ? [ `- Address: ${[ site.organization.address.streetAddress, site.organization.address.postalCode, site.organization.address.addressLocality, site.organization.address.addressCountry, ] .filter(Boolean) .join(", ")}`, ] : []), ...(site.organization.founders?.length ? [`- Founders: ${site.organization.founders.map((person) => person.name).join("; ")}`] : []), ...(site.organization.boardMembers?.length ? [ `- Board: ${site.organization.boardMembers .map((person) => (person.role ? `${person.role} — ${person.name}` : person.name)) .join("; ")}`, ] : []), ...(site.organization.contactPoints?.length ? [ `- Contact points: ${site.organization.contactPoints .map((contactPoint) => [contactPoint.contactType, contactPoint.email].filter(Boolean).join(" — "), ) .join("; ")}`, ] : []), ...(site.organization.donationAccount ? (() => { const { accountHolder, bankName, iban, bic } = site.organization.donationAccount; const hasReal = (v: string | undefined) => typeof v === "string" && v.length > 0 && !v.startsWith("NEED_THIS_"); if (!hasReal(iban) || !hasReal(bic)) { return []; } const parts = [accountHolder, bankName, iban, bic].filter(hasReal); return [`- Donation account: ${parts.join("; ")}`]; })() : []), ]; } /** RFC-0147: render the projected offer (prices + written guarantees + growth modules + terms). */ function formatOffer(site: SemanticSiteModel): string[] { const offer = site.organization.offer; if ( !offer || (!offer.canonicalUri && !offer.prices?.length && !offer.guarantees?.length && !offer.growthModules?.length && !offer.changePrice && !offer.hourlyRate && !offer.billingDay) ) { return []; } const lines: string[] = ["## Offer"]; if (offer.canonicalUri) { lines.push(`- Canonical URI: ${offer.canonicalUri}`); } if (offer.prices?.length) { lines.push(...offer.prices.map((price) => `- ${price.label}: ${price.amount}`)); } if (offer.changePrice || offer.hourlyRate || offer.billingDay) { const terms: string[] = []; if (offer.changePrice) terms.push(`- Change price: ${offer.changePrice} EUR per change`); if (offer.hourlyRate) terms.push(`- Hourly rate: ${offer.hourlyRate} EUR per hour`); if (offer.billingDay) terms.push(`- Billing day: ${offer.billingDay}`); lines.push("", "### Terms", ...terms); } if (offer.guarantees?.length) { lines.push("", "### Guarantees"); lines.push( ...offer.guarantees.map((g) => (g.detail ? `- ${g.label}: ${g.detail}` : `- ${g.label}`)), ); } if (offer.growthModules?.length) { lines.push("", "### Growth modules"); lines.push( ...offer.growthModules.map((m) => { const desc = m.description ? `: ${normalizeGeneratedMarkdownText(m.description).replace(/\n+/g, " ")}` : ""; const price = m.price ? ` (${normalizeGeneratedMarkdownText(m.price).replace(/\n+/g, " ")})` : ""; return `- ${m.label}${desc}${price}`; }), ); } if (offer.capacity) { lines.push( "", "### Capacity policy", `- Wave cadence: ${offer.capacity.cadence}`, `- Starts at: ${offer.capacity.startsAt}`, `- Timezone: ${offer.capacity.timezone}`, `- Slot range: ${offer.capacity.slotRange.min}-${offer.capacity.slotRange.max}`, `- Max slots per wave: ${offer.capacity.maxSlotsPerWave}`, `- Availability status: ${offer.capacity.availabilityStatus}`, ); } lines.push(""); return lines; } /** RFC-0373: render the projected business service catalog. */ function formatServices(site: SemanticSiteModel): string[] { const services = site.organization.services; if (!services?.length) return []; const lines: string[] = ["## Services"]; for (const service of services) { const desc = service.description ? `: ${service.description}` : ""; lines.push(`- ${service.name}${desc}`); } lines.push(""); return lines; } /** RFC-0148: render the projected location (NAP + service area). */ function formatLocation(site: SemanticSiteModel): string[] { const location = site.organization.location; if (!location) return []; const facts = [ ...(location.locality ? [`- Locality: ${location.locality}`] : []), ...(location.region ? [`- Region: ${location.region}`] : []), ...(location.country ? [`- Country: ${location.country}`] : []), ...(location.serviceArea?.length ? [`- Service area: ${location.serviceArea.join("; ")}`] : []), ]; if (facts.length === 0) return []; return ["## Location", ...facts, ""]; } /** RFC-0148: render the projected public team (name, role, bio). */ function formatTeam(site: SemanticSiteModel): string[] { const team = site.organization.team; if (!team?.length) return []; const lines: string[] = ["## Team"]; for (const member of team) { const role = member.role ? ` (${member.role})` : ""; const bio = member.description ? `: ${member.description.replace(/\s*\n\s*/g, " ").trim()}` : ""; lines.push(`- ${member.name}${role}${bio}`); } lines.push(""); return lines; } /** RFC-1076: render projected claims with their evidence references. */ function formatClaims(site: SemanticSiteModel): string[] { if (!site.claims?.length) return []; const lines: string[] = ["## Claims"]; for (const claim of site.claims) { lines.push(`### ${claim.statement}`); lines.push(`- Class: ${claim.claimClass}`); if (claim.verificationLevel) lines.push(`- Verification: ${claim.verificationLevel}`); if (claim.confidence) lines.push(`- Confidence: ${claim.confidence}`); if (claim.evidence.length > 0) { lines.push("- Evidence:"); for (const ref of claim.evidence) { const sha = ref.sha256 ? ` — sha256: ${ref.sha256}` : ""; lines.push(` - ${ref.kind}: ${ref.label}${sha}`); } } else { lines.push("- Evidence: none"); } } lines.push(""); return lines; } function toAbsoluteUrl(site: SemanticSiteModel, pathname: string): string { const rawBase = site.organization.url ?? site.baseUrl; const base = (() => { try { return new URL(rawBase).origin; } catch { return rawBase.replace(/\/$/, ""); } })(); const defaultLang = site.defaultLanguage ?? "de"; const normalizedPathname = site.lang === defaultLang ? pathname.replace(new RegExp(`^/${defaultLang}(?=/|$)`), "") || "/" : pathname; // RFC-0317: ensure trailing slash to match canonicalPageUrl output. const withTrailingSlash = normalizedPathname === "/" ? "/" : normalizedPathname.replace(/\/?$/, "/"); return `${base}${withTrailingSlash}`; } /** RFC-0184: Format a Markdown link row for llms.txt. */ function formatMarkdownLinkRow(site: SemanticSiteModel, page: SemanticPageModel): string { const title = pageLabel(page); const url = toAbsoluteUrl(site, toPathname(page.url)); const summary = pageSummary(page); return `- [${title}](${url}): ${summary}`; } export function buildLlmsIndex(site: SemanticSiteModel, opts?: { servesSsr?: boolean }): string { const indexPages = site.pages.filter(inIndex); const llmsFullUrl = canonicalStaticUrl("/llms-full.txt", { baseUrl: site.baseUrl }); const siteDescription = site.organization.description ?? ""; // RFC-0789: agent discovery links — omitted when agent.enabled is false. // The MCP Server Card exists only when the deployment adapter serves SSR // routes (interfaces.mcp is set) — callers pass servesSsr=false on static // adapters so the card is not advertised (PUBTXT-07 honesty). const agentEnabled = site.agent?.enabled !== false; const servesSsr = opts?.servesSsr !== false; const agentLinks = agentEnabled ? [ `> Machine-readable Agent Surface (structured knowledge + capabilities): [agent.json](${canonicalStaticUrl("/.well-known/agent.json", { baseUrl: site.baseUrl })}).`, `> API discovery catalog (RFC 9727): [api-catalog](${canonicalStaticUrl("/.well-known/api-catalog", { baseUrl: site.baseUrl })}).`, `> ARD agent resource catalog (v0.91): [ard.json](${canonicalStaticUrl("/.well-known/ard.json", { baseUrl: site.baseUrl })}).`, ...(servesSsr ? [ `> MCP Server Card (SEP-1649): [server-card.json](${canonicalStaticUrl("/.well-known/mcp/server-card.json", { baseUrl: site.baseUrl })}).`, ] : []), `> OpenAPI 3.1 specification: [agent.openapi.json](${canonicalStaticUrl("/.well-known/agent.openapi.json", { baseUrl: site.baseUrl })}).`, ] : []; // RFC-0184: canonical Markdown link rows with absolute URLs const primarySources = indexPages.map((page) => formatMarkdownLinkRow(site, page)); return [ `# ${site.organization.name}`, // RFC-0184: blockquoted site description with llms-full.txt reference ...(siteDescription ? [`> ${siteDescription}`] : []), `> For complete documentation in a single file, see [llms-full.txt](${llmsFullUrl}).`, ...agentLinks, "", "## Primary sources", ...primarySources, "", "## Organization", ...formatOrganizationFacts(site), ].join("\n"); } export function buildLlmsFull(site: SemanticSiteModel): string { const pages = site.pages .filter(inFull) .map((page) => { // RFC-0184: absolute URL in the header const header = [ `## ${pageLabel(page)}`, `URL: ${toAbsoluteUrl(site, toPathname(page.url))}`, `Description: ${canonicalizePageText(page, page.description)}`, ...(page.lead ? [`Lead: ${canonicalizePageText(page, page.lead)}`] : []), ]; // RFC-0142: `summary` depth emits only the page header (description / lead), // skipping the answer-block dump and entity sections. if (pageDepth(page) === "summary") { return header.join("\n"); } // RFC-0184: filter empty body sections to avoid blank placeholder gaps const bodySections = [formatBlocks(page), formatPeople(page), formatInitiatives(page)].filter( (s) => s.length > 0, ); if (bodySections.length === 0) { return header.join("\n"); } return [...header, "", ...bodySections].join("\n"); }) .join("\n\n"); // RFC-0184: filter empty organization-level sections const orgSections = [ ...formatOffer(site), ...formatServices(site), ...formatLocation(site), ...formatTeam(site), ...formatClaims(site), ].filter((s) => s.length > 0); return [ `# ${site.organization.name}`, site.organization.description, "", "## Organization facts", ...formatOrganizationFacts(site), ...(orgSections.length > 0 ? ["", ...orgSections] : []), ...(pages.length > 0 ? ["", pages] : []), ].join("\n"); }