docs: document the live Gitea Actions gate and deterministic-gen convention
gates / consistency-and-conventions (push) Successful in 43s

CI is now live (act_runner on the Gitea host), so the docs stop saying a
runner 'needs to be registered' and record how the gate works:
- AGENTS.md: CI bullet now notes the live runner, red run = merge-blocker,
  and the byte-order deterministic generator rule (LC_ALL=C, learned when the
  CI container's locale reordered the category-less pos-config/pos-tree keys
  and the gen-drift gate caught it).
- DEV.md: definition-of-done mentions the live CI re-run; new 'CI: Gitea
  Actions Gate' section (runner location, CONFIG_FILE run.sh gotcha,
  --add-host pin, one-time tokens, runnerv1 status enum 1=success/2=failure,
  deterministic-generator convention, static-only limits).
- AGENT_Context step 7: pushing re-runs the gates, red run blocks.
- AGENT_TODO: dropped a duplicated 'gate added' Done entry and fixed its
  stale 'runner pending' phrasing.
This commit is contained in:
he
2026-08-14 16:08:09 -04:00
parent b507d17e3d
commit 59e6c3530b
4 changed files with 38 additions and 7 deletions
+1 -1
View File
@@ -530,7 +530,7 @@ System-wide flag store at `/usr/local/share/linux_post_install/flags/`:
4. Add system deps to `PACKAGES` array in `preinstall.sh` (if needed); non-apt/manual installers → `command -v` guard in the tool instead
5. Add config logic to `postinstall.sh` (if needed, with `.gitignore` for secrets); runtime tool config → `~/.config/linux_post_install/<tool>.env` (600)
6. Update docs: `DOC/POS.md` (section table + detail — hand-written); `DOC/HOWTO.md` index row + a section in `DOC/howto/<category>.md` (recipes/troubleshooting); `DOC/AGENT_Context_Project.md` generated sections (bin tree, dispatch table, self-contained list, line-count table) and completion flags update via `make gen` — never hand-edit between `GEN:START`/`GEN:END` markers, but hand-add a row to the "Common Tasks for Agents" table; `AGENTS.md` Quick facts if a structural fact changed; root `README.md` only if the category list changes; move the task to `AGENT_TODO.md` Done (dated) in the same commit
7. Test: `make gen && make check && make lint``make check` (bash -n + doc/code sync + smoke) and `make lint` (0 FAIL / 0 WARN, `scripts/lint-conventions.sh`) together are the definition of done; also `bin/pos help <full command> && bin/pos <category> --help`. For tools needing root/systemd/absent deps, behaviour-test via env-override paths + stub PATH (see DEV.md "Testing tools that need root / systemd / missing deps")
7. Test: `make gen && make check && make lint``make check` (bash -n + doc/code sync + smoke) and `make lint` (0 FAIL / 0 WARN, `scripts/lint-conventions.sh`) together are the definition of done; also `bin/pos help <full command> && bin/pos <category> --help`. For tools needing root/systemd/absent deps, behaviour-test via env-override paths + stub PATH (see DEV.md "Testing tools that need root / systemd / missing deps"). Pushing to Gitea re-runs the same four gates on the live Actions runner (`.gitea/workflows/lint.yml`) — a red run is a merge-blocker.
### Testing
+35 -2
View File
@@ -187,7 +187,7 @@ make check # full self-consistency gate (syntax, exec bits, d
make lint # convention gate (scripts/lint-conventions.sh) — must end 0 FAIL, 0 WARN
```
`make check` + `make lint` (0 FAIL / 0 WARN) are the definition of done. `make check` is also run as a pre-commit hook once you've run `make hook`; `make lint` is not part of the hook — run it yourself.
`make check` + `make lint` (0 FAIL / 0 WARN) are the definition of done. `make check` is also run as a pre-commit hook once you've run `make hook`; `make lint` is not part of the hook — run it yourself. Pushing to Gitea re-runs all four gates on the live Actions runner (see `CI: Gitea Actions Gate` below) — a red run is a merge-blocker.
### Testing tools that need root / systemd / missing deps
@@ -199,7 +199,7 @@ make lint # convention gate (scripts/lint-conventions.sh)
Example (session-learned): `PATH=/tmp/stubs:$PATH SMB_CONF=/tmp/smb.conf bin/pos-share-smb-server share /tmp/media …`.
Stub harnesses are **throwaway by design**: no `tests/` dir in this repo — build them outside the project (`/tmp/opencode/<tool>-test/`: `stubs/` + `run-tests.sh` with a `check "desc" "expected" "$actual"` helper and a pass/fail count), run them, then leave them in `/tmp`. Only the *pattern* above is worth keeping in the repo. (CI — `.gitea/workflows/lint.yml` — runs the *static* gates `make gen`+`git diff --exit-code`/`make check`/`make lint` on push/PR; it does not run behaviour suites.)
Stub harnesses are **throwaway by design**: no `tests/` dir in this repo — build them outside the project (`/tmp/opencode/<tool>-test/`: `stubs/` + `run-tests.sh` with a `check "desc" "expected" "$actual"` helper and a pass/fail count), run them, then leave them in `/tmp`. Only the *pattern* above is worth keeping in the repo. (CI — `.gitea/workflows/lint.yml`, live act_runner — runs the *static* gates `make gen`+`git diff --exit-code`/`make check`/`make lint` on every push/PR; it does not run behaviour suites.)
---
@@ -356,6 +356,39 @@ weaken it — and note the change in `MAINTENANCE.md`'s lint section.
---
## CI: Gitea Actions Gate
`.gitea/workflows/lint.yml` re-runs the four gates on every `push` and
`pull_request`: `make gen`, `git diff --exit-code` (gen drift), `make check`,
`make lint`. A red run is a merge-blocker; runs are visible under Gitea →
Actions.
- **Runner** — act_runner v0.6.1 (`linux-post-install`, labels `ubuntu-latest`
job image `node:20-bullseye`) is registered on the Gitea host and always on:
compose project `~/srv/gitea/runner/` (`docker compose up -d`,
`restart: unless-stopped`), standalone next to the ScaleTail gitea compose.
- **Gotchas (session-learned):**
- act_runner's `run.sh` `cd`s into `/data` and only reads the config when the
`CONFIG_FILE` env var is set — the compose service must pass
`CONFIG_FILE=/config.yaml`, not just mount the file.
- The job container can't resolve `gitea.skink-platy.ts.net` by itself; pin it
with `container.options: "--add-host gitea.skink-platy.ts.net:100.111.241.54"`
in `config.yaml`.
- Registration tokens are one-time use; the token lives in `runner/.env`
(chmod 600) and is burned after the first registration.
- Inspecting runs via sqlite: Gitea's status enum is runnerv1-consistent —
**1 = success, 2 = failure** (not the old 0/1/2/3 scheme).
- **Deterministic generators** — any script whose output is committed (gen docs,
completions) must sort in byte order: plain `sort` collates differently per
locale, and the CI container tripped exactly this (category-less tool keys
like `pos-config` start with `|`, which collated after letters under that
locale, reordering the generated tables). `scripts/gen-docs.sh` sets
`export LC_ALL=C`; keep that in mind for any new generator.
- **Limits** — CI proves the *static* gates only; it never runs behaviour suites
(stub harnesses stay throwaway in `/tmp`).
---
## Best Practices
### Alerting