docs: CHANGELOG + REPORT for the CI workflow (no version bump)
gates / gates (push) Successful in 9s
gates / gates (push) Successful in 9s
This commit is contained in:
@@ -1,5 +1,34 @@
|
|||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
### CI — the gate entry point runs on every push (2026-08-02, R-168) — NO VERSION BUMP
|
||||||
|
|
||||||
|
**No version bump, no build, no deploy** — this adds a workflow file only. Stated explicitly so the
|
||||||
|
omission reads as a decision rather than a miss.
|
||||||
|
|
||||||
|
**`.gitea/workflows/gates.yml` (new).** Triggers on `push`, `runs-on: felhom-gates`, obtains the
|
||||||
|
source with a shallow `git fetch` of the **exact pushed SHA** from the in-cluster Gitea Service, and
|
||||||
|
runs this repo's entry point with `--fast` — nothing else. **No `uses:` step anywhere**: JavaScript
|
||||||
|
actions need a node runtime the host-mode runner does not have, and probe P3 measured a plain
|
||||||
|
`git fetch` as sufficient. No `|| true`; the entry point's exit code IS the job's result.
|
||||||
|
|
||||||
|
**It REPORTS, it cannot REFUSE**, and the workflow header says so: this repo pushes straight to
|
||||||
|
`main` with no pull request, so there is no merge for a status check to stand at. The refusing half
|
||||||
|
is `.githooks/pre-push`, which is per-clone and `--no-verify`-able; this half notices when that was
|
||||||
|
skipped. Making CI blocking needs branch protection plus a PR workflow → felhom.eu `OPEN-ITEMS.md`
|
||||||
|
R-169, an operator decision.
|
||||||
|
|
||||||
|
**A failed run emails the operator** via Resend and prints the provider's accepted id, because probe
|
||||||
|
P5 measured that Gitea itself sends nothing at all on a failed run. Demonstrated end to end on a real
|
||||||
|
red run (`RESEND-ACCEPTED id=…`), not assumed. Full detail:
|
||||||
|
`felhom.eu/documentation/audits/SPIKE-ci-runner-2026-08-02.md`.
|
||||||
|
|
||||||
|
**CI reproduces the workspace's SIBLING LAYOUT on purpose.** This repo's entry point invokes the
|
||||||
|
shared `reuse_refs_check.py` that lives in the `felhom.eu` clone next door and is deliberately never
|
||||||
|
copied here, and this repo's `REUSE.md` cites `wgsync/reconciler.go`, which lives in the hub. The workflow
|
||||||
|
therefore clones `felhom.eu` as a sibling; without it the gate fails **closed** with
|
||||||
|
`gate is MISSING` — correctly, but for the wrong reason. Verified that CI and the local hook then
|
||||||
|
agree exactly: 133 cited paths, 126 exact / 6 suffix / 1 cross-repo, 0 failures.
|
||||||
|
|
||||||
### Gate enforcement — one entry point + pre-push hook (2026-08-02) — NO VERSION BUMP
|
### Gate enforcement — one entry point + pre-push hook (2026-08-02) — NO VERSION BUMP
|
||||||
|
|
||||||
**Deliberately no version bump, and no build or deploy.** Nothing compiled changed: this touches
|
**Deliberately no version bump, and no build or deploy.** Nothing compiled changed: this touches
|
||||||
|
|||||||
@@ -1,85 +1,41 @@
|
|||||||
# REPORT — gate enforcement: the `-v` allowlist, one entry point, a pre-push hook (2026-08-02)
|
# REPORT — CI runs the gate entry point on every push (R-168, 2026-08-02)
|
||||||
|
|
||||||
**Overwritten** per the standing rule. The prior contents (D5, controller v0.188.0, 2026-07-30) have
|
**Overwritten** per the standing rule. The prior contents (session 1's gate enforcement, same day) have their durable record in `CHANGELOG.md`.
|
||||||
their durable record in `CHANGELOG.md`; nothing was lost by this overwrite.
|
|
||||||
|
|
||||||
**No version bump, no image build, no deploy.** Nothing compiled changed — this touches
|
**No version bump, no build, no deploy.** This adds `.gitea/workflows/gates.yml` and a CHANGELOG
|
||||||
`controller/scripts/` and `.githooks/` only, so no behaviour on any box moved. Stated explicitly so
|
entry. Nothing compiled changed.
|
||||||
the omission reads as a decision rather than a miss. Controller stays **v0.188.0**; guest 9201 was
|
|
||||||
not touched.
|
|
||||||
|
|
||||||
## What changed
|
## What changed
|
||||||
|
|
||||||
| Commit | What |
|
`.gitea/workflows/gates.yml` — on every push, a Gitea Actions runner obtains this repo at the
|
||||||
|---|---|
|
**exact pushed SHA** (shallow `git fetch`, no `uses:` step anywhere) and runs
|
||||||
| `c432f70` | **the ALLOWLIST entry, alone in its own reviewed diff** |
|
`python3 scripts/controller_gates.py --fast` and nothing else. The exit code is the job's result: no `|| true`, no
|
||||||
| `8cb3d7a` | `controller/scripts/controller_gates.py` + `controller/scripts/test_controller_gates.py` + `.githooks/pre-push` + `CLAUDE.md` |
|
pipe that could swallow it.
|
||||||
| `7c32c74` | `CHANGELOG.md` + `controller/README.md` |
|
|
||||||
|
|
||||||
Baseline on arrival: `4115e88f688b`, clean, `HEAD == origin/main` — matched the spec's anchor.
|
**It REPORTS, it cannot REFUSE**, and the workflow header says so in the pre-push hook's voice: this
|
||||||
|
repo pushes straight to `main` with no pull request, so there is no merge for a status check to stand
|
||||||
|
at. The refusing half is `.githooks/pre-push` (per-clone, `--no-verify`-able); this half notices when
|
||||||
|
that was skipped. Making CI blocking needs branch protection plus a PR workflow — an operator
|
||||||
|
decision, tracked as `felhom.eu` `OPEN-ITEMS.md` **R-169**.
|
||||||
|
|
||||||
### 1. `docker_run_volume_path_gate.py` — one allowlist entry (R-29 leg (a), now CLOSED)
|
**A failed run emails the operator.** Probe P5 measured that Gitea itself sends **nothing** on a
|
||||||
|
failed run — no mail, no notification row, no log line — so the workflow sends its own via Resend and
|
||||||
|
prints the provider's accepted id, making "a message left the machine" an observable. Demonstrated on
|
||||||
|
a real red run in `felhom.eu`: `RESEND-ACCEPTED id=5ff34766-c5f8-4588-8104-08296aeb45ab`.
|
||||||
|
|
||||||
The gate was **RED**, flagging `internal/appexport/estimate.go:179`. The finding is benign and was
|
**CI reproduces the workspace's SIBLING LAYOUT on purpose.** This repo's entry point invokes the
|
||||||
reviewed rather than suppressed: `realVolumeSize` mounts a **named Docker volume** read-only into a
|
shared `reuse_refs_check.py` that lives in the `felhom.eu` clone next door and is deliberately never
|
||||||
throwaway `alpine` to `du` it from a container view. No host path is involved — the daemon resolves
|
copied here, and this repo's `REUSE.md` cites `wgsync/reconciler.go`, which lives in the hub. The workflow clones
|
||||||
the volume name daemon-side — which makes it structurally identical to the already-allowlisted
|
`felhom.eu` as a sibling; without it the gate fails **closed** with `gate is MISSING` — correctly,
|
||||||
`internal/backup/backup.go` entry `'"-v", volName+":/vol:ro"'`. The entry carries its WHY in the
|
but for the wrong reason.
|
||||||
voice of its neighbours.
|
|
||||||
|
|
||||||
`realVolumeSize` was **not** rewritten: the code is correct, the allowlist was incomplete. The diff
|
|
||||||
is alone in its commit because burying an allowlist widening inside a feature commit is how an
|
|
||||||
allowlist stops meaning anything.
|
|
||||||
|
|
||||||
**Red-proof:** renaming the new entry's suffix to a non-existent file returns the gate to **exit 1**,
|
|
||||||
naming `estimate.go:179`; restored → **exit 0**.
|
|
||||||
|
|
||||||
### 2. `controller_gates.py` — THE entry point
|
|
||||||
|
|
||||||
Runs all seven local gates plus `reuse_refs_check` on the repo root, streams each gate's own output,
|
|
||||||
exits worst-wins non-zero, and reports exit 2 distinctly as INCONCLUSIVE. `--fast` selects the gates
|
|
||||||
that touch no network and no container runtime — today all eight. **A missing gate script is a
|
|
||||||
FAILURE with the path printed, never a skip.**
|
|
||||||
|
|
||||||
Why a runner at all: the 2026-08-02 census across the four repos found that **every gate a
|
|
||||||
`CLAUDE.md` names was green, and the ones nobody names were where the red was.** This repo had seven
|
|
||||||
gates and `CLAUDE.md` named two; four more lived behind a line in `REUSE.md`, and the docker-`-v`
|
|
||||||
gate behind one line in `REUSE.md` — while red. The canonical shape is
|
|
||||||
`app-catalog-felhom.eu/scripts/catalog_gates.py` (R-161).
|
|
||||||
|
|
||||||
**The shared checker is never copied here.** `reuse_refs_check.py` stays in `felhom.eu/scripts/` and
|
|
||||||
is invoked at `<repo-root>/../felhom.eu/scripts/`; a copy would recreate exactly the drift it detects.
|
|
||||||
It now resolves this repo's REUSE map cleanly: **133 cited paths — 126 exact, 6 by suffix, 1
|
|
||||||
cross-repo** (`wgsync/reconciler.go`, which lives in the hub), 0 failures.
|
|
||||||
|
|
||||||
### 3. `.githooks/pre-push`
|
|
||||||
|
|
||||||
Runs `controller_gates.py --fast` and refuses the push. It prints a line before and after, because an
|
|
||||||
absent log line is not evidence a hook ran. Its limits are written into the hook itself: **per-clone**
|
|
||||||
(`core.hooksPath` is local config; this clone is armed — `git config --get core.hooksPath` →
|
|
||||||
`.githooks`) and **`git push --no-verify` bypasses it on purpose**, which must be stated in a session
|
|
||||||
report when used. It was **not** used against this repo; both real pushes ran the hook and passed.
|
|
||||||
|
|
||||||
### 4. `test_controller_gates.py` — a seam test, not a smoke test
|
|
||||||
|
|
||||||
Asserts each member gate's **own distinctive stdout**, never the runner's summary line, which an
|
|
||||||
inert runner prints while calling nothing. **Red-proof:** replacing `run_gate`'s body with `return 0`
|
|
||||||
still prints `all controller gates OK` and exits 0 — and turns the seam test red. It also pins that
|
|
||||||
`reuse_refs_check.py` has not been copied into this repo.
|
|
||||||
|
|
||||||
## Verification
|
## Verification
|
||||||
|
|
||||||
```
|
First run: run #1, id=8, conclusion **success**, sha `dcc400e1`.
|
||||||
template-id OK (exit 0) app-row-dedup OK (exit 0)
|
|
||||||
emoji OK (exit 0) mojibake OK (exit 0)
|
|
||||||
native-confirm OK (exit 0) docker-v OK (exit 0)
|
|
||||||
offbox-rename OK (exit 0) reuse-refs OK (exit 0)
|
|
||||||
|
|
||||||
all controller gates OK
|
**CI and the local pre-push hook AGREE**, which is the check that mattered: `133 cited paths — exact 126, suffix 6, ambiguous 0, cross-repo 1, FAILED 0 (siblings searched: felhom.eu)` — identical to the local run.
|
||||||
```
|
|
||||||
|
|
||||||
`python3 scripts/test_controller_gates.py` → **4 tests, OK** (0 before). No Go test count changed; no
|
The runner is unprivileged host-mode, shared with the other three repos on a single owner-scoped
|
||||||
Go file was touched.
|
registration (measured: all four repos' tasks claimed by `felhom-gates-runner`). Full probe detail,
|
||||||
|
the security posture and the teardown: `felhom.eu/documentation/audits/SPIKE-ci-runner-2026-08-02.md`
|
||||||
Full cross-repo detail, every red-proof, the `core.hooksPath` probe measurements and the hub
|
and `felhom.eu/REPORT.md`.
|
||||||
deployment: `felhom.eu/REPORT.md`.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user