ADR: stable control runtime vs dev runtime for Gitea MCP #615
Closed
opened 2026-07-09 19:15:45 -05:00 by jcwalker3
·
12 comments
No Branch/Tag Specified
master
fix/issue-987-native-mcp-bootstrap
feat/issue-985-project-scoped-launcher-identity
fix/issue-983-cross-repo-base-ref
feat/issue-980-stale-worker-retirement
fix/issue-975-client-identity-heartbeat
fix/issue-973-cross-repo-canonical-roots
fix/issue-970-safely-resolve-missing-worktrees
fix/issue-969-native-mcp-bootstrap
feat/issue-664-break-glass-restart
feat/issue-708-mcp-namespace-attachment
feat/issue-665-restart-audit
fix/issue-700-durable-walls
fix/issue-704-prevent-env-workspace-bindings
feat/issue-707-cross-project-boundaries
fix/issue-690-review-profile-switch-guard
fix/issue-953-bootstrap-lock-provenance
feat/issue-949-native-fleet-inventory
fix/issue-943-runtime-context-helpers
fix/issue-945-owning-pr-renewal-evidence
fix/issue-941-scope-guard-bootstrap-wiring
docs/issue-930-remote-mcp-coupling-inventory
fix/issue-892-author-bootstrap-deadlock
fix/issue-686-detect-reject-manual-mcp
fix/issue-672-mcp-config-drift
fix/issue-689-deterministic-mcp-namespace
feat/issue-666-concurrent-mcp-restart-tests
feat/issue-659-maintenance-drain-mode
feat/issue-648-notifications-console
fix/issue-670-direct-master-incident
feat/issue-644-console-recovery
feat/issue-650-providers-insights
feat/issue-669-scoped-component-recovery
docs/issue-668-mcp-ha-rolling-restart
feat/issue-667-console-restart-controls
feat/issue-645-linkage-console
feat/issue-643-request-preview-initiate
fix/issue-897-permission-stale-runtime-classification
feat/issue-641-runtime-session-view
feat/issue-663-restart-classes
feat/issue-661-drain-proof-hard-gate
fix/issue-854-semantic-container-exclusion
issue-640
fix/issue-682-starlette-httpx2
v1.1.0
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
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
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
Something is not working
This issue or pull request already exists
New feature
Need some help
Something is wrong
More information is needed
This won't be fixed
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Scaled-Tech-Consulting/Gitea-Tools#615
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.
Problem
Author/reviewer/merger/reconciler sessions have historically restarted, killed, or relaunched the Gitea MCP server from development worktrees, or edited the stable runtime checkout. That destabilizes the control plane used for real Gitea mutations and causes EOF, stale-runtime, and mixed-identity failures mid-workflow.
Goal
Establish a durable stable control runtime vs dev runtime policy:
branches/worktrees and optional dev/test MCP runtimes.Policy (normative)
Stable control runtime
The Gitea MCP server used for real workflow mutations is the stable control runtime.
Forbidden for normal author / reviewer / merger / reconciler sessions
Development / testing
branches/worktreesPromotion (operator / release-manager only)
Promotion to the stable control runtime must record:
Unhealthy stable runtime
If the stable MCP runtime is unhealthy, normal PR/review/merge work must stop until the runtime is restored or a controlled promotion/rollback completes.
Related docs
docs/mcp-namespace-health.md(#543) — client-namespace health; no PID kill for EOF recoverydocs/mcp-namespace-eof-recovery.md— reconnect-only recoverydocs/mcp-daemon-import-guard.md(#558) — sanctioned daemon onlydocs/bootstrap-review-path.md(#557) — narrow controller bootstrap when live runtime cannot review itselfAcceptance criteria
docs/architecture/documenting this policy.Labels
workflow-hardening, mcp-health, stale-runtime, safety, documentation, type:guardrail, status:ready
Canonical Issue State
STATE: open — ADR tracker; enforcement-layer acceptance criteria being added
WHO_IS_NEXT: author
NEXT_ACTION: Implement #615 runtime mode/SHA reporting and fail-closed mutation gates
NEXT_PROMPT:
WHAT_HAPPENED: Runtime enforcement + proof requirements surfaced by the 2026-07-09 transport flap (#584) appended to the #615 ADR tracker.
WHY: The ADR/policy alone (#615) lacks runtime enforcement and proof requirements; the flap showed all gitea-* namespaces drop together and that author proof does not prove the other namespaces.
RELATED_PRS: none
BLOCKERS: none
VALIDATION: 2026-07-09 clean-binding proof recorded on #584 comment 9115
LAST_UPDATED_BY: prgs-author (jcwalker3)
[THREAD STATE LEDGER] Issue #615 — enforcement-layer acceptance criteria added
What is true now:
What changed:
What is blocked:
Who/what acts next:
Missing acceptance criteria — enforcement layer (from live incident 2026-07-09)
#615 covers the ADR/policy. Adding the runtime enforcement + proof requirements
surfaced by the mid-session transport flap tracked on #584. In that incident,
all
gitea-*tools dropped and self-recovered. Workspace binding was cleanbefore the drop, so the observed failure was not a stale process-root defect;
it was a transport/stale-runtime fault.
Add to runtime context / health checks
Report:
stable-control|dev-test|unknownAdd mutation gates — fail closed when
dev-testand target is the real production repounknownAdd post-transport-flap proof
After any MCP transport flap or daemon restart, each namespace must be independently re-proven before mutation:
Required proof per namespace:
whoamiAuthor proof alone must not be described as global MCP reliability proof.
Extend acceptance criteria
[THREAD STATE LEDGER]examples added for:Link
Transport-flap symptom tracker: #584.
See #584 comment 9115 for the 2026-07-09 clean-binding proof.
Issue claim heartbeat
Canonical Issue State
STATE: open — enforcement layer implemented locally; native publication unavailable this session
WHO_IS_NEXT: controller
NEXT_ACTION: Restore a native author publication path, then re-run the full work-issue workflow to publish branch feat/issue-615-runtime-mode-enforcement and open its PR
NEXT_PROMPT:
WHAT_HAPPENED: The #615 enforcement layer (acceptance criteria 6-11) was implemented and locally committed in the session worktree. Native publication through gitea_commit_files fails closed on the #274 branches-only mutation guard, so no Gitea branch or PR exists yet.
WHY: gitea_commit_files exposes no worktree_path parameter. Author workspace binding resolves only from the worktree_path argument, GITEA_ACTIVE_WORKTREE, or GITEA_AUTHOR_WORKTREE, none of which a session can supply to that tool, so the workspace falls back to the stable control checkout and the branches-only guard refuses the mutation.
RELATED_PRS: none
BLOCKERS: environment/tooling blocker — native author publication path unavailable (gitea_commit_files workspace binding)
VALIDATION: 2026-07-20 full suite in the session worktree: 3827 passed, 6 skipped, 2 failed; clean baseline worktree at master
059ee77c1f: 3780 passed, 6 skipped, same 2 failures (test_issue_702_review_findings_f1_f6.py::TestF1RecoveryBeforeTerminalProbe::test_removed_worktree_recovers_before_probe and test_reconciler_supersession_close.py::TestReconcilerSupersessionMcpTool::test_tool_posts_comment_and_closes_superseded_pr_issue)LAST_UPDATED_BY: prgs-author (jcwalker3)
[THREAD STATE LEDGER] Issue #615 — enforcement layer implemented locally; native publication unavailable
What is true now:
9bf3acfcreated on branch feat/issue-615-runtime-mode-enforcement in worktree branches/issue-615-runtime-mode-enforcement; no Gitea branch and no PR exist059ee77What changed:
What is blocked:
Who/what acts next:
9bf3acfin branches/issue-615-runtime-mode-enforcementAuthor work record (#615 acceptance criteria 6-11)
What the change contains
stable_control_runtime.py(new)classify_runtime_mode()→stable-control|dev-test|unknown, inferred from process root and checkout branch, with an explicitGITEA_MCP_RUNTIME_MODEoperator declaration for packaged layouts that have no git checkout (AC 6).build_runtime_report()→ runtime mode, git SHA, branch, checkout path, MCP process root, active task workspace, repo binding, profile, identity, dirty files, workspace alignment,real_mutations_allowed(AC 6).assess_runtime_mutation_gate()→ fails closed on dev-test targeting production, unknown runtime, dirty stable checkout, dev-worktree-launched runtime, and unsafe process-root/workspace alignment (AC 7).assess_promotion_record()→ promotion must record previous and promoted SHAs plus restart method, health, identity, profile, workspace, capability, and rollback proof (AC 4).gitea_mcp_server.py_profile_operation_gate()consults_runtime_mode_block()alongside the #420 parity gate.gitea.readis never blocked, so an operator can still inspect a sick runtime.gitea_get_runtime_context()reports the live runtime understable_control_runtimeand points at the promotion runbook when mutations are refused.Docs and tooling
docs/stable-runtime-promotion-runbook.md(new): operator promotion procedure, the eleven required record fields, per-namespace re-proving, rollback (AC 10).scripts/promote-stable-runtime(new): read-only helper that emits and validates a promotion record; it never restarts, reloads, or kills anything (AC 10).[THREAD STATE LEDGER]examples added: runtime healthy, transport flap recovered, namespace not yet re-proven, promotion completed, rollback required (AC 11).Validation
tests/test_stable_control_runtime.py(new): 47 tests covering every AC 9 case — stable healthy runtime allows real mutations, dev/test runtime blocks real production mutations, unknown runtime blocks mutations, normal workflow cannot restart stable MCP, transport recovery requires namespace-specific re-proving, author proof does not imply reviewer/merger/reconciler proof, promotion records previous and promoted SHAs.059ee77: 3780 passed, 6 skipped, 2 failed — identical failure signatures, so both are pre-existing and unrelated to this change.git diff --checkclean.Blocker detail
gitea_commit_filesrefused with the #274 branches-only mutation guard:workspace is the stable control checkout. The tool has noworktree_pathparameter, andresolve_namespace_workspace()accepts an author workspace only from aworktree_pathargument,GITEA_ACTIVE_WORKTREE, orGITEA_AUTHOR_WORKTREE— none reachable from a session for this tool — so it falls back to the process project root and fails closed. There is no other native author publish/push tool. No fallback was attempted: no direct git push, no raw API, no daemon restart, no lock-file edit.This is a pre-existing tooling gap, not a defect in the #615 change. It should be tracked in its own issue by a run started in issue-creation mode; this run is
work-issuemode and does not mix modes.Canonical Issue State
STATE: open — enforcement layer implemented and revalidated locally; author ownership cannot be re-established
WHO_IS_NEXT: controller
NEXT_ACTION: Restore an author ownership path for an already-implemented worktree, and an author publication path for gitea_commit_files, then re-run the full work-issue workflow for #615
NEXT_PROMPT:
WHAT_HAPPENED: Implementation commit
9bf3acfwas re-verified and fully revalidated this run. Native ownership recovery through gitea_lock_issue failed closed, so no publication was attempted and no Gitea state changed beyond this comment.WHY: The issue-lock store is absent, which removes the dead-session recovery path, and the fresh-acquisition path requires a base-equivalent worktree that the completed implementation necessarily violates.
RELATED_PRS: none
BLOCKERS: environment/tooling blocker — author ownership path unavailable (issue-lock store absent; base-equivalence versus completed implementation), and author publication path unavailable (gitea_commit_files workspace binding)
VALIDATION: 2026-07-20 session worktree full suite: 3827 passed, 6 skipped, 493 subtests passed, 2 failed (test_issue_702_review_findings_f1_f6.py::TestF1RecoveryBeforeTerminalProbe::test_removed_worktree_recovers_before_probe and test_reconciler_supersession_close.py::TestReconcilerSupersessionMcpTool::test_tool_posts_comment_and_closes_superseded_pr_issue); both signatures match the baseline recorded on comment 13253 at this identical master SHA
059ee77c1fand neither touches a file in this diff; focused tests/test_stable_control_runtime.py 47 passed; git diff --check cleanLAST_UPDATED_BY: prgs-author (jcwalker3)
[THREAD STATE LEDGER] Issue #615 — implementation revalidated; author ownership path unavailable
What is true now:
9bf3acfon branch feat/issue-615-runtime-mode-enforcement in worktree branches/issue-615-runtime-mode-enforcement, clean, one commit ahead of master 059ee77; no Gitea branch and no PR existWhat changed:
9bf3acfre-verified as a single in-scope commit across 8 files with no unrelated or generated filesWhat is blocked:
Who/what acts next:
9bf3acfin branches/issue-615-runtime-mode-enforcementAuthor run record
What was verified
Worktree
branches/issue-615-runtime-mode-enforcementis clean and sits at9bf3acf, whose parent is exactly the live master059ee77. The commit spans 8 files, 1714 insertions, 6 deletions:stable_control_runtime.py(new, 628 lines)tests/test_stable_control_runtime.py(new, 472 lines)thread_state_ledger_examples.py(new, 187 lines)scripts/promote-stable-runtime(new, 171 lines)docs/stable-runtime-promotion-runbook.md(new, 121 lines)gitea_mcp_server.py(+125)docs/architecture/mcp-stable-control-runtime-policy-adr.md(+15)docs/llm-workflow-runbooks.md(+1)No unrelated files, generated files, caches, credentials, or temporary artifacts. No scope drift beyond acceptance criteria 6-11.
Ownership attempt
The lock was attempted exactly once, after a fresh
gitea_whoamiand agitea_resolve_task_capability(task=lock_issue)that returnedallowed_in_current_session: true. It refused with the base-equivalence rule plus a dead-session recovery refusal.Reading
issue_lock_recovery.pyshows why recovery cannot succeed for this issue: a granted recovery is built only when an owning open PR head is present and relates to the recorded head as equal or strict-descendant. #615 has neither a published branch nor a PR, so that branch of the logic is unreachable, independent of the lock store's state.The lock store itself is absent from disk, so there is no dead-session record to match in the first place. The two facts compose into a closed loop: fresh acquisition requires a worktree that has not started implementation, and recovery requires an artifact that only publication can create.
Deliberately avoided
gitea_commit_fileswas not attempted this run. Author ownership was never proven, and the workflow forbids implementation mutation without it. Its own gap is also unchanged by construction: the tool still exposes noworktree_pathparameter and master has not advanced since comment 13253, so it would refuse identically on the #274 branches-only guard.No fallback of any kind was used: no direct git push, no raw API call, no browser or CLI path, no lock-file edit, no worktree reset or clean, no daemon restart, and no second issue selected.
Canonical Issue State
STATE: open — enforcement layer implemented locally at 9bf3acf; the owning-PR dead-session recovery path is structurally unreachable for this issue
WHO_IS_NEXT: controller
NEXT_ACTION: Close the author ownership gap and the author publication gap, then re-run the full work-issue workflow for #615 from the beginning
NEXT_PROMPT:
WHAT_HAPPENED: A directed resume run verified live state, found the instructed recovery premise unsupported, performed no ownership or publication mutation, and recorded this correction. gitea_lock_issue was deliberately not retried.
WHY: The instruction assumed an existing PR whose head equals
9bf3acf. No open PR exists in this repository, so the owning-PR recovery path has no PR to read and returns no exemption. Retrying gitea_lock_issue would repeat a mutation already refused at this identical master SHA with an identical worktree and head.RELATED_PRS: #616 — live state closed, merged_at 2026-07-16T14:58:44-05:00, merge_commit_sha
293808b42d, head branch docs/mcp-stable-control-runtime-policy, acceptance criteria 1-5 only, unrelated to head9bf3acfBLOCKERS: environment/tooling blocker — author ownership path unavailable (owning-PR recovery requires a PR that only publication can create; fresh acquisition refuses on base-equivalence) and author publication path unavailable (gitea_commit_files workspace binding)
VALIDATION: Not re-run this iteration, and deliberately so: master is unchanged at
059ee77c1f, the worktree is clean, and HEAD is unchanged at9bf3acf, so the recorded results remain the proof of record. Last full run (comment 13257, identical master SHA): session worktree 3827 passed, 6 skipped, 493 subtests passed, 2 failed (test_issue_702_review_findings_f1_f6.py::TestF1RecoveryBeforeTerminalProbe::test_removed_worktree_recovers_before_probe and test_reconciler_supersession_close.py::TestReconcilerSupersessionMcpTool::test_tool_posts_comment_and_closes_superseded_pr_issue); clean baseline worktree at the same master SHA 3780 passed, 6 skipped, same 2 failure signatures, so both are pre-existing and neither touches a file in this diff; focused tests/test_stable_control_runtime.py 47 passed; git diff --check cleanLAST_UPDATED_BY: prgs-author (jcwalker3)
[THREAD STATE LEDGER] Issue #615 — directed recovery premise corrected; ownership path still unavailable
What is true now:
9bf3acfon branch feat/issue-615-runtime-mode-enforcement in worktree branches/issue-615-runtime-mode-enforcement, clean, exactly one commit ahead of live master 059ee77; no Gitea branch and no PR exist for this workWhat changed:
9bf3acfWhat is blocked:
Who/what acts next:
9bf3acfin branches/issue-615-runtime-mode-enforcementAuthor run record — directed resume, corrections only
What this run was asked to do
Resume #615 only; verify that an existing PR head equals local commit 9bf3acf; recover the native issue lock through the owning-PR dead-session recovery path; post a corrected durable handoff; stop for an independent reviewer. No implementation change and no new issue allocation.
What live state showed
The first two directions could not be carried out, because they presuppose a PR that does not exist.
Open PR inventory for this repository returned zero PRs with a complete-inventory marker. PR #616, the only PR ever opened against #615, reached live state closed with merged_at 2026-07-16T14:58:44-05:00 from head branch
docs/mcp-stable-control-runtime-policyat merge_commit_sha293808b42d54c4736f8fb55f71b10d93a40ae4ea, and covered acceptance criteria 1-5. The work at9bf3acfcovers acceptance criteria 6-11 and has never been published.Why the recovery path cannot apply
Reading
issue_lock_recovery.pyrather than relying on the earlier summary: the recovery exemption builder requirespr_number, a locked branch name, andpr_head, and returnsNonewhen any is missing. When the relation is equal it further requirespr_head == local_head == remote_head; when the relation is strict-descendant it requirespr_head == recorded_headwith a distinct accepted head equal to the local head. An unpublished branch supplies neither a remote head nor a PR head, so the builder exits before any comparison. No input a session can legitimately supply changes that outcome.Correction to comment 13257
Comment 13257 stated that the durable issue-lock store was absent and inferred from that that no dead-session record existed to recover. The first half is unchanged, but the inference was too broad. The control-plane lease DB holds an active author lease for this exact issue:
lease-13750394b96b4ce4, work item 615, sessionprgs-author-62865-d5cc892b, owner pid 62865 confirmed dead (stale_dead_process), expiry2026-07-20T18:14:33Z. This does not by itself remove either gap, becausegitea_lock_issuereads the issue-lock store rather than the lease substrate, but the record exists and any operator-issued lock or recovery-mode design should reconcile the two substrates rather than assume the issue has no durable ownership trace.Implementation status
Unchanged and untouched. The worktree is clean at
9bf3acf, whose parent is exactly live master059ee77. The commit spans 8 files, 1714 insertions, 6 deletions:stable_control_runtime.py(new),tests/test_stable_control_runtime.py(new),thread_state_ledger_examples.py(new),scripts/promote-stable-runtime(new),docs/stable-runtime-promotion-runbook.md(new),gitea_mcp_server.py,docs/architecture/mcp-stable-control-runtime-policy-adr.md,docs/llm-workflow-runbooks.md. No unrelated, generated, or temporary files.Actions deliberately not attempted
gitea_lock_issuewas not retried. Master, worktree, and head are identical to the run recorded in comment 13257, so a retry would repeat a proven-failing mutation rather than test anything new.gitea_commit_fileswas not attempted, because author ownership was never proven and its own gap is unchanged. No direct git push, no raw API call, no browser or CLI path, no lock-file or lease-record edit, no worktree reset or clean, no daemon restart, no implementation change, and no second issue selected.Canonical Issue State
STATE: open — enforcement layer published as PR #770 at head 9bf3acf; author ownership re-established through owning-PR dead-session recovery; awaiting an independent reviewer
WHO_IS_NEXT: reviewer
NEXT_ACTION: Run an independent native reviewer against PR #770 pinned to head
9bf3acfef6NEXT_PROMPT:
WHAT_HAPPENED: A directed resume run verified that PR #770 now exists at head
9bf3acf, matching the local worktree head exactly, and recovered the native #615 issue lock through the owning-PR dead-session recovery path. No implementation file was modified and no second issue was allocated.WHY: Comment 13262 recorded that no PR existed and that owning-PR recovery was therefore structurally unreachable. PR #770 was created at 2026-07-20T10:35:04-05:00, after that comment was written at 10:29:19-05:00. The publication supplied the pr_head that the recovery builder requires, so the path that was unreachable then is reachable now and was exercised successfully this run.
RELATED_PRS: #770 — open, base master, head
9bf3acfef6, source branch feat/issue-615-runtime-mode-enforcement, mergeable true, commits_behind 0; #616 — closed with merged_at 2026-07-16T14:58:44-05:00, merge_commit_sha293808b42d, acceptance criteria 1-5 only, unrelated headBLOCKERS: no blocker
VALIDATION: Not re-run this iteration, and deliberately so: this run made no implementation change, the worktree is clean, HEAD is unchanged at
9bf3acf, and master is unchanged at059ee77c1f, so the recorded results remain the proof of record. Prior full run at this identical master SHA (comment 13257): session worktree 3827 passed, 6 skipped, 493 subtests passed, 2 failed (test_issue_702_review_findings_f1_f6.py::TestF1RecoveryBeforeTerminalProbe::test_removed_worktree_recovers_before_probe and test_reconciler_supersession_close.py::TestReconcilerSupersessionMcpTool::test_tool_posts_comment_and_closes_superseded_pr_issue); clean baseline worktree at the same master SHA 3780 passed, 6 skipped, same 2 failure signatures, so both are pre-existing and neither touches a file in this diff; focused tests/test_stable_control_runtime.py 47 passed; git diff --check cleanLAST_UPDATED_BY: prgs-author (jcwalker3)
[THREAD STATE LEDGER] Issue #615 — PR #770 published at 9bf3acf; author lock recovered; reviewer is next
What is true now:
9bf3acfef6, exactly one commit ahead of live master 059ee77c1fd483da385d6ccb4d842e808fb54630; that head is published and is the live head of PR #770What changed:
9bf3acfef69bf3acfef6, pr_number 770, prior session pid 62865 confirmed dead, replacement session pid 88416What is blocked:
Who/what acts next:
9bf3acfef69bf3acfAuthor run record — directed resume, ownership recovery only
What this run was asked to do
Resume #615 only; verify the newly created PR head equals local and remote commit 9bf3acf; recover the native issue lock through the owning-PR dead-session recovery path; post a corrected durable author handoff; stop for an independent reviewer. No implementation change and no new issue allocation. All four directions were carried out.
Head verification
Three independent sources agree on the full 40-character head:
branches/issue-615-runtime-mode-enforcementHEAD:9bf3acfef681f9766ae1d93680b03996a93f98a1, on branchfeat/issue-615-runtime-mode-enforcement, clean tracked and untracked statehead_sharead through native MCP:9bf3acfef681f9766ae1d93680b03996a93f98a1remote_head:9bf3acfef681f9766ae1d93680b03996a93f98a1Base head is live master
059ee77c1fd483da385d6ccb4d842e808fb54630withcommits_behind0, so no branch sync is required.Ownership recovery
gitea_lock_issuewas called once, after a freshgitea_whoamiand agitea_resolve_task_capability(task=lock_issue)returningallowed_in_current_session: true, with the exact branch name and the exact worktree path. It granted the lock through the recovery path rather than fresh acquisition, so the base-equivalence rule that refused the two prior runs was not applied and did not need to be worked around.The refusals recorded in comments 13257 and 13262 were correct for the state that existed then. The single fact that changed is publication: with a PR head available, the recovery builder's precondition is satisfied and it returns a granted exemption whose
head_relationisequal.Correction to the substrate question raised in comment 13262
Comment 13262 noted that the control-plane lease DB and the durable issue-lock store are distinct substrates, and that lease
lease-13750394b96b4ce4existed while the issue-lock store did not. That observation stands. This run adds the resolution: recovery reads durable ownership evidence keyed to branch, worktree, head, and claimant, and once the PR head existed the evidence matched without any operator-issued lock and without reconciling the two substrates by hand. The stale lease for the dead pid 62865 remains a control-plane record; the live author lock is now held by pid 88416.Implementation status
Unchanged and untouched this run. No file under the worktree was edited, created, or deleted. The commit remains a single in-scope commit spanning 8 files, 1714 insertions, 6 deletions, covering acceptance criteria 6-11 only.
Actions deliberately not attempted
No implementation change, no commit, no push, no PR update, no amend, no rebase, no force-push. No review, approval, or merge action of any kind. No second issue selected and no allocator call. No direct git push, no raw API call, no browser or CLI path, no lock-file or lease-record hand-edit, no worktree reset or clean, no worktree or branch deletion, and no daemon restart. The control checkout was not used for task work and remains clean on master at
059ee77.Canonical Issue State
STATE: open — PR #770 independently reviewed at head 9bf3acfef681f9766ae1d93680b03996a93f98a1; REQUEST_CHANGES review posted to Gitea as review_id 483
WHO_IS_NEXT: author
NEXT_ACTION: Remediate reviewer findings F1, F2, and F3 on branch feat/issue-615-runtime-mode-enforcement, push to PR #770, and request a fresh independent review
NEXT_PROMPT:
WHAT_HAPPENED: An independent reviewer in the prgs-reviewer namespace acquired the PR #770 reviewer lease, inspected all 8 changed files at the pinned head, re-ran the focused suite, reproduced a blocking fail-closed defect directly against the PR code, and posted exactly one native REQUEST_CHANGES review to Gitea.
WHY: Acceptance criteria 6, 8, 10, and 11 are correctly implemented and well tested at the module level, but the acceptance criterion 7 alignment blocker, as derived by the server wiring, inverts its intent: it would refuse every correctly bound author, reviewer, and merger session the moment the enforcement layer is promoted, leaving gitea.read as the only surviving operation.
RELATED_PRS: #770 — open, base master, head
9bf3acfef6, review_id 483 REQUEST_CHANGES at that exact head, undismissed and not stale, mergeable true, commits_behind 0, no approval at current head; #616 — closed with merged_at 2026-07-16T14:58:44-05:00 and merge_commit_sha293808b42d, acceptance criteria 1-5 only, unrelated headBLOCKERS: code blocker — F1 fail-closed alignment derivation and F2 process-lifetime snapshot of session-scoped facts, both in gitea_mcp_server.py; test blocker — F3, acceptance criterion 9's healthy-runtime case is proven only against a fixture
VALIDATION: Reviewer re-ran tests/test_stable_control_runtime.py independently in worktree branches/review-pr-770 at head
9bf3acf: 47 passed, confirming the author's count. git diff --check clean against base059ee77c1f. Diff independently confirmed as 8 files, 1714 insertions, 6 deletions, no unrelated or generated files, no secrets, tokens, keychain identifiers, or raw service URLs. F1 reproduced by executing the PR's own build_runtime_report with runtime_mode stable-control, a clean checkout on master, and a branches/ worktree workspace: real_mutations_allowed False, blocker unsafe_process_root_workspace_alignment. The author's two full-suite failures were not re-run this session; they are recorded as pre-existing at this identical master SHA and neither touches a file in this diff.LAST_UPDATED_BY: prgs-reviewer (sysadmin)
[THREAD STATE LEDGER] Issue #615 — PR #770 reviewed at 9bf3acf; REQUEST_CHANGES posted to Gitea; author is next
What is true now:
9bf3acfef6, visible, undismissed, not staleWhat changed:
What is blocked:
Who/what acts next:
9bf3acfef6Canonical Issue State
STATE: open — review 483 findings F1, F2, and F3 remediated and fully revalidated in local commit ab34280f9025406d5c392d4e07c9d34d3ecd47fe; publication to PR #770 refused by the #274 branches-only guard, so the PR head remains the unremediated
9bf3acfef6WHO_IS_NEXT: controller
NEXT_ACTION: Restore a native author publication path for gitea_commit_files, then re-run the full work-issue workflow for #615 to publish local commit
ab34280to PR #770 and request a fresh independent reviewNEXT_PROMPT:
WHAT_HAPPENED: A directed resume run recovered the native author lock through the owning-PR dead-session recovery path, remediated all three review 483 findings, revalidated focused and full suites, proved both blocking findings against the pre-fix code independently, and committed the result locally. The single publication attempt through gitea_commit_files was refused fail-closed and was not retried.
WHY: F1 and F2 were code defects in the gitea_mcp_server.py wiring and F3 was the coverage gap that let F1 through; all three are fixed. Publication is blocked by a pre-existing environment gap unrelated to this change: the author namespace has no worktree binding, so the only native commit tool resolves its workspace to the control checkout and the #274 guard refuses.
RELATED_PRS: #770 — open, base master, head still
9bf3acfef6, review 483 REQUEST_CHANGES undismissed and not stale at that head, mergeable true, commits_behind 0, no approval at current headBLOCKERS: environment/tooling blocker — author publication path unavailable (gitea_commit_files workspace binding, #274 branches-only guard)
VALIDATION: Focused suite in the session worktree at
ab34280: tests/test_stable_control_runtime.py 52 passed (47 pre-existing plus 5 new wiring tests). Full suite atab34280: 3832 passed, 6 skipped, 493 subtests passed, 2 failed. Both failures proved pre-existing independently this session in a fresh clean baseline worktree at pristine master059ee77c1f(branches/baseline-master-615, clean before and after): identical two signatures, test_issue_702_review_findings_f1_f6.py::TestF1RecoveryBeforeTerminalProbe::test_removed_worktree_recovers_before_probe and test_reconciler_supersession_close.py::TestReconcilerSupersessionMcpTool::test_tool_posts_comment_and_closes_superseded_pr_issue; neither touches a file in this diff. git diff --check clean. F1 and F2 each reproduced against the pre-fix head9bf3acfin a separate baseline worktree before the fix was written.LAST_UPDATED_BY: prgs-author (jcwalker3)
[THREAD STATE LEDGER] Issue #615 — review 483 findings remediated locally at ab34280; publication blocked; PR #770 head unchanged
What is true now:
ab34280f90, two commits ahead of live master 059ee77c1fd483da385d6ccb4d842e808fb54630; that commit is NOT published, so PR #770 still serves9bf3acfWhat changed:
9bf3acf, pr_number 770, prior session pid 88416 confirmed dead, replacement pid 34249What is blocked:
Who/what acts next:
ab342809bf3acf, since that is the exact code review 483 rejected; merge; self-approve; dismiss review 483; open a second PR; publish with a direct git push; hand-edit the issue lock or lease record; reset or clean any worktree; allocate another issueab34280f90in branches/issue-615-runtime-mode-enforcementAuthor run record — review 483 remediation
F1 (blocking) — alignment derivation
_current_runtime_mode_reportderived the gate input asrealpath(workspace_root) == process_project_root. That redefinedworkspace_roots_aligned, whose established meaning atgitea_mcp_server.py:573is
ctx["roots_aligned"]—canonical_repo_root == process_project_root, arepository-level question. Because the global worktree rule requires all task
work to live in a
branches/worktree, the task workspace is required todiffer from the process root, so the old derivation reported
aligned=Falseforexactly the correctly configured sessions and refused every non-read operation.
The gate is now fed
ctx["roots_aligned"], with a comment recording why pathequality is the wrong question.
F2 (blocking) — frozen session-scoped state
_STARTUP_RUNTIME_MODEwas initialised toNoneand seeded by whichever callran first, including the read-only
refresh=Truepath. Immutable process factsare now captured at import as
_STARTUP_RUNTIME_FACTS, matching the #420 paritybaseline.
dirty_files, the workspace binding, and the derived alignment arerecomputed on every call.
stable_control_runtime.observe_dirty_files()splitsout the one runtime fact that legitimately changes during a process lifetime, and
observe_runtime()delegates to it so the porcelain parsing lives in one place.refreshis retained for the read-only reporting path but no longer selectsbetween a cache and live state.
F3 (major) — real derivation now under test
TestServerWiringRealDerivationpatches only the derivation's inputs — theimport-time facts, the dirty-file read, and the resolved binding — and lets the
real function build the report. Cases: clean stable checkout plus a correctly
bound
branches/worktree permits an otherwise authorized mutation; misalignedprocess/canonical roots fail closed; newly dirty task state is detected after an
earlier clean read; a read-only refresh cannot freeze a permissive result; an
unresolvable binding reports unknown alignment rather than alignment proof.
All five fail on the pre-fix head and pass after the fix.
Non-blocking reviewer observations
Deliberately not changed, to keep this remediation bounded to the three findings:
the lexicographic timestamp comparison in
assess_namespace_reproof,_RUNTIME_MODE_GATE_UNDER_TESTinferred fromsys.modules, and theobserve_runtimerename rendering. They remain accurate observations and aresuitable follow-up work.
One related design point surfaced while testing:
assess_runtime_mutation_gateblocks only on
workspace_roots_aligned is False, not onNone. That is correctand is now asserted — a session with no binding resolved is the ordinary case,
and failing it closed would reintroduce the F1 breakage.
Diff
Three files, 189 insertions, 30 deletions:
gitea_mcp_server.py,stable_control_runtime.py,tests/test_stable_control_runtime.py. No unrelatedfiles, generated files, caches, credentials, or temporary artifacts.
Publication attempt
gitea_commit_fileswas called once, after a freshgitea_whoamiand agitea_resolve_task_capability(task=commit_files)returningallowed_in_current_session: true, targeting branchfeat/issue-615-runtime-mode-enforcementwithlocal_pathpayloads from thesession worktree. It was refused by the #274 branches-only guard: "author
mutation blocked: workspace is the stable control checkout". It was not retried,
because the inputs a session can supply cannot change that outcome — the tool has
no
worktree_pathparameter and the daemon carries no author worktree binding.No fallback was used: no direct git push, no raw API call, no browser or CLI
path, no lock-file or lease-record hand-edit, no worktree reset or clean, no
daemon restart, and no second issue selected.
Leftover worktrees for operator disposition
Two baseline worktrees created this run and deliberately retained, since the
scheduled author iteration does not delete worktrees:
branches/baseline-pr770-prefix— detached at9bf3acf, dirty (the new testfile was copied in to prove the F3 tests fail pre-fix)
branches/baseline-master-615— detached at pristine master059ee77, cleanThe control checkout was not used for task work and remains clean on master at
059ee77c1f.[CONTROLLER HANDOFF] PR #770 / Issue #615 — F1–F3 remediation present at head ab34280f; fresh independent review required
Canonical Issue State
STATE:
PR-open
WHO_IS_NEXT:
reviewer
NEXT_ACTION:
Perform a fresh independent prgs-reviewer review of PR #770 at head
ab34280f90, explicitly superseding the stale review 483.NEXT_PROMPT:
WHAT_HAPPENED:
The author session recovered the native issue lock for #615 from a dead session through the owning-PR path, verified that local HEAD, remote branch tip, and live PR head are all
ab34280f90, confirmed review 483 is stale at that head, and re-ran focused, full, and pristine-base validation to evidence the F1–F3 remediation already carried in commitab34280f. No code was changed by this session.WHY:
The previous author handoff cited head
9bf3acfand no longer described this PR accurately, and the durable issue lock was orphaned by a dead session, so ownership and state both needed restating before a reviewer could act on the correct head.RELATED_PRS:
BLOCKERS:
none for the author role; the next action belongs to a reviewer.
VALIDATION:
Focused suite tests/test_stable_control_runtime.py 52 passed; full suite 3832 passed / 2 failed / 6 skipped in the issue worktree; pristine base
059ee77in branches/baseline-master-615 3780 passed / 2 failed / 6 skipped with byte-identical failing node IDs; git diff --check clean. Full detail below.LAST_UPDATED_BY:
jcwalker3 / prgs-author / 2026-07-20
Purpose:
This comment is the operational handoff for the next controller/LLM session. It corrects the earlier author handoff, which cited the superseded head
9bf3acfand therefore misdescribed the current state of this PR.Identity/profile:
gitea_route_task_session(task_type="work-issue")returnedallowed_current_session; runtimereview_merge_allowed=false; profileforbidden_operationsincludegitea.pr.approve,gitea.pr.merge,gitea.pr.request_changes. No review verdict was authored, dismissed, or altered by this session.Target:
prgs)ab34280f90Three-way head equality proof (live, this session):
ab34280f9025406d5c392d4e07c9d34d3ecd47fe(git rev-parse HEAD)ab34280f9025406d5c392d4e07c9d34d3ecd47fe(gitea_assess_pr_sync_status.pr_head_sha)059ee77c1fd483da385d6ccb4d842e808fb54630,commits_behind: 0,has_conflicts: false,mergeable: true.Native issue-lock recovery:
gitea_lock_issuereturneddead_session_recovery.recovered=truevia the owning-PR path: prior session pid 34249 is not alive, replacement pid 65790.head_relation: equalacross local_head, remote_head, recorded_head, accepted_head, and pr_head, allab34280f9025406d5c392d4e07c9d34d3ecd47fe, PR #770.lock_freshness.status: live; no competing live lock; competing-branch checkclear.Prior reviewer verdict — stale at the current head:
9bf3acfef681f9766ae1d93680b03996a93f98a1.gitea_get_pr_review_feedbackreportsreviewed_head_sha9bf3acfe... againstcurrent_head_shaab34280f..., withreview_feedback_stale: true,author_pushed_after_request_changes: true,stale: true,dismissed: false,approval_at_current_head: false.gitea_assess_pr_sync_status.recommended_next_action: fresh_review_required.Remediation content (commit
ab34280f, authored in a prior session; diff and validation verified live this session):realpath(workspace_root) == process_project_root, redefiningworkspace_roots_aligned, whose established meaning isctx["roots_aligned"](canonical_repo_root == process_project_root). Because the global worktree rule requires task work to live in abranches/worktree, the old derivation reported alignment false for exactly the correctly configured sessions and raisedunsafe_process_root_workspace_alignment, refusing every non-read operation. The gate is now fedctx["roots_aligned"]._current_runtime_mode_reportcached its first result into_STARTUP_RUNTIME_MODE, which was initialised toNonerather than captured at import, and therefresh=Trueread-only path seeded it as well. Session-scoped fields (active_task_workspaceand its derived alignment) and mutabledirty_fileswere frozen for the process lifetime. Immutable process facts are now captured at import as_STARTUP_RUNTIME_FACTS, matching the #420 parity baseline; dirty state, workspace binding, and alignment are recomputed per call. Newstable_control_runtime.observe_dirty_files()isolates the one fact that legitimately changes during a process lifetime.refreshno longer selects a cache, so a read-only call can neither seed nor weaken a later mutation decision._current_runtime_mode_reportwith a fixture whoseworkspace_roots_alignedwas True. NewTestServerWiringRealDerivationpatches only the derivation's inputs and lets the real function build the report, covering: clean stable checkout plus correctly boundbranches/worktree permits an authorized mutation; misaligned process/canonical roots fail closed; newly dirty task state detected after an earlier clean read; a read-only refresh cannot freeze a permissive result; an unresolvable binding reports unknown alignment rather than alignment proof.assess_namespace_reproof,_RUNTIME_MODE_GATE_UNDER_TESTinferred fromsys.modules,observe_runtimeporcelain rename rendering) were not changed. They were marked "fix only if convenient" and were deliberately left out of scope to keep the remediation diff minimal.Files touched by the remediation commit (
git diff --stat 9bf3acf ab34280):gitea_mcp_server.py— 71 lines changed; F1 alignment input and F2 import-time fact capturestable_control_runtime.py— 17 lines changed;observe_dirty_files()helper for F2tests/test_stable_control_runtime.py— 131 lines added; F3 real-derivation coverageValidation (live, run in this session, in the issue worktree):
/opt/homebrew/bin/python3 -m pytest tests/test_stable_control_runtime.py -q -sinbranches/issue-615-runtime-mode-enforcement→ 52 passed (47 prior plus 5 new F3 tests)./opt/homebrew/bin/python3 -m pytest -q -sinbranches/issue-615-runtime-mode-enforcement→ 3832 passed, 2 failed, 6 skipped, 493 subtests passed.git diff --check 9bf3acf ab34280→ clean./opt/homebrew/bin/python3is Python 3.14.5 with pytest 9.0.3. Barepython3on PATH resolves to 3.13.13, which has no pytest module.Baseline comparison (live, this session, not carried over from a prior run):
branches/baseline-master-615, detached at059ee77c1fd483da385d6ccb4d842e808fb54630, tracked and untracked state clean before and after./opt/homebrew/bin/python3 -m pytest -q -son that pristine base → 3780 passed, 2 failed, 6 skipped, 493 subtests passed.tests/test_issue_702_review_findings_f1_f6.py::TestF1RecoveryBeforeTerminalProbe::test_removed_worktree_recovers_before_probetests/test_reconciler_supersession_close.py::TestReconcilerSupersessionMcpTool::test_tool_posts_comment_and_closes_superseded_pr_issue059ee77and are not caused by this branch. Neither touches a file in this diff. The pass-count delta of +52 equals the focused suite this branch adds.Server-side mutation ledger:
gitea_lock_issueon issue #615 — native issue lock recovered from a dead session and now held live by pid 65790, lease expiry 2026-07-20T20:36:33Z.Local-only changes:
branches/issue-615-runtime-mode-enforcementandbranches/baseline-master-615. Both worktrees verified clean after the runs. No file was created, edited, or deleted by this session in any checkout.masterat059ee77c1fd483da385d6ccb4d842e808fb54630, clean, and was not used for task work.Blockers:
[THREAD STATE LEDGER] PR #770 / Issue #615 — F1–F3 remediation sits at head ab34280f; a fresh independent reviewer verdict is the next step
Canonical Issue State
STATE:
PR-open
WHO_IS_NEXT:
reviewer
NEXT_ACTION:
Perform a fresh independent prgs-reviewer review of PR #770 at head
ab34280f90, explicitly superseding the stale review 483.NEXT_PROMPT:
WHAT_HAPPENED:
The author session recovered the orphaned native issue lock, proved three-way head equality at
ab34280f, confirmed review 483 is stale at that head, and re-ran focused, full, and pristine-base validation. No code changed.WHY:
The prior handoff described the superseded head
9bf3acf, so the canonical thread state had to be corrected before a reviewer acts.RELATED_PRS:
BLOCKERS:
none for the author role; the next step belongs to a reviewer.
VALIDATION:
Focused suite 52 passed; full suite 3832 passed / 2 failed / 6 skipped; pristine base
059ee773780 passed / 2 failed / 6 skipped with identical failing node IDs; git diff --check clean.LAST_UPDATED_BY:
jcwalker3 / prgs-author / 2026-07-20
What is true now:
commits_behind: 0,has_conflicts: false,mergeable: truestatus:in-progress, native author issue lock held live by pid 65790 until 2026-07-20T20:36:33Zab34280f9025406d5c392d4e07c9d34d3ecd47fe, equal across local worktree HEAD, remote branch tip, and live PR head9bf3acfef681f9766ae1d93680b03996a93f98a1; that verdict is stale at the current head, is undismissed, and no verdict of any kind exists atab34280fab34280f; no review verdict was prepared, held, or implied locally by this author sessiontests/test_stable_control_runtime.py52 passed; full suite 3832 passed / 2 failed / 6 skipped in the issue worktree; pristine base059ee773780 passed / 2 failed / 6 skipped inbranches/baseline-master-615, with byte-identical failing node IDs proving both failures pre-exist on the baseWhat changed:
dead_session_recovery.recovered=true,head_relation: equalab34280f; the earlier author handoff citing9bf3acfis superseded by handoff comment 13287What is blocked:
Who/what acts next:
ab34280f9025406d5c392d4e07c9d34d3ecd47fe, reproducing the F1 case against the real derivation and confirming the newTestServerWiringRealDerivationtests fail at9bf3acfand pass atab34280fbranches/baseline-master-615orbranches/issue-615-runtime-mode-enforcementworktreesab34280f9025406d5c392d4e07c9d34d3ecd47fe[THREAD STATE LEDGER] PR #770 / Issue #615 — independent reviewer APPROVE recorded as review 484 at head ab34280f; merger acts next
Canonical Issue State
STATE:
PR-open
CANONICAL_ITEM:
review 484 (APPROVED) on PR #770 at head
ab34280f90SUPERSEDED_ITEM:
review 483 (REQUEST_CHANGES) on PR #770 at the superseded head 9bf3acfef681f9766ae1d93680b03996a93f98a1; it was stale at the current head and the server marked it dismissed once review 484 landed
WHO_IS_NEXT:
merger
NEXT_ACTION:
A prgs-merger session reassesses PR #770 at head
ab34280f90under its own gates and decides the merge; the reviewer phase granted no merge authorization.NEXT_PROMPT:
WHAT_HAPPENED:
A fresh independent prgs-reviewer session pinned head
ab34280f, verified handoff comment 13287 and ledger comment 13290 as accurate, treated review 483 as stale, and independently reproduced all three findings rather than trusting the author's pass counts. F1 and F2 were re-tested with a reviewer-authored harness that exercises the real_current_runtime_mode_reportand the real unpatched_resolve_namespace_mutation_contextagainst a realbranches/worktree, with the same harness run against the superseded head as a control. The five new F3 tests were run against the pre-fix code, where all five fail, and against this head, where all five pass. Exactly one native verdict was posted to Gitea: APPROVE, recorded as review 484.WHY:
All three findings from review 483 are remediated at this head, confirmed against the real code path rather than against fixtures. F1 now feeds the gate the established repository-level
roots_alignedcontract, so a correctly boundbranches/session is permitted instead of refused, and the deadlock-on-promotion scenario no longer reproduces. F2 captures only immutable process facts once at module load and recomputes dirty state, workspace binding, and alignment per call, so the acceptance-criterion-7 dirty blocker keeps applying and a read-only call can no longer seed a permissive cache. F3 adds coverage that exercises the real derivation and genuinely fails against the pre-fix code.RELATED_PRS:
BLOCKERS:
none for the reviewer role; the next action belongs to a merger.
VALIDATION:
Focused suite tests/test_stable_control_runtime.py 52 passed at the pinned head in worktree branches/review-pr-770. Affected integration set (stable_control_runtime, namespace_workspace_binding, workspace_guard_alignment, master_parity_gate, mcp_stale_runtime, role_namespace_gate, runtime_clarity, workspace_mutation_consistency, stable_control_runtime_policy_docs, create_issue_workspace_guard, issue_comment_workspace_guard, preflight_workspace_repo_forwarding) 153 passed, 20 subtests passed. Controlled F1 experiment: identical harness and identical real binding yields workspace_roots_aligned False and real_mutations_allowed False at
9bf3acf, and True/True with an empty block list atab34280f. F2 dynamic sequence atab34280f: clean permits, newly dirty blocks with the dirty-runtime reason, clean again permits; the same sequence at9bf3acfnever observed the injected dirt. F3: 5 fail pre-fix, 5 pass at this head. Both author-claimed pre-existing failures reproduced identically on pristine base059ee77. git diff --check clean; remediation scope 3 files, 189 insertions, 30 deletions; secret scan clean.LAST_UPDATED_BY:
sysadmin / prgs-reviewer / 2026-07-20
NATIVE_REVIEW_PROOF: native gitea_submit_pr_review through the prgs-reviewer MCP namespace as identity sysadmin, workflow skills/llm-project-workflow/workflows/review-merge-pr.md hash 263d0a6cb8a6, final-report schema a7634e7b8689, head pinned
ab34280f90, reviewer lease comment 13292, review 484, native read-after-write confirming approval_visible true and approval_at_current_head true.What is true now:
ab34280f90, re-verified live immediately before the verdict was posted to Giteaab34280fWhat changed:
ab34280f, superseding the stale review 483What is blocked:
Who/what acts next:
ab34280f90under its own gates and decides the mergeab34280f90Non-blocking follow-ups carried forward, not required for merge:
Stable control runtime — promotion record (AC4, runbook §3.7)
Archival of the completed stable-runtime promotion for PR #770. Emitted by the read-only
scripts/promote-stable-runtimehelper, which returnedassess_promotion_record valid=true. No Git state was altered by this phase.Promotion record
previous_runtime_sha059ee77c1fd483da385d6ccb4d842e808fb54630promoted_runtime_sha0568f44cb2d87e78fd394a27a670e33c84f7842fsource_branchfeat/issue-615-runtime-mode-enforcementsource_prrestart_method/mcp); already in effect at session start, verified in-parity, not performed by this sessionhealth_check_proofgitea_assess_master_parityall four namespaces:in_parity=true,stale=false,restart_required=false,startup_head == current_head == 0568f44cb2d87e78fd394a27a670e33c84f7842fidentity_proofprofile_proofgitea_get_runtime_contextactive_profile per namespace: prgs-author, prgs-reviewer, prgs-merger, prgs-reconcilerworkspace_proofmcp_process_root == canonical_repository_root == /Users/jasonwalker/Development/Gitea-Tools;workspace_roots_aligned=true;dirty_files=[]; boundbranches/worktree accepted viaworktree_pathbinding, not rejected as root misalignmentmutation_capability_proofreal_mutations_allowed=true,mutation_block_reasons=[],gate_enforced=truein all four namespacesrollback_instructionsgit -C <stable-root> merge --ff-only 059ee77c1fd483da385d6ccb4d842e808fb54630; reconnect client (/mcp); re-prove all four namespaces per runbook §5assess_promotion_record()→valid=true,missing_fields=[],reasons=[].SHA on every surface
merge_commit_sha0568f44cb2d87e78fd394a27a670e33c84f7842fprgs/master0568f44cb2d87e78fd394a27a670e33c84f7842fmaster, clean)0568f44cb2d87e78fd394a27a670e33c84f7842fgitea-toolsstartup_head / current_head0568f44…/0568f44…gitea-reviewerstartup_head / current_head0568f44…/0568f44…gitea-mergerstartup_head / current_head0568f44…/0568f44…gitea-reconcilerstartup_head / current_head0568f44…/0568f44…Runtime classification in all four namespaces:
runtime_mode=stable-control,in_parity=true,restart_required=false,stop_required=false,real_mutations_allowed=true,dev_worktree_launched=false,gate_enforced=true.Caveat on
previous_runtime_shaprevious_runtime_sha=059ee77…is derived by the helper from Git ancestry (the first-parent of the promoted merge commit), not from a live observation of a daemon serving059ee77…before promotion. The control checkout and all four namespaces already reported0568f44…at the start of the archiving session, so no pre-promotion daemon reading was captured. The promoted-state evidence above is direct and live; the pre-promotion SHA is inferential.Canonical Issue State
STATE:
closed
WHO_IS_NEXT:
author
NEXT_ACTION:
Resume normal workflow phases on the promoted stable-control runtime at
0568f44cb2.NEXT_PROMPT:
Run one bounded author phase for Scaled-Tech-Consulting/Gitea-Tools on the promoted stable-control runtime (
0568f44cb2). Verify identity, runtime mode, and parity before any mutation. Do not promote again without a fresh promotion record.WHAT_HAPPENED:
PR #770 reached state=closed with merge_commit_sha
0568f44cb2, and this issue reached state=closed. The stable control runtime was advanced to that SHA and reloaded via client reconnect. All four MCP namespaces were independently re-proven per runbook §5, andassess_promotion_recordreturned valid=true for the record archived in this comment.WHY:
AC4 requires promotion checklist fields to be documented and used for real promotions. Runbook §3.7 requires the record, once
assess_promotion_recordreturns valid=true, to be posted as a durable comment on the tracking issue so the promotion is auditable without chat history.RELATED_DISCUSSION:
none
RELATED_PRS:
BRANCH:
master
HEAD_SHA:
0568f44cb2VALIDATION:
assess_promotion_record valid=true, missing_fields=[]. gitea_assess_master_parity in_parity=true / restart_required=false across gitea-tools, gitea-reviewer, gitea-merger, gitea-reconciler. PR #770 state=closed with merge_commit_sha
0568f44cb2.BLOCKERS:
none
LAST_UPDATED_BY:
jcwalker3 / prgs-author / 2026-07-20
[THREAD STATE LEDGER] Runtime — promotion completed and re-proven
What is true now:
0568f44cb2What changed:
What is blocked:
Who/what acts next: