Stage-03 spec: bootstrap var-go/oath enforcement in cad-atlas CI #1

Closed
opened 2026-07-19 10:13:25 +00:00 by mathias · 1 comment
Owner

Context

cad-atlas is dogfooded through the CAD workflow (see .context/PROJECT.md; brain: wiki/homelab/decisions/cad-atlas-audit-chain-is-viz-data.md). Phase A shipped — the static atlas is served at /. This issue bootstraps the enforcement tooth so every future cad-atlas PR is Oath-gated, closing the anti-rubber-stamp loop the atlas itself draws at stage 06.

Self-referential on purpose: the first Oath-governed task is making Oaths enforceable.

Scope

Wire cmd/vargo-gate (var-go, from mathias/swedsl) into .gitea/workflows/cd.yml as an oath job on pull_request: fetch this issue's Oath, run the gate, post commit status var-go/oath. Add branch protection requiring the status. Re-scoped (see decision below): branch protection split into #8, blocked on swedsl#27.

Risk: LOW

CI-only, no runtime/prod mutation. DMABE_GITEA_API_TOKEN was already provisioned as a Gitea Actions secret (2026-07-19, see docs/INCEPTION-OATH.md) — no secret-write needed to land this.

Acceptance criteria (ISC — binary)

  • An oath job exists in CI and runs on pull_request. Verified with a real throwaway PR (#7, closed without merge): job ran (actions/jobs/3796).
  • The job posts a commit status with context var-go/oath (success/failure). Verified: status id 8, context var-go/oath, "gate error: no var oath block in issue body (fail closed)" — correct v1 behavior for a PR not filed against its own oath issue.
  • A failing Oath blocks merge regardless of reviewer approval. Deliberately deferred → #8. cmd/vargo-gate's candidate is a hardcoded toy self-test registry, not a real PR-diff checker — it fails closed against every real oath (confirmed empirically above, and true even for THIS issue's own oath text). Requiring it in branch protection now would permanently block every cad-atlas PR. #8 tracks turning this on once swedsl ships a real-diff Executor (swedsl#27).
  • Self-test-candidate limitation disclosed in code doc + .context/PROJECT.md + CI config (honest-stub discipline). Also updated docs/INCEPTION-OATH.md S3.

Oath

When a pull request opens against cad-atlas
Then CI runs a job named "oath"
And the job posts a commit status with context "var-go/oath"
And a pull request whose oath fails cannot merge even if a reviewer approves

Note: per the AC re-scope above, the 3rd clause ("cannot merge even if a reviewer approves") is not yet mechanically true — tracked as #8. Stated here rather than silently glossed over.

Notes

  • Shipped in commit f7a0281 (2026-07-20).
  • Depends on var-go availability (mathias/swedsl, cmd/vargo-gate) + the Actions secret above — both satisfied.
  • Real enforcement (branch protection) tracked in #8, blocked on swedsl#27.
## Context cad-atlas is dogfooded through the CAD workflow (see [`.context/PROJECT.md`](../src/branch/main/.context/PROJECT.md); brain: `wiki/homelab/decisions/cad-atlas-audit-chain-is-viz-data.md`). Phase A shipped — the static atlas is served at `/`. This issue bootstraps the **enforcement tooth** so every future cad-atlas PR is Oath-gated, closing the anti-rubber-stamp loop the atlas itself draws at stage 06. Self-referential on purpose: **the first Oath-governed task is making Oaths enforceable.** ## Scope Wire `cmd/vargo-gate` (var-go, from `mathias/swedsl`) into `.gitea/workflows/cd.yml` as an `oath` job on `pull_request`: fetch this issue's Oath, run the gate, post commit status `var-go/oath`. ~~Add branch protection requiring the status.~~ **Re-scoped (see decision below): branch protection split into #8, blocked on swedsl#27.** ## Risk: LOW CI-only, no runtime/prod mutation. `DMABE_GITEA_API_TOKEN` was already provisioned as a Gitea Actions secret (2026-07-19, see `docs/INCEPTION-OATH.md`) — no secret-write needed to land this. ## Acceptance criteria (ISC — binary) - [x] An `oath` job exists in CI and runs on `pull_request`. Verified with a real throwaway PR (#7, closed without merge): job ran (`actions/jobs/3796`). - [x] The job posts a commit status with context `var-go/oath` (success/failure). Verified: status id 8, context `var-go/oath`, "gate error: no `var` oath block in issue body (fail closed)" — correct v1 behavior for a PR not filed against its own oath issue. - [ ] ~~A failing Oath blocks merge regardless of reviewer approval.~~ **Deliberately deferred → #8.** `cmd/vargo-gate`'s candidate is a hardcoded toy self-test registry, not a real PR-diff checker — it fails closed against every real oath (confirmed empirically above, and true even for THIS issue's own oath text). Requiring it in branch protection now would permanently block every cad-atlas PR. #8 tracks turning this on once swedsl ships a real-diff Executor (swedsl#27). - [x] Self-test-candidate limitation disclosed in code doc + `.context/PROJECT.md` + CI config (honest-stub discipline). Also updated `docs/INCEPTION-OATH.md` S3. ## Oath ```var When a pull request opens against cad-atlas Then CI runs a job named "oath" And the job posts a commit status with context "var-go/oath" And a pull request whose oath fails cannot merge even if a reviewer approves ``` Note: per the AC re-scope above, the 3rd clause ("cannot merge even if a reviewer approves") is not yet mechanically true — tracked as #8. Stated here rather than silently glossed over. ## Notes - Shipped in commit `f7a0281` (2026-07-20). - Depends on var-go availability (`mathias/swedsl`, `cmd/vargo-gate`) + the Actions secret above — both satisfied. - Real enforcement (branch protection) tracked in #8, blocked on swedsl#27.
Author
Owner

Deferred — this is the fast-follow for real Oath enforcement (Inception sprint S3 descoped here)

Measured var-go v1 before wiring; real enforcement of cad-atlas's own Oath is not achievable yet, for two reasons in mathias/swedsl:

  1. Candidate is a hardcoded self-test. selfTestCandidate() in oath/cmd/vargo-gate/main.go only registers the toy vocabulary "I add {int} and {int}" / "the total is {int}". A green var-go/oath status proves the mechanism ran, not that the PR satisfied its Oath. Real PR-diff verification needs an Executor (blocked on swedsl#27).
  2. Module not cross-repo consumable. oath/go.mod declares module swedsl/oath (not a git.d-ma.be/... path), so cad-atlas can't go install/import it — you'd clone swedsl and run in-tree, and even then hit (1).

So wiring now would post a status that gates a toy oath — meaningless for cad-atlas, and marking it "done" would make the Inception Oath a rubber stamp (the exact failure var-go exists to prevent). Per the honesty rule, S3 is descoped and tracked here, not claimed.

Prerequisites before this can land

  • swedsl#27 resolved: a real (non-toy) candidate/Executor turning a PR diff into a step registry
  • oath published as a cross-repo-consumable module (proper module path), or an installable vargo-gate binary/Action
  • then: add the oath job to .gitea/workflows/cd.yml (fetch → gate → post var-go/oath), require it in branch protection

Pre-provisioned: the DMABE_GITEA_API_TOKEN Actions secret is already set on this repo, so landing this needs no secret-write.

Ref: docs/INCEPTION-OATH.md (S3), brain wiki/homelab/decisions/inception-sprint-and-oath.md.

## Deferred — this is the fast-follow for real Oath enforcement (Inception sprint S3 descoped here) Measured var-go v1 before wiring; real enforcement of cad-atlas's own Oath is **not achievable yet**, for two reasons in `mathias/swedsl`: 1. **Candidate is a hardcoded self-test.** `selfTestCandidate()` in `oath/cmd/vargo-gate/main.go` only registers the toy vocabulary `"I add {int} and {int}"` / `"the total is {int}"`. A green `var-go/oath` status proves the *mechanism ran*, not that the PR satisfied its Oath. Real PR-diff verification needs an Executor (blocked on swedsl#27). 2. **Module not cross-repo consumable.** `oath/go.mod` declares `module swedsl/oath` (not a `git.d-ma.be/...` path), so cad-atlas can't `go install`/import it — you'd clone swedsl and run in-tree, and even then hit (1). So wiring now would post a status that gates a toy oath — meaningless for cad-atlas, and marking it "done" would make the Inception Oath a rubber stamp (the exact failure var-go exists to prevent). Per the honesty rule, **S3 is descoped and tracked here**, not claimed. ### Prerequisites before this can land - [ ] swedsl#27 resolved: a real (non-toy) candidate/Executor turning a PR diff into a step registry - [ ] `oath` published as a cross-repo-consumable module (proper module path), or an installable `vargo-gate` binary/Action - [ ] then: add the `oath` job to `.gitea/workflows/cd.yml` (fetch → gate → post `var-go/oath`), require it in branch protection **Pre-provisioned:** the `DMABE_GITEA_API_TOKEN` Actions secret is already set on this repo, so landing this needs no secret-write. Ref: `docs/INCEPTION-OATH.md` (S3), brain `wiki/homelab/decisions/inception-sprint-and-oath.md`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mathias/cad-atlas#1