The knowledge base — publishing the docs
Audience: developers & AI agents · Scope: the published site at kb.betacalco.com — what it is, how content flows there, and the two deploy channels that must stay separate · Last reviewed: 2026-08-27
TL;DR — Everything under docs/ and admin-guide/ is published as a searchable site at
https://kb.betacalco.com, with a docs assistant and an MCP endpoint on top. It is built by a
separate repo (beta-calco/documentation) from the GitHub mirror of this one, and it deploys
through a separate channel from the website: publishing docs never deploys code, and deploying
code never publishes docs. To publish docs now: tools/kb-publish.sh.
Two channels, on purpose
| The website | The knowledge base | |
|---|---|---|
| What | docroot/ — the Joomla/ConfigBox site | docs/ + admin-guide/ rendered by Docusaurus |
| Source of truth | branches for_live / for_staging on the bare SSH repos | branch master on the GitHub mirror beta-calco/betacalco-site |
| Trigger | git push live master:for_live (post-receive hook rsyncs docroot/) | tools/kb-publish.sh, a daily sync, or a push to the mirror (see below) |
| Where it runs | the live/staging EC2 servers | AWS account 770497312327, us-east-1: S3 + CloudFront + one Lambda |
| Doc | configbox/environment.md | this page, and DEPLOYING.md in the KB repo |
A future CI/CD pipeline for the website belongs on the left column and changes nothing on the right.
How a doc gets to the site
docs/, admin-guide/ on master
│ git push github master ← tools/kb-publish.sh step 1 (nothing deploys from the mirror)
▼
beta-calco/betacalco-site (GitHub mirror)
│ workflow_dispatch (ref=<sha>) ← step 2; also: daily 06:00 UTC, or .github/workflows/kb-publish.yml
▼
beta-calco/documentation · .github/workflows/deploy.yml
├─ build: sync the two trees from the mirror → rewrite links → Docusaurus build
├─ deploy: S3 sync + CloudFront invalidation → https://kb.betacalco.com
└─ publish-mcp: arm64 image → ECR → Lambda → /mcp (MCP server) and /chat (assistant)
The sync (scripts/sync-docs.mjs in the KB repo) is where the repo-shaped docs become site-shaped:
- Relative links between docs stay relative; links across the two trees become site routes.
- Links into code (
docroot/…,tools/…) become GitHub URLs — there is no page for them. _-prefixed planning docs (_known-issues.md,_todo.md) are not published; links to them become GitHub URLs too, so a doc may cite a known issue without breaking the build..htmlcompanion pages are served from the site'sstatic/at the same path.- Frontmatter is completed, never overwritten: every page gets a
titleand a "View source" link.
The build runs with onBrokenLinks: throw: a link that resolves in the repo but not on the site fails
the run, and the site keeps serving the previous build. gh run view <id> --repo beta-calco/documentation --log-failed
lists exactly which links.
Publishing
Now: commit, then
tools/kb-publish.sh # push master to the mirror, build + deploy that commit, wait, print the URL
tools/kb-publish.sh --no-wait # same, don't wait
tools/kb-publish.sh --dry-run # show what would happen
It refuses to run off master or with uncommitted changes under docs//admin-guide/, and needs only
the github remote and a logged-in gh. The push carries the whole of master (code included) to the
private mirror — that is what the mirror is for; nothing deploys from it.
Automatically: .github/workflows/kb-publish.yml runs on the
mirror on every push to master that touches docs/** or admin-guide/** and dispatches the KB build for
that commit. It needs one secret on the mirror repo, KB_DISPATCH_TOKEN (fine-grained PAT, Actions:
read & write on beta-calco/documentation, nothing else); until that exists it exits with a notice.
Fallback: the KB syncs the mirror every day at 06:00 UTC regardless.
What is on the site
- Both trees, as two sidebars: Developer Docs (
docs/) and Admin Guide (admin-guide/). - The docs assistant (right rail, "Ask the docs"): grounded answers with citations, over the same
corpus, via
/chat(streaming) on the Lambda. Its model key lives in Secrets Manager, not in any repo. - The MCP endpoint at
https://kb.betacalco.com/mcpfor tools that want to search the docs; it needs a bearer token (MCP_API_TOKENSin the same secret). - The site is public-by-obscurity: no login,
X-Robots-Tag: noindex. Deciding on real access control is an open item in the KB repo'sTODO.md.
Where the pieces live
| Piece | Where |
|---|---|
| Site source, sync script, Terraform, workflow, runbook | ~/PhpstormProjects/betacalco-docs · GitHub beta-calco/documentation (main) |
| Go-live runbook, account facts, the gotchas met on the way | DEPLOYING.md in that repo |
| Infrastructure | Terraform in infra/ — S3 betacalco-docs-prod-site, CloudFront E1X9Q25CGD6GPB, Lambda betacalco-docs-prod-mcp, ECR, the GitHub-OIDC deploy role; DNS record in the betacalco.com zone (account 752918619438) |
| Credentials the pipeline reads | GitHub secrets on beta-calco/documentation: DOCS_SOURCE_TOKEN (reads this repo), AWS_DEPLOY_ROLE_ARN; runtime keys in AWS Secrets Manager |
Related
- configbox/environment.md — the website's deploy path (
for_live, the post-receive hook) - standards/ — how the docs are written; the site renders exactly what the standards describe
tools/kb-publish.sh·.github/workflows/kb-publish.yml