/*
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");
}