Conversation
Three independent fixes from the second-pass audit (2026-05-09):
1) Broken anchors (P1). Wrote .scripts/anchor-scan.mjs and ran it
against the built HTML. Found 13 unique broken internal anchors (24
link instances when counting duplicates across source files); the
remaining scanner output is calculator state-encoded `#s=eyJ...` URLs
and one relative-path link my scanner can't resolve — both false
positives. Fixed:
Slug typos / drift:
/how-to/budget-allocation-and-management-in-cycles
#starting-a-new-billing-period-reset_spent → -reset-spent
(3× from troubleshooting-and-faq.md — slugifier replaces _ with -)
/how-to/monitoring-and-alerting
#balance-polling-alerts-no-custom-metric-required
→ #balance-polling-alerts-for-signals-without-a-counter
(2× from incidents/* — section was renamed)
/admin-api/guide
#pillar-4-events--webhooks-v0125 → -events-webhooks-v0-1-25
(1× from security.md — slugifier strips `&` and splits version
number with hyphens)
/how-to/integrating-cycles-with-openclaw
#try-it-without-a-server → #dry-run-mode (1× from blog)
#observability-with-metricsemitter-v050
→ #observability-with-otlp-metrics-v0-5-0 (1× from blog)
Stable explicit anchors (target heading slug is fragile or contains
unicode em dash that doesn't survive slugify the same way the link
expects):
how-to/api-key-management-in-cycles.md: <a id="available-permissions">
before `### Available permissions (27 total)` — slug carried the
`(27 total)` count which is fragile (3 inbound links).
how-to/troubleshooting-and-faq.md:
<a id="spring-boot-illegalstateexception-nested-cycles">
before `### Spring Boot: IllegalStateException — nested @Cycles`
— em dash got slugified to a literal `—` char in the rendered id.
Stale reference (target section never existed):
how-to/handling-streaming-responses-with-cycles.md:244 referenced
`#programmatic-cycleslient` — typo, AND the spring-boot starter
page has no such section. Reworded to point at the page generally;
section can be added later if/when programmatic CyclesClient docs
land for the starter.
2) Homepage description (P2). index.md had no `description:` in
frontmatter, so the home page fell back to the site-wide default
defined in .vitepress/config.ts. Added an intentional description
matching the page's hero copy: "Runtime authority for autonomous
AI agents — pre-execution gating on cost, risk, and tool actions.
Open protocol, self-hosted, Apache 2.0." (140 chars; under SEO
budget).
3) Duplicate calculator titles (P2). calculators/ai-agent-blast-radius-
risk.md and calculators/ai-agent-blast-radius-standalone.md both used
the exact title "AI Agent Blast Radius Risk Calculator". Renamed the
standalone variant to "AI Agent Blast Radius Calculator (Full Screen)"
with a distinct description, so the two pages don't compete for the
same SERP slot. Risk variant (the docs page) keeps the original title
unchanged.
Tooling: .scripts/anchor-scan.mjs is a one-shot scanner that parses
all id="..." attrs from .vitepress/dist/*.html and reports any markdown
link with a `#anchor` whose target page lacks that id. Useful for
future audits; ~50 lines, no dependencies.
Verified:
- vitest 90/90 pass
- vitepress build clean
- anchor-scan: 24 broken → 11 (all 11 are scanner false positives —
9 calculator state URLs, 2 relative-path resolution gaps).
- Homepage description in rendered HTML: meta + og:description both
reflect the new value (was: default fallback).
- Standalone calculator: <title>"AI Agent Blast Radius Calculator
(Full Screen) — Cycles"</title>; risk variant unchanged at "AI
Agent Blast Radius Risk Calculator — Cycles".
This was referenced May 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR A from the second-pass audit (2026-05-09). Three independent fixes bundled — all P1/P2 surgical edits, no semantic changes.
1. Broken internal anchors (13 unique, 19 link instances)
Wrote
.scripts/anchor-scan.mjsto parse allid="..."attrs from the built HTML and report any markdown link with#anchorwhose target lacks that id. The pre-PR scan reported 24 broken anchors; 11 are scanner false positives (9 calculator state-encoded#s=eyJ...URLs which are intentional client-side state, and 2 relative-path links the scanner can't resolve). The other 13 are real and fixed.Slug typos / drift:
#starting-a-new-billing-period-reset_spent#starting-a-new-billing-period-reset-spent(slugifier replaces_→-)troubleshooting-and-faq.md#balance-polling-alerts-no-custom-metric-required#balance-polling-alerts-for-signals-without-a-counter(section renamed)incidents/*#pillar-4-events--webhooks-v0125#pillar-4-events-webhooks-v0-1-25(slugifier strips&and splits the version number)security.md#try-it-without-a-server#dry-run-mode(target section was renamed)#observability-with-metricsemitter-v050#observability-with-otlp-metrics-v0-5-0(target section was renamed in v0.5.0 release)Stable explicit anchors (target slug fragile or contains unicode em dash):
how-to/api-key-management-in-cycles.md: added<a id="available-permissions">before### Available permissions (27 total). The(27 total)count was leaking into the slug, so the count-bumps would silently break inbound links. 3 inbound links resolved by this single anchor.how-to/troubleshooting-and-faq.md: added<a id="spring-boot-illegalstateexception-nested-cycles">before### Spring Boot: IllegalStateException — nested @Cycles. The em dash in the heading slugified to a literal—character in the rendered id (spring-boot-illegalstateexception-—-nested-cycles), which the link-as-written can't reach.Stale reference dropped:
how-to/handling-streaming-responses-with-cycles.md:244referenced#programmatic-cycleslient— typo and the spring-boot starter page has no such section. Reworded to link to the page generally; the section can be added later if programmatic-CyclesClientdocs ever land for the starter.2. Homepage description (P2)
index.mdhad nodescription:in frontmatter, so the homepage fell back to the site-wide default defined in.vitepress/config.ts:641. The home page is the single most-trafficked page; it should not share its description with every other page that omits one.Added:
"Runtime authority for autonomous AI agents — pre-execution gating on cost, risk, and tool actions. Open protocol, self-hosted, Apache 2.0."(140 chars, under SEO budget).3. Duplicate calculator titles (P2)
calculators/ai-agent-blast-radius-risk.mdandcalculators/ai-agent-blast-radius-standalone.mdboth used the exact title"AI Agent Blast Radius Risk Calculator". Two indexable URLs competing for the same SERP slot.Renamed the standalone variant to
"AI Agent Blast Radius Calculator (Full Screen)"with a distinct description ("Full-screen interactive calculator for AI agent blast radius — reversibility, visibility, audience size, with an editable runtime-authority containment factor."). Risk variant (the docs page that hosts the marketing copy + embedded calc) keeps its original title.Tooling:
.scripts/anchor-scan.mjsStandalone, ~50 lines, no dependencies. Walks
.vitepress/dist/*.htmlforid="..."attrs and walks all.mdsource for[text](path#anchor)links; reports anchors not present in the target page's id set. Mirrors the precedent set by.scripts/link-audit.mjsand the other one-shot maintenance scripts already in.scripts/. Useful for future audit rounds.Verification
vitest run— 90/90 passvitepress build— clean<meta name="description">and<meta property="og:description">Out of scope
P1 #2 (truncation sweep — 87 titles + 73 descriptions over budget) and P2 #5 (Person vs Organization in JSON-LD) are deferred to follow-up PRs, as proposed in the evaluation. P1 #1 (PDF links) is mostly a false positive — the deployed site has the PDFs, only
npm run build(without:with-pdfs) misses them.