Skip to content

chore(site): serve the docs from the codearbiter.dev apex domain - #588

Merged
SUaDtL merged 3 commits into
mainfrom
chore/apex-domain-base
Aug 1, 2026
Merged

chore(site): serve the docs from the codearbiter.dev apex domain#588
SUaDtL merged 3 commits into
mainfrom
chore/apex-domain-base

Conversation

@SUaDtL

@SUaDtL SUaDtL commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Points the docs site at the purchased apex domain codearbiter.dev and ships the GitHub Pages
CNAME in the built artifact.

DNS is not cut over yet. The old arbiterforge.github.io/codeArbiter/ URL keeps serving until
the Pages custom domain is set, and GitHub redirects it afterwards. This PR is the repo half, ready
to merge the moment DNS resolves.

The trap worth knowing about

BASE is "", not "/". rehypeBaseLinks prefixes every root-absolute href/src with BASE,
so "/" would rewrite /diagrams/x.svg into //diagrams/x.svg — a protocol-relative URL that
resolves against a different host
. That fails silently rather than 404-ing, which makes it far
worse than a broken link. Empty string makes the plugin a correct no-op. Astro's own base still
needs a real path, so it takes BASE || "/".

BASE="/codeArbiter"  "/diagrams/x.svg" -> "/codeArbiter/diagrams/x.svg"
BASE="/"             "/diagrams/x.svg" -> "//diagrams/x.svg"      <-- wrong host
BASE=""              "/diagrams/x.svg" -> "/diagrams/x.svg"       <-- correct

A correction to an earlier read

The 19 diagram <img src> attributes across 16 pages are not defects. Hardcoding the base
literal is the sanctioned Task-21 convention for .md/.mdx, because raw HTML in markdown is not
walked by rehypeBaseLinks. The literal simply moves with the base, so all 19 become
root-absolute. astro.config.mjs previously read as though hardcoding was banned outright; that
comment now states the documented exception and points at the guard.

Root cause of the four test failures

BASE is now exported, and the four tests that assert base-dependent output import it instead
of re-declaring the literal. Three kept their own const BASE = "/codeArbiter" — that duplication
is what turned a one-line base change into four failures. The convention guard in particular now
derives its regex from the config it exists to guard, so the two cannot disagree again.

One assertion changed meaning, not just value: astro-config's "does not contain the unprefixed
href" check asserts the opposite of correct behaviour once BASE is "", so it is now conditional
on a non-empty base rather than quietly deleted.

Verification

  • 496/496 site tests green (npm test, the vitest generator suite — a build alone does not run it)
  • The convention guard dies to a mutant (bare relative src="diagrams/x.svg") and recovers,
    so it still detects drift rather than matching everything
  • Build emits pages at the root, dist/CNAME present, zero surviving /codeArbiter/ asset
    paths in built HTML, sitemap and canonical on https://codearbiter.dev

Remaining, outside this PR

DNS at Spaceship (four A records at @ → the Pages IPs, www CNAME → arbiterforge.github.io),
then setting the Pages custom domain and enforcing HTTPS once the cert provisions.

Points the Astro build at the purchased apex domain and ships the
GitHub Pages CNAME in the built artifact, so the site resolves at
https://codearbiter.dev instead of the arbiterforge.github.io/codeArbiter
project path. DNS is not yet cut over; the old URL keeps serving and
GitHub redirects it once the custom domain is live.

BASE is "" rather than "/". rehypeBaseLinks prefixes root-absolute
href/src values with BASE, and "/" would turn "/diagrams/x.svg" into
"//diagrams/x.svg" — a protocol-relative URL resolving against another
host, failing silently rather than 404-ing. Empty string makes the
plugin a correct no-op. Astro still needs a real path, so it takes
`BASE || "/"`.

The 19 diagram <img src> attributes across 16 pages were not defects:
hardcoding the base literal is the sanctioned Task-21 convention for
.md/.mdx, because raw HTML in markdown is not walked by rehypeBaseLinks.
The literal simply moves with the base, so all 19 become root-absolute.

BASE is now exported and the four tests that assert base-dependent
output import it instead of re-declaring the literal. Three kept their
own copy, which is what turned a one-line base change into four
failures — the convention guard now derives its regex from the config
it is supposed to be guarding.

One assertion changed meaning rather than value: astro-config's
"does not contain the unprefixed href" check asserts the opposite of
correct behaviour when BASE is "", so it is now conditional on a
non-empty base.

Verified: 496/496 site tests green; the convention guard dies to a
bare-relative src mutant and recovers; the build emits pages at the
root with dist/CNAME present, zero surviving /codeArbiter/ asset paths
in the HTML, and the sitemap on the new host.
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 8ece3a16-4957-4c1e-94b2-0d66d75b78b2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • The documentation site is now available at the apex domain codearbiter.dev.
  • Bug Fixes
    • Updated documentation diagrams and assets to load correctly from the new site URL.
    • Corrected links and redirects for apex-domain hosting.
  • Tests
    • Updated site validation checks to support both root-domain and prefixed deployments.

Walkthrough

The site now targets codearbiter.dev at the apex domain. Astro exports an empty BASE, documentation assets use root-relative paths, and tests derive path assertions from the shared configuration.

Changes

Apex domain deployment

Layer / File(s) Summary
Apex domain configuration
site/astro.config.mjs, site/public/CNAME
Astro exports BASE = "", configures the root deployment path, and adds codearbiter.dev as the custom domain.
Documentation asset paths
site/src/content/docs/codearbiter-directory.md, site/src/content/docs/concepts/*, site/src/content/docs/enforcement.md, site/src/content/docs/feature-forge/overview.md, site/src/content/docs/getting-started/*, site/src/content/docs/guides/*, site/src/content/docs/overview.md
Documentation image sources no longer include the /codeArbiter prefix.
Base-dependent path validation
site/test/astro-config.test.ts, site/test/content/documentation-presentation.test.ts, site/test/generator/*
Tests import BASE and derive expected asset and link paths from the configured value.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes serving the documentation site from the codearbiter.dev apex domain.
Description check ✅ Passed The description directly explains the apex-domain configuration, CNAME addition, base-path changes, testing, and remaining DNS work.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/apex-domain-base

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@site/test/astro-config.test.ts`:
- Line 23: Add site/astro.config.d.mts declaring typed BASE and the default
Astro configuration so strict TypeScript accepts all named imports from
astro.config.mjs. Remove the existing suppression in
site/test/astro-config.test.ts and apply the shared declaration to the imports
in site/test/content/documentation-presentation.test.ts,
site/test/generator/diagram-href-convention.test.ts, and
site/test/generator/diagrams.test.ts.

In `@site/test/generator/diagram-href-convention.test.ts`:
- Around line 50-53: Update the regular expression construction in the diagram
href validation to escape the BASE value before interpolating it into RegExp.
Preserve the existing BASE-derived path matching while ensuring regex
metacharacters, including periods, are treated literally.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 6d1c3796-06c7-41ab-9f96-a5a28282f68f

📥 Commits

Reviewing files that changed from the base of the PR and between 1565be5 and 5c082dc.

📒 Files selected for processing (22)
  • site/astro.config.mjs
  • site/public/CNAME
  • site/src/content/docs/codearbiter-directory.md
  • site/src/content/docs/concepts/gated-lanes.md
  • site/src/content/docs/concepts/jit-context-injection.md
  • site/src/content/docs/concepts/provenance-drift.md
  • site/src/content/docs/enforcement.md
  • site/src/content/docs/feature-forge/overview.md
  • site/src/content/docs/getting-started/claude-code-and-codex.md
  • site/src/content/docs/guides/adding-a-dependency.md
  • site/src/content/docs/guides/autonomous-sprints.md
  • site/src/content/docs/guides/feature-lane.md
  • site/src/content/docs/guides/opt-in-a-repo.md
  • site/src/content/docs/guides/recording-adrs.md
  • site/src/content/docs/guides/releasing-a-version.md
  • site/src/content/docs/guides/the-statusline.md
  • site/src/content/docs/guides/troubleshooting.md
  • site/src/content/docs/overview.md
  • site/test/astro-config.test.ts
  • site/test/content/documentation-presentation.test.ts
  • site/test/generator/diagram-href-convention.test.ts
  • site/test/generator/diagrams.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (5)
  • GitHub Check: Analyze (rust)
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (actions)
⚠️ CI failures not shown inline (2)

GitHub Actions: Deploy docs / 1_Site [Build] - Astro Pages.txt: chore(site): serve the docs from the codearbiter.dev apex domain

Conclusion: failure

View job details

ure/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/fix/  (outside base path: resolves to /reference/commands/fix/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/init/  (outside base path: resolves to /reference/commands/init/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/metrics/  (outside base path: resolves to /reference/commands/metrics/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/new-skill/  (outside base path: resolves to /reference/commands/new-skill/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/override/  (outside base path: resolves to /reference/commands/override/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/pr/  (outside base path: resolves to /reference/commands/pr/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/preview/  (outside base path: resolves to /reference/commands/preview/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/prune/  (outside base path: resolves to /reference/commands/prune/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/reconcile/  (outside base path: resolves to /reference/commands/reconcile/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/refactor/  (outside base path: resolves to /reference/commands/refactor/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/release/  (outside base path: resolves to /reference/commands/release/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/review/  (outside base path: resolves to /reference/commands/review/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /referen...

GitHub Actions: Deploy docs / Site [Build] - Astro Pages: chore(site): serve the docs from the codearbiter.dev apex domain

Conclusion: failure

View job details

ure/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/fix/  (outside base path: resolves to /reference/commands/fix/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/init/  (outside base path: resolves to /reference/commands/init/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/metrics/  (outside base path: resolves to /reference/commands/metrics/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/new-skill/  (outside base path: resolves to /reference/commands/new-skill/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/override/  (outside base path: resolves to /reference/commands/override/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/pr/  (outside base path: resolves to /reference/commands/pr/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/preview/  (outside base path: resolves to /reference/commands/preview/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/prune/  (outside base path: resolves to /reference/commands/prune/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/reconcile/  (outside base path: resolves to /reference/commands/reconcile/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/refactor/  (outside base path: resolves to /reference/commands/refactor/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/release/  (outside base path: resolves to /reference/commands/release/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /reference/commands/review/  (outside base path: resolves to /reference/commands/review/, not under /codeArbiter)
   reference/skills/tribunal/index.html  ->  /referen...
🧰 Additional context used
📓 Path-based instructions (1)
**/*.md

⚙️ CodeRabbit configuration file

Prose in this repo is part of the product — skills and commands are read and executed by agents, so an ambiguous instruction is a defect, not a style nit. Prioritise findings where prose and the mechanism it describes disagree, where a documented command or flag no longer exists, or where an instruction cannot be followed literally without a contradiction. Deprioritise wording, tone and formatting preferences.

Files:

  • site/src/content/docs/concepts/provenance-drift.md
  • site/src/content/docs/feature-forge/overview.md
  • site/src/content/docs/concepts/jit-context-injection.md
  • site/src/content/docs/guides/recording-adrs.md
  • site/src/content/docs/guides/autonomous-sprints.md
  • site/src/content/docs/getting-started/claude-code-and-codex.md
  • site/src/content/docs/guides/feature-lane.md
  • site/src/content/docs/enforcement.md
  • site/src/content/docs/codearbiter-directory.md
  • site/src/content/docs/guides/opt-in-a-repo.md
  • site/src/content/docs/overview.md
  • site/src/content/docs/guides/releasing-a-version.md
  • site/src/content/docs/guides/troubleshooting.md
  • site/src/content/docs/guides/the-statusline.md
  • site/src/content/docs/guides/adding-a-dependency.md
  • site/src/content/docs/concepts/gated-lanes.md
🪛 ast-grep (0.45.0)
site/test/generator/diagram-href-convention.test.ts

[warning] 52-52: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^${BASE}/diagrams/[\\w.-]+\\.svg$)
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)

🪛 GitHub Actions: Deploy docs / 2_Site [Test] - Generator.txt
site/test/astro-config.test.ts

[error] 23-23: TypeScript typecheck failed in 'npm run typecheck' (tsc --noEmit): Could not find a declaration file for module '../astro.config.mjs'; the module implicitly has an 'any' type (TS7016).

🪛 GitHub Actions: Deploy docs / Site [Test] - Generator
site/test/astro-config.test.ts

[error] 23-23: TypeScript error TS7016: Could not find a declaration file for module '../astro.config.mjs'; the module implicitly has an 'any' type. Command failed: npm run typecheck.

🔇 Additional comments (22)
site/astro.config.mjs (1)

9-21: LGTM!

Also applies to: 47-48, 57-77

site/src/content/docs/guides/opt-in-a-repo.md (1)

26-26: LGTM!

site/src/content/docs/guides/recording-adrs.md (1)

21-21: LGTM!

site/src/content/docs/guides/releasing-a-version.md (1)

20-20: LGTM!

site/src/content/docs/guides/the-statusline.md (1)

25-25: LGTM!

site/src/content/docs/guides/troubleshooting.md (1)

75-75: LGTM!

site/src/content/docs/overview.md (1)

49-49: LGTM!

site/test/astro-config.test.ts (1)

44-51: LGTM!

site/test/content/documentation-presentation.test.ts (1)

100-101: LGTM!

site/test/generator/diagram-href-convention.test.ts (1)

8-11: LGTM!

site/test/generator/diagrams.test.ts (1)

108-108: LGTM!

site/public/CNAME (1)

1-1: LGTM!

site/src/content/docs/codearbiter-directory.md (1)

75-75: LGTM!

site/src/content/docs/concepts/gated-lanes.md (1)

27-27: LGTM!

Also applies to: 56-56

site/src/content/docs/concepts/jit-context-injection.md (1)

57-57: LGTM!

site/src/content/docs/concepts/provenance-drift.md (1)

35-35: LGTM!

site/src/content/docs/enforcement.md (1)

59-59: LGTM!

Also applies to: 109-109

site/src/content/docs/feature-forge/overview.md (1)

24-32: LGTM!

site/src/content/docs/getting-started/claude-code-and-codex.md (1)

66-66: LGTM!

site/src/content/docs/guides/adding-a-dependency.md (1)

23-23: LGTM!

site/src/content/docs/guides/autonomous-sprints.md (1)

21-21: LGTM!

site/src/content/docs/guides/feature-lane.md (1)

32-32: LGTM!

Comment thread site/test/astro-config.test.ts
Comment thread site/test/generator/diagram-href-convention.test.ts Outdated
SUaDtL added 2 commits August 1, 2026 11:27
CI caught two failures the local run missed, both the same root cause:
the base literal was copied into six places, each with a comment saying
it had to match the others. The apex move desynced all six at once.

  - tsc (not vitest) failed on four untyped .mjs imports; `npm test`
    runs vitest only, so the local run was green while CI was red.
  - link-audit reported 19,940 failures because
    scripts/link-audit/lib.ts held its own "/codeArbiter" constant.

site/base.mjs is now the only definition. astro.config.mjs re-exports it
so existing importers are unchanged, and link-audit imports it directly
instead of restating it. The resolution logic already handled an empty
base correctly; only the literal was wrong.

The link-audit unit tests now pin a fixed TEST_BASE rather than the
site's live value. They exercise prefix stripping and the outside-base
classification, which only exist when the base is non-empty — binding
them to the live base made nine cases silently stop testing anything the
moment the site moved to an apex domain.

A new describe block covers the apex case, and it records a real
behaviour change rather than asserting a comfortable one: with base "",
posix.normalize clamps at the root, so every root-absolute target is
inside the base and the outside-base guard is INERT. What still catches
a bad target is the dangling-file check. Pinned so the next reader does
not assume a protection that no longer bears load.

Verified: 500/500 vitest, tsc clean, build green, link-audit resolves
20,057 links across 140 pages.
The convention guard built its matcher with
`new RegExp(\`^${BASE}/diagrams/...\`)`. Interpolating a value into a
regex means any metacharacter it contains changes the pattern's meaning:
a base such as "/docs.v2" or "/v1.0" carries a "." that matches any
character, so the guard would accept "/docsXv2/diagrams/a.svg" and
quietly stop guarding. This file exists specifically to survive a base
change, so it must not be the thing that breaks on one.

Matching the base as a plain string prefix and validating the remainder
against a literal regex removes the class of problem outright, and is
simpler than escaping would be.

Honest scope note: this is hardening against a defect in principle, not
a demonstrated live failure. Repeated attempts to reproduce the
metacharacter case in a throwaway script were confounded by shell and
template-literal escaping — the harness kept degrading the pattern so
that it failed the legitimate case too. The behaviour was never
reproduced against the real code, whose current base is "" and therefore
carries no metacharacters at all.

Guard still dies to a bare-relative src mutant and recovers.
500/500 vitest green, tsc clean.
@SUaDtL
SUaDtL merged commit 3d414aa into main Aug 1, 2026
42 checks passed
@SUaDtL
SUaDtL deleted the chore/apex-domain-base branch August 1, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant