fix(scope): wire author bootstrap scope into workflow scope guard #942
Merged
sysadmin
merged 1 commits from 2026-07-26 06:20:01 -05:00
fix/issue-941-scope-guard-bootstrap-wiring into master
Labels
Clear labels
allocator
anti-stomp
architecture
bug
chore
codex
concurrency
contamination
control-plane
dashboard
database
design
documentation
enhancement
gitea
glitchtip
important
incident
incident-bridge
integration
jenkins
labels
leases
mcp
mcp-health
mcp-menu
multi-project
mutating
nice-to-have
observability
portability
preflight
protected-branch
queue
read-only
reconnect
recovery
refactor
release
reliability
resumable-review
reviewer
roadmap
safety
security
self-hosted
sentry
stale-runtime
status:blocked
status:in-progress
status:pr-open
status:ready
terminal-lock
testing
tracker
type:bug
type:feature
type:feature
type:guardrail
visibility
workflow
workflow-hardening
workflow-hardening
Controller-owned work allocator
Prevent concurrent LLM session stomping
Architecture / structural design
OpenAI Codex client / workflow session surface
Concurrent session safety
Workflow or session contamination incident
MCP control-plane coordination and allocation authority
MCP operational dashboard/queue view
Internal coordination storage (SQLite/Postgres)
Design / investigation, no implementation
Docs / runbooks
New feature or improvement
Gitea MCP workflow
GlitchTip integration
Operational or process incident requiring durable audit trail
Sentry-to-Gitea incident bridging
Integration testing
Jenkins integration
Label taxonomy management
Lease adopt/release/expire lifecycle
MCP server / tooling
MCP namespace and runtime health
MCP menu surface
Work spanning multiple monitoring projects or Gitea repos
Mutating action; requires gating
Observability, metrics, traces, error reporting
Cross-platform / portability
Shared preflight gates before mutation
Protected branch / stable-branch policy concern
Work queue visibility and allocation
Read-only, no mutation
MCP client reconnect/reload recovery path
Recovery paths for stale/foreign leases
Code refactor / restructure
Release / versioning
Reliability / failure handling
Persist and resume prepared review verdicts across sessions
Reviewer workflow tooling
Roadmap / umbrella issue
Safety rails and fail-closed mutation guards
Security / trust boundary
Self-hosted infrastructure integration
Sentry error monitoring integration
Stale backend daemon / runtime-vs-master parity failures
Issue is blocked
Issue is being worked on
Issue has an open pull request
Issue is ready for work
Terminal review lock (#332) path
Tests / test coverage
Issue tracker hygiene / meta
Bug or defect
Feature or enhancement
Feature or enhancement
Safety gate or guardrail
Workflow state visibility for LLMs/operators
Cross-tool workflow
LLM workflow coordination hardening
LLM workflow coordination hardening
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Scaled-Tech-Consulting/Gitea-Tools#942
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #941
The recursive bootstrap deadlock
gitea_bootstrap_author_issue_worktreeexists to create an author's firstbranches/worktree from a clean control checkout, breaking the lock↔worktree cycle recorded in #892. It failed closed on every call:Because that is the tool an author needs before it can touch any file, #941 could not be implemented through the canonical path — the defect blocked its own repair. Every other worktree-producing route requires a worktree that does not yet exist:
gitea_lock_issuerefuses with the #274 "worktree path does not exist" branch,gitea_publish_unpublished_issue_branchrequiresworktree_pathon an already registered clean worktree,gitea_recover_dirty_orphaned_issue_worktreerequiressource_worktree_path, andgitea_rebind_dirty_same_claimant_author_sessionrequiresworktree_pathplus a dead owner PID.Why PR #926 reached only two of the three enforcement paths
PR #926 (which closed #892) made
create_issue_bootstrap.bootstrap_permits_control_checkoutaccepttask_scope=author_issue_bootstrap, and wired that canonical decision into the two guards its own description named: the #274 branches-only enforcer and the #604 anti-stomp preflight. Both consume a single server-derived assessment computed once per preflight, which is the #757 "one shared decision" rule.A third enforcement path was never connected.
workflow_scope_guardholds an independent copy of the clean-root author decision:The exemption test is a task-name allowlist —
CREATE_ISSUE_TASKS = frozenset({"create_issue", "gitea_create_issue"})— which never containedbootstrap_author_issue_worktree(the literal set atgitea_mcp_server.py:10157). Before this change,grep -c 'bootstrap_permits_control_checkout' workflow_scope_guard.pyreturned0.So on the real path
the guard raised before
assess_author_issue_bootstrapwas ever consulted. The #926 waiver was unreachable here, so the #892 deadlock stayed partially present and #931 remained blocked.A second instance of the identical mistake sat immediately downstream:
_enforce_issue_scope_guardalso computedrequire_lockfromis_create_issue_task, so once the worktree block cleared, the bootstrap task failed onmissing_issue_scope("no owning issue lock is bound"). No lock can exist at bootstrap time — that is the cycle the tool breaks. This PR fixes both, and fixes them the same way.How the fix reuses the canonical decision
workflow_scope_guard.assess_root_source_mutationgains an optionalbootstrap_assessmentparameter and, in the clean-root author case, consultscreate_issue_bootstrap.bootstrap_permits_control_checkoutover that evidence. Theis_create_issue_taskarm is untouched and still evaluated first.workflow_scope_guard.assess_production_mutation_guardsforwards the evidence unchanged._enforce_issue_scope_guardaccepts and threads the assessment the #274 and #604 guards already consume, so all three judge identical evidence per #757, and derives the pre-ownership lock waiver from that one canonical decision rather than a second task-name allowlist.verify_preflight_puritypasses the already-computed assessment at both of its call sites — the assessment was previously computed one line above the scope-guard call and simply not handed to it.No task-name allowlist decides the bootstrap case anymore. The module-local list survives only for
create_issue, whose #749 behaviour is unchanged.Why ordinary control-checkout mutation stays forbidden
The new arm delegates to a predicate that is fail-closed by construction. It returns
Falseunless every proof obligation is present and affirmative: the task iscreate_issueor the author bootstrap task;allowed,proventrue andblock,not_applicablefalse;reasonsempty;task_scopematching the task class exactly, so create-issue scope cannot license the bootstrap and bootstrap scope cannot license create-issue;bootstrap_path == clean_canonical_control_checkout; no dirty files;under_branchesfalse;base_tips_verifiedwith local and remote tips both recorded, non-empty and equal, re-derived rather than trusted; and the assessment describing exactly the workspace and root being guarded, with that workspace being the canonical control checkout.Anything else — a missing assessment, a non-dict, a truncated or hand-built one, a dirty root, a drifted head, a mismatched binding, or any other author task — leaves the ordinary block in force.
commit_files,lock_issue, and every other author mutation from the control checkout still raise. The evidence is server-derived from inspected repository state and is never accepted from a tool argument, so no caller can assert eligibility it has not proven. Protections tied to #274, #604, #618, and #683 are unchanged; nothing is removed or loosened.Regression coverage
tests/test_issue_941_scope_guard_bootstrap_wiring.py(24 tests) drives the real enforcer, not the authorization helper in isolation. This distinction is the whole point: #892's own predicate tests all passed while the live bootstrap stayed blocked, because its "integration" test calledbootstrap_permits_control_checkoutdirectly and asserted on a hand-built dict. A helper-only test cannot observe this defect._enforce_issue_scope_guardfrom a clean control checkout; a spy asserts the guard actually reachesbootstrap_permits_control_checkout.task_scope, non-emptyreasons, mismatched base tips, unverified tips, mismatched workspace binding, mismatched repo-root binding, and blocked assessments each still raise.commit_filesandlock_issuefrom the control checkout, cross-task smuggling of valid bootstrap evidence ontocommit_files, and a dirty control checkout under the bootstrap task.create_issueunchanged — both literals still allowed from a clean control checkout, still blocked when the checkout is dirty.missing_issue_worktree, the reconciler exemption survives, and omitting the new parameter preserves prior behaviour.Pre-fix the suite failed; post-fix it passes:
Validation
Run from the
branches/worktree, not a temporary directory.The 28 full-suite failures are the pre-existing baseline, not regressions. The four that touch these guards were each re-run on unmodified master
8c1d22a658ecb5715e3f4db6eb7ebb408830c101and fail identically there:A full-suite baseline run on unmodified master was still executing when this PR was opened; the reviewer should treat the 28-vs-28 comparison as verified only for those four until that run is posted as a follow-up comment. The failure count matches the standing repository baseline of 28.
Author bootstrap provenance
The worktree for this PR was created under a one-time, issue-scoped operator authorization, because the defect blocks its own repair. Exactly one
git worktree add -bcreatedfix/issue-941-scope-guard-bootstrap-wiringat the verified live master SHA8c1d22a658ecb5715e3f4db6eb7ebb408830c101, followed immediately bygitea_lock_issuebinding. No existing worktree was borrowed, the stable control checkout was not edited, and no remote branch was created by hand. The full record, including the refusal text that forced it, is issue comment17385on #941. The authorization was consumed once and is expired.Every Gitea mutation in this PR went through sanctioned
gitea-authorcapabilities:gitea_allocate_next_work,gitea_lock_issue,gitea_create_issue_comment,gitea_commit_files,gitea_create_pr. Notea, nocurl, no raw API, no direct database access, no manual push.Scope
workflow_scope_guard.py,gitea_mcp_server.py,tests/test_issue_941_scope_guard_bootstrap_wiring.pyfix/issue-941-scope-guard-bootstrap-wiringmasterat8c1d22a658ecb5715e3f4db6eb7ebb408830c101a09c485fc0eba75b35986a1833dba986be6c2101branches/issue-941-scope-guard-bootstrap-wiringasn-15133423bf614c11, leaselease-ecf79c663f354894No transport work, no role-permission changes, no refactoring beyond the wiring, and no manual worktree escape hatch added to the code.
Effect on #931
Issue #931 remains blocked and received nothing from this session — no assignment, lease, worktree, branch, commit, or PR. It was explicitly excluded from the allocator candidate set. #931 stays blocked until this PR is independently approved, merged, deployed, and the fleet restarted and commissioned, because the running servers continue to execute the pre-fix guard until then.
Handoff
WHO_IS_NEXT: reviewer — independent review against the #941 acceptance criteria. Do not self-review or self-merge.
Canonical Issue State
STATE: ready-for-review — full-suite baseline comparison now complete; the PR body's open item is closed. Head unchanged at
a09c485fc0eba75b35986a1833dba986be6c2101.WHO_IS_NEXT: reviewer
NEXT_ACTION: Review PR #942 at exact head
a09c485fc0eba75b35986a1833dba986be6c2101against the #941 acceptance criteria, using the completed baseline evidence below. Do not self-review or self-merge.NEXT_PROMPT:
WHAT_HAPPENED: Completed the full-suite baseline comparison that the PR body listed as still executing. Two attempts to baseline from the stable control checkout produced no output at all —
pytest tests/there exits without emitting a single line, in the background and in the foreground, while a single test file from the same directory runs normally (11 passed). Rather than report an unverified comparison, the baseline was instead taken in the identical worktree location by temporarily restoringworkflow_scope_guard.pyandgitea_mcp_server.pyto their8c1d22acontent and holding the new test file aside, running the suite, then restoring all three from the committed head. This also removes the location sensitivity that makes cross-directory baselines unreliable in this repository.WHY: The PR body promised this comparison and explicitly told the reviewer to treat the 28-vs-28 claim as verified only for four guard-critical failures until the run was posted. It is now verified for all 28.
RELATED_PRS: PR #942 (this PR, open, Closes #941). PR #926 (merged, closed #892). PR #940 (merged, delivered #930).
BLOCKERS: none blocking review. Issue #931 stays blocked until this PR is approved, merged, deployed, and the fleet restarted and commissioned.
VALIDATION: Pre-fix run in the worktree, production files reverted to
8c1d22aand the new test file held aside —28 failed, 5501 passed, 6 skipped, 994 subtests passed in 182.50s. Post-fix run in the identical location —28 failed, 5525 passed, 6 skipped, 994 subtests passed in 147.74s. The twoFAILEDlists were extracted, sorted, and compared withcomm: zero entries present only post-fix, zero present only pre-fix. The failure sets are identical, so there are no regressions and no accidental fixes. The pass delta of exactly +24 is accounted for bytests/test_issue_941_scope_guard_bootstrap_wiring.py, which contributes 24 tests. After the comparison, all three files were restored fromHEAD; the worktree is clean ata09c485fc0eba75b35986a1833dba986be6c2101and the control checkout is clean onmasterat8c1d22a658ecb5715e3f4db6eb7ebb408830c101. The published branch head is unchanged, so this comment does not invalidate the reviewer pin.LAST_UPDATED_BY: author / jcwalker3 / prgs-author / session prgs-author-14609-c5ebad14
Baseline comparison
8c1d22a, new test held asidea09c485fThe 28 pre-existing failures span
test_branch_cleanup_guard,test_commit_payloads,test_dirty_orphan_worktree_recovery,test_issue_702_review_findings_f1_f6,test_issue_781_edit_issue_tool,test_issue_784_dependency_edges,test_mcp_server,test_post_merge_moot_lease,test_pr_ownership_issue_pr_mismatch,test_preflight_workspace_repo_forwarding,test_reconciler_cleanup_integration,test_reconciler_close_workspace_guard,test_reconciler_supersession_close, andtest_workspace_guard_alignment. None is introduced or altered by this change.Four of them assert that ordinary author mutation stays blocked on the control checkout — the property this PR must not weaken. They fail identically before and after, and were additionally re-run on unmodified
masterin the control checkout, where they also fail (4 failed in 2.92s). Their failure is therefore pre-existing and independent of this change, not evidence that the guard was loosened. The positive proof that ordinary control-checkout mutation still fails closed is in the new regression file:commit_filesandlock_issuefrom a clean control checkout both still raise, valid bootstrap evidence cannot be smuggled onto another task, and a dirty control checkout still blocks the bootstrap task.Separate observation, not part of this PR
pytest tests/produces no output whatsoever when invoked from the stable control checkout, in background and foreground, while individual test files from that same directory run normally. That is unrelated to this change — it reproduces on unmodifiedmaster— but it makes control-checkout baselines unusable and is worth a separate issue. It is plausibly connected to #927 (collection recursing intobranches/), which has an open PR #928. No issue was filed for it from this session, which is scoped to #941 only.repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #942
issue: #941
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 825-bf1d3c57e99f
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr942-941
phase: claimed
candidate_head:
a09c485fc0target_branch: master
target_branch_sha:
8c1d22a658last_activity: 2026-07-26T11:09:15Z
expires_at: 2026-07-26T11:19:15Z
blocker: none
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #942
issue: #941
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 825-bf1d3c57e99f
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr942-941
phase: claimed
candidate_head:
a09c485fc0target_branch: master
target_branch_sha:
8c1d22a658last_activity: 2026-07-26T11:11:52Z
expires_at: 2026-07-26T11:21:52Z
blocker: none
Canonical PR State
STATE: approved-at-current-head
WHO_IS_NEXT: merger
NEXT_ACTION: Merge PR #942 into
masterat exact heada09c485fc0eba75b35986a1833dba986be6c2101using the sanctionedgitea-mergernamespace. This reviewer did not merge and did not modify any tracked file.NEXT_PROMPT:
WHAT_HAPPENED: Independent reviewer review of PR #942 at exact head
a09c485fc0eba75b35986a1833dba986be6c2101. The diff is one commit againstmasterat8c1d22a658ecb5715e3f4db6eb7ebb408830c101, touching exactlyworkflow_scope_guard.py,gitea_mcp_server.py, andtests/test_issue_941_scope_guard_bootstrap_wiring.py(+408 / -2). The change wires the third enforcement path onto the canonicalcreate_issue_bootstrap.bootstrap_permits_control_checkoutdecision and removes the second task-name allowlist that governed the pre-ownership lock waiver. All nine #941 acceptance criteria were checked against the code and against reviewer-run tests. No blocking finding remains, so the verdict is APPROVE.WHY: PR #926 taught the canonical predicate to accept
task_scope=author_issue_bootstrapand wired it into the #274 branches-only enforcer and the #604 anti-stomp preflight, butworkflow_scope_guardkept an independent copy of the clean-root author decision keyed on a task-name allowlist that never containedbootstrap_author_issue_worktree. The waiver was therefore unreachable on the real path and the #892 deadlock stayed partially present. This PR routes that third path — and the downstreamrequire_lockderivation — through the one shared server-derived decision, so all three guards judge identical evidence per #757.ISSUE: #941
HEAD_SHA:
a09c485fc0REVIEW_STATUS: APPROVED
MERGE_READY: true
BLOCKERS: none
VALIDATION: Reviewer identity
sysadmin, profileprgs-reviewer, rolereviewer, namespacegitea-reviewer, distinct from authorjcwalker3; no self-review. Parityin_parity:true,stale:false,restart_required:false,mutation_safe:true, all heads at8c1d22a658ec. Control checkout clean undergit status --porcelain --untracked-files=all. Review performed from a dedicated detached worktreebranches/review-pr942-941at the reviewed head, clean throughout; no tracked file was modified. Remoterefs/heads/fix/issue-941-scope-guard-bootstrap-wiringresolves to the reviewed head andrefs/heads/masterto the recorded base; merge-base equals the recorded base andgit rev-list --countreturns 1.gitea_get_pr_review_feedbackreturnedreviews: []before review work, so no prior approval or change request was superseded. Author assignmentasn-15133423bf614c11and leaselease-ecf79c663f354894are bothreleasedwith a dead owner PID; repository-wide active lease count was 0 before this reviewer lease. Reviewer-run tests, all from abranches/worktree: new regression at head 24 passed; the same file on unmodified base8c1d22a658ecreproduces 5 failed / 19 passed with the real-path failure beingProductionGuardError: Workflow scope guard (#683) [missing_issue_worktree]; focused sweep across the 941, 892, 683, 757, create-issue-bootstrap, author-issue-bootstrap, anti-stomp, root-checkout-guard, and 618 suites 218 passed with 47 subtests passed; a reviewer-authored harness that computes the assessment through the real_create_issue_bootstrap_assessmentrather than mocking it, then drives both the #274 and #683 guards, 5 passed at head with the positive case failing on base. Full-suite baseline equivalence was established by this reviewer rather than assumed: head 28 failed / 5525 passed / 6 skipped / 994 subtests, base 28 failed / 5501 passed / 6 skipped / 994 subtests, and the sortedFAILEDname sets diff empty at 28 versus 28. The pass delta of exactly +24 equals the new test file, so no regression is introduced. Issue #931 received no implementation artifact: no local branch, no remote ref matching*931*onprgs, no registered worktree, no pull request in a complete 14-PR open inventory, and the issue remains open,status:ready, unassigned.NATIVE_REVIEW_PROOF: Submitted through the native
gitea-reviewerMCP namespace viagitea_submit_pr_reviewaftergitea_load_review_workflow(sourceskills/llm-project-workflow/workflows/review-merge-pr.md, hash263d0a6cb8a6, boundary clean) andgitea_mark_final_review_decisionhead-scoped toa09c485fc0eba75b35986a1833dba986be6c2101. Native runtime:native_mcp_transport:true,production_native_mcp_transport:true,pytest:false, modeproduction, transportstdio, entrypointmcp_server, pid 825, token fingerprint8700c667bf00f4ef. Reviewer PR lease session825-bf1d3c57e99f, lease comment17432, candidate head pinned to the reviewed head. Notea, nocurl, no raw API, no direct database access.LAST_UPDATED_BY: reviewer / sysadmin / prgs-reviewer / session 825-bf1d3c57e99f
Findings
No blocking findings. Severity legend: BLOCKER, MAJOR, MINOR, NIT, OBSERVATION.
Acceptance-criteria verification
AC1 — canonical decision replaces the task-name allowlist. Met.
workflow_scope_guard.assess_root_source_mutation(workflow_scope_guard.py:347-359) delegates the clean-root author case tocreate_issue_bootstrap.bootstrap_permits_control_checkout. A sweep of production call sites shows every path is wired:assess_root_source_mutationhas one caller (workflow_scope_guard.py:437),assess_production_mutation_guardsone (gitea_mcp_server.py:1742), and_enforce_issue_scope_guardtwo (gitea_mcp_server.py:1544andgitea_mcp_server.py:1584), both passing the assessment already computed one line above for the #274 guard.BLOCKER_MISSING_WORKTREEhas exactly one raise site (workflow_scope_guard.py:366), now behind the canonical decision. No remaining production use ofis_create_issue_taskdecides the bootstrap case.AC2 — a correctly scoped bootstrap proceeds from a clean control checkout. Met, verified independently. A reviewer harness computed the assessment through the real
_create_issue_bootstrap_assessmentfrom a temporary git control checkout and passed it to the #274 and #683 guards exactly asverify_preflight_puritydoes. The bootstrap task clears both and the assessment carriestask_scope=author_issue_bootstrapwithallowed=true.AC3 — ordinary control-checkout mutation stays forbidden. Met. On real computed evidence,
commit_filesandlock_issuefrom the control checkout still raise, a dirty control checkout still blocks the bootstrap task, and a drifted head with remote tip unequal to local tip still blocks it. Cross-task smuggling of valid bootstrap evidence ontocommit_filesis refused by the predicate's exacttask_scopematch.AC4 — missing, malformed, incorrect, or mismatched evidence fails closed. Met.
create_issue_bootstrap.py:253-314returnsFalsefor a non-dict, a non-bootstrap task, any missing or contradictory disposition, non-emptyreasons, a mismatchedtask_scope, abootstrap_pathother thanclean_canonical_control_checkout, dirty files,under_branches, unverified or unequal base tips re-derived rather than trusted, and any workspace or repo-root binding that is not the canonical control checkout. Each case leaves the ordinary block in force.AC5 — no general bypass. Met. The waiver is reachable only inside the pre-existing
not under_branches and workspace == root and not dirty_src and role == "author"arm and only for the one sanctioned task. Evidence is server-derived from inspected repository state; the new parameters live on internal helpers and are never accepted as an MCP tool argument. The pre-ownership lock waiver atgitea_mcp_server.py:1729-1740derives from the same decision, and an explicitrequire_author_lock=Truefrom a caller still overrides it in the fail-closed direction.assess_issue_scope_ownershipis untouched, so a session locked to a different issue still blocks as out-of-scope.AC6 — existing create_issue behaviour unchanged. Met. The
is_create_issue_taskarm is evaluated first and is unmodified. Forcreate_issuethe new conjunct cannot changerequire_lock, becausenot is_create_issueis already false.AC7 — #274, #604, #618, #683 protections not weakened. Met. The change is additive threading plus one
elifarm; nothing is removed or loosened. The reconciler exemption, the dirty-root diagnostic block, and the branches-only rule retain their prior behaviour.AC8 and AC9 — real-path regression that fails before the fix. Met. The new file drives the real enforcer rather than the authorization helper in isolation, and on unmodified master it fails with the exact production refusal, not merely a signature error.
Non-blocking items
workflow_scope_guard.py:374. The friendlierEXACT_NEXT_ACTION_BOOTSTRAPguidance string is still selected viais_create_issue_taskalone, so a dirty control checkout under the bootstrap task returns the generic root-diagnostic next action rather than the bootstrap-specific one. The block itself is correct; only the operator guidance text differs. No change required for this PR.tests/test_issue_941_scope_guard_bootstrap_wiring.py:148. The harness mocks_create_issue_bootstrap_assessment, so the new file does not itself exercise the real assessment production for the bootstrap task, nor the two threading lines added toverify_preflight_purity. This reviewer closed that gap with an independent harness and found the behaviour correct, so it is not actionable here.gitea_bootstrap_author_issue_worktreetool succeeds end to end necessarily awaits merge, deployment, fleet restart, and commissioning, because running servers execute the pre-fix guard until then. The PR body states this correctly and does not overclaim.Break-glass provenance
The one-time operator authorization recorded in issue comment
17385was scoped to #941, one branch, one worktree, at the verified live master SHA, and is expired. It did not broaden the delivered change: the diff is the three declared files, adds no manual worktree escape hatch, no role-permission change, no transport work, and no refactoring beyond the wiring.Reviewer evidence correction to the PR body
The PR body asked the reviewer to treat the 28-versus-28 comparison as verified only for four failures, because the baseline run was still executing at publication. That caveat is now resolved: this reviewer ran both full suites and diffed the sorted failure name sets mechanically, and they are identical.
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #942
issue: #941
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 825-bf1d3c57e99f
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr942-941
phase: released
candidate_head:
a09c485fc0target_branch: master
target_branch_sha:
8c1d22a658last_activity: 2026-07-26T11:14:21Z
expires_at: 2026-07-26T11:24:21Z
blocker: manual-release
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #942
issue: #941
reviewer_identity: sysadmin
profile: prgs-merger
session_id: 74405-788d0a8e91a5
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr942-941
phase: claimed
candidate_head:
a09c485fc0target_branch: master
target_branch_sha:
8c1d22a658last_activity: 2026-07-26T11:18:55Z
expires_at: 2026-07-26T11:28:55Z
blocker: none
Stale #332 review-decision lock cleanup (#594)
Status: APPLIED
sysadminprgs-merger2026-07-26T11:20:03.646732+00:00approveon PR fix(scope): wire author bootstrap scope into workflow scope guard (#942)closed(merged=True)aab54d4825270f5a5c6f9c1abc1ab09eb4f3e2181prgs-reviewerManual deletion of session-state files is not the workflow.
This path only clears a lock when the referenced PR is merged/closed.