Work Done
Added this knowledge repo as a second top-level section of the VIRDX docs site
(mono/apps/docs, Astro + @cloudflare/nimbus-docs), synced at build time —
PR mono#305, branch
feat/docs-knowledge-section. Docusaurus/Mintlify split: a horizontal tab strip
for the top level, left sidebar scoped one level below.
apps/docs/bin/sync-knowledge.tsnormalizes this repo into Nimbus’s strictdocscontent collection: frontmatter reduced totitle/description(+sidebar.order), H1 stripped (Nimbus renders the title from frontmatter), relative*.mdlinks rewritten to extensionless site URLs. Publisheswiki/andinbox/only.- Product docs moved under
/documentation/*soDocumentationandKnowledgeare the two tabs;/inferenceand/vxdata-apiredirect. Sidebar collapsed by default, and “Edit this page” suppressed on mirrored pages. llms.txtnow renders the full page tree rather than a flat list.sources/is deliberately not published (legacy, superseded bywiki/). Links fromwiki/into it resolve to GitHub blob URLs instead of dead site routes — 15 such links existed.
The interesting half was the build. docs became the first image built from two repos, and knowledge changes far more often than mono does, so nothing in mono’s history moves when the content does.
Settled on: apps/docs/Containerfile does an unconditional COPY .knowledge/
and the sync reads it via KNOWLEDGE_PATH, so no git credentials go inside the
image build; whoever builds supplies the checkout. GitHub Actions (Cloudflare
Pages) does it with actions/create-github-app-token@v2 against the existing
org App — no new secret. For the cluster image,
apps/docs/deployments/build.sh now submits an inline pipelineSpec that
clones both repos, referencing the existing git-clone, check-image and
buildkit-build Tasks unchanged.
Detour worth recording: I first put that recipe in infra_k8s as a
docs-image Pipeline plus a nightly CronJob
(infra_k8s#174, closed).
Inlining it in build.sh needs zero cluster-side changes and puts the
recipe next to the COPY .knowledge/ that is its only reason to exist. Nightly
rebuilds were dropped; the Cloudflare deploy already refreshes nightly.
Verified with a real build, verify-docs-image-qj4vd, succeeded 4/4:
mono@8213fc81 + knowledge@7b1108a8 -> check-image exists=false,
tag 45aabe8b046a -> pushed zot.fra.virdx.dev:5000/docs:45aabe8b046a
(build/archive/sign all exit 0). additional-tags was blanked so :latest did
not move and nothing redeployed.
Lessons Learned: Pitfalls
sops/executing-jobs-on-the-cluster.mdis wrong about PipelineRun submission. It says abuildkit-imagePipelineRun “needs ashared-workspacevolumeClaimTemplate (e.g. 200Gi, storageClassNamelvm) and labelsvirdx.dev/requestor+virdx.dev/username”. In reality the Kyverno ClusterPolicytekton-mutate-pipelineruninjects all of it —spec.workspaces,spec.taskRunTemplate.serviceAccountName: tekton-build-sa, and both labels — on every CREATE intekton-builds. You cannot usefully set the labels yourself: the patch is JSON Patchop: add, which replaces. This cost real time: I concludeddeployments/build.shwas broken for missingserviceAccountNameand workspaces and told the user so, which was wrong. Confirmed by server dry-run showing both injected.check-imagemakes builds idempotent on a tag derived from exactly ONE repo’s commit —sha256({commit,context,dockerfile,project[,imageRepository]})[:12]— andbuildruns onlywhen exists == false. Nothing documents this, and it is the central trap for any multi-input image: a knowledge-only change produces no new image, so a naive nightly cron is a silent no-op. Fix is to feed a compositecommit(<mono-sha>-<knowledge-sha>); the tag then moves when either input does, and still short-circuits when neither did.- A ServiceAccount cannot create a PipelineRun in
tekton-buildsat all.inject-requestorbuildsvirdx.dev/requestorviareplace_all(username, '.', '-'). A SA username issystem:serviceaccount:<ns>:<name>— no dots, and colons are illegal in a label value, so the API server rejects the object. Reproduced live. Every PipelineRun in the cluster was created by a human OIDC user, and Tekton Triggers is installed (v0.36.0) with no EventListener using it — this is almost certainly why. One-line fix: strip the SA prefix before the dot swap, as the siblingvirdx.dev/usernamerule already does. git-clonehardcodes its destination as/workspace/source/repo, so two invocations collide. Any second checkout has to be an inline step, unless you change a Task every build in the cluster depends on.sources/reads as current but is legacy.index.mddescribes it neutrally as “any supplementary material” with no staleness marker, and it still holds the guide an agent would reach for on image builds. Onlyargo-buildah-image-builds.mdcarries a superseded banner.- Nine
sources/monthly-reports/*.mdfiles open at##with no H1. Cosmetic inside this repo; not cosmetic once published, since the sync falls back to the filename and rendered titles like01 2026_diffsim. They are unpublished today only becausesources/is excluded. bun run builddoes not catch broken internal links — onlybun run lint:docsdoes, and it covers.mdxonly. Knowledge pages are.md(plain markdown avoids MDX parse errors on the<placeholder>and{brace}syntax these notes are full of), so they are never link-linted. Moving the product docs to/documentation/*broke 17 links that the build reported as green.
Lessons Learned: Improvements
- Correct and extend
sops/executing-jobs-on-the-cluster.md— highest-value change. Replace the “PipelineRun needs workspaces + labels” claim with “Kyverno injectstaskRunTemplate.serviceAccountName,spec.workspaces(200Gilvm) and both identity labels; submit neither”. Then add:- the
check-imagetag formula and thewhen exists == falseshort-circuit, plus the composite-committrick for multi-input images; - that a ServiceAccount cannot submit a PipelineRun today, and the one-line policy fix that would change it (blocks all build automation, including the dormant Triggers install);
- that a PipelineRun may carry an inline
pipelineSpec, so a one-off recipe needs nothing deployed toinfra_k8s— worth stating, since the instinct is to add a Pipeline; - that
git-clonehardcodes/workspace/source/repo.
- the
- Add a short “docs site” SOP under
wiki/workstreams/infrastructure/sops/: two surfaces (docs.virdx.devvia Cloudflare Pages,docs.fra.virdx.devvia the cluster image, both behind Cloudflare Access, including*.pages.devpreviews), that this repo is mirrored in at build time and how, and the rule that content stays here because agents commit here freely while mono is review-gated. Would have removed most of the discovery in this session. - Mark
sources/as legacy inindex.md— one clause, e.g. “legacy, superseded bywiki/; not published to the docs site”. Prevents an agent reaching for a stale guide, and now also signals what does and does not reach readers. - Give the nine monthly reports an H1 matching their filename, so published titles are authored rather than slug-derived.
- Record that
github-patis a fine-grained PAT on a personal account (AlexLeakeQC), in the secrets list of the cluster SOP. Every Tekton build clones through one engineer’s credential, so an offboarding or rotation breaks all builds at once. Verified it can read this repo. Belongs next to the existingrattler-credentials/zot-registry-credentialsnotes, ideally with a follow-up to move it to a machine identity. - Note in the docs SOP that only
.mdxis link-linted, so a.mdpage’s links must be checked againstdist/by hand.