ci: port the workflows to .forgejo/, and correct the context-format finding - #527
Merged
Merged
Conversation
…inding Two things, both from running Forgejo Actions rather than reasoning about it. FIRST, A CORRECTION. #526 claimed `run-name:` pins the middle segment of Forgejo's status context. That is wrong. A two-job workflow with `run-name: probe` produces: multi / alpha (pull_request) multi / beta (pull_request) `probe` appears in neither. A job carrying `name: Pretty Job Name` produces `naming / Pretty Job Name (pull_request)`. So the format is <workflow name:> / <job name:, or the job id> (<event>) and it is STABLE BY DEFAULT — no `run-name:` required, and each job gets its own context exactly as on GitHub, just prefixed. The commit-message form I first observed appears only when a run fails before any job starts, where Forgejo falls back to the file name and run title. I generalised a fallback into a rule. SECOND, THE PORT. Forgejo executes `.github/workflows/` as well as `.forgejo/`, so pushing OC to the instance handed a single local runner the whole GitHub CI suite — 27 tasks dispatched, most failing, the audit queued behind them. The three workflows are now ported to `.forgejo/workflows/` with their jobs byte-identical (verified by parsing both and comparing the `jobs` mappings) and one deliberate change: `on:` is pull_request only, because a `push` trigger produces a second, separate context on the same head. The 13 contexts these produce are enumerated in the spec, and are what Forgejo branch protection must require. This change is ADDITIVE on purpose. Deleting `.github/workflows/` cannot merge here: it removes the `audit` status branch protection requires, with enforce_admins on, so that PR could never go green. The deletion lands on Forgejo after the fleet cuts over. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Owner
Author
Failed checks: code_quality |
ProtocolWarden
added a commit
that referenced
this pull request
Aug 21, 2026
…le backlog items half that is genuinely cosmetic and leaves the half that is not. Renames (each had exactly one importer or none, no behavior change): * `propagation/plane_adapter.py` -> `board_adapter.py`, `PlaneTaskCreator` -> `BoardTaskCreator`. Docstrings in `propagator.py` still pointed at `PlaneClient.create_issue`, a class deleted in #521. * `tests/test_plane_parsing.py` -> `test_task_parsing.py` — it tests `TaskParser` and never touched Plane. * `docs/design/plane_kodo_wrapper.md` -> `docs/history/plane-kodo-wrapper.md`, `status: implemented` -> `superseded`. It sat among live design docs describing a retired board AND a retired engine. And one that was not cosmetic. `config/plane_task_template.example.md` was a stale copy of `render_task_template()` output (it still said "the change you want Kodo to make"). No code read it — `oc setup` writes `config/task_template.local.md`. But `.gitignore`, `docs/operator/setup.md` and BOTH secrets scripts still named the dead `plane_task_template.local.md` path, so `backup-secrets.sh` was backing up a file that cannot exist and the operator's real template was in no backup at all. All four repointed; the stale example deleted. Also dropped `.gitignore` entries for `deployment/plane/**` and `tools/report/kodo_plane/` — no such directories. Left alone on purpose: `plane_task_id` (read from on-disk review state), `plane_issue_id` (read from proposer artifacts), and `"plane"` as an alert channel name (validated against operator config). Those are wire formats; a bare rename orphans in-flight reviews. Filed in Up Next as a write-both migration. Both Up Next items were already done and just unrecorded — moved to Done with evidence: the ~1,830-test CI gap is covered by the `test-rest` job (`pytest tests/ --ignore=tests/unit`, #525, survived the #527 port), and `audit` on Forgejo Actions is live (runner registered, workflow ported to `.forgejo/workflows/custodian-audit.yml`, branch protection requiring `custodian-audit / audit (pull_request)` with apply_to_admins). Verified with imports forced to the worktree (PYTHONPATH), not the live checkout the fleet runs from: 67 targeted tests pass, ruff check and format clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ProtocolWarden
added a commit
that referenced
this pull request
Aug 21, 2026
…le backlog items half that is genuinely cosmetic and leaves the half that is not. Renames (each had exactly one importer or none, no behavior change): * `propagation/plane_adapter.py` -> `board_adapter.py`, `PlaneTaskCreator` -> `BoardTaskCreator`. Docstrings in `propagator.py` still pointed at `PlaneClient.create_issue`, a class deleted in #521. * `tests/test_plane_parsing.py` -> `test_task_parsing.py` — it tests `TaskParser` and never touched Plane. * `docs/design/plane_kodo_wrapper.md` -> `docs/history/plane-kodo-wrapper.md`, `status: implemented` -> `superseded`. It sat among live design docs describing a retired board AND a retired engine. And one that was not cosmetic. `config/plane_task_template.example.md` was a stale copy of `render_task_template()` output (it still said "the change you want Kodo to make"). No code read it — `oc setup` writes `config/task_template.local.md`. But `.gitignore`, `docs/operator/setup.md` and BOTH secrets scripts still named the dead `plane_task_template.local.md` path, so `backup-secrets.sh` was backing up a file that cannot exist and the operator's real template was in no backup at all. All four repointed; the stale example deleted. Also dropped `.gitignore` entries for `deployment/plane/**` and `tools/report/kodo_plane/` — no such directories. Left alone on purpose: `plane_task_id` (read from on-disk review state), `plane_issue_id` (read from proposer artifacts), and `"plane"` as an alert channel name (validated against operator config). Those are wire formats; a bare rename orphans in-flight reviews. Filed in Up Next as a write-both migration. Both Up Next items were already done and just unrecorded — moved to Done with evidence: the ~1,830-test CI gap is covered by the `test-rest` job (`pytest tests/ --ignore=tests/unit`, #525, survived the #527 port), and `audit` on Forgejo Actions is live (runner registered, workflow ported to `.forgejo/workflows/custodian-audit.yml`, branch protection requiring `custodian-audit / audit (pull_request)` with apply_to_admins). Verified with imports forced to the worktree (PYTHONPATH), not the live checkout the fleet runs from: 67 targeted tests pass, ruff check and format clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ProtocolWarden
added a commit
that referenced
this pull request
Aug 21, 2026
…le backlog items (#529) half that is genuinely cosmetic and leaves the half that is not. Renames (each had exactly one importer or none, no behavior change): * `propagation/plane_adapter.py` -> `board_adapter.py`, `PlaneTaskCreator` -> `BoardTaskCreator`. Docstrings in `propagator.py` still pointed at `PlaneClient.create_issue`, a class deleted in #521. * `tests/test_plane_parsing.py` -> `test_task_parsing.py` — it tests `TaskParser` and never touched Plane. * `docs/design/plane_kodo_wrapper.md` -> `docs/history/plane-kodo-wrapper.md`, `status: implemented` -> `superseded`. It sat among live design docs describing a retired board AND a retired engine. And one that was not cosmetic. `config/plane_task_template.example.md` was a stale copy of `render_task_template()` output (it still said "the change you want Kodo to make"). No code read it — `oc setup` writes `config/task_template.local.md`. But `.gitignore`, `docs/operator/setup.md` and BOTH secrets scripts still named the dead `plane_task_template.local.md` path, so `backup-secrets.sh` was backing up a file that cannot exist and the operator's real template was in no backup at all. All four repointed; the stale example deleted. Also dropped `.gitignore` entries for `deployment/plane/**` and `tools/report/kodo_plane/` — no such directories. Left alone on purpose: `plane_task_id` (read from on-disk review state), `plane_issue_id` (read from proposer artifacts), and `"plane"` as an alert channel name (validated against operator config). Those are wire formats; a bare rename orphans in-flight reviews. Filed in Up Next as a write-both migration. Both Up Next items were already done and just unrecorded — moved to Done with evidence: the ~1,830-test CI gap is covered by the `test-rest` job (`pytest tests/ --ignore=tests/unit`, #525, survived the #527 port), and `audit` on Forgejo Actions is live (runner registered, workflow ported to `.forgejo/workflows/custodian-audit.yml`, branch protection requiring `custodian-audit / audit (pull_request)` with apply_to_admins). Verified with imports forced to the worktree (PYTHONPATH), not the live checkout the fleet runs from: 67 targeted tests pass, ruff check and format clean. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two things, both from running Forgejo Actions rather than reasoning about it.
First, a correction to #526
#526 claimed
run-name:pins the middle segment of Forgejo's status context. That is wrong. A two-job workflow withrun-name: probeproduces:probeappears in neither. A job carryingname: Pretty Job Nameproducesnaming / Pretty Job Name (pull_request). So the format is:…and it is stable by default — no
run-name:needed, and each job gets its own context exactly as on GitHub, just prefixed by the workflow name.The commit-message form I first observed (
audit.yml / ci: probe the status context name (push)) appears only when a run fails before any job starts — with no job to name, Forgejo falls back to the file name and run title. I generalised a fallback into a rule.Second, the port
Forgejo executes
.github/workflows/as well as.forgejo/. Pushing OC to the instance handed a single local runner the entire GitHub CI suite — 27 tasks dispatched, most failing, the audit stuck behind them.All three workflows are ported to
.forgejo/workflows/with their jobs byte-identical (verified by parsing both files and comparing thejobsmappings), and one deliberate change:on:ispull_requestonly, because apushtrigger produces a second, separate context on the same head.The 13 contexts these produce
These are what Forgejo branch protection must require.
Why this is additive
Deleting
.github/workflows/cannot merge here. It removes theauditstatus branch protection requires, withenforce_adminson — so that PR could never go green, by construction. The deletion lands on Forgejo after the fleet cuts over.GitHub CI is untouched and still gates this PR.
🤖 Generated with Claude Code