fix: mutation budget counts server-side changes only (Closes #617) #775
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#775
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 #617
Head
Published branch head:
296601647d3f0c067a656aa55dff2793d7b0143f(basemaster@702ceb2480704a08c3f48f7fa0f64c6f08548465, 0 commits behind).Provenance
Resumed from a dead author session's preserved unpublished commit
b46f0f9f138d569edbc73e0d36df4b34239f9934, recovered entirely through native MCP:gitea_lock_issueunpublished-claim recovery (#772):recovery_mode=unpublished_claim,recorded_base=0568f44c,accepted_head=b46f0f9fprovendescends_from_recorded_base, CAS on prior generation (dead pid 68614 to replacement 65541).master(merge,b46f0f9preserved as ancestor); published content is base-masterplus this delta.Changes
Auto-mode classifier now distinguishes four attempt outcomes and counts only durable server-side Gitea state as mutation budget:
mutation_budget_classifier.py(new):classify_mutation_attemptreturns one of local validator rejection,capability_gate_rejection,transport_failure_before_api, successful server-side mutation (proven bycomment_id/ label / review id / merge result); plus attempt-ledger recording and final-report accounting.final_report_validator.py(+72): wires a shared rule requiring the final report to separately account for local failed attempts, blocked API attempts, and successful server-side mutations, cross-checked against the attempt ledger.tests/test_mutation_budget_classifier.py(new): 32 tests.Acceptance criteria
[THREAD STATE LEDGER]pre-API; missing## Canonical Issue Statepre-API; corrected comment after two local rejections allowed; successful comment withcomment_idcounts one; transport-before-API not counted; capability gate before API not counted) — covered.Validation
Runner:
/opt/homebrew/bin/python3 -m pytest(pytest 9.0.3).tests/test_mutation_budget_classifier.py: 32 passed.-k "final_report or validator"): 170 passed.Baseline proof for the 11 failures
All 11 reproduce identically on the pristine current
master702ceb2control checkout, so they are pre-existing and not introduced by this branch (signature: stale mocks expectingverify_preflight_purity('prgs', task=...)without theorg=/repo=arguments added by #735). Failing set:tests/test_commit_payloads.py(6),tests/test_issue_702_review_findings_f1_f6.py(2),tests/test_mcp_server.py::TestPreflightVerification::test_declared_clean_task_worktree_ignores_control_checkout_violation,tests/test_post_merge_moot_lease.py::...test_acquire_tool_fails_closed_on_merged_pr_without_posting,tests/test_reconciler_supersession_close.py::...test_tool_posts_comment_and_closes_superseded_pr_issue.git diff --checkclean; no secrets; scope limited to the three files above.CTH: Author Handoff
Canonical Issue State
STATE: author-complete-awaiting-independent-review
WHO_IS_NEXT: reviewer
NEXT_ACTION: run an independent prgs-reviewer review of PR #775 at head
296601647dand submit a formal verdictNEXT_PROMPT: perform one independent reviewer phase for Gitea-Tools PR #775 (issue #617) at head 296601647d3f0c067a656aa55dff2793d7b0143f; verify the mutation-budget classifier scope is limited to the three files, confirm the 11 full-suite failures reproduce on pristine master
702ceb2and are pre-existing, then submit APPROVE or REQUEST_CHANGESWHAT_HAPPENED: recovered the dead author session preserved commit b46f0f9f138d569edbc73e0d36df4b34239f9934 through native MCP unpublished-claim recovery (#772) and author-worktree lock binding (#618), reconciled onto current master, and published the branch head via native commit
WHY: the author role cannot review or merge its own PR, so an independent reviewer verdict is required before merge
RELATED_PRS: PR #775 (head
296601647d), closes issue #617BLOCKERS: none
VALIDATION: focused classifier tests 32 passed; validator suites 170 passed; full suite 3933 passed, 6 skipped, 11 failed with all 11 reproduced identically on pristine master
702ceb2(pre-existing, not branch-caused)LAST_UPDATED_BY: jcwalker3 (prgs-author)
Author lock for issue #617 remains live by design; do not release or edit it manually.
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #775
issue: #617
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 65607-bb4a5c9175ec
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr-775
phase: claimed
candidate_head:
296601647dtarget_branch: master
target_branch_sha:
702ceb2480last_activity: 2026-07-21T00:19:13Z
expires_at: 2026-07-21T00:29:13Z
blocker: none
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #775
issue: #617
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: llm-lock-canary-gt-controller-702ceb2-20260720
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr-775
phase: claimed
candidate_head:
296601647dtarget_branch: master
target_branch_sha:
702ceb2480last_activity: 2026-07-21T00:30:05Z
expires_at: 2026-07-21T00:40:05Z
blocker: none
Canonical PR State
STATE: approved
WHO_IS_NEXT: user
NEXT_ACTION: Operator must explicitly authorize merge of PR #775; only then may merger merge at pinned head
NEXT_PROMPT:
WHAT_HAPPENED: Canary fire 3 formal review completed; APPROVE submitted at current head; merge not performed
WHY: Classifier correctly counts only durable server-side mutations; pre-API failures do not consume budget; ambiguous outcomes fail closed; final-report ledger accounting correct
ISSUE: #617
HEAD_SHA:
296601647dREVIEW_STATUS: approved / approval_at_current_head
MERGE_READY: false
BLOCKERS: operator merge authorization not granted this canary fire
VALIDATION: pytest tests/test_mutation_budget_classifier.py 32 passed; final_report or mutation_budget 118 passed; eligibility sysadmin!=jcwalker3; control clean @
702ceb2480NATIVE_REVIEW_PROOF: transport=native_mcp; entrypoint=mcp_server; token_fingerprint=beafd9c22e5b95be
LAST_UPDATED_BY: sysadmin
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #775
issue: #617
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: llm-lock-canary-gt-controller-702ceb2-20260720
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr-775
phase: released
candidate_head:
296601647dtarget_branch: master
target_branch_sha:
702ceb2480last_activity: 2026-07-21T00:31:10Z
expires_at: 2026-07-21T00:41:10Z
blocker: manual-release
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #775
issue: #617
reviewer_identity: sysadmin
profile: prgs-merger
session_id: 80637-b0e55d7c910a
worktree: branches/review-pr-775
phase: claimed
candidate_head:
296601647dtarget_branch: master
target_branch_sha:
702ceb2480last_activity: 2026-07-21T01:28:15Z
expires_at: 2026-07-21T01:38:15Z
blocker: none
Stale #332 review-decision lock cleanup (#594)
Status: APPLIED
sysadminprgs-merger2026-07-21T01:28:33.325537+00:00approveon PR fix: mutation budget counts server-side changes only (Closes #617) (#775)closed(merged=True)52ded0ea714b31468ba991bac61084e103b08dcb1prgs-reviewerManual deletion of session-state files is not the workflow.
This path only clears a lock when the referenced PR is merged/closed.
Canonical Issue State
STATE: terminal_cleanup_complete_with_preserved_local_branch_and_file_lock
WHO_IS_NEXT: user
NEXT_ACTION: No further reconciler action required for PR #775 / Issue #617. Optional operator-only follow-up if durable author issue-lock file or local non-ancestor branch ref must be force-removed outside this reconciler path.
NEXT_PROMPT:
WHAT_HAPPENED: prgs-reconciler terminal cleanup for merged PR #775 / closed Issue #617. Gate Zero PASS at
52ded0ea. Removed residual status:pr-open. Moot merger lease 80637-b0e55d7c910a/comment 13485 assessed then found naturally expired. Removed clean worktrees review-pr-775, issue-617-mutation-budget-classifier, baseline-master-617 via scripts/worktree-clean. Deleted remote fix/issue-617-mutation-budget-classifier via gitea_cleanup_merged_pr_branch (verified_absent). Local branch -d refused (not fully merged). Author file lock preserved.WHY: Post-merge residual cleanup only; prove equivalence before removal; never force-delete; fail closed on unmerged local branch ancestry.
RELATED_PRS: #775 (this PR; merge
52ded0ea); closes #617; review_id 489 APPROVED at296601647dBLOCKERS: none for terminal cleanup of landable remote/worktree residue. Non-blocking preserves: (1) local branch fix/issue-617-mutation-budget-classifier @ 174310d4 — safe git branch -d fails despite identical tree
c3fa30c1to master/merged head; (2) file lock ~/.cache/gitea-tools/issue-locks/prgs-Scaled-Tech-Consulting-Gitea-Tools-617.json — dead author pids, no sanctioned reconciler unlock tool.VALIDATION: Gate Zero parity in_parity at 52ded0ea; whoami sysadmin/prgs-reconciler; PR closed merge_commit_sha=52ded0ea; Issue 617 closed labels=[bug,type:guardrail]; review 489 APPROVED at 29660164; trees author=merged=master=c3fa30c1; remote branch verified_absent; worktrees absent; control clean porcelain=0 @
52ded0eaLAST_UPDATED_BY: sysadmin (prgs-reconciler)
Terminal cleanup ledger — PR #775 / Issue #617
Gate Zero
52ded0ea71(fetch prune; FF not needed; local master == prgs/master).Terminal verification
52ded0ea71.296601647dis on live master (ancestor).29660164(not re-reviewed).Moot lease
Leases
Mutations + readback
Comparison 174310d4 vs
29660164Identical tree
c3fa30c183(also equals master). No unique unpublished content. Author not merge-ancestor of master; merged head is. Clean worktrees (0 dirty).Untouched
#681, preserve refs, unrelated dirty worktrees, branches/mcp-author-clean-ns.
Control final
Clean master @
52ded0ea71.