${titleSafe}
${slugSafe}
Compiled truth
Timeline
Canonical facts (_facts)
${factsJson}
${slugSafe}
${factsJson}
${escapeHtml(ledger.generated_at)}`);
}
if (ledger.model) {
lines.push(`via ${escapeHtml(ledger.model)}`);
}
if (typeof ledger.costUsd === 'number') {
lines.push(`cost $${ledger.costUsd.toFixed(2)}`);
}
return lines.join(' \u00b7 ');
}
// ─── Top-level render ───────────────────────────────────────────
export function renderWorldHtml(pages: Page[], ledger: Ledger = {}): string {
const entityCards = pages
.slice()
.sort((a, b) => {
const byType = a.type.localeCompare(b.type);
return byType !== 0 ? byType : a.title.localeCompare(b.title);
})
.map(renderEntityCard)
.join('\n');
const rail = renderRail(pages);
const ledgerLine = renderLedger(ledger, pages.length);
return `
Click an entity in the sidebar to jump to it. All content is HTML-entity-encoded to prevent XSS; Opus-generated prose can contain tag-like fragments. Use this as a reference when writing Tier 5.5 queries.
${entityCards}