feat(oath): gate cad-atlas's own real candidate, not swedsl's toy stub (#8)
CD / Detect unsubstituted template (push) Successful in 0s
CD / Lint / Test / Vet (push) Successful in 5s
CD / var-go/oath (push) Has been skipped
CD / Build & Import (push) Successful in 14s
CD / Deploy via GitOps (push) Successful in 1s

oathcandidate/ is a separate Go module (mirrors swedsl's own
oath/testdata/selfcandidate pattern, keeping var-go's transitive deps
out of the deployed atlas binary) whose Build() parses the committed
.gitea/workflows/cd.yml and checks the "oath" job exists and invokes
cmd/vargo-gate. TDD: passes against the real file, fails closed on a
fixture missing the job.

Rewires the oath CI job to go-run vargo-gate from its real module path
(git.d-ma.be/mathias/swedsl/oath/cmd/vargo-gate@oath/v0.28.0, unblocked
by swedsl#35/#38) against VARGO_CANDIDATE_DIR=oathcandidate, instead of
checking out swedsl and gating its hardcoded toy fixture. Private-module
auth via a short-lived GIT_ASKPASS script (token never in argv, never
written to git config, matches act_runner's env:-block-with-secrets
gotcha).

Discovered along the way: var-go's parser needs single-line,
period-separated oath sentences with no Given/When/Then/And keyword
stripping — this repo's older oaths (incl. #1) used an unverified
multi-line keyword-prefixed style. #8's oath uses the proven format.

Still not required by branch protection pending a real-PR confirmation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-20 14:33:17 +02:00
co-authored by Claude Sonnet 5
parent 346037c5c8
commit 805b76d7c3
7 changed files with 288 additions and 41 deletions
+11 -6
View File
@@ -4,8 +4,9 @@ The acceptance contract for standing up cad-atlas. The sprint is finalized only
Oath holds. Methodology: brain `wiki/homelab/decisions/inception-sprint-and-oath.md`.
> **Status of enforcement:** this Oath is currently **advisory** (human-verified). `var-go/oath`
> is wired (issue #1) and runs on every PR, but its candidate is a toy self-test — it fails closed
> against any real oath and is not required by branch protection. See the honesty rule below.
> gates a real candidate now (`oathcandidate/`, #8 — parses the committed CI workflow, TDD'd
> pass/fail-closed) but isn't yet required by branch protection pending a real-PR confirmation.
> See the honesty rule below.
## General clauses (any inception sprint)
@@ -25,7 +26,7 @@ Oath holds. Methodology: brain `wiki/homelab/decisions/inception-sprint-and-oath
|---|--------|--------|----------|
| S1 | Atlas served at `/`, renders all 9 stages signal→pod | ✅ | `internal/web/handler.go` + `static/cad-atlas.html` |
| S2 | Oath covered in the viz (stages 03 + 06) | ✅ | var-go Oath nodes in the atlas |
| S3 | `var-go/oath` enforces cad-atlas's own PRs | ⏸ **wired, not enforcing → #8** | `oath` job runs + posts status (#1, verified with a real PR). Not branch-protection-required: candidate is still swedsl's toy self-test, fails closed on every real oath. Blocked on `swedsl/oath` import path (swedsl#35) → cad-atlas writing its own candidate (#8). Not blocked on an Executor — that path was killed by swedsl's ADR-0002. See honesty rule. |
| S3 | `var-go/oath` enforces cad-atlas's own PRs | ⏸ **real candidate wired, not enforcing → #8** | `oathcandidate/` gates the real `.gitea/workflows/cd.yml` (TDD green: passes real file, fails closed on a fixture missing the job) via swedsl's sandboxed `SubprocessGate` (swedsl#35/#38). Not yet branch-protection-required — awaiting confirmation on a real PR. See honesty rule. |
## Deployment
@@ -38,9 +39,13 @@ namespace `cad-atlas`, 1 replica, `cad-atlas:80 → :8080` (manifests in `mathia
A clause blocked by an external dependency is **descoped and tracked, never marked satisfied**
a self-lying Oath is a rubber stamp, the exact failure the Oath exists to prevent. S3's real
enforcement depends on `swedsl/oath` becoming importable (swedsl#35) and cad-atlas writing its own
candidate (#8); it is tracked there, not claimed here. The `DMABE_GITEA_API_TOKEN` Actions secret
is pre-provisioned so #1 landed without a secret-write.
candidate is wired (#8) but branch-protection enforcement waits on a real-PR confirmation, tracked
there, not claimed here. The `DMABE_GITEA_API_TOKEN` Actions secret is pre-provisioned so #1 and
#8 both landed without a secret-write.
Also surfaced by #8: this file's own "Oath (advisory form)" below predates the discovery that
var-go's parser requires single-line, period-separated sentences with no `Given`/`Then`/`And`
keyword stripping — it has never been machine-gated and would need reformatting first if it ever is.
## The Oath (advisory form)