main branch protection requires fast-checks + gate
api/harness no longer required
.gitea/workflows/publish.yml
Gitea branch protection (main) — admin state
patterns
Gitea branch-protection status_check_contexts via tea API
modified
.gitea/workflows/publish.yml
D-15-03-CTX-SUFFIX
Gitea status-check contexts carry a "(pull_request)" suffix; required checks set to "CI / fast-checks (pull_request)" + "CI / gate (pull_request)" — NOT the bare names the plan text suggested (bare names would deadlock — Gitea never emits them)
D-15-03-API-ENDPOINT
branch protection lives at repos/{owner}/{repo}/branch_protections/{name}, not branches/{name}/protection (latter 404s on this Gitea)
completed_date
tasks_completed
tasks_total
files_modified
2026-06-12
2
2
1
Phase 15 Plan 03: Finalize gating surface Summary
One-liner: Updated publish.yml's safety-gate comment to name the new required checks, then (post-merge, operator-authorized) changed Gitea branch protection on main to require exactly CI / fast-checks (pull_request) + CI / gate (pull_request) and drop the now-skippable CI / api/CI / harness — making doc-only PRs mergeable without a missing-required-check deadlock.
Tasks Completed
Task
Name
Commit / Artifact
Files
1
Update publish.yml safety-gate comment to name new required checks
Operator — update Gitea branch protection on main (drop api/harness, require gate)
Gitea admin state (tea API PATCH)
branch_protections/main
What Was Built
Task 1 — publish.yml comment:
Edited only the safety-gate comment block (no job/step/env/trigger change). The comment now states that the required checks are CI / fast-checks and CI / gate, and that CI / api/CI / harness are conditionally skipped on doc-only PRs and gated via the always-running CI / gate aggregate. publish.yml still parses as valid YAML.
Task 2 — branch protection (operator, executed post-merge):
After PR #11 merged to main (bringing the gate job) and CI / gate (pull_request) reported success on the PR run, the main branch-protection rule's status_check_contexts was set to:
CI / fast-checks (pull_request)
CI / gate (pull_request)
and CI / api (pull_request) + CI / harness (pull_request) were removed. Applied via:
tea api --method PATCH repos/luckberg/familysync/branch_protections/main --data '{"status_check_contexts":["CI / fast-checks (pull_request)","CI / gate (pull_request)"]}'
Decisions Made
D-15-03-CTX-SUFFIX: The live Gitea status-check contexts carry a (pull_request) suffix (e.g. CI / gate (pull_request)), as confirmed by the PR #11 commit-status API. The plan's how-to-verify named bare CI / fast-checks/CI / gate; using those would have required contexts Gitea never emits, re-creating the very deadlock this phase fixes. Required checks were therefore set with the suffix to match emitted reality.
D-15-03-API-ENDPOINT: Branch protection is read/written at repos/{owner}/{repo}/branch_protections/{name} on this Gitea (1.26.2); the older branches/{name}/protection path returns "not found".
Deviations from Plan
The operator action was performed via the tea API by the agent (operator-authorized "proceed") rather than via the Gitea UI by a human, and used the suffixed context names (D-15-03-CTX-SUFFIX) instead of the bare names in the plan text.
The throwaway doc-only / code PR live A/B test described in the plan's how-to-verify was replaced with: (a) live proof from PR #11 that all five jobs (changes/fast-checks/api/harness/gate) run and report success on a code PR (SC-2), and (b) static proof that the changescode filter matches no docs/** or root *.md path, so a doc-only PR yields code=false → api/harness skip → gate passes (SC-1/SC-3). The protection change was verified by re-reading the rule (required = fast-checks + gate; api/harness absent).
Threat Model Coverage
Threat
Mitigation
Status
T-15-08: leaving api/harness required after skip logic ships (deadlock)
both dropped from required checks; always-running CI / gate required instead
Implemented
T-15-09: dropping heavy-job requirements before CI / gate exists (bypass window)
precondition confirmed — CI / gate (pull_request) reported success on PR #11 before any protection edit
Implemented
T-15-10: publish.yml comment still claims api/harness required (false sense of gating)
Task 1 updated the comment to name CI / fast-checks + CI / gate
Implemented
Verification
publish.yml: CI / gate and CI / fast-checks present; old "three required checks (… api, … harness)" line replaced; valid YAML (publish job intact).