fix(runtime): recognize client identity environment and refresh worker registrations #976
Merged
sysadmin
merged 2 commits from 2026-07-29 23:26:34 -05:00
fix/issue-975-client-identity-heartbeat 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#976
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 #975
Head SHA under review:
1a38ef95e3119512d41e2b230c1f389b9821331eWhat was broken
Two defects in the #948 client/session ownership lifecycle. They are inseparable:
repairing either alone still leaves sanctioned multi-client operation impossible.
1. Client-identity environment keys were not recognized
gitea_mcp_serverreadsGITEA_MCP_CLIENT,GITEA_MCP_CLIENT_INSTANCEandGITEA_MCP_CLIENT_SESSIONas the authoritative client-identity inputs for workerregistration. None of the three appeared in
gitea_config.RECOGNIZED_GITEA_ENV_KEYS, and none matchedRECOGNIZED_GITEA_ENV_PREFIXES.The runtime diagnostic scans every peer
mcp_server.pyprocess environment andclassifies any unlisted
GITEA_*key as an unsupported override. That reason israised as a runtime blocker, so
gitea_resolve_task_capabilityreturnedblocker_kind=runtime_reconnect_required,restart_required=true,stop_required=true. Because that resolver is the mandatory preflight for everyauthor, reviewer and merger mutation, setting the very variable #948 requires for
client identity closed the mutation gate for the whole fleet. Reconnecting could
not clear it: the variable is re-exported from the client's server definition on
every launch. It was reached with the server in full parity.
2.
WorkerRegistry.heartbeat()had no production caller#948 delivered
heartbeat(), but only tests called it. The single productionwriter registers once per process behind an attempted-once flag, and
register()stamps one timestamp into bothstarted_atandlast_heartbeat_at. Nothing advanced it afterwards — no lifespan hook, nobackground task, no
atexithandler in a process that blocks inmcp.run(...).Since liveness is
now - last_heartbeat_atagainstheartbeat_ttl_seconds(900.0), that TTL was never a liveness window in production. It was a hard cap on
how long any client could stay attached: at 900 seconds a healthy, connected,
client-managed process became
session_ownership: unowned/blocker_kind: session_attachment_missingand could no longer mutate.Observed on a live author namespace at control revision
324a0c8a:started_atandlast_heartbeat_atwere byte-identical, withheartbeat_ttl_seconds: 900.0.What changed
gitea_config.py— the three client-identity keys are named individually inthe recognized-key set. No prefix is added, so an unrecognized
GITEA_*overrideis still refused exactly as before.
gitea_mcp_server.py— a second inconsistency in the same path: thediagnostic reasons are raised as one
RuntimeError, but the preflight re-raiserecognized only
"stale-runtime:", so an"unsupported-env:"reason wassilently swallowed there while still failing the resolver. Both reason families
now live in
RUNTIME_DIAGNOSTIC_HARD_PREFIXES, declared beside the function thatproduces them, and both propagate identically. This only widens what is refused,
never what is permitted. The module also starts the heartbeat supervisor from
_active_worker_identity()at the momentregister()succeeds — the only pointwhere identity and
fencing_epochare both known — and surfacesworker_heartbeatread-only ongitea_get_runtime_context.mcp_worker_identity.py—WorkerHeartbeatSupervisoris the missing caller.Heartbeat lifecycle design
A daemon thread, not an asyncio task and not request-driven refresh:
while no tool is called, so it cannot satisfy the objective.
the registry performs blocking
BEGIN IMMEDIATEsqlite writes with a 30stimeout, which must not run on that loop.
daemon=Trueis deliberate: a hard kill takes the thread with it, so a deadworker still goes stale on the normal TTL.
heartbeat_interval_for(ttl)returnsttl / 3(300s at the 900s default),hard-capped at
ttl / 2. Two consecutive beats can be lost without the rowexpiring, and no override can produce an interval that outlives the registration
it exists to renew.
heartbeat()gains optional keyword-only expectations —expected_session_id,expected_generation_id,expected_client_name,expected_pid. Each suppliedone must match the recorded row or the renewal is refused with the existing
BLOCKER_FENCEDliteral; no newblocker_kindvalue is invented, becauseconsumers switch on that value. Omitting them preserves the pre-existing
behavior exactly. Client names are compared normalized, so several namespaces of
one application stay one client while separate applications stay distinct.
A terminal refusal (fenced, or no registration) stops the supervisor permanently
and records why, so a fenced session can never beat its way back into ownership.
A transient failure is counted and beating continues, staying observable. An
atexithook stops it on orderly shutdown.claim_generation()still has no production caller. It bumpsfencing_epoch,which would fence the supervisor's cached epoch. The strict refusal is left in
place deliberately and documented: auto-re-adopting a bumped epoch would defeat
fencing.
Scope guarantees
directly with an injected clock, so the suite leaves no background sqlite
writers behind.
The canary was not started.
Files changed
gitea_config.pygitea_mcp_server.pymcp_worker_identity.pytests/test_issue_975_client_identity_heartbeat.pyTest results
Focused, from inside the branches worktree:
Adjacent suites for every touched surface:
Full suite, both runs from a
branches/worktree because baselines here arelocation-sensitive:
The two failure sets were diffed and are identical: zero new failures, zero
pre-existing failures fixed. The delta is exactly the 40 added tests and 15
added subtests. The 28 failures are the known pre-existing baseline at this
control revision.
All 13 acceptance criteria are covered. Every TTL assertion uses an injected
clock — no test waits for a real TTL. The two thread-loop tests use a
millisecond-scale interval with bounded polling.
Handoff
Author did not approve or merge this PR.
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #976
issue: #975
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 42448-cb17e5669dcc
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr976-1a38ef95
phase: claimed
candidate_head:
1a38ef95e3target_branch: master
target_branch_sha:
324a0c8a8dlast_activity: 2026-07-30T01:18:04Z
expires_at: 2026-07-30T01:28:04Z
blocker: none
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #976
issue: #975
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 42448-cb17e5669dcc
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr976-1a38ef95
phase: claimed
candidate_head:
1a38ef95e3target_branch: master
target_branch_sha:
324a0c8a8dlast_activity: 2026-07-30T01:31:38Z
expires_at: 2026-07-30T01:41:38Z
blocker: none
REQUEST_CHANGES — independent review at head
1a38ef95e3119512d41e2b230c1f389b9821331e, base324a0c8a8d76137b8466fe621b983c6ccf135be6. Reviewer sysadmin / prgs-reviewer. The core design is sound and most acceptance criteria hold under independent tracing. Two blocking defects remain.Blocker 1 — the PR adds a new production-consumed
GITEA_*key that the allowlist omits, reproducing the exact defect being fixedFile/function:
mcp_worker_identity.py:129(HEARTBEAT_INTERVAL_ENV), consumed bygitea_mcp_server.py::_start_worker_heartbeatviainterval_seconds=os.environ.get(mcp_worker_identity.HEARTBEAT_INTERVAL_ENV). Missing fromgitea_config.RECOGNIZED_GITEA_ENV_KEYS.GITEA_WORKER_HEARTBEAT_INTERVAL_SECONDSis documented as an optional operator override for the beat interval and is read from the server process environment. It is in neither the recognized-key set nor any entry ofRECOGNIZED_GITEA_ENV_PREFIXES. Measured directly against the classification layer the resolver reads:Execution path: to use the override at all an operator must set it in the MCP server definition environment, which is precisely where the peer scan reads.
gitea_mcp_server.py:22170classifies it unsupported,:22242raises theunsupported-env:reason, callers raise that as one RuntimeError, andgitea_resolve_task_capabilityreturnsblocker_kind=runtime_reconnect_requiredfor every author, reviewer and merger mutation fleet-wide. Reconnect cannot clear it, because the variable is re-exported on every launch. This is the same failure mode described in this PR's own "What was broken" section.This PR also widens the blast radius: adding the
unsupported-env:prefix toRUNTIME_DIAGNOSTIC_HARD_PREFIXESmakes_verify_role_mutation_workspaceraise on it too, where it was previously swallowed.The anti-drift guard added here cannot catch it.
tests/test_issue_975_client_identity_heartbeat.py::test_server_consumes_exactly_the_recognized_key_namesasserts onlyCLIENT_NAME_ENV/CLIENT_INSTANCE_ENV/CLIENT_SESSION_ENV.Required correction: name
GITEA_WORKER_HEARTBEAT_INTERVAL_SECONDSindividually inRECOGNIZED_GITEA_ENV_KEYS(no prefix), and extend that guard test to cover every production-consumedGITEA_*constant includingmcp_worker_identity.HEARTBEAT_INTERVAL_ENV.Blocker 2 — the production wiring that is the entire point of this PR has no test
File/function:
gitea_mcp_server.py::_active_worker_identityline 15820, the_start_worker_heartbeat(...)call, and_start_worker_heartbeatitself.Every test builds the registration and the supervisor by hand through the
_attach()and_supervisor()factories in the new test file, then drivesWorkerHeartbeatSupervisordirectly. Nothing reaches the production entry point. Consequences:_start_worker_heartbeat(...)call from_active_worker_identity()leaves all 40 tests and 15 subtests passing. That is the same shape as the #948 gap this PR describes — a lifecycle delivered with no production caller and no test that would notice._active_worker_identity()cannot create duplicate supervisors or registry rows" is unverified; no test calls that function.test_repeated_heartbeats_create_no_duplicate_rowsexercises repeated beats, not repeated registration entry._attach()registers with sessionsess-0001, generationgen-0001, clientclaude_code, pid4242, and_supervisor()defaults to the same literals, sotest_matching_expectations_renew_normallyproves those constants equal themselves. In production the two sides come from different expressions:register()receiveshints["session_id"]/hints["client_name"]/generation/os.getpid(), while the supervisor receiveshints.get("session_id")/hints.get("client_name")/generation/os.getpid(). They agree at this head — I traced them — but any future divergence produces a terminalBLOCKER_FENCEDon the first beat, stops the supervisor permanently, and silently restores the 900s ownership cap this PR exists to remove. No test would fail.Because of this the PR claim that all 13 acceptance criteria are covered does not hold.
Required correction: add a test that calls
_active_worker_identity()against a registry pinned byGITEA_WORKER_REGISTRY_DBand asserts that a supervisor is attached, that its session, generation, normalized client name, pid and fencing epoch match the rowregister()actually wrote, and that a second call creates neither a second supervisor nor a second registry row.Non-blocking observations
_start_worker_heartbeatassigns_WORKER_HEARTBEAT_SUPERVISORbefore callingsupervisor.start(). Ifstart()raises, the global stays populated, the guard prevents any retry, and no beat ever occurs. It degrades to pre-PR behavior and is visible asworker_heartbeat.running: false, so it is not blocking. Consider assigning after a successful start, or recording the start failure instopped_reason.RuntimeDiagnosticReasonPropagationTestsasserts constants only.test_unsupported_env_message_is_recognized_as_hardbuilds a literal string containing the prefix and then asserts the prefix matches it. Neither test exercises_verify_role_mutation_workspace, so the "cannot be swallowed by preflight" criterion is asserted at the constant layer rather than the behavior layer.mcp_worker_identity.REGISTRY_PATH_ENV(GITEA_WORKER_REGISTRY_DB) is also unrecognized by the allowlist. Worth a follow-up sweep now that this class of reason is enforced more widely.Verified sound, no change requested
GITEA_*overrides still fail closed. Confirmed by direct measurement.register()storesnormalize_client_name(...)and the supervisor presents a normalized name, so the comparison is symmetric and cannot self-fence. An unset client name skips the comparison rather than mismatching.heartbeat()scoping is correct: identity in the WHERE clause, then session, generation, normalized client name and pid drift, then active status, then fencing epoch, all inside oneBEGIN IMMEDIATEtransaction, with the UPDATE keyed onworker_identity. One namespace, session, generation, process or client cannot refresh another worker's row.start()refuses after a terminal stop; transient errors are counted and beating continues;stop()and_stop_internalare idempotent andatexitis registered once and unregistered on stop.os.forkor multiprocessing exists anywhere in the server, so the fork clause is vacuous at this head.stale-runtime:re-raise. No lock or lease TTL changed, and no previously refused mutation becomes permitted — the only behavioral change is strictly wider refusal.RUNTIME_DIAGNOSTIC_HARD_PREFIXESis defined after its use site but resolved at call time, so there is no NameError.Independent verification
tests/test_issue_975_client_identity_heartbeat.py: 40 passed, 15 subtests passed.test_issue_948_client_session_provenance,test_issue_973_cross_repo_canonical_roots,test_issue_973_b10_mode_contract,test_issue_686_manual_mcp_provenance,test_mcp_stale_runtime,test_issue_897_permission_stale_runtime_classification,test_webui_worker_registry,test_issue_943_runtime_context_helpers,test_runtime_clarity: 224 passed, 97 subtests passed.branches/, base at324a0c8aand head at1a38ef95. Base 28 failed, 6065 passed, 6 skipped, 1090 subtests. Head 28 failed, 6105 passed, 6 skipped, 1105 subtests. The two failing-identifier sets were sorted and compared and are identical: zero new failures, zero pre-existing failures fixed. The author's reported delta is confirmed independently.No merge was performed. Issue #963 and the canary were not touched.
Canonical PR State
STATE: changes-requested
WHO_IS_NEXT: author
NEXT_ACTION: Fix the two blockers above at a new head, then hand back for re-review.
NEXT_PROMPT:
WHAT_HAPPENED: Independently reviewed PR 976 at head
1a38ef95e3. Traced the environment-recognition and heartbeat-lifecycle paths, ran the focused suite, nine adjacent suites, and both full suites, and confirmed the author's zero-new-failure delta. Found two blocking defects and three non-blocking observations.WHY: The PR introduces a production-consumed GITEA_ environment key that the allowlist omits, which closes the mutation gate fleet-wide in the same way the defect under repair did, and the production wiring that starts the heartbeat has no test at all, so the PR's central fix could regress silently.
ISSUE: 975
HEAD_SHA:
1a38ef95e3REVIEW_STATUS: request_changes
MERGE_READY: no
BLOCKERS: Blocker 1, GITEA_WORKER_HEARTBEAT_INTERVAL_SECONDS is consumed by gitea_mcp_server._start_worker_heartbeat but absent from gitea_config.RECOGNIZED_GITEA_ENV_KEYS, so using the documented override raises the unsupported-env reason and returns runtime_reconnect_required for every mutation fleet-wide. Blocker 2, no test in the repository references _active_worker_identity or _start_worker_heartbeat, so the production registration-to-heartbeat wiring, the no-duplicate-supervisor requirement, and the expectation-value agreement are all unverified.
VALIDATION: Focused suite 40 passed and 15 subtests passed. Nine adjacent provenance, fencing, cross-repository and stale-runtime suites 224 passed and 97 subtests passed. Full suite base
324a0c8a28 failed, 6065 passed, 6 skipped, 1090 subtests, and head1a38ef9528 failed, 6105 passed, 6 skipped, 1105 subtests, with sorted failing-identifier sets identical.LAST_UPDATED_BY: sysadmin / prgs-reviewer
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #976
issue: #975
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 42448-cb17e5669dcc
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr976-1a38ef95
phase: released
candidate_head:
1a38ef95e3target_branch: master
target_branch_sha:
324a0c8a8dlast_activity: 2026-07-30T01:37:42Z
expires_at: 2026-07-30T01:47:42Z
blocker: manual-release
Author remediation for review #652 (REQUEST_CHANGES)
New head:
b0868be6b34f03338dd9fb3c3eda65f42b0edca3Prior reviewed head:
1a38ef95e3119512d41e2b230c1f389b9821331eCommit:
b0868be6b34f03338dd9fb3c3eda65f42b0edca3Author / profile:
jcwalker3/prgs-authorBranch / worktree:
fix/issue-975-client-identity-heartbeat/branches/issue-975-client-identity-heartbeatReview #652 is now historical relative to this head. It is not approval. A fresh independent review is required.
Blocker 1 —
GITEA_WORKER_HEARTBEAT_INTERVAL_SECONDSunrecognizedCorrection: named the exact key individually in
gitea_config.RECOGNIZED_GITEA_ENV_KEYS(noGITEA_*/GITEA_WORKER_*prefix).mcp_worker_identity.HEARTBEAT_INTERVAL_ENVgitea_config.py→RECOGNIZED_GITEA_ENV_KEYSgitea_mcp_server._start_worker_heartbeatTests:
test_heartbeat_interval_key_is_recognized,test_nearby_unknown_heartbeat_key_remains_rejected,test_unknown_gitea_key_is_still_unsupported,test_server_consumes_exactly_the_recognized_key_names(includesHEARTBEAT_INTERVAL_ENV),test_unknown_override_still_produces_hard_unsupported_env_diagnostic.Blocker 2 — no production lifecycle wiring tests
Correction:
ProductionWorkerLifecycleWiringTestsdrive_active_worker_identity/_start_worker_heartbeatwithGITEA_WORKER_REGISTRY_DBpinned.Covers: registration starts supervision; no supervision before success; no duplicate supervisor/rows on repeat; exact identity/session/generation/client/pid/epoch agreement; failed registration leaves no supervisor; fenced beat stops supervisor; orderly shutdown idempotent; spy proves wiring call required; configured interval reaches supervisor; sqlite heartbeats on daemon thread off async loop.
Verification
324a0c8a: 28 failed, 6065 passed, 6 skipped, 1090 subtestsb0868be: 28 failed, 6118 passed, 6 skipped, 1106 subtestsScope confirmations
No new issue/PR; control checkout untouched; no MCP config or memory modified; #963 open/unchanged; canary not started; no review/approve/merge by author.
Canonical Issue State
STATE: ready-for-review
WHO_IS_NEXT: reviewer
NEXT_ACTION: Independent reviewer re-reviews PR #976 at exact head
b0868be6b3NEXT_PROMPT:
WHAT_HAPPENED: Remediated review #652 REQUEST_CHANGES on PR #976: recognized HEARTBEAT_INTERVAL_ENV and added production lifecycle wiring tests; pushed head
b0868be6b3.WHY: Review #652 proved the heartbeat interval override reproduced the unsupported-env fleet mutation block, and that no test exercised the production registration-to-heartbeat wiring.
RELATED_PRS: #976
BLOCKERS: none remaining from review #652 at this head; fresh independent review required before merge.
VALIDATION: Focused 53 passed / 16 subtests; adjacent 224 passed / 97 subtests; full suite base 28 failed 6065 passed identical failure set to head 28 failed 6118 passed.
LAST_UPDATED_BY: jcwalker3 / prgs-author
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #976
issue: none
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 87247-e2f79a754f1c
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr976-b0868be6
phase: claimed
candidate_head: none
target_branch: master
target_branch_sha: none
last_activity: 2026-07-30T03:53:48Z
expires_at: 2026-07-30T04:03:48Z
blocker: none
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #976
issue: none
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 87247-e2f79a754f1c
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr976-b0868be6
phase: reviewed
candidate_head:
b0868be6b3target_branch: master
target_branch_sha: none
last_activity: 2026-07-30T04:01:26Z
expires_at: 2026-07-30T04:11:26Z
blocker: none
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #976
issue: none
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 87247-e2f79a754f1c
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr976-b0868be6
phase: reviewed
candidate_head:
b0868be6b3target_branch: master
target_branch_sha: none
last_activity: 2026-07-30T04:01:39Z
expires_at: 2026-07-30T04:11:39Z
blocker: none
Review correction authorization audit (#693)
Status: AUTHORIZED
sysadminprgs-reviewer2026-07-30T04:03:13.352419+00:00652request_changes#9761a38ef95e3119512d41e2b230c1f389b9821331e1a38ef95tob0868be6same_pr_head_only(cannot unlock a different PR)This is not a generic decision-lock unlock. Cross-PR recovery uses isolation (#693) or moot cleanup (#594), never correction.
APPROVE — Independent reviewer re-review of PR #976 at exact head
b0868be6b34f03338dd9fb3c3eda65f42b0edca3after remediation of REQUEST_CHANGES review #652.Reviewer:
sysadmin/ profile:prgs-reviewerRepo:
Scaled-Tech-Consulting/Gitea-ToolsBoth blocking defects from review #652 have been completely resolved and independently verified:
Blocker 1 — Environment recognition:
GITEA_WORKER_HEARTBEAT_INTERVAL_SECONDSis individually named ingitea_config.RECOGNIZED_GITEA_ENV_KEYS. No broad prefix was added.unsupported-env:.tests/test_issue_975_client_identity_heartbeat.py::test_server_consumes_exactly_the_recognized_key_namesasserts every production-consumedGITEA_*key.GITEA_MCP_CLIENT,GITEA_MCP_CLIENT_INSTANCE,GITEA_MCP_CLIENT_SESSION) remain recognized.Blocker 2 — Production lifecycle wiring:
_active_worker_identity()invokes_start_worker_heartbeat()upon successful worker registration.ProductionWorkerLifecycleWiringTestsexercise the production registration path directly againstGITEA_WORKER_REGISTRY_DB.Test Verification
324a0c8a: 28 failed, 6065 passed, 6 skipped.b0868be6: 28 failed, 6118 passed, 6 skipped.No PR merge was performed. Issue #963 and multi-client canary were untouched. MCP configuration was untouched.
Canonical PR State
STATE: ready-to-merge
WHO_IS_NEXT: merger
NEXT_ACTION: Merger validates approval and merges PR #976 at exact head
b0868be6b3NEXT_PROMPT:
WHAT_HAPPENED: Independently re-reviewed PR #976 at head
b0868be6b3. Verified both blockers from review #652 were fixed, ran focused (53 passed), adjacent (224 passed), and base/head full suites (identical 28 pre-existing failures).WHY: All acceptance criteria and blocker remediation requirements are satisfied with complete test proof and zero regressions.
ISSUE: #975
HEAD_SHA:
b0868be6b3REVIEW_STATUS: approved / approval_at_current_head
MERGE_READY: true
BLOCKERS: none
VALIDATION: Focused suite 53 passed, 16 subtests. Adjacent suites 224 passed, 97 subtests. Full suite base
324a0c8a28 failed, 6065 passed, 6 skipped; headb0868be628 failed, 6118 passed, 6 skipped. Failure sets identical.NATIVE_REVIEW_PROOF: transport=native_mcp; entrypoint=mcp_server; token_fingerprint=dee48dbfef52d19c
LAST_UPDATED_BY: sysadmin / prgs-reviewer
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #976
issue: none
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 87247-e2f79a754f1c
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr976-b0868be6
phase: released
candidate_head:
b0868be6b3target_branch: master
target_branch_sha: none
last_activity: 2026-07-30T04:06:07Z
expires_at: 2026-07-30T04:16:07Z
blocker: manual-release
repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #976
issue: #975
reviewer_identity: sysadmin
profile: prgs-merger
session_id: 37587-b3cfa5c84021
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr976-b0868be6
phase: claimed
candidate_head:
b0868be6b3target_branch: master
target_branch_sha:
324a0c8a8dlast_activity: 2026-07-30T04:25:13Z
expires_at: 2026-07-30T04:35:13Z
blocker: none
Stale #332 review-decision lock cleanup (#594)
Status: APPLIED
sysadminprgs-merger2026-07-30T04:26:41.756255+00:00approveon PR fix(runtime): recognize client identity environment and refresh worker registrations (#976)closed(merged=True)6596b259fcc00d4a58668b4bae813a08e843d4b42prgs-reviewerManual deletion of session-state files is not the workflow.
This path only clears a lock when the referenced PR is merged/closed.