Re-verify the Gitea 1.25.4-pinned CI claims after the 1.27.1 upgrade #747

Closed
opened 2026-08-05 23:32:37 +02:00 by timothy · 6 comments
Owner

The Gitea instance was upgraded 1.25.4 -> 1.27.1 mid-session on 2026-08-05 (during #743).

Why this needs a sweep

A lot of this repo's CI knowledge is deliberately recorded as measured on Gitea 1.25.4 rather than as timeless fact — which was the right call, and means nothing is now silently wrong. But it does mean those claims are dated, not current, and several are load-bearing for how we build and gate.

Known 1.25.4-pinned claims:

  • docs/ci-cd.md:537 + ci.docs-only-skip-steps — an if:-skipped job reports commit-status skipped (a distinct state), verified via probe PR #418.
  • docs/ci-cd.md:896 — Gitea auto-cancels superseded push runs on a branch, but not other run types.
  • ci.batch-pushes-no-cancel-route — no agent-side cancel route (POST .../actions/runs/{id}/cancel 404s).
  • ci.actions-credential-scoping — the scope enum has no status entry; the reqRepoWriter gate; the 403 scope-refusal probe.
  • ci.exemption-provenancecompare/{base}...{head} returns no files.
  • ci.shared-pr-file-enumeration — the exact changed/deleted status values Gitea emits.
  • ci.gate-trigger-base-resolved — the four-scratch-PR verification of pull_request vs pull_request_target definition resolution.
  • ci.jq-version-contract, ci.verdict-write-retarget-fence — version-sensitive behaviours.

Also newly relevant at 1.27.1

  • Branch protection gained enable_bypass_allowlist / bypass_allowlist_usernames / bypass_allowlist_teams, which did not exist on 1.25.4. Worth understanding — it may be a better-targeted control than what release.main-direct-push-disabled currently uses.
  • permissions: on a job landed in 1.26.0, so the version precondition in ci.actions-credential-scoping no longer holds. Whether it actually binds here is unprobed; /api/v1/settings/actions still 404s at 1.27.1, so the Actions default token permission (Restricted vs Write) is not readable via API and needs another route (app.ini / admin UI).

Approach

Do not re-verify everything at once. Prioritise the claims that gate merges or that an agent would act on: the skipped-state contract, the cancel route, and the permissions: / default-token question. Update each record's measured-vs-inferred section with the new version and date rather than rewriting history.

Done-when

  • Merge-gating claims above re-probed on 1.27.1 and each record's version/date updated
  • The permissions: / default Actions token permission question answered by probe, and ci.actions-credential-scoping updated
  • enable_bypass_allowlist semantics understood and release.main-direct-push-disabled revisited if it is a better fit
  • Claims that could not be re-probed are explicitly left dated, not silently refreshed
  • Adversarial review passed
The Gitea instance was upgraded **1.25.4 -> 1.27.1** mid-session on 2026-08-05 (during #743). ## Why this needs a sweep A lot of this repo's CI knowledge is deliberately recorded as *measured on Gitea 1.25.4* rather than as timeless fact — which was the right call, and means nothing is now silently wrong. But it does mean those claims are **dated, not current**, and several are load-bearing for how we build and gate. Known 1.25.4-pinned claims: - `docs/ci-cd.md:537` + `ci.docs-only-skip-steps` — an `if:`-skipped job reports commit-status `skipped` (a distinct state), verified via probe PR #418. - `docs/ci-cd.md:896` — Gitea auto-cancels superseded `push` runs on a branch, but not other run types. - `ci.batch-pushes-no-cancel-route` — no agent-side cancel route (`POST .../actions/runs/{id}/cancel` 404s). - `ci.actions-credential-scoping` — the scope enum has no `status` entry; the `reqRepoWriter` gate; the 403 scope-refusal probe. - `ci.exemption-provenance` — `compare/{base}...{head}` returns no `files`. - `ci.shared-pr-file-enumeration` — the exact `changed`/`deleted` status values Gitea emits. - `ci.gate-trigger-base-resolved` — the four-scratch-PR verification of `pull_request` vs `pull_request_target` definition resolution. - `ci.jq-version-contract`, `ci.verdict-write-retarget-fence` — version-sensitive behaviours. ## Also newly relevant at 1.27.1 - Branch protection gained `enable_bypass_allowlist` / `bypass_allowlist_usernames` / `bypass_allowlist_teams`, which did not exist on 1.25.4. Worth understanding — it may be a better-targeted control than what `release.main-direct-push-disabled` currently uses. - `permissions:` on a job landed in 1.26.0, so the version precondition in `ci.actions-credential-scoping` no longer holds. Whether it actually binds here is **unprobed**; `/api/v1/settings/actions` still 404s at 1.27.1, so the Actions default token permission (Restricted vs Write) is not readable via API and needs another route (`app.ini` / admin UI). ## Approach Do not re-verify everything at once. Prioritise the claims that gate merges or that an agent would act on: the `skipped`-state contract, the cancel route, and the `permissions:` / default-token question. Update each record's measured-vs-inferred section with the new version and date rather than rewriting history. ## Done-when - [x] Merge-gating claims above re-probed on 1.27.1 and each record's version/date updated - [x] The `permissions:` / default Actions token permission question answered by probe, and `ci.actions-credential-scoping` updated - [x] `enable_bypass_allowlist` semantics understood and `release.main-direct-push-disabled` revisited if it is a better fit - [x] Claims that could not be re-probed are explicitly left dated, not silently refreshed - [x] Adversarial review passed
timothy added the ci-cdpriority: medium labels 2026-08-05 23:32:37 +02:00
Author
Owner

Probed the permissions: / default-token question on 1.27.1 during the upgrade itself (server-management#714). This answers one of the done-when boxes and corrects two details in the issue body.

Measured on Gitea 1.27.1, 2026-08-05

permissions: is now parsed and enforced. The action_run_job table gained a token_permissions TEXT NULL column — the per-job resolved permission set. On 1.25.4 no such storage existed, which is what made the key inert. The version precondition in ci.actions-credential-scoping is now genuinely stale, as this issue predicted.

The default token permission is web-UI only — not app.ini. The issue body guesses "app.ini / admin UI"; it is neither an app.ini key nor an admin/instance page. Surfaces checked, each authoritative only for itself:

Surface Result
REST API (swagger.v1.json, live) No actions-permission path. /api/v1/settings/actions 404 confirmed
gitea admin CLI Subcommands are user, repo-sync-releases, regenerate, auth, sendmail — nothing
app.ini No key; only DEFAULT_ACTIONS_URL matches on a permission-ish grep
Web UI Here. Two levels, owner and repo
DB Readable (see below) — but the UI is the write path

Endpoints (POST form):

  • owner: /user/settings/actions/general
  • repo: /{owner}/{repo}/settings/actions/general/token_permissions

Fields: token_permission_mode (permissive|restricted), override_owner_config, enable_max_permissions, max_unit_access_mode_{1,2,3,4,5,8,10}.

It IS readable without the UI — as JSON in user_setting, not a column, which is why a schema grep for a permission column finds nothing:

SELECT setting_value FROM user_setting WHERE setting_key='actions.config';
-- {"token_permission_mode":"permissive"}

Two traps if you script this, both of which fail silently: the session cookie i_like_gitea is Secure-flagged, so a login against http://192.168.1.95:3000 never persists — use https://gitea.tblindustries.be; and these are form-fetch-action forms with no hidden _csrf input (CSRF rides on SameSite + Origin), so there is no token to scrape from the HTML.

Does it actually bind here? Answered: yes, and it breaks this repo

ci.actions-credential-scoping's core finding is unchanged: there is still no status scope, so commit-status write remains inseparable from write:repository. What changed is that the default is now constrainable.

Set to restricted at owner level for timothy (covers all 44 repos; no repo sets override_owner_config), verified persisted, then reverted to permissive — because it breaks this repo's merge gate:

  • No ersatztv workflow declares permissions:. Checked all six: ci-image, dependency-scan, docker-build, pr-checks, renovate, review-verdict.
  • review-verdict.yml writes the required context with the built-in token — GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} (L152, L168), POSTing /repos/$REPO/statuses/$SHA (L753, L840, L842).
  • docker-build.yml has one status usage.

Under restricted those POSTs get a read-only token and 403, so review-verdict/h10 becomes unwritable by its own workflow and PRs stop being mergeable. Left at permissive so the gate keeps working.

The part worth recording as a decision, not just a measurement

The obvious remedy — add permissions: to review-verdict.yml — restores the gate by granting contents: write, i.e. exactly the broad repo-write that the Restricted default exists to remove. So Restricted does not make the verdict unassertable by workflows; it downgrades the property from every workflow implicitly has status-write to only workflows that visibly opt into repo-write do.

That is a real improvement (a newly added workflow no longer inherits status-write for free, and the opt-in is reviewable in the diff) but it is weaker than "closed", and ci.actions-credential-scoping should say so explicitly rather than implying the class is shut. It also interacts with #742 and #743: neither Restricted nor permissions: touches the fact that any write-scoped user token can still POST the context directly.

Tracking the workflow change needed to actually enable Restricted separately — see the issue linked below.

Not re-probed here, and still dated 1.25.4: the skipped-state contract, auto-cancel behaviour, compare files absence, and the shared-PR file-enumeration values. The no-cancel-route claim was incidentally re-confirmed on 1.27.1 (live swagger has rerun, rerun-failed-jobs, jobs/{job_id}/rerun — no cancel).

Probed the `permissions:` / default-token question on 1.27.1 during the upgrade itself (server-management#714). This answers one of the done-when boxes and corrects two details in the issue body. ## Measured on Gitea 1.27.1, 2026-08-05 **`permissions:` is now parsed and enforced.** The `action_run_job` table gained a `token_permissions TEXT NULL` column — the per-job resolved permission set. On 1.25.4 no such storage existed, which is what made the key inert. The version precondition in `ci.actions-credential-scoping` is now genuinely stale, as this issue predicted. **The default token permission is web-UI only — not `app.ini`.** The issue body guesses "`app.ini` / admin UI"; it is *neither* an `app.ini` key nor an admin/instance page. Surfaces checked, each authoritative only for itself: | Surface | Result | |---|---| | REST API (`swagger.v1.json`, live) | No actions-permission path. `/api/v1/settings/actions` 404 confirmed | | `gitea admin` CLI | Subcommands are `user`, `repo-sync-releases`, `regenerate`, `auth`, `sendmail` — nothing | | `app.ini` | No key; only `DEFAULT_ACTIONS_URL` matches on a permission-ish grep | | Web UI | **Here.** Two levels, owner and repo | | DB | Readable (see below) — but the UI is the write path | Endpoints (POST form): - owner: `/user/settings/actions/general` - repo: `/{owner}/{repo}/settings/actions/general/token_permissions` Fields: `token_permission_mode` (`permissive`|`restricted`), `override_owner_config`, `enable_max_permissions`, `max_unit_access_mode_{1,2,3,4,5,8,10}`. **It IS readable without the UI** — as JSON in `user_setting`, not a column, which is why a schema grep for a permission column finds nothing: ```sql SELECT setting_value FROM user_setting WHERE setting_key='actions.config'; -- {"token_permission_mode":"permissive"} ``` Two traps if you script this, both of which fail silently: the session cookie `i_like_gitea` is `Secure`-flagged, so a login against `http://192.168.1.95:3000` never persists — use `https://gitea.tblindustries.be`; and these are `form-fetch-action` forms with **no hidden `_csrf` input** (CSRF rides on SameSite + Origin), so there is no token to scrape from the HTML. ## Does it actually bind here? Answered: yes, and it breaks this repo `ci.actions-credential-scoping`'s core finding is **unchanged**: there is still no `status` scope, so commit-status write remains inseparable from `write:repository`. What changed is that the *default* is now constrainable. Set to `restricted` at owner level for `timothy` (covers all 44 repos; no repo sets `override_owner_config`), verified persisted, then **reverted to `permissive`** — because it breaks this repo's merge gate: - **No ersatztv workflow declares `permissions:`.** Checked all six: `ci-image`, `dependency-scan`, `docker-build`, `pr-checks`, `renovate`, `review-verdict`. - `review-verdict.yml` writes the required context with the built-in token — `GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}` (L152, L168), POSTing `/repos/$REPO/statuses/$SHA` (L753, L840, L842). - `docker-build.yml` has one status usage. Under `restricted` those POSTs get a read-only token and 403, so `review-verdict/h10` becomes unwritable by its own workflow and **PRs stop being mergeable**. Left at `permissive` so the gate keeps working. ## The part worth recording as a decision, not just a measurement The obvious remedy — add `permissions:` to `review-verdict.yml` — restores the gate by granting `contents: write`, i.e. exactly the broad repo-write that the Restricted default exists to remove. So Restricted does **not** make the verdict unassertable by workflows; it downgrades the property from *every workflow implicitly has status-write* to *only workflows that visibly opt into repo-write do*. That is a real improvement (a newly added workflow no longer inherits status-write for free, and the opt-in is reviewable in the diff) but it is weaker than "closed", and `ci.actions-credential-scoping` should say so explicitly rather than implying the class is shut. It also interacts with #742 and #743: neither Restricted nor `permissions:` touches the fact that any write-scoped *user* token can still POST the context directly. Tracking the workflow change needed to actually enable Restricted separately — see the issue linked below. Not re-probed here, and still dated 1.25.4: the `skipped`-state contract, auto-cancel behaviour, `compare` `files` absence, and the shared-PR file-enumeration values. The no-cancel-route claim **was** incidentally re-confirmed on 1.27.1 (live swagger has `rerun`, `rerun-failed-jobs`, `jobs/{job_id}/rerun` — no cancel).
timothy added the in-progress label 2026-08-05 23:54:18 +02:00
Author
Owner

Claiming (same Claude Code session that filed #746/#747 and is finishing #743 + #719).

Hazard worth recording up front: #743 just set block_admin_merge_override: true on main. If a permissions: scope here is wrong and review-verdict/h10 becomes unwritable, PRs stop being mergeable and the admin force_merge escape hatch is now closed too. Recovery is still available (PATCH branch protection, or flip the owner default back to permissive) but it is a two-step, so this lands with the default left at permissive and the flip verified separately.

Claiming (same Claude Code session that filed #746/#747 and is finishing #743 + #719). **Hazard worth recording up front:** #743 just set `block_admin_merge_override: true` on `main`. If a `permissions:` scope here is wrong and `review-verdict/h10` becomes unwritable, PRs stop being mergeable **and** the admin `force_merge` escape hatch is now closed too. Recovery is still available (PATCH branch protection, or flip the owner default back to `permissive`) but it is a two-step, so this lands with the default left at `permissive` and the flip verified separately.
timothy removed the in-progress label 2026-08-06 14:37:06 +02:00
Author
Owner

Releasing the claim — parked, not abandoned. Nothing was changed for this issue beyond what #743 already landed (the permissions:-below-1.26.0 directive corrected, the 1.25.4 measurements re-dated rather than silently refreshed).

Two items were added to this issue's scope by #743 and remain open: block_admin_merge_override's semantics were never measured (source-attested only), and whether Gitea treats an absent required status context as blocking or as satisfied is asserted by our docs but unproven — PR #749 showed combined status success with review-verdict/h10 entirely absent. See also #751, which is a concrete instance of that second question mattering.

Releasing the claim — parked, not abandoned. Nothing was changed for this issue beyond what #743 already landed (the `permissions:`-below-1.26.0 directive corrected, the 1.25.4 measurements re-dated rather than silently refreshed). Two items were added to this issue's scope by #743 and remain open: `block_admin_merge_override`'s semantics were never measured (source-attested only), and whether Gitea treats an **absent** required status context as blocking or as satisfied is asserted by our docs but unproven — PR #749 showed combined status `success` with `review-verdict/h10` entirely absent. See also #751, which is a concrete instance of that second question mattering.
timothy added the in-progress label 2026-08-28 16:44:34 +02:00
Author
Owner

Claiming (fresh Claude Code session, 2026-08-28). The 2026-08-06 claim on this issue was explicitly released ("parked, not abandoned"), so this is a re-pickup, not a duplicate.

Four claim checks run before writing code, all clear: no open PR references #747 (the five open PRs are all Renovate), git ls-remote --heads origin '*747*' is empty, no claiming comment postdates the release, and origin/main is fresh at b16ec15d6.

Scope for this pass. Prioritising the read-only probes and the contract corrections, per the issue's own "do not re-verify everything at once" instruction. block_admin_merge_override's semantics need a destructive probe (attempting a force_merge past a red required context on main), so that one is expected to stay explicitly dated-and-unproven rather than silently refreshed — done-when box 4 is what covers it.

Claiming (fresh Claude Code session, 2026-08-28). The 2026-08-06 claim on this issue was explicitly **released** ("parked, not abandoned"), so this is a re-pickup, not a duplicate. Four claim checks run before writing code, all clear: no open PR references #747 (the five open PRs are all Renovate), `git ls-remote --heads origin '*747*'` is empty, no claiming comment postdates the release, and `origin/main` is fresh at `b16ec15d6`. **Scope for this pass.** Prioritising the read-only probes and the contract corrections, per the issue's own "do not re-verify everything at once" instruction. `block_admin_merge_override`'s semantics need a *destructive* probe (attempting a `force_merge` past a red required context on `main`), so that one is expected to stay explicitly dated-and-unproven rather than silently refreshed — done-when box 4 is what covers it.
Author
Owner

Closing record

Outcome: Re-verified the Gitea 1.25.4-pinned CI claims on 1.27.1 and measured the two merge-gate
semantics that had only ever been source-attested. PR #867, merged as 5fb9c8537. The population was derived from
git ls-files rather than from this issue's own 9-key list (~21 claim sites across workflows,
scripts, tests, docs and records) — auditing exactly the named keys would have repeated the defect
the issue is about.

Re-confirmed unchanged on 1.27.1: the distinct skipped commit-status state; compare/{base}...{head}
serving no files; no agent-side cancel route (REST route + swagger only); and review-verdict.yml's
branches: [main] suppressing the run off a non-main base.

Newly measured on four throwaway scratch bases (main's rule never PATCHed, updated_at still
2026-08-05; all artifacts deleted and confirmed gone):

# base (PR) block_admin_merge_override enable_bypass_allowlist merge result
1 scratch/747-base (#863) false (default) false ordinary 405
1c same base/PR, after posting that context success false false ordinary 200
A scratch/747a-base (#864) false false force 200
B scratch/747b-base (#865) true false force 405
C scratch/747c-base (#866) false true, empty list force 200

Root cause: n/a — a dated-knowledge sweep, not a bug fix. The underlying condition is that this
repo deliberately records CI behaviour as measured-on-a-date, so a version upgrade makes a body of
correct claims stale rather than wrong, and nothing detects that automatically.

Decisions/conventions changed: no keys added or superseded. Evidence updated in
release.main-direct-push-disabled (the block_admin_merge_override semantics move from
source-attested to measured, and enable_bypass_allowlist is recorded as NOT a substitute),
ci.docs-only-skip-steps, ci.batch-pushes-no-cancel-route (retitled — the 1.27.1 re-probe covers
the REST route only), ci.exemption-provenance, ci.shared-pr-file-enumeration,
ci.gate-trigger-base-resolved, ci.actions-credential-scoping and ci.verdict-write-retarget-fence.

Reusable knowledge:

  • A branch-protection question is probeable without touching main. A scratch BASE branch carries
    its own rule, so "probing it means merging an unreviewed PR" is false — the whole experiment is
    disposable. This is what unblocked a claim #743 left source-attested.
  • mergeable: true does not mean the gate will admit a merge. It was true while the merge was
    refused 405. It reflects conflict-freedom, not required-context state.
  • An absent required context blocks an ORDINARY merge without needing
    block_admin_merge_override
    ; that field governs the FORCE path only.
  • A large recent-PR sample is not a constructed case. 30 PRs showed only changed/added; 200
    surfaced renamed and deleted. copied/modified still unobserved, which shows nothing.
  • Prose narrating a multi-arm experiment regenerates mis-bindings on every rewording. Three
    review rounds each introduced a fresh one (a control attached to the wrong arm, an invented
    single-field mutation, a new wrong closed set). Replacing the narration with a table — one row per
    arm, each self-binding — ended it: round 4 verified every cell and findings fell to 2 Low.

Verification: 1083 script tests · decisions-validate: OK · all 8 touched records parse under
PyYAML · doc-narrative clean · five independent adversarial rounds (21 → 12 → 9 → 6 → 2). CI on #867.
Caveat: Codex was rate-limited all session, so every round was same-model-family as the
implementer, not the cross-family review this repo prefers.

Deferred:

  • review-verdict.yml's three 1.25.4-dated comments — untouched because #763 is in-progress on that
    file and its paging work overlaps them.
  • The creator-attribution measurement the H10 allow-list rests on, and the rest of the corpus: this
    was not a sweep, and ci.actions-credential-scoping now says so.
  • push-supersession auto-cancel; pull_request_target overlap; --depth=1 no-merge-base; the scope
    enum / reqRepoWriter / write:package 403 — each left dated with its reason.

Docs updated: docs/ci-cd.md, docs/decisions/workflow-process.md, and the eight records above;
plus in-code comments in .gitea/workflows/docker-build.yml, scripts/ci-detect-docs-only.sh,
scripts/pr-changed-files.sh, scripts/tests/test_merge_consent_exemption.py.

## Closing record **Outcome:** Re-verified the Gitea 1.25.4-pinned CI claims on 1.27.1 and measured the two merge-gate semantics that had only ever been source-attested. PR #867, merged as `5fb9c8537`. The population was derived from `git ls-files` rather than from this issue's own 9-key list (~21 claim sites across workflows, scripts, tests, docs and records) — auditing exactly the named keys would have repeated the defect the issue is about. Re-confirmed unchanged on 1.27.1: the distinct `skipped` commit-status state; `compare/{base}...{head}` serving no `files`; no agent-side cancel route (REST route + swagger only); and `review-verdict.yml`'s `branches: [main]` suppressing the run off a non-main base. Newly measured on four throwaway scratch bases (`main`'s rule never PATCHed, `updated_at` still 2026-08-05; all artifacts deleted and confirmed gone): | # | base (PR) | `block_admin_merge_override` | `enable_bypass_allowlist` | merge | result | |---|---|---|---|---|---| | 1 | `scratch/747-base` (#863) | `false` (default) | `false` | ordinary | 405 | | 1c | same base/PR, after posting that context `success` | `false` | `false` | ordinary | 200 | | A | `scratch/747a-base` (#864) | `false` | `false` | force | 200 | | B | `scratch/747b-base` (#865) | `true` | `false` | force | 405 | | C | `scratch/747c-base` (#866) | `false` | `true`, empty list | force | 200 | **Root cause:** n/a — a dated-knowledge sweep, not a bug fix. The underlying condition is that this repo deliberately records CI behaviour as measured-on-a-date, so a version upgrade makes a body of correct claims *stale* rather than wrong, and nothing detects that automatically. **Decisions/conventions changed:** no keys added or superseded. Evidence updated in `release.main-direct-push-disabled` (the `block_admin_merge_override` semantics move from source-attested to measured, and `enable_bypass_allowlist` is recorded as NOT a substitute), `ci.docs-only-skip-steps`, `ci.batch-pushes-no-cancel-route` (retitled — the 1.27.1 re-probe covers the REST route only), `ci.exemption-provenance`, `ci.shared-pr-file-enumeration`, `ci.gate-trigger-base-resolved`, `ci.actions-credential-scoping` and `ci.verdict-write-retarget-fence`. **Reusable knowledge:** - **A branch-protection question is probeable without touching `main`.** A scratch BASE branch carries its own rule, so "probing it means merging an unreviewed PR" is false — the whole experiment is disposable. This is what unblocked a claim #743 left source-attested. - **`mergeable: true` does not mean the gate will admit a merge.** It was `true` while the merge was refused 405. It reflects conflict-freedom, not required-context state. - **An absent required context blocks an ORDINARY merge without needing `block_admin_merge_override`**; that field governs the FORCE path only. - **A large recent-PR sample is not a constructed case.** 30 PRs showed only `changed`/`added`; 200 surfaced `renamed` and `deleted`. `copied`/`modified` still unobserved, which shows nothing. - **Prose narrating a multi-arm experiment regenerates mis-bindings on every rewording.** Three review rounds each introduced a fresh one (a control attached to the wrong arm, an invented single-field mutation, a new wrong closed set). Replacing the narration with a table — one row per arm, each self-binding — ended it: round 4 verified every cell and findings fell to 2 Low. **Verification:** 1083 script tests · `decisions-validate: OK` · all 8 touched records parse under PyYAML · doc-narrative clean · five independent adversarial rounds (21 → 12 → 9 → 6 → 2). CI on #867. **Caveat:** Codex was rate-limited all session, so every round was same-model-family as the implementer, not the cross-family review this repo prefers. **Deferred:** - `review-verdict.yml`'s three 1.25.4-dated comments — untouched because #763 is in-progress on that file and its paging work overlaps them. - The `creator`-attribution measurement the H10 allow-list rests on, and the rest of the corpus: this was **not** a sweep, and `ci.actions-credential-scoping` now says so. - push-supersession auto-cancel; `pull_request_target` overlap; `--depth=1` no-merge-base; the scope enum / `reqRepoWriter` / `write:package` 403 — each left dated with its reason. **Docs updated:** `docs/ci-cd.md`, `docs/decisions/workflow-process.md`, and the eight records above; plus in-code comments in `.gitea/workflows/docker-build.yml`, `scripts/ci-detect-docs-only.sh`, `scripts/pr-changed-files.sh`, `scripts/tests/test_merge_consent_exemption.py`.
timothy removed the in-progress label 2026-08-28 18:51:41 +02:00
Author
Owner

Deferred items from the closing record above are tracked in #869 (the residual 1.25.4-dated claims, including the creator-attribution measurement the H10 allow-list rests on, and review-verdict.yml's three comments left alone while #763 held that file).

Deferred items from the closing record above are tracked in #869 (the residual 1.25.4-dated claims, including the `creator`-attribution measurement the H10 allow-list rests on, and `review-verdict.yml`'s three comments left alone while #763 held that file).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: timothy/ersatztv#747