Skip to content

fix(docs+site): resolve the URLs this repo hands out, gate the rule, retire the undeployed site (#57) - #68

Merged
macanderson merged 2 commits into
mainfrom
fix/deploy-topology-57
Jul 30, 2026
Merged

fix(docs+site): resolve the URLs this repo hands out, gate the rule, retire the undeployed site (#57)#68
macanderson merged 2 commits into
mainfrom
fix/deploy-topology-57

Conversation

@macanderson

@macanderson macanderson commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Summary

This repo advertised absolute URLs for its own artifacts on hosts it does not
deploy, so they 404'd — including the badge every conformant provider is told to
paste into its README. This fixes the live breakage, writes the host boundary
down as ADR 0008, gates it in CI, and retires the undeployed site/ app,
which is the ratified answer to #57's last open question.

Closes #57.

The bug, verified 2026-07-30

One Vercel project (prj_s3lf…, team oxagen) owns contextgraphprotocol.org,
cgp.oxagen.sh, and context-graph-protocol.vercel.app. Its Git integration
points at macanderson/cgp-website, root dir . — not at this repository.
The changeover is in the deploy history: last production from this repo
2026-07-23T21:41:03Z, superseded by cgp-website@main (8958d2e) at
21:51:53Z, still live.

https://cgp.oxagen.sh/badges/conformant.svg                                404
https://contextgraphprotocol.org/schema/contextgraph-envelope.schema.json  404
https://contextgraphprotocol.org/registry/…report.json                     404

docs/registry.md and docs/implementing-a-provider.md hand that first URL to
every provider that earns a registry row — on a page whose own copy said the
badge "never depends on this site's uptime." #58 hit the same wall from the
schema side and fixed $id alone.

Nothing failed loudly because no build step dereferences a URL.

What changed

Fix the URLs, gate the rule

  • Badge URLs repointed to this repo's GitHub-raw path (image/svg+xml, so it
    renders in a third-party README).
  • ADR 0008 — the verified topology, the host boundary ("advertise an
    artifact URL only on a host this repo serves"), and never-vercel link-this-
    checkout-to-the-apex.
  • .github/scripts/check-deploy-hygiene.py + a required CI job: no artifact
    URL on a host we don't deploy, every advertised artifact exists at the path
    its URL names, no checkout linked to the apex project. Offline, no network.
  • Scaffold READMEs point at the canonical apex; validate-examples.py's $id
    note cites ADR 0008.

Retire site/ (second commit)

site/ was a fumadocs/Next app built on every PR as a hard gate and
deployed nowhere, holding a second hand-maintained copy of docs/. That
copy had drifted stale, not richer:

  • protocol-surface.mdx still documented capabilities.upsert, .subscribe,
    .filters, .writes — the dead surface ADR 0004 removed.
  • changelog.mdx was 87 lines against CHANGELOG.md's 353; four more pages
    were partial copies of root files with no docs/ counterpart.

So deleting it removes wrong documentation, not unique documentation, and ends
the three-copies-across-two-repos drift ADR 0007 exists to prevent.

The two genuinely published artifacts moved out first, to homes that don't
depend on an app:

was now
site/public/badges/conformant.svg assets/badges/conformant.svg
site/public/registry/…report.json registry/contextgraph-example-docs.report.json
site/public/schema/… gone — byte-identical mirror of schema/…

Also removes the docs site builds CI job and tests/docs_site_witness_test.py
(it witnessed the app that no longer exists), and the schema mirror's copy-sync
check. Net: −14,621 / +139.

Note on the raw URLs: they point at main, so they go live on merge. The
guard's "every advertised artifact exists at the path its URL names" check is
the offline proxy that proves the badge move and the URL edit stayed in sync —
it is exactly the check that would have caught this move going wrong.

Verification

  • New guard fails on main's four offenders, passes here (and passed in CI on
    the first commit).
  • schema/validate-examples.py exits 0.
  • .github/workflows/ci.yml parses; 18 jobs, no site.
  • No dangling site/ references outside deliberate historical prose.
  • No Rust touched.

Two things found in passing (not fixed here)

  1. main is redsdk (go|python|typescript) fail on
    provenance-fixture-consistency, a check Chore/backlog sweep 2026 07 #67 added that skips for the SDK
    example providers, and conformance-external.sh treats a skip as
    non-conformant by design. This PR inherits those three failures; they are not
    from this diff.
  2. The stray local Vercel link.vercel/ and site/.vercel/ in the
    maintainer's checkout still name the apex project; vercel --prod from there
    replaces the public apex. rm -rf .vercel site/.vercel clears it (my delete
    was permission-blocked). The new hygiene check fails locally until it's done.

Checklist

Registry submission

  • Not applicable — no registry row added or changed (the badge URL and the
    report's path are corrected; the listing itself is untouched)

Protocol-stability impact

  • Not applicable — no wire or spec change

…le (#57)

The Vercel project that owns contextgraphprotocol.org, cgp.oxagen.sh, and
context-graph-protocol.vercel.app is Git-connected to macanderson/cgp-website,
not to this repository. `site/` is built as a hard CI gate here and published
nowhere. Nothing in the build dereferences a URL, so the consequence shipped
silently: every absolute URL this repo advertises for one of its own artifacts
404s.

The sharpest case is the conformance badge. docs/registry.md and
docs/implementing-a-provider.md (plus their site/content/docs/ mirrors) tell
every provider that earns a registry row to paste
`https://cgp.oxagen.sh/badges/conformant.svg` into its README. That host serves
the microsite, which carries nothing under /badges/ — so the badge was broken
for everyone who followed the instruction, on a page whose own copy claims the
badge "never depends on this site's uptime". #58 hit the same wall from the
schema side and fixed `$id` alone; this generalises that fix.

- All four badge references now use this repo's GitHub-raw path, which GitHub
  serves as image/svg+xml and therefore renders in a third-party README.
- docs/adr/0008 records the verified topology (with the 2026-07-23 deploy
  timestamps that show the changeover), states the host boundary it implies,
  and leaves #57's remaining "port or retire site/" call to the maintainer with
  the evidence laid out — including that the protocol's prose now exists in
  three places, which is the drift ADR 0007 was written to end.
- .github/scripts/check-deploy-hygiene.py enforces two invariants offline, as a
  required CI check: no artifact URL on a host this repo does not deploy, and
  no checkout linked to the apex Vercel project (a `vercel --prod` from one
  replaces the public apex — that has happened, in both directions).
- The scaffold READMEs' homepage links move to the canonical apex, matching
  Cargo.toml's `homepage` and README.md.

Verified: the new guard fails on main's four offenders and passes after the
fix; schema/validate-examples.py green; docs-site witness green; `pnpm build`
in site/ exits 0.

Claude-Session: https://claude.ai/code/session_01KAUdWoz398UztsZ6aDqoXk
Signed-off-by: macanderson <mac@oxagen.sh>
@sourcery-ai

sourcery-ai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Reviewer's Guide

Fixes broken artifact URLs by pointing them at GitHub-raw, documents the deploy topology and URL rules in ADR 0008, and adds a Python-based CI guard to enforce that only served hosts are advertised and that no checkout is linked to the apex Vercel project, while aligning scaffold READMEs and schema commentary with the new rules.

Sequence diagram for CI deploy-hygiene check

sequenceDiagram
  participant GH as GitHubActions
  participant CI as deploy-hygiene_job
  participant Script as check-deploy-hygiene.py
  participant Git as git
  participant FS as filesystem

  GH->>CI: run job deploy-hygiene
  CI->>Script: python3 .github/scripts/check-deploy-hygiene.py

  Script->>Git: git ls-files -z
  Git-->>Script: tracked file list
  Script->>FS: read_text on tracked files
  Script-->>Script: extract ARTIFACT_URL matches
  Script->>FS: is_file for RAW_PREFIX targets
  Script-->>Script: missing artifact paths
  Script->>Git: git ls-files -- *.vercel/project.json .vercel/*
  Git-->>Script: committed Vercel link files
  Script->>FS: glob **/.vercel/project.json
  FS-->>Script: local Vercel project.json files
  Script->>Script: json.loads projectId

  Script-->>CI: exit 0 on PASS / 1 on FAIL
  CI-->>GH: report job status
Loading

File-Level Changes

Change Details Files
Conformance badge URL now resolves via this repo’s GitHub-raw path and related docs explain the host boundary. docs/registry.md
site/content/docs/registry.mdx
docs/implementing-a-provider.md
site/content/docs/implementing-a-provider.mdx
Deploy topology and artifact URL rules are captured as ADR 0008 and surfaced in contributor documentation. docs/adr/0008-deploy-topology-and-advertised-urls.md
CONTRIBUTING.md
New deploy-hygiene Python script and CI job enforce artifact URL host rules and prevent linking this repo to the apex Vercel project.
  • Introduced .github/scripts/check-deploy-hygiene.py to scan tracked text files for artifact URLs, ensuring they use allowed hosts and point to existing files, and to detect committed or local .vercel links to the apex project.
  • Defined SERVED_HOSTS allowlist and RAW_PREFIX constants, and excluded ADR and changelog paths from enforcement to preserve historical accuracy.
  • Added a deploy-hygiene job in .github/workflows/ci.yml that runs the Python script with Python 3.12 as a required CI check.
.github/scripts/check-deploy-hygiene.py
.github/workflows/ci.yml
Scaffolded provider READMEs now point to the canonical protocol homepage domain instead of cgp.oxagen.sh.
  • Updated the main create-contextgraph-provider README to use https://contextgraphprotocol.org as the protocol homepage URL.
  • Updated the Python and TypeScript template READMEs to use the canonical contextgraphprotocol.org homepage URL.
  • Aligned documentation with Cargo.toml’s homepage and ADR 0008’s distinction between artifact URLs and prose links.
sdk/create-contextgraph-provider/README.md
sdk/create-contextgraph-provider/templates/python/README.md
sdk/create-contextgraph-provider/templates/typescript/README.md
Schema validation commentary now treats the GitHub-raw $id choice as part of the general deploy-topology rule rather than a one-off workaround.
  • Extended comments in schema/validate-examples.py to reference ADR 0008 and explain that the GitHub-raw $id choice follows the repo’s host boundary rule.
  • Clarified that the script’s $id handling is “the schema’s half” of the deploy hygiene rule enforced globally by the new CI guard.
schema/validate-examples.py
Changelog documents the broken badge URL issue and the new guard as the fixed behavior under Unreleased. CHANGELOG.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

ADR 0008 posed the last open question on #57 — port the microsite's content
into `site/`, or retire `site/`. The decision is retire.

`site/` was a fumadocs/Next app built on every PR as a hard gate and deployed
nowhere. It held a second, hand-maintained copy of the prose in `docs/`, and
that copy had drifted stale rather than richer: protocol-surface.mdx still
documented `capabilities.upsert`/`.subscribe`/`.filters`/`.writes` — the dead
surface ADR 0004 removed — and changelog.mdx was 87 lines against CHANGELOG's
353. Four more pages were partial copies of root files with no docs/
counterpart. Deleting the app removes wrong documentation, not unique
documentation, and ends the three-copies-in-two-repos drift ADR 0007 exists to
prevent.

The two genuinely published artifacts move out of site/public/ first, to homes
that don't depend on an app:

- assets/badges/conformant.svg
- registry/contextgraph-example-docs.report.json

The third, site/public/schema/, was a byte-identical mirror of schema/ and is
simply gone, along with the copy-sync check that guarded it — the schema `$id`
already names the GitHub-raw source, and now permanently: with no site to
deploy, GitHub-raw is the only host this repo can honestly advertise.

- CI loses the `docs site builds` job; tests/docs_site_witness_test.py is
  deleted with the app it witnessed.
- ADR 0008 is Accepted, records the ratified decision and the evidence behind
  it, and states what would change if cgp-website ever serves these artifacts
  (one line: SERVED_HOSTS in the hygiene check).
- CONTRIBUTING gains "don't add another site" alongside the two existing rules.

Verified: deploy-hygiene guard green — including "every advertised artifact
exists at the path its URL names", which is what proves the badge move landed;
schema/validate-examples.py green; ci.yml parses with 18 jobs and no `site`;
no dangling `site/` references outside deliberate historical prose.

Claude-Session: https://claude.ai/code/session_01KAUdWoz398UztsZ6aDqoXk
Signed-off-by: macanderson <mac@oxagen.sh>
@macanderson macanderson changed the title fix(docs): make the URLs this repo hands out resolve, and gate the rule (#57) fix(docs+site): resolve the URLs this repo hands out, gate the rule, retire the undeployed site (#57) Jul 30, 2026
@macanderson
macanderson marked this pull request as ready for review July 30, 2026 04:07

@sourcery-ai sourcery-ai 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.

Sorry @macanderson, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@macanderson
macanderson merged commit 22168c7 into main Jul 30, 2026
15 of 18 checks passed
@macanderson
macanderson deleted the fix/deploy-topology-57 branch July 30, 2026 04:07
macanderson added a commit that referenced this pull request Jul 30, 2026
Resolves the conflicts on PR #69. Most of this branch had already landed on
main via #66 and #67, so the merge is mainly about keeping what is genuinely
new (#28, #21, #2) and taking main's side everywhere #68 made a decision.

Resolution rules applied:

- site/ is retired (ADR 0008, #68). All nine modify/delete conflicts under
  site/ take main's deletion; the branch's edits to the .mdx mirrors and to
  site/public/schema/ are dropped rather than resurrected. tests/
  docs_site_witness_test.py goes with it — it asserted the site mirrored the
  markdown docs.
- Advertised artifact URLs take main's rewrite: cgp.oxagen.sh/badges/... and
  site/public/... become the GitHub-raw paths that check-deploy-hygiene.py
  enforces. This covers the three SDK READMEs, docs/registry.md,
  docs/implementing-a-provider.md and the CHANGELOG entry for #20.
- The CGP abbreviation convention (#21) is kept where it does not collide with
  the above: docs/index.md, docs/composition-walkthrough.md, and the
  "CGP maintainers" cell in the registry table now sit on top of main's paths.
- .github/workflows/ci.yml: the branch's publish-dry-run job is dropped
  because main already carries it (via #66) — keeping both would have created
  a duplicate YAML job key. The branch's `site: docs site builds` job is
  dropped for the same reason site/ is; main's deploy-hygiene job stands.
- schema/validate-examples.py keeps the new lifecycle-record section (#28) —
  13 fixtures plus the detached attestation — with its site/public/schema/
  mirror checks removed, since there is no second copy to keep in sync.
- docs/profiles/context-exchange-provider.md LF2 is restated: the normative
  MUST was a byte-identical site/public/schema/ mirror enforced by a check
  that no longer exists. It now pins the $id to GitHub-raw per ADR 0008. This
  was in cleanly auto-merged text, so git did not flag it.

Net contribution over main after the merge is 34 files / +2,507: the Context
Exchange Provider lifecycle profile (#28), the CGP abbreviation pass (#21),
and the README CI badge (#2 partial).

Verified: cargo fmt --check, cargo test --workspace --all-features,
cargo clippy -D warnings, python3 schema/validate-examples.py (all examples
validate), python3 .github/scripts/check-deploy-hygiene.py (deploy hygiene
holds), and all relative links in 58 markdown files resolve.

Claude-Session: https://claude.ai/code/session_014H5SE4vnAP4Nw1MBMHfUpt
macanderson added a commit that referenced this pull request Jul 30, 2026
Resolves the conflicts on PR #69. Most of this branch had already landed on
main via #66 and #67, so the merge is mainly about keeping what is genuinely
new (#28, #21, #2) and taking main's side everywhere #68 made a decision.

Resolution rules applied:

- site/ is retired (ADR 0008, #68). All nine modify/delete conflicts under
  site/ take main's deletion; the branch's edits to the .mdx mirrors and to
  site/public/schema/ are dropped rather than resurrected. tests/
  docs_site_witness_test.py goes with it — it asserted the site mirrored the
  markdown docs.
- Advertised artifact URLs take main's rewrite: cgp.oxagen.sh/badges/... and
  site/public/... become the GitHub-raw paths that check-deploy-hygiene.py
  enforces. This covers the three SDK READMEs, docs/registry.md,
  docs/implementing-a-provider.md and the CHANGELOG entry for #20.
- The CGP abbreviation convention (#21) is kept where it does not collide with
  the above: docs/index.md, docs/composition-walkthrough.md, and the
  "CGP maintainers" cell in the registry table now sit on top of main's paths.
- .github/workflows/ci.yml: the branch's publish-dry-run job is dropped
  because main already carries it (via #66) — keeping both would have created
  a duplicate YAML job key. The branch's `site: docs site builds` job is
  dropped for the same reason site/ is; main's deploy-hygiene job stands.
- schema/validate-examples.py keeps the new lifecycle-record section (#28) —
  13 fixtures plus the detached attestation — with its site/public/schema/
  mirror checks removed, since there is no second copy to keep in sync.
- docs/profiles/context-exchange-provider.md LF2 is restated: the normative
  MUST was a byte-identical site/public/schema/ mirror enforced by a check
  that no longer exists. It now pins the $id to GitHub-raw per ADR 0008. This
  was in cleanly auto-merged text, so git did not flag it.

Net contribution over main after the merge is 34 files / +2,507: the Context
Exchange Provider lifecycle profile (#28), the CGP abbreviation pass (#21),
and the README CI badge (#2 partial).

Verified: cargo fmt --check, cargo test --workspace --all-features,
cargo clippy -D warnings, python3 schema/validate-examples.py (all examples
validate), python3 .github/scripts/check-deploy-hygiene.py (deploy hygiene
holds), and all relative links in 58 markdown files resolve.
macanderson added a commit that referenced this pull request Aug 1, 2026
…og, and backfill the gaps (#73)

CHANGELOG.md relied on every PR remembering to write its own [Unreleased]
entry. An audit of the 22 merges since v0.1.0 whose numbers never appear
in the file found 9 user-visible changes with no entry at all — including
the OCP -> CGP rename itself, the repo's biggest breaking change. The
Unreleased section had also accumulated duplicate category headings
(two '### Added', two '### Changed', two '### Fixed') from PRs appending
their own blocks.

Go-forward: .github/workflows/changelog.yml watches pushes to main. When
a merge lands without touching CHANGELOG.md, it drafts the missing
entries from the merge's actual diff (.github/scripts/changelog-ai.sh,
Vercel AI Gateway, degrade-open: no key or a failed call is a log line,
never a red check) and proposes them as a bot/changelog PR — a draft for
human review, never a direct push. The gap is measured from the last
commit that touched CHANGELOG.md, so merging the bot PR resets it, and
each run regenerates the whole current gap, so a superseded bot PR loses
nothing.

Backfill: entries for the rename (#1), frame identity/composition/usage
reports (#32), golden wire fixtures (#35), ADR 0007 (#61, #27),
composition conformance + the canary scheduled-run gate (#70) — written
from each PR's diff, in the file's existing voice. Three further audit
hits (#68, #69, #71) turned out to be already covered by newer entries
and were left alone. Duplicate category headings merged: one heading per
category, Keep-a-Changelog order.
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.

P0: Vercel deploy topology: the project is Git-linked to the wrong repo, so contextgraphprotocol.org can be silently overwritten

1 participant