fix(guard): derive target base ref for cross-repository checkouts #983
Closed
opened 2026-07-30 20:57:38 -05:00 by jcwalker3
·
2 comments
No Branch/Tag Specified
master
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
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
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#983
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.
Summary
Cross-repository mutation gating and parity reporting each hardcode a PRGS-specific
base ref. A namespace whose canonical repository root points at any repository that
does not use the remote
prgswith branchmastercannot prove base equivalence,so every gated mutation fails closed with no reachable remedy.
Two independent hardcoded assumptions, in two different modules, disagreeing with
each other and with reality.
Observed failure
A valid cross-repository target:
fails create-issue bootstrap with:
The guard probes only
prgs/masterandrefs/remotes/prgs/master. Neither existsin that checkout, so the resolver returns
None, base equivalence is unprovable,and the bootstrap fails closed. The target repository is correct and healthy; the
guard is asking it the wrong question.
Confirmed defect sites (verified at
108cbfa173)1.
root_checkout_guard.py— mutation gatingREMOTE_MASTER_REFS = ("prgs/master", "refs/remotes/prgs/master")resolve_remote_master_sha()accepts aremote_refsoverride, butall four production callers omit it and silently inherit the PRGS default:
gitea_mcp_server.py:1055— author issue bootstrapgitea_mcp_server.py:1085— create-issue bootstrap (#749/#757 path)gitea_mcp_server.py:1306— namespace mutation preflightgitea_mcp_server.py:1990—_enforce_root_checkout_guard(#475)prgs/masterinto the operator-facingfailure message, so even a correct non-PRGS failure is reported misleadingly.
2.
master_parity_gate.py— parity reportingDEFAULT_TARGET_TRACKING_REF = "refs/remotes/origin/master"assess_target_repository_parity(..., tracking_ref=DEFAULT_TARGET_TRACKING_REF)git remote get-url origin— ahardcoded remote name.
The two modules do not even agree with each other: gating assumes remote
prgs,reporting assumes remote
origin. At most one can be right for any givenrepository, and for a repository using neither, both are wrong.
Live evidence in this very repository
This reporting defect is observable on Gitea-Tools itself, today:
There is no
originremote in this checkout (git config --get remote.origin.urlexits 1;
git remotelists onlyprgs).refs/remotes/origin/masteris anorphan remote-tracking ref left behind by a remote that was removed. The parity
gate read that abandoned ref, compared HEAD against a long-dead commit, and reported
the target repository as stale — while simultaneously failing to derive the
repository identity because the
originremote it assumed does not exist.So the reporting bug is not hypothetical or MDCPS-specific. It already produces a
false
stale: trueand a null identity against the PRGS repository itself.Why no new configuration field is needed
Git already records the authoritative default branch per remote:
And
canonical_repository_root.repository_identity_slug()(the existingauthoritative repository/context resolver, #706/#973) already probes remotes in
order and successfully identifies the right one — it simply discards the remote
name after using it, returning only the
owner/reposlug.The information required to fix this is therefore already present and already
resolved. The fix extends the existing resolver to stop throwing away what it
learned. No second source of repository truth, and no new configuration field.
Scope of work
prgs/masterassumptions from cross-repository mutation gating.origin/masterassumptions from related parity reporting.MDCPSmust neverbe folded to
mdcps) and the authoritative integration/default branch.never again disagree.
prgs+mastermust keep resolving torefs/remotes/prgs/masterand the same SHA as today.MDCPS/devwithout special-casing MDCPS anywhere.underivable base ref must never fall back to an unrelated PRGS commit.
Explicit non-goals
Not to be done under any circumstance:
masterbranch in a target repository.originremote.MDCPS,WeeklyBriefings-Meta, ordev.Acceptance criteria
prgs/masteris unchanged.MDCPSand branchdevresolvesrefs/remotes/MDCPS/dev.originresolves correctly.[THREAD STATE LEDGER] Issue #983 / PR #984 — author implementation complete, pull request open
What is true now:
2d5d5c9d172d5d5c9d17108cbfa, failure sets byte-identicalWhat changed:
2d5d5c9published to prgs, only the issue branch pushedWhat is blocked:
Who/what acts next:
2d5d5c9d17Server-side mutation ledger:
2d5d5c9d17Canonical Issue State
STATE: implementation complete, pull request #984 open and awaiting reviewer
WHO_IS_NEXT: reviewer
NEXT_ACTION: review pull request #984 at head
2d5d5c9d17, confirming that the derived base ref removes the prgs/master gating assumption and the origin/master reporting assumption, that remote-name case is preserved exactly, and that fail-closed refusals carry a reason_codeNEXT_PROMPT: Review pull request #984 on Scaled-Tech-Consulting/Gitea-Tools at head
2d5d5c9d17. Verify that root_checkout_guard no longer inherits the prgs/master default at any of its five production consumers, that master_parity_gate derives its tracking ref and repository identity instead of assuming a remote named origin, that canonical_repository_root.resolve_target_base_ref preserves exact remote-name case and refuses ambiguous or underivable targets with a reason_code, and that tests/test_issue_983_cross_repo_base_ref.py covers the MDCPS/dev cross-repository case without special-casing MDCPS. Confirm the twenty-eight full-suite failures are pre-existing at base commit108cbfaand not introduced by this branch.WHAT_HAPPENED: the guard and the parity report each hardcoded a different base ref, so the author derived the target instead by extending canonical_repository_root, the existing authoritative repository resolver, to return the remote name it already discovered while resolving repository identity and to build refs/remotes// from git's own recorded remote default branch; five production consumers now share that one resolved target, twenty-four hermetic regression tests were added, and one commit was published and opened as pull request #984
WHY: cross-repository mutation gating assumed the base ref was prgs/master while parity reporting independently assumed origin/master, so any repository using neither could not prove base parity and every gated mutation failed closed with no reachable remedy; the two modules also disagreed with each other, so at most one could be correct for any given repository
RELATED_PRS: PR #984 is the only pull request for this issue, opened from fix/issue-983-cross-repo-base-ref against master; no other pull request touches this work
BLOCKERS: none — the pull request is open and mergeable, no blocker applies
VALIDATION: focused suite tests/test_issue_983_cross_repo_base_ref.py 24 passed in 4.41s; sixteen directly affected suites 375 passed and 130 subtests passed in 36.93s; full suite on branch 28 failed, 6191 passed, 6 skipped, 1106 subtests passed; full suite on clean baseline worktree at the identical base commit
108cbfa28 failed, 6166 passed, 6 skipped, 1106 subtests passed; both sorted FAILED lists diffed byte-identical, so zero failures were introduced and the plus twenty-five passed delta is the new testsLAST_UPDATED_BY: author (prgs-author, jcwalker3)
[THREAD STATE LEDGER] Issue #983 / PR #984 — REQUEST_CHANGES review 658 remediated at new head
03b434a0b6What is true now:
sysadmin, at head2d5d5c9d174ae5f7a36c57e724af298fc5cff8dc) is untouched — not dismissed, not overwritten, not concealed.has_blocking_change_requests=true,approval_visible=false,approval_at_current_head=false.master, head branchfix/issue-983-cross-repo-base-ref, body linksCloses #983.108cbfashowing 28 failed / 6166 passed / 6 skipped / 1106 subtests passed. Sorted FAILED lists are byte-identical (sha1092dae4bc8c4e77d14504d90690d50e0fcd2f637) — zero introduced failures.What changed:
03b434a0b631a197005068725176b3726a46ae89pushed tofix/issue-983-cross-repo-base-ref; remote head equals local head; worktree clean.refs/remotes/<remote>/HEADis no longer authoritative. It is a clone-time cache that an ordinary fetch never refreshes, so on the real target it namedmainwhile the checkout tracked and sat exactly ondev.resolve_target_base_refnow derives from the identity remote, then the checkout's own configured upstream (branch.<current>.remote+branch.<current>.merge) accepted only when it names that remote and its tracking ref exists, then exactly one presentmaster/main/devtracking ref. The cached symref is demoted to an observation reported ascached_remote_head_branch/cached_remote_head_conflictsand named in refusal text; it never decides the branch and never breaks a tie.explicit_remotethroughresolve_target_base_ref,resolve_remote_master_sha, andresolve_remote_master_ref_state;assess_target_repository_paritypasses none and now resolves identity through the new ambiguity-awareassess_identity_remote. An ambiguous target yields a null slug, no tracking ref, and the samereason_codethe guard emits.resolve_identity_remote/repository_identity_slugkeep first-wins behaviour for the #706/#973 canonical-root validation path./Users/jasonwalker/Development/weekly-briefingsnow derivesMDCPS/dev/refs/remotes/MDCPS/dev, sourceconfigured_branch_upstream,cached_remote_head_conflicts=true, checkout not stale ata37ac427c18b. PRGS is unchanged —prgs/master/refs/remotes/prgs/master, identical SHA108cbfa173de, not stale.dev, cachedrefs/remotes/MDCPS/HEADpointing atmain, both refs present at different commits) instead of manufacturing the cache state; plus cache-alone never proves a target, cache never breaks a tie, guard and parity report agree on an ambiguous remote and on an ambiguous branch, explicit disambiguation stays distinct from inferred identity, no production caller passesexplicit_remote, and a read-only proof snapshotting refs, remotes, local config, HEAD, branch, working-tree status, and the cached symref.What is blocked:
gitea_edit_prexposes noworktree_path). Treat this comment as the accurate record: the section "How the authoritative target is resolved" still describes step 2 asrefs/remotes/<remote>/HEAD; "PRGS compatibility" still cites sourceremote_head_symref; and "Exact test results" still cites the previous head's counts of 24 focused tests, 375 affected-suite passes, and 6191 full-suite passes.Who/what acts next:
03b434a0b631a197005068725176b3726a46ae89asprgs-reviewer/sysadmin, confirming B1 and B2 remediation and the regression fixtures, then record a formal verdict through the native review API.git fetch,git remote set-head, or any ref mutation against the Weekly Briefings target; do not synchronize the production control checkout; do not restart MCP servers; do not change the author binding tomdcps-author.Canonical Issue State
STATE: remediated-at-new-head-awaiting-independent-formal-review
WHO_IS_NEXT: reviewer
NEXT_ACTION: Review new head
03b434a0b6on PR #984 as prgs-reviewer and record an independent formal verdict; review 658 at the prior head stays on the record untouched.NEXT_PROMPT:
WHAT_HAPPENED: Author cycle remediated the two blocking findings of review 658 and pushed commit
03b434a0b6to fix/issue-983-cross-repo-base-ref, replacing the stale remote-HEAD cache with the checkout's configured upstream as the authoritative base signal, and separating explicit caller disambiguation from internally inferred identity so an ambiguous target fails closed identically in gating and in reporting; the prior review verdict was left in place and a fresh independent review of the new head is required.WHY: The previous head derived the integration branch from a clone-time cache that fetch never refreshes, which produced MDCPS/main for a Weekly Briefings checkout sitting exactly on its MDCPS/dev tip and kept that target's author work failing closed; and the parity report re-supplied its own inferred remote to the resolver, suppressing the ambiguity gate so gating and reporting could evaluate different repositories.
RELATED_PRS: PR #984 (open, base master, head fix/issue-983-cross-repo-base-ref, links Closes #983) is the only pull request for issue #983; no other pull request is involved.
BLOCKERS: None outstanding for the author role. The PR description text remains inaccurate about the resolution order, the PRGS source label, and the previous head's test counts, and cannot be edited from the author role under the #618 wall; this comment is the accurate record.
VALIDATION: Focused tests/test_issue_983_cross_repo_base_ref.py 37 passed; nineteen affected suites 441 passed with 167 subtests passed; full suite 28 failed, 6204 passed, 6 skipped, 1106 subtests passed; clean baseline worktree at base commit
108cbfa28 failed, 6166 passed, 6 skipped, 1106 subtests passed; sorted FAILED lists byte-identical at sha1 092dae4bc8c4e77d14504d90690d50e0fcd2f637 so zero failures were introduced; remote head equals local head at03b434a0b6.LAST_UPDATED_BY: author