/);
assert.match(memoryHtml, /https:\/\/docs\.langchain\.com\/oss\/python\/deepagents\/memory/);
assert.match(memoryHtml, /href="\/guides\/connect-claude-codex-shared-workspace\//);
assert.match(memoryHtml, /href="\/guides\/human-in-the-loop-ai-agents\//);
assert.match(memoryHtml, /href="\/guides\/agent-to-agent-messaging\//);
const humanReviewGuide = guidePages.find((page) => page.path === '/guides/human-in-the-loop-ai-agents/');
assert.equal(humanReviewGuide.title, 'Human-in-the-Loop Review for AI Agent Teams | Commonly AI');
const humanReviewHtml = renderStaticPage(guideTemplate, humanReviewGuide);
assert.match(humanReviewHtml, /Human-in-the-loop review is a deliberate pause at a meaningful handoff/);
assert.match(humanReviewHtml, /It is not a person reading every token an agent produces\./);
assert.match(humanReviewHtml, /href="\/guides\/ai-agent-memory\//);
assert.match(humanReviewHtml, /https:\/\/learn\.microsoft\.com\/en-us\/agent-framework\/workflows\/human-in-the-loop/);
assert.match(humanReviewHtml, /href="\/guides\/ai-agent-handoffs\//);
assert.match(humanReviewHtml, /href="\/guides\/agent-to-agent-messaging\//);
const handoffsGuide = guidePages.find((page) => page.path === '/guides/ai-agent-handoffs/');
assert.equal(handoffsGuide.title, 'AI Agent Handoffs: Transfer Work Without Losing Context | Commonly AI');
const handoffsHtml = renderStaticPage(guideTemplate, handoffsGuide);
assert.match(handoffsHtml, /An AI agent handoff is the transfer of a piece of work to a new owner/);
assert.match(handoffsHtml, /href="\/guides\/ai-agent-memory\//);
assert.match(handoffsHtml, /href="\/guides\/human-in-the-loop-ai-agents\//);
assert.match(handoffsHtml, /https:\/\/openai\.com\/business\/guides-and-resources\/a-practical-guide-to-building-ai-agents\//);
assert.match(handoffsHtml, /https:\/\/learn\.microsoft\.com\/en-us\/agent-framework\/workflows\/orchestrations\/handoff/);
assert.match(handoffsHtml, /href="\/guides\/how-to-build-an-ai-agent-team\//);
assert.match(handoffsHtml, /href="\/guides\/agent-to-agent-messaging\//);
const teamGuide = guidePages.find((page) => page.path === '/guides/how-to-build-an-ai-agent-team/');
assert.equal(teamGuide.title, 'How to Build an AI Agent Team: Roles, Handoffs, and Review | Commonly AI');
const teamHtml = renderStaticPage(guideTemplate, teamGuide);
assert.match(teamHtml, /An AI agent team is a small group of people and agents with distinct responsibilities/);
assert.match(teamHtml, /href="\/guides\/ai-agent-memory\//);
assert.match(teamHtml, /href="\/guides\/human-in-the-loop-ai-agents\//);
assert.match(teamHtml, /href="\/guides\/ai-agent-handoffs\//);
assert.match(teamHtml, /https:\/\/openai\.com\/business\/guides-and-resources\/a-practical-guide-to-building-ai-agents\//);
assert.match(teamHtml, /href="\/guides\/agent-to-agent-messaging\//);
const messagingGuide = guidePages.find((page) => page.path === '/guides/agent-to-agent-messaging/');
assert.equal(messagingGuide.title, 'Agent-to-Agent Messaging: How AI Agents DM | Commonly AI');
const messagingHtml = renderStaticPage(guideTemplate, messagingGuide);
assert.match(messagingHtml, /An agent-to-agent message is a focused, one-to-one request or response/);
assert.match(messagingHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(messagingHtml, /commonly_dm_agent/);
assert.match(messagingHtml, /href="\/guides\/multi-agent-collaboration-platform\//);
assert.match(messagingHtml, /href="\/guides\/connect-claude-codex-shared-workspace\//);
assert.match(messagingHtml, /href="\/guides\/ai-agent-handoffs\//);
assert.match(messagingHtml, /href="\/guides\/human-in-the-loop-ai-agents\//);
assert.match(messagingHtml, /https:\/\/a2a-protocol\.org\//);
assert.match(messagingHtml, /Conceptually, the tool flow looks like this:<\/p>\s*/);
assert.match(messagingHtml, /Use this pattern:<\/p>\s*
/);
assert.match(messagingHtml, /
When a shared thread is better than a DM<\/h2>\s*
Choose a thread[^<]*<\/p>\s*
/);
assert.match(messagingHtml, /
When a DM is the better choice<\/h2>\s*
Choose a DM[^<]*<\/p>\s*
/);
const selfHostedGuide = guidePages.find((page) => page.path === '/guides/self-hosted-ai-agent-platform/');
assert.equal(selfHostedGuide.title, 'Self-Hosted AI Agent Platform: What to Look For | Commonly AI');
const selfHostedHtml = renderStaticPage(guideTemplate, selfHostedGuide);
assert.match(selfHostedHtml, /A self-hosted AI agent platform is software you deploy and operate/);
assert.match(selfHostedHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(selfHostedHtml, /https:\/\/csrc\.nist\.gov\/pubs\/sp\/800\/190\/final/);
assert.match(selfHostedHtml, /https:\/\/docs\.docker\.com\/compose\/trust-model\//);
assert.match(selfHostedHtml, /https:\/\/docs\.docker\.com\/compose\/how-tos\/use-secrets\//);
assert.match(selfHostedHtml, /https:\/\/docs\.docker\.com\/compose\/how-tos\/production\//);
assert.match(selfHostedHtml, /
Step 1: Map the architecture you are about to run<\/h2>/);
assert.match(selfHostedHtml, /You still need to decide:<\/p>\s*
/);
assert.match(selfHostedHtml, /The local path is intentionally short:<\/p>\s*
/);
assert.match(selfHostedHtml, /Before installing a public instance[^<]*:<\/p>\s*
/);
assert.match(selfHostedHtml, /Self-hosting Commonly can give[^<]*does not, by itself:<\/p>\s*
/);
assert.match(selfHostedHtml, /
Choose the responsibility you are ready to operate<\/h2>
These gaps are not reasons to avoid self-hosting\./);
assert.match(selfHostedHtml, /href="\/guides\/connect-claude-codex-shared-workspace\//);
assert.match(selfHostedHtml, /href="\/guides\/ai-agent-memory\//);
const permissionsGuide = guidePages.find((page) => page.path === '/guides/ai-agent-permissions-and-tokens/');
assert.equal(permissionsGuide.title, 'AI Agent Permissions and Tokens: Scope Runtime Access Safely | Commonly AI');
const permissionsHtml = renderStaticPage(guideTemplate, permissionsGuide);
assert.match(permissionsHtml, /An AI agent runtime token is a bearer credential that identifies a specific agent installation/);
assert.match(permissionsHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(permissionsHtml, /
Separate authentication, authorization, and tool permissions<\/h2>\s*
These three ideas[^<]*They are different layers:<\/p>\s*
/);
assert.match(permissionsHtml, /
Why the layers must stay separate<\/h2>/);
assert.match(permissionsHtml, /https:\/\/csrc\.nist\.gov\/glossary\/term\/least_privilege/);
assert.match(permissionsHtml, /https:\/\/cheatsheetseries\.owasp\.org\/cheatsheets\/Secrets_Management_Cheat_Sheet\.html/);
assert.match(permissionsHtml, /It does authorize meaningful work[^<]*<\/p>\s*
Commonly documents two agent-related token categories[^<]*<\/p>\s*
/);
assert.match(permissionsHtml, /Adding an agent to a pod is also an access decision for its runtime token\.<\/strong>/);
assert.match(permissionsHtml, /Before adding an existing agent[^<]*questions:<\/p>\s*
/);
assert.match(permissionsHtml, /Once issued, a runtime request uses the token in the authorization header:<\/p>\s*
/);
assert.match(permissionsHtml, /Commonly’s documentation recommends an environment variable[^<]*:<\/p>\s*
/);
assert.match(permissionsHtml, /Use a controlled test sequence:<\/p>\s*/);
assert.match(permissionsHtml, /A practical response sequence is:<\/p>\s*/);
assert.match(permissionsHtml, /
Sharing a token between installations<\/h2>/);
assert.match(permissionsHtml, /
Assuming token scope governs local tools<\/h2>/);
assert.match(permissionsHtml, /href="\/guides\/connect-claude-codex-shared-workspace\//);
assert.match(permissionsHtml, /href="\/guides\/ai-agent-task-management\//);
const cursorGuide = guidePages.find((page) => page.path === '/guides/connect-cursor-shared-workspace/');
assert.equal(cursorGuide.title, 'How to Connect Cursor to a Shared Workspace | Commonly AI');
const cursorHtml = renderStaticPage(guideTemplate, cursorGuide);
assert.match(cursorHtml, /Connecting Cursor to a shared workspace gives the agent you use in Cursor/);
assert.match(cursorHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(cursorHtml, /~\/\.cursor\/mcp\.json/);
assert.match(cursorHtml, /@commonlyai\/mcp/);
assert.match(cursorHtml, /cm_agent_\.\.\./);
assert.match(cursorHtml, /It is not a bundled development environment\.<\/p>\s*
/);
assert.match(cursorHtml, /In Cursor, invoke the agent with a request like this:<\/p>\s*
/);
assert.match(cursorHtml, /
Verify both sides of the access boundary<\/h2>\s*
[^<]*<\/p>\s*
Confirm all four:<\/p>\s*
/);
assert.match(cursorHtml, /
Give the first task a boundary<\/h2>/);
const observabilityGuide = guidePages.find((page) => page.path === '/guides/ai-agent-observability/');
assert.equal(observabilityGuide.title, 'AI Agent Observability: Make Work, Handoffs, and Decisions Visible | Commonly AI');
const observabilityHtml = renderStaticPage(guideTemplate, observabilityGuide);
assert.match(observabilityHtml, /AI agent observability is the ability to answer a practical set of questions/);
assert.match(observabilityHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(observabilityHtml, /pending, claimed, blocked, and done/);
assert.match(observabilityHtml, /A strong thread update has five parts:<\/p>\s*
/);
assert.match(observabilityHtml, /Objective: The outcome this work is intended to produce\.[\s\S]*Owner: The person or agent responsible for that action\./);
assert.match(observabilityHtml, /The right response is to connect the signals:<\/p>\s*
/);
const eventsGuide = guidePages.find((page) => page.path === '/guides/ai-agent-events/');
assert.equal(eventsGuide.title, 'AI Agent Events: Mentions, Tasks, Heartbeats, and Safe Handling | Commonly AI');
const eventsHtml = renderStaticPage(guideTemplate, eventsGuide);
assert.match(eventsHtml, /An AI agent event is a structured signal/);
assert.match(eventsHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
for (const eventType of ['chat\\.mention', 'thread\\.mention', 'task\\.assigned', 'heartbeat', 'integration\\.event']) {
assert.match(eventsHtml, new RegExp(eventType));
}
assert.match(eventsHtml, /When a polled event includes payload\.deliveryId, the acknowledgement must echo that exact value\.[^<]*For example:<\/p>\s*
/);
assert.match(eventsHtml, /cm_agent_\.\.\./);
assert.doesNotMatch(eventsHtml, /cm_agent_[A-Za-z0-9]{8,}/);
const comparisonGuide = guidePages.find((page) => page.path === '/guides/multi-agent-vs-single-agent/');
assert.equal(comparisonGuide.title, 'Multi-Agent vs. Single-Agent Systems: How to Choose | Commonly AI');
const comparisonHtml = renderStaticPage(guideTemplate, comparisonGuide);
assert.match(comparisonHtml, /A single-agent system gives one named agent responsibility/);
assert.match(comparisonHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(comparisonHtml, /A useful contract includes:<\/p>\s*
/);
assert.match(comparisonHtml, /pending, claimed, blocked, and done/);
assert.match(comparisonHtml, /A task claim is a visible coordination signal/);
assert.doesNotMatch(comparisonHtml, /cm_agent_[A-Za-z0-9]{8,}/);
const patternsGuide = guidePages.find((page) => page.path === '/guides/ai-agent-collaboration-patterns/');
assert.equal(patternsGuide.title, 'AI Agent Collaboration Patterns: Leads, Reviewers, Claims, and Races | Commonly AI');
const patternsHtml = renderStaticPage(guideTemplate, patternsGuide);
assert.match(patternsHtml, /AI agent collaboration patterns are repeatable ways/);
assert.match(patternsHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(patternsHtml, /Use this task contract:<\/p>\s*
/);
assert.match(patternsHtml, /returns the existing task rather than creating another one/);
assert.match(patternsHtml, /A claim is a coordination signal/);
assert.doesNotMatch(patternsHtml, /cm_agent_[A-Za-z0-9]{8,}/);
const onboardingGuide = guidePages.find((page) => page.path === '/guides/onboarding-an-ai-agent-to-your-team/');
assert.equal(onboardingGuide.title, 'How to Onboard an AI Agent to Your Team | Commonly AI');
const onboardingHtml = renderStaticPage(guideTemplate, onboardingGuide);
assert.match(onboardingHtml, /Onboarding an AI agent to a team is the process of/);
assert.match(onboardingHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(onboardingHtml, /
[\s\S]*codex mcp add commonly/);
assert.match(onboardingHtml, /pending, claimed, blocked, and done/);
assert.match(onboardingHtml, /cm_agent_…/);
assert.doesNotMatch(onboardingHtml, /cm_agent_[A-Za-z0-9]{8,}/);
const discordGuide = guidePages.find((page) => page.path === '/guides/ai-agent-discord-integration/');
assert.equal(discordGuide.title, 'AI Agent Discord Integration: Reviewable Work Signals | Commonly AI');
const discordHtml = renderStaticPage(guideTemplate, discordGuide);
assert.match(discordHtml, /An AI agent Discord integration connects a Discord conversation/);
assert.match(discordHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(discordHtml, /\/discord-push/);
assert.match(discordHtml, /every hour/);
assert.match(discordHtml, /@commonly-bot/);
assert.match(discordHtml, /pending, claimed, blocked, and done/);
assert.match(discordHtml, /
[\s\S]*DISCORD_BOT_TOKEN=\.\.\./);
assert.doesNotMatch(discordHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.doesNotMatch(discordHtml, /DISCORD_(?:BOT_TOKEN|CLIENT_ID|CLIENT_SECRET)=(?!\.\.\.)[^\s<]+/);
const runtimeGuide = guidePages.find((page) => page.path === '/guides/what-is-an-ai-agent-runtime/');
assert.equal(runtimeGuide.title, 'What Is an AI Agent Runtime? | Commonly AI');
const runtimeHtml = renderStaticPage(guideTemplate, runtimeGuide);
assert.match(runtimeHtml, /An AI agent runtime is the process that receives a trigger/);
assert.match(runtimeHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(runtimeHtml, /commonly agent run/);
assert.match(runtimeHtml, /
[\s\S]*GET \/api\/agents\/runtime\/events/);
assert.match(runtimeHtml, /cannot discover or join pods/);
assert.match(runtimeHtml, /cm_agent_…/);
assert.doesNotMatch(runtimeHtml, /cm_agent_[A-Za-z0-9]{8,}/);
const heartbeatsGuide = guidePages.find((page) => page.path === '/guides/ai-agent-heartbeats-and-scheduled-work/');
assert.equal(heartbeatsGuide.title, 'AI Agent Heartbeats and Scheduled Work | Commonly AI');
const heartbeatsHtml = renderStaticPage(guideTemplate, heartbeatsGuide);
assert.match(heartbeatsHtml, /An AI agent heartbeat is a scheduled trigger/);
assert.match(heartbeatsHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(heartbeatsHtml, /everyMinutes/);
assert.match(heartbeatsHtml, /HEARTBEAT_OK/);
assert.match(heartbeatsHtml, /pending, claimed, blocked, and done/);
assert.match(heartbeatsHtml, /crash-loops the gateway/);
assert.doesNotMatch(heartbeatsHtml, /cm_agent_[A-Za-z0-9]{8,}/);
const marketplaceRolesGuide = guidePages.find((page) => page.path === '/guides/ai-agent-marketplace-roles/');
assert.equal(marketplaceRolesGuide.title, 'AI Agent Marketplace Roles: Build a Clear Team | Commonly AI');
const marketplaceRolesHtml = renderStaticPage(guideTemplate, marketplaceRolesGuide);
assert.match(marketplaceRolesHtml, /AI agent marketplace roles are reusable starting points/);
assert.match(marketplaceRolesHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(marketplaceRolesHtml, /Theo/);
assert.match(marketplaceRolesHtml, /X-Curator/);
assert.match(marketplaceRolesHtml, /coordinates tasks, reviews/);
assert.match(marketplaceRolesHtml, /pending, claimed, blocked, and done/);
assert.match(marketplaceRolesHtml, /AgentInstallation/);
assert.doesNotMatch(marketplaceRolesHtml, /cm_agent_[A-Za-z0-9]{8,}/);
const customHttpGuide = guidePages.find((page) => page.path === '/guides/connect-a-custom-agent-http-api/');
assert.equal(customHttpGuide.title, 'Connect a Custom AI Agent with the HTTP API | Commonly AI');
const customHttpHtml = renderStaticPage(guideTemplate, customHttpGuide);
assert.match(customHttpHtml, /Connecting a custom AI agent over HTTP means/);
assert.match(customHttpHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(customHttpHtml, /x-commonly-agent-token/);
assert.match(customHttpHtml, /deliveryId/);
assert.match(customHttpHtml, /sourceRef/);
assert.match(customHttpHtml, /runtime\/pods/);
assert.match(customHttpHtml, /pending, claimed, blocked, and done/);
assert.doesNotMatch(customHttpHtml, /cm_agent_[A-Za-z0-9]{8,}/);
const agentPodGuide = guidePages.find((page) => page.path === '/guides/what-is-an-agent-pod/');
assert.equal(agentPodGuide.title, 'What Is an Agent Pod? Shared Workspace for AI Teams | Commonly AI');
const agentPodHtml = renderStaticPage(guideTemplate, agentPodGuide);
assert.match(agentPodHtml, /An agent pod is a shared workspace/);
assert.match(agentPodHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(agentPodHtml, /agent-admin/);
assert.match(agentPodHtml, /invite-only/);
assert.match(agentPodHtml, /pending, claimed, blocked, and done/);
assert.match(agentPodHtml, /AgentInstallation/);
assert.match(agentPodHtml, /capped at 10 versions/);
assert.doesNotMatch(agentPodHtml, /cm_agent_[A-Za-z0-9]{8,}/);
const openClawGuide = guidePages.find((page) => page.path === '/guides/connect-openclaw-agent/');
const openClawHtml = renderStaticPage(guideTemplate, openClawGuide);
assert.match(openClawHtml, /Connecting an OpenClaw agent means/);
assert.match(openClawHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(openClawHtml, /moltbot\.json/);
assert.match(openClawHtml, /heartbeat\.global/);
assert.match(openClawHtml, /HEARTBEAT\.md/);
assert.match(openClawHtml, /AgentsHub/);
assert.doesNotMatch(openClawHtml, /cm_agent_[A-Za-z0-9]{8,}/);
const securityGuide = guidePages.find((page) => page.path === '/guides/ai-agent-security-best-practices/');
const securityHtml = renderStaticPage(guideTemplate, securityGuide);
assert.match(securityHtml, /AI agent security is the practice of/);
assert.match(securityHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(securityHtml, /least privilege/);
assert.match(securityHtml, /excessive agency/);
assert.match(securityHtml, /installation-scoped/);
assert.doesNotMatch(securityHtml, /cm_agent_[A-Za-z0-9]{8,}/);
const cliGuide = guidePages.find((page) => page.path === '/guides/ai-agent-cli/');
assert.equal(cliGuide.title, 'AI Agent CLI: Run a Local Agent as a Pod Member | Commonly AI');
const cliHtml = renderStaticPage(guideTemplate, cliGuide);
assert.match(cliHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-cli\/"/);
assert.match(cliHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(cliHtml, /commonly agent run/);
assert.doesNotMatch(cliHtml, /cm_agent_[A-Za-z0-9]{8,}/);
const rolesGuide = guidePages.find((page) => page.path === '/guides/ai-agent-roles/');
assert.equal(rolesGuide.title, 'AI Agent Roles: Define Work, Boundaries, and Handoffs | Commonly AI');
assert.deepEqual(guides['ai-agent-roles'].sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 8], [3, 6], [3, 7], [3, 6], [4, 8], [2, 4], [2, 7]]);
assert.equal(guides['ai-agent-roles'].sections.flatMap((section) => section.links || []).length, 11);
const rolesHtml = renderStaticPage(guideTemplate, rolesGuide);
assert.match(rolesHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-roles\//);
assert.match(rolesHtml, /An AI agent role is a bounded responsibility that tells an agent what result it owns/);
assert.match(rolesHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(rolesHtml, /seo-page-dark/);
assert.match(rolesHtml, /stop condition/);
assert.doesNotMatch(rolesHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((rolesHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/what-is-an-ai-agent/',
'/guides/how-to-write-ai-agent-instructions/',
'/guides/ai-agent-use-cases/',
'/guides/ai-agent-tools/',
]) {
assert.match(renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath)), /href="\/guides\/ai-agent-roles\/"/);
}
const escalationGuide = guidePages.find((page) => page.path === '/guides/ai-agent-escalation/');
assert.equal(escalationGuide.title, 'AI Agent Escalation: Stop, Hand Off, and Decide | Commonly AI');
assert.deepEqual(guides['ai-agent-escalation'].sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 5], [3, 9], [3, 9], [3, 6], [3, 4], [3, 6], [2, 8]]);
assert.deepEqual(guides['ai-agent-escalation'].sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(guides['ai-agent-escalation'].sections.flatMap((section) => section.links || []).length, 7);
const escalationHtml = renderStaticPage(guideTemplate, escalationGuide);
assert.match(escalationHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-escalation\//);
assert.match(escalationHtml, /AI agent escalation is a deliberate handoff to a person or role that can make a decision the agent should not make alone/);
assert.match(escalationHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(escalationHtml, /seo-page-dark/);
assert.match(escalationHtml, /escalation packet/);
assert.doesNotMatch(escalationHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((escalationHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-handoffs/',
'/guides/human-in-the-loop-ai-agents/',
'/guides/ai-agent-task-management/',
'/guides/prompt-injection-defense-for-ai-agents/',
]) {
assert.match(renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath)), /href="\/guides\/ai-agent-escalation\/"/);
}
const acceptanceCriteriaGuide = guidePages.find((page) => page.path === '/guides/ai-agent-acceptance-criteria/');
assert.equal(acceptanceCriteriaGuide.title, 'AI Agent Acceptance Criteria: Testable, Reviewable Work | Commonly AI');
assert.deepEqual(guides['ai-agent-acceptance-criteria'].sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 8], [2, 7], [2, 4], [2, 6], [3, 5], [2, 8]]);
assert.deepEqual(guides['ai-agent-acceptance-criteria'].sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(guides['ai-agent-acceptance-criteria'].sections.flatMap((section) => section.links || []).length, 9);
const acceptanceCriteriaHtml = renderStaticPage(guideTemplate, acceptanceCriteriaGuide);
assert.match(acceptanceCriteriaHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-acceptance-criteria\//);
assert.match(acceptanceCriteriaHtml, /AI agent acceptance criteria are the observable conditions that tell a team whether an agent's result is ready for its next handoff/);
assert.match(acceptanceCriteriaHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(acceptanceCriteriaHtml, /seo-page-dark/);
assert.match(acceptanceCriteriaHtml, /safe stop/);
assert.doesNotMatch(acceptanceCriteriaHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((acceptanceCriteriaHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/how-to-evaluate-ai-agents/',
'/guides/ai-agent-roles/',
'/guides/ai-agent-escalation/',
'/guides/how-to-write-ai-agent-instructions/',
]) {
assert.match(renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath)), /href="\/guides\/ai-agent-acceptance-criteria\//);
}
const decisionPacketGuide = guidePages.find((page) => page.path === '/guides/ai-agent-decision-packet/');
assert.equal(decisionPacketGuide.title, 'AI Agent Decision Packet: Evidence, Options, and Ownership | Commonly AI');
assert.deepEqual(guides['ai-agent-decision-packet'].sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 7], [3, 9], [3, 6], [3, 6], [3, 5], [3, 6], [3, 5], [2, 8]]);
assert.deepEqual(guides['ai-agent-decision-packet'].sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(guides['ai-agent-decision-packet'].sections.flatMap((section) => section.links || []).length, 9);
const decisionPacketHtml = renderStaticPage(guideTemplate, decisionPacketGuide);
assert.match(decisionPacketHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-decision-packet\//);
assert.match(decisionPacketHtml, /An AI agent decision packet is a compact, evidence-backed artifact that gives a named person or role one answerable choice/);
assert.match(decisionPacketHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(decisionPacketHtml, /seo-page-dark/);
assert.match(decisionPacketHtml, /answerable choice/);
assert.doesNotMatch(decisionPacketHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((decisionPacketHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-escalation/',
'/guides/ai-agent-handoffs/',
'/guides/human-in-the-loop-ai-agents/',
'/guides/context-engineering-for-ai-agents/',
]) {
assert.match(renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath)), /href="\/guides\/ai-agent-decision-packet\//);
}
const auditTrailGuide = guidePages.find((page) => page.path === '/guides/ai-agent-audit-trail/');
assert.equal(auditTrailGuide.title, 'AI Agent Audit Trail: Make Work and Decisions Inspectable | Commonly AI');
assert.deepEqual(guides['ai-agent-audit-trail'].sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 8], [3, 6], [3, 6], [3, 6], [3, 6], [3, 5], [3, 6]]);
assert.deepEqual(guides['ai-agent-audit-trail'].sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(guides['ai-agent-audit-trail'].sections.flatMap((section) => section.links || []).length, 10);
const auditTrailHtml = renderStaticPage(guideTemplate, auditTrailGuide);
assert.match(auditTrailHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-audit-trail\//);
assert.match(auditTrailHtml, /An AI agent audit trail is a structured, linked account of a piece of work/);
assert.match(auditTrailHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(auditTrailHtml, /seo-page-dark/);
assert.match(auditTrailHtml, /source-of-record/);
assert.doesNotMatch(auditTrailHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((auditTrailHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-governance/',
'/guides/ai-agent-memory/',
'/guides/ai-agent-acceptance-criteria/',
'/guides/ai-agent-task-management/',
]) {
assert.match(renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath)), /href="\/guides\/ai-agent-audit-trail\//);
}
const noOpGuide = guidePages.find((page) => page.path === '/guides/ai-agent-no-op/');
assert.equal(noOpGuide.title, 'AI Agent No-Op: When Doing Nothing Is the Right Result | Commonly AI');
assert.deepEqual(guides['ai-agent-no-op'].sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 8], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 5], [3, 6]]);
assert.deepEqual(guides['ai-agent-no-op'].sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(guides['ai-agent-no-op'].sections.flatMap((section) => section.links || []).length, 9);
const noOpHtml = renderStaticPage(guideTemplate, noOpGuide);
assert.match(noOpHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-no-op\//);
assert.match(noOpHtml, /An AI agent no-op is a deliberate decision to take no further action/);
assert.match(noOpHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(noOpHtml, /seo-page-dark/);
assert.match(noOpHtml, /eligibility rule/);
assert.doesNotMatch(noOpHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((noOpHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-heartbeats-and-scheduled-work/',
'/guides/ai-agent-escalation/',
'/guides/ai-agent-acceptance-criteria/',
'/guides/how-to-write-ai-agent-instructions/',
]) {
assert.match(renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath)), /href="\/guides\/ai-agent-no-op\//);
}
const sourceOfRecordGuide = guidePages.find((page) => page.path === '/guides/ai-agent-source-of-record/');
assert.equal(sourceOfRecordGuide.title, 'AI Agent Source of Record: Which Record Is Authoritative? | Commonly AI');
assert.deepEqual(guides['ai-agent-source-of-record'].sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[4, 6], [3, 7], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(guides['ai-agent-source-of-record'].sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(guides['ai-agent-source-of-record'].sections.flatMap((section) => section.links || []).length, 9);
const sourceOfRecordHtml = renderStaticPage(guideTemplate, sourceOfRecordGuide);
assert.match(sourceOfRecordHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-source-of-record\//);
assert.match(sourceOfRecordHtml, /An AI agent source of record is the designated place a team relies on for a specific kind of fact/);
assert.match(sourceOfRecordHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(sourceOfRecordHtml, /seo-page-dark/);
assert.match(sourceOfRecordHtml, /verification path/);
assert.doesNotMatch(sourceOfRecordHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((sourceOfRecordHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-blockers/',
'/guides/ai-agent-no-op/',
'/guides/ai-agent-escalation/',
'/guides/ai-agent-status-updates/',
]) {
assert.match(renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath)), /href="\/guides\/ai-agent-resume-conditions\//);
}
const prioritizationGuide = guidePages.find((page) => page.path === '/guides/ai-agent-task-prioritization/');
assert.equal(prioritizationGuide.title, 'AI Agent Task Prioritization: Choose What’s Next | Commonly AI');
const prioritization = guides['ai-agent-task-prioritization'];
assert.deepEqual(prioritization.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(prioritization.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(prioritization.sections.flatMap((section) => section.links || []).length, 9);
assert.equal(prioritization.faq.length, 6);
assert.equal(prioritization.intro.length, 4);
for (const section of prioritization.sections.filter((section) => section.links)) {
assert.equal(section.paragraphs.length, 2);
}
const prioritizationExampleIndex = prioritization.sections.findIndex((section) => section.title === 'A worked example with three eligible tasks');
const prioritizationExample = prioritization.sections[prioritizationExampleIndex];
assert.equal(prioritizationExample.paragraphs.length, 6);
assert.equal(prioritizationExample.tables, undefined);
assert.equal(prioritizationExample.links, undefined);
assert.equal(prioritizationExample.orderedItems, undefined);
assert.equal(prioritization.sections.slice(0, prioritizationExampleIndex).filter((section) => section.tables).length, 9);
assert.equal(prioritization.sections[prioritizationExampleIndex - 1].title, 'Update the current plan');
assert.equal(prioritization.sections[prioritizationExampleIndex + 1].title, 'Prioritize agent tasks in seven steps');
assert.match(prioritization.sections.find((section) => section.title === 'Use a range').paragraphs[1], /^If uncertainty could reverse the priority choice, a short discovery step may be useful when it is within the assignment\./);
for (const [title, tail] of [
['Build the shortlist', /Dependency management explains what must wait; prioritization compares what can happen now\.$/],
['Identify which choices', /A task claimant owns a contribution, not necessarily the team’s priorities\.$/],
['Describe the expected effect', /without pretending to quantify every benefit\.$/],
['Choose enough of an order', /because another task is more interesting but unavailable\.$/],
['Record unfinished work', /A priority change is a sequencing choice unless the actual stop condition or authority says otherwise\.$/],
['State the missing decision', /“Not selected next” is not, by itself, a blocker\.$/],
['Update the current plan', /need not change what any of those tasks is authorized to do\.$/],
]) {
assert.match(prioritization.sections.find((section) => section.title === title).paragraphs[1], tail);
}
const recordProportionate = prioritization.sections.find((section) => section.title === 'Keep the record proportionate');
assert.equal(recordProportionate.paragraphs.length, 1);
assert.equal(recordProportionate.links, undefined);
assert.match(recordProportionate.paragraphs[0], /“Return the source correction first to release the waiting review, then finish the brief before its agreed handoff; reassess if the correction requires broader work\.”/);
assert.match(prioritization.intro[0], /^AI agent task prioritization is the process of choosing which eligible contribution an agent should make next when several tasks compete for its attention\./);
const prioritizationHtml = renderStaticPage(guideTemplate, prioritizationGuide);
assert.match(prioritizationHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-task-prioritization\/"/);
assert.match(prioritizationHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(prioritizationHtml, /task prioritization/);
assert.doesNotMatch(prioritizationHtml, /seo-page-dark/);
assert.doesNotMatch(prioritizationHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((prioritizationHtml.match(/
Choose the next useful contribution<\/h2>/g) || []).length, 1);
assert.ok(prioritizationHtml.indexOf('
Frequently asked questions
') < prioritizationHtml.indexOf('
Choose the next useful contribution
'));
assert.equal(prioritization.cta.secondary.label, 'Explore Commonly’s guides');
const disagreementGuide = guidePages.find((page) => page.path === '/guides/ai-agent-disagreement-resolution/');
assert.equal(disagreementGuide.title, 'AI Agent Disagreement Resolution Guide | Commonly AI');
const disagreement = guides['ai-agent-disagreement-resolution'];
assert.deepEqual(disagreement.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(disagreement.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(disagreement.sections.flatMap((section) => section.links || []).length, 9);
assert.equal(disagreement.faq.length, 6);
assert.equal(disagreement.intro.length, 4);
for (const section of disagreement.sections.filter((section) => section.links)) {
assert.equal(section.paragraphs.length, 2);
}
const disagreementExampleIndex = disagreement.sections.findIndex((section) => section.title === 'A worked example of conflicting review feedback');
const disagreementExample = disagreement.sections[disagreementExampleIndex];
assert.equal(disagreementExample.paragraphs.length, 6);
assert.equal(disagreementExample.tables, undefined);
assert.equal(disagreementExample.links, undefined);
assert.equal(disagreementExample.orderedItems, undefined);
assert.equal(disagreement.sections.slice(0, disagreementExampleIndex).filter((section) => section.tables).length, 9);
assert.equal(disagreement.sections[disagreementExampleIndex - 1].title, 'Preserve a material unresolved concern');
assert.equal(disagreement.sections[disagreementExampleIndex + 1].title, 'Resolve agent disagreements in seven steps');
for (const [title, tail] of [
['Inspect the strongest relevant evidence', /^If the evidence remains incomplete, narrow the statement or keep the uncertainty visible\./],
['Name the decision', /^If two apparently authorized owners give incompatible directions/],
]) {
assert.match(disagreement.sections.find((section) => section.title === title).paragraphs[1], tail);
}
for (const [title, tail] of [
['Record the reason', /the original outcome may still need another approach or an owner’s explicit decision to stop pursuing it\.$/],
['Keep motives and status out', /A thread can organize a decision without becoming the authority that makes it valid\.$/],
['Revise the affected part', /supplies a required reviewer acceptance\.$/],
['Pause only the affected path', /not the full discussion with an unexplained request to “sort it out\.”$/],
['Preserve a material unresolved concern', /proof that a deployment, transfer, or other external operation occurred\.$/],
]) {
assert.match(disagreement.sections.find((section) => section.title === title).paragraphs[1], tail);
}
const shortestProcess = disagreement.sections.find((section) => section.title === 'Use the shortest process');
assert.equal(shortestProcess.paragraphs.length, 1);
assert.equal(shortestProcess.links, undefined);
assert.match(disagreement.intro[0], /^AI agent disagreement resolution is the process of turning conflicting claims, review comments, or recommendations about an agent’s work into an evidence-backed correction, a bounded owner decision, or an explicit unresolved condition\./);
const disagreementHtml = renderStaticPage(guideTemplate, disagreementGuide);
assert.match(disagreementHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-disagreement-resolution\/"/);
assert.match(disagreementHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(disagreementHtml, /disagreement resolution/);
assert.doesNotMatch(disagreementHtml, /seo-page-dark/);
assert.doesNotMatch(disagreementHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((disagreementHtml.match(/
Make stopping a useful, truthful contribution<\/h2>/g) || []).length, 1);
assert.ok(stopConditionsHtml.indexOf('
Frequently asked questions
') < stopConditionsHtml.indexOf('
Make stopping a useful, truthful contribution
'));
assert.equal(stopConditions.cta.secondary.label, 'Explore Commonly’s guides');
const audienceBoundariesGuide = guidePages.find((page) => page.path === '/guides/ai-agent-audience-boundaries/');
assert.equal(audienceBoundariesGuide.title, 'AI Agent Audience Boundaries: Who an Agent May Address | Commonly AI');
const audienceBoundaries = guides['ai-agent-audience-boundaries'];
assert.deepEqual(audienceBoundaries.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(audienceBoundaries.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(audienceBoundaries.sections.flatMap((section) => section.links || []).length, 9);
const boundedReview = audienceBoundaries.sections.find((section) => section.title === 'Use a named reviewer for bounded review, not a general audience');
assert.equal(boundedReview.paragraphs.length, 6);
assert.equal(boundedReview.tables, undefined);
assert.deepEqual(boundedReview.links.map((link) => link.path), ['/guides/ai-agent-focused-threads/']);
for (const title of ['If a test fails', 'The boundary is complete']) {
const section = audienceBoundaries.sections.find((section) => section.title === title);
assert.equal(section.paragraphs.length, 1);
assert.equal(section.links, undefined);
}
assert.match(audienceBoundaries.intro[0], /^AI agent audience boundaries define who an agent may address, what it may share with each audience, and which messages require a named owner before they become a commitment\./);
const audienceBoundariesHtml = renderStaticPage(guideTemplate, audienceBoundariesGuide);
assert.match(audienceBoundariesHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-audience-boundaries\/"/);
assert.match(audienceBoundariesHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(audienceBoundariesHtml, /audience boundary/);
assert.doesNotMatch(audienceBoundariesHtml, /seo-page-dark/);
assert.doesNotMatch(audienceBoundariesHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((audienceBoundariesHtml.match(/
Keep the right message with the right owner<\/h2>/g) || []).length, 1);
assert.ok(audienceBoundariesHtml.indexOf('
Frequently asked questions
') < audienceBoundariesHtml.indexOf('
Keep the right message with the right owner
'));
assert.equal(audienceBoundaries.cta.secondary.label, 'Explore Commonly’s guides');
const interimResultsGuide = guidePages.find((page) => page.path === '/guides/ai-agent-interim-results/');
assert.equal(interimResultsGuide.title, 'AI Agent Interim Results: Useful Work Before Completion | Commonly AI');
const interimResults = guides['ai-agent-interim-results'];
assert.deepEqual(interimResults.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(interimResults.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(interimResults.sections.flatMap((section) => section.links || []).length, 9);
const preservedInterim = interimResults.sections.find((section) => section.title === 'Preserve an interim result for the next owner without turning it into authority');
assert.equal(preservedInterim.paragraphs.length, 6);
assert.equal(preservedInterim.tables, undefined);
assert.deepEqual(preservedInterim.links.map((link) => link.path), ['/guides/ai-agent-retained-context/']);
assert.ok(interimResults.sections.some((section) => section.title === 'For example, an interim result names its gap'));
for (const title of ['If the result fails a test', 'The result is complete']) {
const section = interimResults.sections.find((section) => section.title === title);
assert.equal(section.paragraphs.length, 1);
assert.equal(section.links, undefined);
}
assert.match(interimResults.intro[0], /^An AI agent interim result is a bounded artifact, finding, check, or status record returned before the primary task is complete\./);
const interimResultsHtml = renderStaticPage(guideTemplate, interimResultsGuide);
assert.match(interimResultsHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-interim-results\/"/);
assert.match(interimResultsHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(interimResultsHtml, /remaining gap/);
assert.doesNotMatch(interimResultsHtml, /seo-page-dark/);
assert.doesNotMatch(interimResultsHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((interimResultsHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-blockers/',
'/guides/ai-agent-resume-conditions/',
'/guides/ai-agent-no-op/',
'/guides/ai-agent-status-updates/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.equal((html.match(/href="\/guides\/ai-agent-interim-results\/"/g) || []).length, 1);
}
const taskSplittingGuide = guidePages.find((page) => page.path === '/guides/ai-agent-task-splitting/');
assert.equal(taskSplittingGuide.title, 'AI Agent Task Splitting: Divide Work Clearly | Commonly AI');
const taskSplitting = guides['ai-agent-task-splitting'];
assert.deepEqual(taskSplitting.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(taskSplitting.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(taskSplitting.sections.flatMap((section) => section.links || []).length, 9);
const sharedDecision = taskSplitting.sections.find((section) => section.title === 'Do not split work that still needs one shared decision');
assert.equal(sharedDecision.paragraphs.length, 6);
assert.equal(sharedDecision.tables, undefined);
assert.deepEqual(sharedDecision.links.map((link) => link.path), ['/guides/ai-agent-work-contract/']);
assert.match(taskSplitting.sections.find((section) => section.title === 'An @mention').paragraphs[0], /^An @mention, a reaction, or a helpful reply can show participation\./);
for (const title of ['If the split fails a test', 'The split is successful']) {
const section = taskSplitting.sections.find((section) => section.title === title);
assert.equal(section.paragraphs.length, 1);
assert.equal(section.links, undefined);
}
assert.match(taskSplitting.intro[0], /^AI agent task splitting is the practice of turning one broad request into several bounded tasks when the work needs distinct artifacts, owners, dependencies, acceptance criteria, or review points\./);
const taskSplittingHtml = renderStaticPage(guideTemplate, taskSplittingGuide);
assert.match(taskSplittingHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-task-splitting\/"/);
assert.match(taskSplittingHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(taskSplittingHtml, /merge point/);
assert.doesNotMatch(taskSplittingHtml, /seo-page-dark/);
assert.doesNotMatch(taskSplittingHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((taskSplittingHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-task-management/',
'/guides/ai-agent-dependency-management/',
'/guides/ai-agent-follow-on-work/',
'/guides/ai-agent-task-closure/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.equal((html.match(/href="\/guides\/ai-agent-task-splitting\/"/g) || []).length, 1);
}
const revisionLoopGuide = guidePages.find((page) => page.path === '/guides/ai-agent-revision-loop/');
assert.equal(revisionLoopGuide.title, 'AI Agent Revision Loop: Request, Revise, Re-Review | Commonly AI');
const revisionLoop = guides['ai-agent-revision-loop'];
assert.deepEqual(revisionLoop.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(revisionLoop.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(revisionLoop.sections.flatMap((section) => section.links || []).length, 9);
const revisionDiscussion = revisionLoop.sections.find((section) => section.title === 'Keep the revision discussion focused on the review question');
assert.equal(revisionDiscussion.paragraphs.length, 6);
assert.equal(revisionDiscussion.tables, undefined);
assert.deepEqual(revisionDiscussion.links.map((link) => link.path), ['/guides/ai-agent-focused-threads/']);
for (const title of ['If the artifact fails a test', 'This sequence keeps revision work useful and finite']) {
const section = revisionLoop.sections.find((section) => section.title === title);
assert.equal(section.paragraphs.length, 1);
assert.equal(section.links, undefined);
}
assert.match(revisionLoop.intro[0], /^An AI agent revision loop is the bounded path from requested changes to a revised artifact and a new review answer\./);
const revisionLoopHtml = renderStaticPage(guideTemplate, revisionLoopGuide);
assert.match(revisionLoopHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-revision-loop\/"/);
assert.match(revisionLoopHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(revisionLoopHtml, /return point/);
assert.doesNotMatch(revisionLoopHtml, /seo-page-dark/);
assert.doesNotMatch(revisionLoopHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((revisionLoopHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-review-decisions/',
'/guides/ai-agent-review-packet/',
'/guides/ai-agent-artifact-versions/',
'/guides/ai-agent-focused-threads/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.equal((html.match(/href="\/guides\/ai-agent-revision-loop\/"/g) || []).length, 1);
}
const retainedContextGuide = guidePages.find((page) => page.path === '/guides/ai-agent-retained-context/');
assert.equal(retainedContextGuide.title, 'AI Agent Retained Context: Keep Useful Context | Commonly AI');
const retainedContext = guides['ai-agent-retained-context'];
assert.deepEqual(retainedContext.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(retainedContext.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(retainedContext.sections.flatMap((section) => section.links || []).length, 9);
for (const [title, path] of [
['Retain the work boundary, not an implied permission', '/guides/ai-agent-work-contract/'],
['Make follow-on work explicit instead of burying it in memory', '/guides/ai-agent-follow-on-work/'],
]) {
const section = retainedContext.sections.find((section) => section.title === title);
assert.equal(section.paragraphs.length, 6);
assert.equal(section.tables, undefined);
assert.deepEqual(section.links.map((link) => link.path), [path]);
}
for (const title of ['Shared memory can preserve provenance and version history', 'If the note fails a test', 'The resulting note should help a future reader']) {
const section = retainedContext.sections.find((section) => section.title === title);
assert.equal(section.paragraphs.length, 1);
assert.equal(section.links, undefined);
}
assert.match(retainedContext.intro[0], /^AI agent retained context is the selected information kept after a task so a later person or agent can reuse a sourced conclusion, understand where it applies, and find the record that supersedes or verifies it\./);
const retainedContextHtml = renderStaticPage(guideTemplate, retainedContextGuide);
assert.match(retainedContextHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-retained-context\/"/);
assert.match(retainedContextHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(retainedContextHtml, /successor record/);
assert.doesNotMatch(retainedContextHtml, /seo-page-dark/);
assert.doesNotMatch(retainedContextHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((retainedContextHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-memory/',
'/guides/ai-agent-task-closure/',
'/guides/ai-agent-context-packet/',
'/guides/ai-agent-artifact-versions/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.equal((html.match(/href="\/guides\/ai-agent-retained-context\/"/g) || []).length, 1);
}
const approvalBoundariesGuide = guidePages.find((page) => page.path === '/guides/ai-agent-approval-boundaries/');
assert.equal(approvalBoundariesGuide.title, 'AI Agent Approval Boundaries: What Review Can Authorize | Commonly AI');
const approvalBoundaries = guides['ai-agent-approval-boundaries'];
assert.deepEqual(approvalBoundaries.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(approvalBoundaries.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(approvalBoundaries.sections.flatMap((section) => section.links || []).length, 9);
const approvalOwner = approvalBoundaries.sections.find((section) => section.title === 'Give each approval a decision owner');
assert.equal(approvalOwner.paragraphs.length, 8);
assert.equal(approvalOwner.tables, undefined);
assert.deepEqual(approvalOwner.links.map((link) => link.path), ['/guides/ai-agent-decision-owner/']);
const sharedApprovalBoundary = approvalBoundaries.sections.find((section) => section.title === 'Use the same boundary across human and agent work');
assert.equal(sharedApprovalBoundary.paragraphs.length, 3);
assert.equal(sharedApprovalBoundary.tables, undefined);
assert.equal(sharedApprovalBoundary.links, undefined);
const boundedAnswer = approvalBoundaries.sections.find((section) => section.title === 'Start by naming the actual question');
assert.equal(boundedAnswer.paragraphs.length, 2);
assert.equal(boundedAnswer.links, undefined);
assert.equal(approvalBoundaries.sections.find((section) => section.title === 'If one of these steps is missing').links, undefined);
assert.match(approvalBoundaries.intro[0], /^AI agent approval boundaries define what a visible approval changes—and what it does not\./);
assert.match(approvalBoundaries.intro[1], /@mentions/);
const approvalBoundariesHtml = renderStaticPage(guideTemplate, approvalBoundariesGuide);
assert.match(approvalBoundariesHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-approval-boundaries\/"/);
assert.match(approvalBoundariesHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(approvalBoundariesHtml, /continuing limit/);
assert.doesNotMatch(approvalBoundariesHtml, /seo-page-dark/);
assert.doesNotMatch(approvalBoundariesHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((approvalBoundariesHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-permissions-and-tokens/',
'/guides/human-in-the-loop-ai-agents/',
'/guides/ai-agent-governance/',
'/guides/ai-agent-review-decisions/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.equal((html.match(/href="\/guides\/ai-agent-approval-boundaries\/"/g) || []).length, 1);
}
const focusedThreadsGuide = guidePages.find((page) => page.path === '/guides/ai-agent-focused-threads/');
assert.equal(focusedThreadsGuide.title, 'AI Agent Focused Threads: One Review or Decision | Commonly AI');
const focusedThreads = guides['ai-agent-focused-threads'];
assert.deepEqual(focusedThreads.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(focusedThreads.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(focusedThreads.sections.flatMap((section) => section.links || []).length, 9);
const focusedThreadRoles = focusedThreads.sections.find((section) => section.title === 'Use focused threads across human and agent roles');
assert.equal(focusedThreadRoles.paragraphs.length, 5);
assert.equal(focusedThreadRoles.tables, undefined);
assert.deepEqual(focusedThreadRoles.links.map((link) => link.path), ['/guides/ai-agent-status-updates/']);
assert.equal(focusedThreads.sections.find((section) => section.title === 'The thread earns its focus').links, undefined);
assert.match(focusedThreads.intro[0], /^AI agent focused threads are dedicated conversations for one review question, decision, or bounded issue\./);
assert.match(focusedThreads.intro[1], /@mentions/);
const focusedThreadsHtml = renderStaticPage(guideTemplate, focusedThreadsGuide);
assert.match(focusedThreadsHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-focused-threads\/"/);
assert.match(focusedThreadsHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(focusedThreadsHtml, /answerable question/);
assert.doesNotMatch(focusedThreadsHtml, /seo-page-dark/);
assert.doesNotMatch(focusedThreadsHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((focusedThreadsHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-task-management/',
'/guides/ai-agent-review-packet/',
'/guides/ai-agent-decision-owner/',
'/guides/ai-agent-review-decisions/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.equal((html.match(/href="\/guides\/ai-agent-focused-threads\/"/g) || []).length, 1);
}
const contextPacketGuide = guidePages.find((page) => page.path === '/guides/ai-agent-context-packet/');
assert.equal(contextPacketGuide.title, 'AI Agent Context Packet: Current Context for One Step | Commonly AI');
const contextPacket = guides['ai-agent-context-packet'];
assert.deepEqual(contextPacket.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(contextPacket.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(contextPacket.sections.flatMap((section) => section.links || []).length, 9);
assert.deepEqual(contextPacket.sections.find((section) => section.title === 'The source link is part of the field').links.map((link) => link.path), ['/guides/ai-agent-source-of-record/', '/guides/ai-agent-work-contract/']);
assert.equal(contextPacket.sections.find((section) => section.title === 'The packet should be short enough to work from').links, undefined);
assert.match(contextPacket.intro[0], /^An AI agent context packet is the smallest current, source-linked bundle an agent or reviewer needs to complete one bounded task step\./);
const contextPacketHtml = renderStaticPage(guideTemplate, contextPacketGuide);
assert.match(contextPacketHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-context-packet\/"/);
assert.match(contextPacketHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(contextPacketHtml, /source-linked bundle/);
assert.doesNotMatch(contextPacketHtml, /seo-page-dark/);
assert.doesNotMatch(contextPacketHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((contextPacketHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/context-engineering-for-ai-agents/',
'/guides/ai-agent-source-of-record/',
'/guides/ai-agent-task-intake/',
'/guides/ai-agent-task-closure/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.equal((html.match(/href="\/guides\/ai-agent-context-packet\/"/g) || []).length, 1);
}
const taskClosureGuide = guidePages.find((page) => page.path === '/guides/ai-agent-task-closure/');
assert.equal(taskClosureGuide.title, 'AI Agent Task Closure: Record What Done Means | Commonly AI');
const taskClosure = guides['ai-agent-task-closure'];
assert.deepEqual(taskClosure.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(taskClosure.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(taskClosure.sections.flatMap((section) => section.links || []).length, 9);
assert.deepEqual(taskClosure.sections.find((section) => section.title === 'Closing a path does not erase the reason it existed').links.map((link) => link.path), ['/guides/ai-agent-no-op/', '/guides/ai-agent-blockers/']);
assert.equal(taskClosure.sections.find((section) => section.title === 'Closure is a short final accounting').links, undefined);
assert.match(taskClosure.intro[0], /^AI agent task closure is the act of recording why a bounded task is done, what artifact or result it produced, what evidence supports that result, which decision or review applies, and what remains outside the task\./);
const taskClosureHtml = renderStaticPage(guideTemplate, taskClosureGuide);
assert.match(taskClosureHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-task-closure\/"/);
assert.match(taskClosureHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(taskClosureHtml, /verification boundary/);
assert.doesNotMatch(taskClosureHtml, /seo-page-dark/);
assert.doesNotMatch(taskClosureHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((taskClosureHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-task-management/',
'/guides/ai-agent-artifact-versions/',
'/guides/ai-agent-follow-on-work/',
'/guides/ai-agent-no-op/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.equal((html.match(/href="\/guides\/ai-agent-task-closure\/"/g) || []).length, 1);
}
const artifactVersionsGuide = guidePages.find((page) => page.path === '/guides/ai-agent-artifact-versions/');
assert.equal(artifactVersionsGuide.title, 'AI Agent Artifact Versions: Make Work Reviewable | Commonly AI');
const artifactVersions = guides['ai-agent-artifact-versions'];
assert.deepEqual(artifactVersions.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(artifactVersions.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(artifactVersions.sections.flatMap((section) => section.links || []).length, 9);
assert.deepEqual(artifactVersions.sections.find((section) => section.title === 'Version identity can be a document revision').links.map((link) => link.path), ['/guides/ai-agent-review-packet/', '/guides/ai-agent-source-of-record/']);
assert.equal(artifactVersions.sections.find((section) => section.title === 'The goal is not a ceremonial version number').links, undefined);
assert.match(artifactVersions.intro[0], /^AI agent artifact versions are stable, identifiable states of a draft, evidence packet, plan, review packet, decision packet, task result, or other work product\./);
const artifactVersionsHtml = renderStaticPage(guideTemplate, artifactVersionsGuide);
assert.match(artifactVersionsHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-artifact-versions\/"/);
assert.match(artifactVersionsHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(artifactVersionsHtml, /superseded/);
assert.doesNotMatch(artifactVersionsHtml, /seo-page-dark/);
assert.doesNotMatch(artifactVersionsHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((artifactVersionsHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-review-packet/',
'/guides/ai-agent-review-decisions/',
'/guides/ai-agent-verification-path/',
'/guides/ai-agent-audit-trail/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.equal((html.match(/href="\/guides\/ai-agent-artifact-versions\/"/g) || []).length, 1);
}
const decisionOwnerGuide = guidePages.find((page) => page.path === '/guides/ai-agent-decision-owner/');
assert.equal(decisionOwnerGuide.title, 'AI Agent Decision Owner: Who Can Give the Answer? | Commonly AI');
const decisionOwner = guides['ai-agent-decision-owner'];
assert.deepEqual(decisionOwner.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(decisionOwner.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(decisionOwner.sections.flatMap((section) => section.links || []).length, 9);
assert.deepEqual(decisionOwner.sections.find((section) => section.title === 'The question should make ownership legible').links.map((link) => link.path), ['/guides/ai-agent-decision-packet/', '/guides/ai-agent-source-of-record/']);
assert.equal(decisionOwner.sections.find((section) => section.title === 'The process makes ownership a property of a defined choice').links, undefined);
assert.match(decisionOwner.intro[0], /^An AI agent decision owner is the person, role, or designated authority accountable for answering a specific bounded question\./);
const decisionOwnerHtml = renderStaticPage(guideTemplate, decisionOwnerGuide);
assert.match(decisionOwnerHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-decision-owner\/"/);
assert.match(decisionOwnerHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(decisionOwnerHtml, /accountable owner/);
assert.doesNotMatch(decisionOwnerHtml, /seo-page-dark/);
assert.doesNotMatch(decisionOwnerHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((decisionOwnerHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-decision-packet/',
'/guides/ai-agent-review-decisions/',
'/guides/ai-agent-task-intake/',
'/guides/ai-agent-escalation/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.equal((html.match(/href="\/guides\/ai-agent-decision-owner\/"/g) || []).length, 1);
}
const intakeGuide = guidePages.find((page) => page.path === '/guides/ai-agent-task-intake/');
assert.equal(intakeGuide.title, 'AI Agent Task Intake: Make Work Eligible | Commonly AI');
const intake = guides['ai-agent-task-intake'];
assert.deepEqual(intake.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(intake.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(intake.sections.flatMap((section) => section.links || []).length, 9);
const intakeHandoff = intake.sections.find((section) => section.title === 'Preserve intake context in the task and handoff');
assert.equal(intakeHandoff.paragraphs.length, 5);
assert.equal(intakeHandoff.tables, undefined);
assert.deepEqual(intakeHandoff.links.map((link) => link.path), ['/guides/ai-agent-follow-on-work/']);
assert.equal(intake.sections.find((section) => section.title === 'Intake succeeds when the next contribution is clear').links, undefined);
assert.match(intake.intro[0], /^AI agent task intake is the process of turning a request, observation, or decision into a bounded task/);
const intakeHtml = renderStaticPage(guideTemplate, intakeGuide);
assert.match(intakeHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-task-intake\/"/);
assert.match(intakeHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(intakeHtml, /first artifact/);
assert.doesNotMatch(intakeHtml, /seo-page-dark/);
assert.doesNotMatch(intakeHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((intakeHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-task-management/',
'/guides/ai-agent-work-contract/',
'/guides/ai-agent-non-goals/',
'/guides/ai-agent-blockers/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.equal((html.match(/href="\/guides\/ai-agent-task-intake\/"/g) || []).length, 1);
}
const dependencyGuide = guidePages.find((page) => page.path === '/guides/ai-agent-dependency-management/');
assert.equal(dependencyGuide.title, 'AI Agent Dependency Management: Required States | Commonly AI');
const dependency = guides['ai-agent-dependency-management'];
assert.deepEqual(dependency.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(dependency.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(dependency.sections.flatMap((section) => section.links || []).length, 9);
assert.deepEqual(dependency.sections.find((section) => section.title === 'The distinction makes the board easier to read').links.map((link) => link.path), ['/guides/ai-agent-blockers/', '/guides/ai-agent-follow-on-work/']);
assert.equal(dependency.sections.find((section) => section.title === 'This keeps dependencies from becoming a background excuse').links, undefined);
assert.match(dependency.intro[0], /^AI agent dependency management is the practice of making one task’s required relationship/);
const dependencyHtml = renderStaticPage(guideTemplate, dependencyGuide);
assert.match(dependencyHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-dependency-management\/"/);
assert.match(dependencyHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(dependencyHtml, /prerequisite owner/);
assert.doesNotMatch(dependencyHtml, /seo-page-dark/);
assert.doesNotMatch(dependencyHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((dependencyHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-blockers/',
'/guides/ai-agent-resume-conditions/',
'/guides/ai-agent-task-management/',
'/guides/ai-agent-work-contract/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.equal((html.match(/href="\/guides\/ai-agent-dependency-management\/"/g) || []).length, 1);
}
const evidenceLabelsGuide = guidePages.find((page) => page.path === '/guides/ai-agent-evidence-labels/');
assert.equal(evidenceLabelsGuide.title, 'AI Agent Evidence Labels: Facts, Inferences, Decisions | Commonly AI');
const evidenceLabels = guides['ai-agent-evidence-labels'];
assert.deepEqual(evidenceLabels.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(evidenceLabels.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(evidenceLabels.sections.flatMap((section) => section.links || []).length, 9);
const evidenceHandoff = evidenceLabels.sections.find((section) => section.title === 'Carry labels through handoffs and durable context');
assert.equal(evidenceHandoff.paragraphs.length, 6);
assert.deepEqual(evidenceHandoff.links.map((link) => link.path), ['/guides/ai-agent-handoffs/']);
assert.equal(evidenceHandoff.tables, undefined);
assert.equal(evidenceLabels.sections.find((section) => section.title === 'The labels are a reading aid').links, undefined);
assert.match(evidenceLabels.intro[0], /^AI agent evidence labels identify what kind of statement a record makes and how a reviewer should treat it\./);
const evidenceLabelsHtml = renderStaticPage(guideTemplate, evidenceLabelsGuide);
assert.match(evidenceLabelsHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-evidence-labels\/"/);
assert.match(evidenceLabelsHtml, /AI agent evidence labels identify what kind of statement/);
assert.match(evidenceLabelsHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(evidenceLabelsHtml, /seo-page-dark/);
assert.match(evidenceLabelsHtml, /reported status/);
assert.doesNotMatch(evidenceLabelsHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((evidenceLabelsHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-verification-path/',
'/guides/ai-agent-source-of-record/',
'/guides/ai-agent-review-packet/',
'/guides/ai-agent-decision-packet/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.equal((html.match(/href="\/guides\/ai-agent-evidence-labels\/"/g) || []).length, 1);
}
const nonGoalsGuide = guidePages.find((page) => page.path === '/guides/ai-agent-non-goals/');
assert.equal(nonGoalsGuide.title, 'AI Agent Non-Goals: Write Clear Task Boundaries | Commonly AI');
const nonGoals = guides['ai-agent-non-goals'];
assert.deepEqual(nonGoals.sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(nonGoals.sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(nonGoals.sections.flatMap((section) => section.links || []).length, 9);
assert.deepEqual(nonGoals.sections.find((section) => section.title === 'The wording should be testable').links.map((link) => link.path), ['/guides/ai-agent-work-contract/', '/guides/ai-agent-task-management/']);
assert.equal(nonGoals.sections.find((section) => section.title === 'The purpose is not to make a task defensive').links, undefined);
assert.match(nonGoals.intro[0], /^AI agent non-goals are explicit statements of work a task, role, or review stage will not do\./);
const nonGoalsHtml = renderStaticPage(guideTemplate, nonGoalsGuide);
assert.match(nonGoalsHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-non-goals\/"/);
assert.match(nonGoalsHtml, /AI agent non-goals are explicit statements of work/);
assert.match(nonGoalsHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(nonGoalsHtml, /seo-page-dark/);
assert.match(nonGoalsHtml, /excluded work/);
assert.doesNotMatch(nonGoalsHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((nonGoalsHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-work-contract/',
'/guides/ai-agent-scope-creep/',
'/guides/ai-agent-follow-on-work/',
'/guides/ai-agent-no-op/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.equal((html.match(/href="\/guides\/ai-agent-non-goals\/"/g) || []).length, 1);
}
const reviewDecisionsGuide = guidePages.find((page) => page.path === '/guides/ai-agent-review-decisions/');
assert.equal(reviewDecisionsGuide.title, 'AI Agent Review Decisions: Five Clear Answers | Commonly AI');
assert.deepEqual(guides['ai-agent-review-decisions'].sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])), [[3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6], [3, 6]]);
assert.deepEqual(guides['ai-agent-review-decisions'].sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(guides['ai-agent-review-decisions'].sections.flatMap((section) => section.links || []).length, 9);
assert.equal(guides['ai-agent-review-decisions'].sections.find((section) => section.title === 'Record the decision where the next step can use it').paragraphs.length, 4);
const reviewDecisionsHtml = renderStaticPage(guideTemplate, reviewDecisionsGuide);
assert.match(reviewDecisionsHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-review-decisions\//);
assert.match(reviewDecisionsHtml, /AI agent review decisions are the explicit answers/);
assert.match(reviewDecisionsHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(reviewDecisionsHtml, /seo-page-dark/);
assert.match(reviewDecisionsHtml, /review stage/);
assert.doesNotMatch(reviewDecisionsHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((reviewDecisionsHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/ai-agent-review-packet/',
'/guides/ai-agent-acceptance-criteria/',
'/guides/ai-agent-decision-packet/',
'/guides/ai-agent-escalation/',
]) {
assert.match(renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath)), /href="\/guides\/ai-agent-review-decisions\//);
}
for (const guidePath of [
'/guides/what-is-an-ai-agent-runtime/',
'/guides/connect-a-custom-agent-http-api/',
'/guides/ai-agent-heartbeats-and-scheduled-work/',
'/guides/ai-agent-security-best-practices/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/ai-agent-cli\//);
}
const orchestrationGuide = guidePages.find((page) => page.path === '/guides/ai-agent-orchestration/');
assert.equal(orchestrationGuide.title, 'AI Agent Orchestration: Coordinate Work Through Shared State | Commonly AI');
const orchestrationHtml = renderStaticPage(guideTemplate, orchestrationGuide);
assert.match(orchestrationHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-orchestration\/"/);
assert.match(orchestrationHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.match(orchestrationHtml, /shared state/);
assert.doesNotMatch(orchestrationHtml, /cm_agent_[A-Za-z0-9]{8,}/);
const skillsGuide = guidePages.find((page) => page.path === '/guides/ai-agent-skills/');
assert.equal(skillsGuide.title, 'AI Agent Skills: Reusable Workflows for Reliable Agents | Commonly AI');
const skillsHtml = renderStaticPage(guideTemplate, skillsGuide);
assert.match(skillsHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-skills\/"/);
assert.match(skillsHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(skillsHtml, /seo-page-dark/);
assert.match(skillsHtml, /source-backed-review/);
assert.doesNotMatch(skillsHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/ai-agent-task-management/',
'/guides/ai-agent-memory/',
'/guides/ai-agent-handoffs/',
'/guides/ai-agent-heartbeats-and-scheduled-work/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/ai-agent-skills\//);
}
const autonomousGuide = guidePages.find((page) => page.path === '/guides/autonomous-ai-agents/');
assert.equal(autonomousGuide.title, 'Autonomous AI Agents: A Practical Operating Model for Teams | Commonly AI');
const autonomousHtml = renderStaticPage(guideTemplate, autonomousGuide);
assert.match(autonomousHtml, /href="https:\/\/commonly\.me\/guides\/autonomous-ai-agents\/"/);
assert.match(autonomousHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(autonomousHtml, /seo-page-dark/);
assert.match(autonomousHtml, /role contract/);
assert.doesNotMatch(autonomousHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/ai-agent-heartbeats-and-scheduled-work/',
'/guides/ai-agent-task-management/',
'/guides/ai-agent-security-best-practices/',
'/guides/human-in-the-loop-ai-agents/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/autonomous-ai-agents\//);
}
const sandboxingGuide = guidePages.find((page) => page.path === '/guides/ai-agent-sandboxing/');
assert.equal(sandboxingGuide.title, 'AI Agent Sandboxing: Reduce the Blast Radius of Untrusted Input | Commonly AI');
const sandboxingHtml = renderStaticPage(guideTemplate, sandboxingGuide);
assert.match(sandboxingHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-sandboxing\/"/);
assert.match(sandboxingHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(sandboxingHtml, /seo-page-dark/);
assert.match(sandboxingHtml, /blast radius/);
assert.doesNotMatch(sandboxingHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/ai-agent-permissions-and-tokens/',
'/guides/ai-agent-security-best-practices/',
'/guides/what-is-an-ai-agent-runtime/',
'/guides/autonomous-ai-agents/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/ai-agent-sandboxing\//);
}
const toolsGuide = guidePages.find((page) => page.path === '/guides/ai-agent-tools/');
assert.equal(toolsGuide.title, 'AI Agent Tools: What They Are and How to Choose Them | Commonly AI');
const toolsHtml = renderStaticPage(guideTemplate, toolsGuide);
assert.match(toolsHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-tools\/"/);
assert.match(toolsHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(toolsHtml, /seo-page-dark/);
assert.match(toolsHtml, /toolset/);
assert.doesNotMatch(toolsHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/ai-agent-skills/',
'/guides/ai-agent-task-management/',
'/guides/ai-agent-memory/',
'/guides/ai-agent-cli/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/ai-agent-tools\//);
}
const promptInjectionGuide = guidePages.find((page) => page.path === '/guides/prompt-injection-defense-for-ai-agents/');
assert.equal(promptInjectionGuide.title, 'Prompt Injection Defense for AI Agents: Contain the Capability | Commonly AI');
const promptInjectionHtml = renderStaticPage(guideTemplate, promptInjectionGuide);
assert.match(promptInjectionHtml, /href="https:\/\/commonly\.me\/guides\/prompt-injection-defense-for-ai-agents\/"/);
assert.match(promptInjectionHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(promptInjectionHtml, /seo-page-dark/);
assert.match(promptInjectionHtml, /capability boundaries/);
assert.doesNotMatch(promptInjectionHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/ai-agent-sandboxing/',
'/guides/ai-agent-security-best-practices/',
'/guides/ai-agent-permissions-and-tokens/',
'/guides/human-in-the-loop-ai-agents/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/prompt-injection-defense-for-ai-agents\//);
}
const mcpGuide = guidePages.find((page) => page.path === '/guides/mcp-for-ai-agent-teams/');
assert.equal(mcpGuide.title, 'MCP for AI Agent Teams: Connect Tools Without Losing Context | Commonly AI');
const mcpHtml = renderStaticPage(guideTemplate, mcpGuide);
assert.match(mcpHtml, /href="https:\/\/commonly\.me\/guides\/mcp-for-ai-agent-teams\/"/);
assert.match(mcpHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(mcpHtml, /seo-page-dark/);
assert.match(mcpHtml, /connection path/);
assert.doesNotMatch(mcpHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/connect-a-custom-agent-http-api/',
'/guides/what-is-an-ai-agent-runtime/',
'/guides/ai-agent-permissions-and-tokens/',
'/guides/ai-agent-tools/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/mcp-for-ai-agent-teams\//);
}
const agenticAiGuide = guidePages.find((page) => page.path === '/guides/what-is-agentic-ai/');
assert.equal(agenticAiGuide.title, 'What Is Agentic AI? A Practical Definition for Teams | Commonly AI');
const agenticAiHtml = renderStaticPage(guideTemplate, agenticAiGuide);
assert.match(agenticAiHtml, /href="https:\/\/commonly\.me\/guides\/what-is-agentic-ai\/"/);
assert.match(agenticAiHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(agenticAiHtml, /seo-page-dark/);
assert.match(agenticAiHtml, /work loop/);
assert.doesNotMatch(agenticAiHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/autonomous-ai-agents/',
'/guides/ai-agent-tools/',
'/guides/ai-agent-task-management/',
'/guides/human-in-the-loop-ai-agents/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/what-is-agentic-ai\//);
}
const aiAgentGuide = guidePages.find((page) => page.path === '/guides/what-is-an-ai-agent/');
assert.equal(aiAgentGuide.title, 'What Is an AI Agent? A Practical Definition for Teams | Commonly AI');
const aiAgentHtml = renderStaticPage(guideTemplate, aiAgentGuide);
assert.match(aiAgentHtml, /href="https:\/\/commonly\.me\/guides\/what-is-an-ai-agent\/"/);
assert.match(aiAgentHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(aiAgentHtml, /seo-page-dark/);
assert.match(aiAgentHtml, /participant/);
assert.doesNotMatch(aiAgentHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/what-is-agentic-ai/',
'/guides/what-is-an-ai-agent-runtime/',
'/guides/what-is-an-agent-pod/',
'/guides/ai-agent-task-management/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/what-is-an-ai-agent\/"/);
}
const contextEngineeringGuide = guidePages.find((page) => page.path === '/guides/context-engineering-for-ai-agents/');
assert.equal(contextEngineeringGuide.title, 'Context Engineering for AI Agents: Give Each Decision the Right State | Commonly AI');
const contextEngineeringHtml = renderStaticPage(guideTemplate, contextEngineeringGuide);
assert.match(contextEngineeringHtml, /href="https:\/\/commonly\.me\/guides\/context-engineering-for-ai-agents\/"/);
assert.match(contextEngineeringHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(contextEngineeringHtml, /seo-page-dark/);
assert.match(contextEngineeringHtml, /context packet/);
assert.doesNotMatch(contextEngineeringHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/ai-agent-memory/',
'/guides/ai-agent-task-management/',
'/guides/prompt-injection-defense-for-ai-agents/',
'/guides/what-is-agentic-ai/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/context-engineering-for-ai-agents\//);
}
const evaluationGuide = guidePages.find((page) => page.path === '/guides/how-to-evaluate-ai-agents/');
assert.equal(evaluationGuide.title, 'How to Evaluate AI Agents: Test the Work, Not Just the Answer | Commonly AI');
const evaluationHtml = renderStaticPage(guideTemplate, evaluationGuide);
assert.match(evaluationHtml, /href="https:\/\/commonly\.me\/guides\/how-to-evaluate-ai-agents\/"/);
assert.match(evaluationHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(evaluationHtml, /seo-page-dark/);
assert.match(evaluationHtml, /acceptance criteria/);
assert.doesNotMatch(evaluationHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/ai-agent-task-management/',
'/guides/context-engineering-for-ai-agents/',
'/guides/human-in-the-loop-ai-agents/',
'/guides/prompt-injection-defense-for-ai-agents/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/how-to-evaluate-ai-agents\//);
}
const chatbotGuide = guidePages.find((page) => page.path === '/guides/ai-agent-vs-chatbot/');
assert.equal(chatbotGuide.title, 'AI Agent vs. Chatbot: What Is the Difference? | Commonly AI');
const chatbotHtml = renderStaticPage(guideTemplate, chatbotGuide);
assert.match(chatbotHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-vs-chatbot\/"/);
assert.match(chatbotHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(chatbotHtml, /seo-page-dark/);
assert.match(chatbotHtml, /bounded contribution/);
assert.doesNotMatch(chatbotHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/what-is-an-ai-agent/',
'/guides/what-is-agentic-ai/',
'/guides/multi-agent-vs-single-agent/',
'/guides/ai-agent-tools/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/ai-agent-vs-chatbot\//);
}
const useCasesGuide = guidePages.find((page) => page.path === '/guides/ai-agent-use-cases/');
assert.equal(useCasesGuide.title, 'AI Agent Use Cases: Eight Roles Teams Can Start Safely | Commonly AI');
const useCasesHtml = renderStaticPage(guideTemplate, useCasesGuide);
assert.match(useCasesHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-use-cases\/"/);
assert.match(useCasesHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(useCasesHtml, /seo-page-dark/);
assert.match(useCasesHtml, /reviewable result/);
assert.doesNotMatch(useCasesHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/what-is-an-ai-agent/',
'/guides/ai-agent-orchestration/',
'/guides/human-in-the-loop-ai-agents/',
'/guides/how-to-evaluate-ai-agents/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/ai-agent-use-cases\//);
}
const collaborationGuide = guidePages.find((page) => page.path === '/guides/human-ai-collaboration/');
assert.equal(collaborationGuide.title, 'Human-AI Collaboration: How Teams Work Together With AI Agents | Commonly AI');
const collaborationHtml = renderStaticPage(guideTemplate, collaborationGuide);
assert.match(collaborationHtml, /href="https:\/\/commonly\.me\/guides\/human-ai-collaboration\//);
assert.match(collaborationHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(collaborationHtml, /seo-page-dark/);
assert.match(collaborationHtml, /decision owner/);
assert.doesNotMatch(collaborationHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/human-in-the-loop-ai-agents/',
'/guides/ai-agent-handoffs/',
'/guides/ai-agent-collaboration-patterns/',
'/guides/ai-agent-memory/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/human-ai-collaboration\//);
}
const workflowsGuide = guidePages.find((page) => page.path === '/guides/agentic-workflows/');
assert.equal(workflowsGuide.title, 'Agentic Workflows: How to Design AI Agent Work That Teams Can Trust | Commonly AI');
const workflowsHtml = renderStaticPage(guideTemplate, workflowsGuide);
assert.match(workflowsHtml, /href="https:\/\/commonly\.me\/guides\/agentic-workflows\//);
assert.match(workflowsHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(workflowsHtml, /seo-page-dark/);
assert.match(workflowsHtml, /eligible trigger/);
assert.doesNotMatch(workflowsHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/what-is-agentic-ai/',
'/guides/context-engineering-for-ai-agents/',
'/guides/ai-agent-use-cases/',
'/guides/ai-agent-handoffs/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/agentic-workflows\//);
}
const projectManagementGuide = guidePages.find((page) => page.path === '/guides/ai-agents-for-project-management/');
assert.equal(projectManagementGuide.title, 'AI Agents for Project Management: Coordinate Work Without Losing Ownership | Commonly AI');
const projectManagementHtml = renderStaticPage(guideTemplate, projectManagementGuide);
assert.match(projectManagementHtml, /href="https:\/\/commonly\.me\/guides\/ai-agents-for-project-management\//);
assert.match(projectManagementHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(projectManagementHtml, /seo-page-dark/);
assert.match(projectManagementHtml, /decision packet/);
assert.doesNotMatch(projectManagementHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/ai-agent-task-management/',
'/guides/ai-agent-use-cases/',
'/guides/human-in-the-loop-ai-agents/',
'/guides/ai-agent-orchestration/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/ai-agents-for-project-management\//);
}
const instructionsGuide = guidePages.find((page) => page.path === '/guides/how-to-write-ai-agent-instructions/');
assert.equal(instructionsGuide.title, 'How to Write AI Agent Instructions: A Practical Role Contract | Commonly AI');
const instructionsHtml = renderStaticPage(guideTemplate, instructionsGuide);
assert.match(instructionsHtml, /href="https:\/\/commonly\.me\/guides\/how-to-write-ai-agent-instructions\//);
assert.match(instructionsHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(instructionsHtml, /seo-page-dark/);
assert.match(instructionsHtml, /role contract/);
assert.doesNotMatch(instructionsHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/context-engineering-for-ai-agents/',
'/guides/how-to-evaluate-ai-agents/',
'/guides/human-ai-collaboration/',
'/guides/ai-agent-handoffs/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/how-to-write-ai-agent-instructions\//);
}
const researchGuide = guidePages.find((page) => page.path === '/guides/ai-agents-for-research/');
assert.equal(researchGuide.title, 'AI Agents for Research: Build Evidence Packets Teams Can Use | Commonly AI');
const researchHtml = renderStaticPage(guideTemplate, researchGuide);
assert.match(researchHtml, /href="https:\/\/commonly\.me\/guides\/ai-agents-for-research\//);
assert.match(researchHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(researchHtml, /seo-page-dark/);
assert.match(researchHtml, /evidence packet/);
assert.doesNotMatch(researchHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/ai-agent-use-cases/',
'/guides/context-engineering-for-ai-agents/',
'/guides/how-to-evaluate-ai-agents/',
'/guides/ai-agents-for-project-management/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/ai-agents-for-research\//);
}
const supportGuide = guidePages.find((page) => page.path === '/guides/ai-agents-for-customer-support/');
assert.equal(supportGuide.title, 'AI Agents for Customer Support: Triage, Context, and Safe Handoffs | Commonly AI');
const supportHtml = renderStaticPage(guideTemplate, supportGuide);
assert.match(supportHtml, /href="https:\/\/commonly\.me\/guides\/ai-agents-for-customer-support\//);
assert.match(supportHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(supportHtml, /seo-page-dark/);
assert.match(supportHtml, /triage packet/);
assert.doesNotMatch(supportHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((supportHtml.match(/
Frequently asked questions<\/h2>/g) || []).length, 1);
for (const guidePath of [
'/guides/prompt-injection-defense-for-ai-agents/',
'/guides/ai-agent-use-cases/',
'/guides/how-to-write-ai-agent-instructions/',
'/guides/human-in-the-loop-ai-agents/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/ai-agents-for-customer-support\//);
}
const multiAgentSystemGuide = guidePages.find((page) => page.path === '/guides/what-is-a-multi-agent-system/');
assert.equal(multiAgentSystemGuide.title, 'What Is a Multi-Agent System? A Practical Definition for Teams | Commonly AI');
assert.deepEqual(
guides['what-is-a-multi-agent-system'].sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])),
[[3, 6], [3, 5], [3, 6], [3, 5], [2, 6], [3, 5], [4, 5], [3, 7]],
);
assert.deepEqual(guides['what-is-a-multi-agent-system'].sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [6, 6]);
assert.equal(guides['what-is-a-multi-agent-system'].sections.flatMap((section) => section.links || []).length, 6);
const multiAgentSystemHtml = renderStaticPage(guideTemplate, multiAgentSystemGuide);
assert.match(multiAgentSystemHtml, /href="https:\/\/commonly\.me\/guides\/what-is-a-multi-agent-system\//);
assert.match(multiAgentSystemHtml, /A multi-agent system is a coordinated set of two or more AI agents/);
assert.match(multiAgentSystemHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(multiAgentSystemHtml, /seo-page-dark/);
assert.match(multiAgentSystemHtml, /operating model/);
assert.doesNotMatch(multiAgentSystemHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/multi-agent-vs-single-agent/',
'/guides/how-to-write-ai-agent-instructions/',
'/guides/ai-agent-memory/',
'/guides/ai-agent-task-management/',
'/guides/ai-agent-handoffs/',
'/guides/human-in-the-loop-ai-agents/',
]) {
assert.match(multiAgentSystemHtml, new RegExp('href="' + guidePath + '"'));
}
for (const guidePath of [
'/guides/multi-agent-vs-single-agent/',
'/guides/what-is-an-ai-agent/',
'/guides/ai-agent-task-management/',
'/guides/ai-agent-handoffs/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/what-is-a-multi-agent-system\/"/);
}
const glossaryGuide = guidePages.find((page) => page.path === '/guides/ai-agent-glossary/');
assert.equal(glossaryGuide.title, 'AI Agent Glossary: Essential Terms for Building Agent Teams | Commonly AI');
const glossaryData = guides['ai-agent-glossary'];
assert.deepEqual(
glossaryData.sections.filter((section) => !section.paragraphs).map((section) => section.title),
['Core agent terms', 'Collaboration and workspace terms', 'Context and memory terms', 'Capability and safety terms', 'Governance and evaluation terms'],
);
assert.equal(glossaryData.sections.filter((section) => section.paragraphs).length, 36);
assert.equal(glossaryData.sections.flatMap((section) => section.links || []).length, 19);
assert.equal(glossaryData.sections.some((section) => section.tables || section.bullets || section.orderedItems || section.codeBlocks), false);
const glossaryHtml = renderStaticPage(guideTemplate, glossaryGuide);
assert.match(glossaryHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-glossary\//);
assert.match(glossaryHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(glossaryHtml, /seo-page-dark/);
assert.match(glossaryHtml, /shared vocabulary/);
assert.doesNotMatch(glossaryHtml, /cm_agent_[A-Za-z0-9]{8,}/);
for (const guidePath of [
'/guides/what-is-an-ai-agent/',
'/guides/what-is-agentic-ai/',
'/guides/what-is-a-multi-agent-system/',
'/guides/how-to-write-ai-agent-instructions/',
]) {
const html = renderStaticPage(guideTemplate, pages.find((page) => page.path === guidePath));
assert.match(html, /href="\/guides\/ai-agent-glossary\/"/);
}
const governanceGuide = guidePages.find((page) => page.path === '/guides/ai-agent-governance/');
assert.equal(governanceGuide.title, 'AI Agent Governance: Roles, Boundaries, and Review | Commonly AI');
assert.deepEqual(
guides['ai-agent-governance'].sections.flatMap((section) => (section.tables || []).map((table) => [table.headers.length, table.rows.length])),
[[3, 6], [4, 5], [3, 7], [3, 5], [3, 6], [3, 6], [3, 6], [3, 5]],
);
assert.deepEqual(guides['ai-agent-governance'].sections.filter((section) => section.orderedItems).map((section) => section.orderedItems.length), [7]);
assert.equal(guides['ai-agent-governance'].sections.flatMap((section) => section.links || []).length, 9);
const governanceHtml = renderStaticPage(guideTemplate, governanceGuide);
assert.match(governanceHtml, /href="https:\/\/commonly\.me\/guides\/ai-agent-governance\//);
assert.match(governanceHtml, /AI agent governance is the operating model that decides who may assign work/);
assert.match(governanceHtml, /Commonly \(commonly\.me\), the shared workspace where humans and AI agents work together/);
assert.doesNotMatch(governanceHtml, /seo-page-dark/);
assert.match(governanceHtml, /review trigger/);
assert.doesNotMatch(governanceHtml, /cm_agent_[A-Za-z0-9]{8,}/);
assert.equal((governanceHtml.match(/
Example page<\/h1>/);
assert.match(rendered, / {
// The landing adds both from React, which crawlers that run no JS never see. Runs the real generator
// against a temp build dir seeded with the Vite template, so the production FAQ read is covered too.
const outputDir = await mkdtemp(join(tmpdir(), 'seo-faq-'));
try {
// What Vite emits: the source entry rewritten to a hashed asset (the generator strips it on static-only pages).
const source = await readFile(resolve(frontendDir, 'index.html'), 'utf8');
await writeFile(join(outputDir, 'index.html'), source.replace('src="/src/index.tsx"', 'src="/assets/index-test.js"'));
const [faqText, faqSource] = await Promise.all([
readFile(resolve(frontendDir, 'src/content/landing-faq.json'), 'utf8'),
readFile(resolve(frontendDir, 'src/v2/landing/landingFaq.ts'), 'utf8'),
]);
const landingFaq = JSON.parse(faqText);
const pages = await generateSeoPages({ outputDir });
const rendered = await readFile(join(outputDir, 'index.html'), 'utf8');
assert.equal(landingFaq.length, 6);
assert.ok(rendered.includes('"@type":"FAQPage"'));
// The landing effect finds this tag by id and reuses it rather than adding a second FAQPage.
assert.ok(faqSource.includes("FAQ_JSONLD_ID = 'landing-faq-jsonld'"));
assert.equal(rendered.match(/id="landing-faq-jsonld"/g).length, 1);
const faqLd = JSON.parse(rendered.match(/id="landing-faq-jsonld">([^<]*)<\/script>/)[1]);
assert.deepEqual(faqLd.mainEntity.map((q) => [q.name, q.acceptedAnswer.text]), landingFaq.map((item) => [item.question, item.answer]));
const escape = (value) => value.replaceAll('&', '&').replaceAll('"', '"').replaceAll("'", ''');
for (const item of landingFaq) {
assert.ok(rendered.includes(`
${escape(item.question)}
`), item.question);
assert.ok(rendered.includes(`
${escape(item.answer)}
`), item.answer);
}
// Every other page stays without it.
assert.ok(pages.filter((page) => page.path !== '/').every((page) => !page.faqSchema));
} finally {
await rm(outputDir, { recursive: true, force: true });
}
});
test('the compare page is unlisted: noindex, out of the sitemap, and linked from nothing', async () => {
const [translationText, useCaseText, guideText, llmsText] = await Promise.all([
readFile(resolve(frontendDir, 'src/i18n/locales/en.json'), 'utf8'),
readFile(resolve(frontendDir, 'src/content/use-cases.json'), 'utf8'),
readFile(resolve(frontendDir, 'src/content/guides.json'), 'utf8'),
readFile(resolve(frontendDir, 'public/llms.txt'), 'utf8'),
]);
const translations = JSON.parse(translationText);
const useCases = JSON.parse(useCaseText);
const guides = JSON.parse(guideText);
const pages = buildPageDefinitions({ landing: translations.landing, compare: translations.compare, useCases, guides });
const template = '';
const compare = pages.find((page) => page.path === '/compare/');
assert.equal(compare.noindex, true);
assert.match(renderStaticPage(template, compare), //);
for (const page of pages.filter((item) => item.path !== '/compare/')) {
assert.match(renderStaticPage(template, page), //, page.path);
assert.doesNotMatch(renderStaticPage(template, page), /href="\/compare\/"/, page.path);
}
assert.doesNotMatch(guideText, /"\/compare\/"/);
assert.doesNotMatch(llmsText, /\/compare\//);
const outputDir = await mkdtemp(resolve(tmpdir(), 'seo-compare-'));
await writeFile(resolve(outputDir, 'index.html'), template);
await generateSeoPages({ outputDir });
const sitemap = await readFile(resolve(outputDir, 'sitemap.xml'), 'utf8');
assert.doesNotMatch(sitemap, /https:\/\/commonly\.me\/compare\/<\/loc>/);
assert.match(sitemap, /https:\/\/commonly\.me\/compare\/openagents\/<\/loc>/);
assert.match(sitemap, /https:\/\/commonly\.me\/use-cases\/team-chat\/<\/loc>/);
});
test('a compare page renders GTM markdown and refuses to build while a HOLD is open', () => {
const html = renderMarkdown([
'# Title',
'',
'A **bold** claim with `code` and [a link](https://example.com/x) and https://example.org/y.',
'',
'| | Left | Right |',
'|---|---|---|',
'| **Row** | one [1] | two |',
'',
'- first',
'- second',
'',
'1. step one',
'',
'',
].join('\n'));
assert.match(html, /