Provenance: generated from site-authored sources with
github.com/gopherguides/hypev0.8.0.
The working-checkout merge-gate trap
Verified against Detent v0.57.0 at
154392918736.
Detent can take a pull request through successful CI and still refuse to promote it because the merge gate is asking for a check that no longer exists. The policy may not come from the branch under test.
The mechanism
There are two configuration layers to keep straight:
- The project's entry in Detent's global configuration selects
projects[].workflow,projects[].workdir, and optionallyprojects[].workflow_ref. - That workflow's sibling
detent.yamlcontainsworkspace.source_rootand the merge-gate policy atgate.required_status_checks.
When projects[].workflow_ref is empty, Detent loads the workflow from its configured path in the working tree. The project-definition loader then reads detent.yaml beside that workflow. A different branch in that checkout can therefore change the effective gate for every issue, regardless of the branch in an issue's isolated worktree. Source: working-tree workflow selection and sibling detent.yaml loading.
The configured working checkout for this site is explicit:
workspace:
root: /Users/corylanou/code/detent.build-workspaces
source_root: /Users/corylanou/projects/digitaldrywood/detent.build
cache_strategy: isolated
auto_branch: true
cleanup_idle_ttl_ms: 86400000
cleanup_sweep_interval_ms: 600000
source: detent.yaml:workspace-checkout
Its gate is also explicit:
gate:
kind: command
run: make check && CGO_ENABLED=0 go build -o /dev/null ./cmd/server
require_automated_review: false
required_status_checks: []
ci_failure_action: rework
transient_ci_retry_limit: 2
validator:
enabled: false
# The settings below are inert while enabled is false. Uncomment them
# together with enabled: true. Leave model empty to inherit the
# route/provider default; a pin needs manual updates before retirement.
# model: ""
# min_score: 0.8
# max_inline_diff_bytes: 65536
# block_on:
# - p1
source: detent.yaml:merge-gate
This site sets required_status_checks: [], so it does not reproduce the failure. In a project with named required checks, Detent treats an absent name as missing, and missing, skipped, failed, cancelled, neutral, or running checks block promotion. Source: required-check evaluation and gate contract.
What it looks like
The operational symptom is a pull request whose actual CI is green while Detent keeps withholding promotion because the loaded policy names a retired check. The issue, pull request, and board describe the work under test; none of them inherently tells you which branch supplies the daemon's project definition.
On versions before the current safeguards, that mismatch could send work around the gate repeatedly with no useful board-level explanation. At the pinned v0.57.0, Detent records consecutive missing-check evaluations and blocks after three rather than cycling forever. Source: persistent missing-check threshold and streak evaluation.
Confirm it
Run the read-only doctor from the Detent host:
detent doctor --port 0
Find Project <id> workflow source policy in the output. With no workflow_ref, v0.57.0 reports that the project reads merge policy from a mutable working tree, names the checked-out branch, and compares the effective detent.yaml with the repository's default branch. A branch mismatch or different file is a failure; even a matching default branch remains a warning because it is mutable. Source: doctor mutable-source diagnostic.
Also inspect the two facts doctor is testing:
git -C <projects[].workdir> branch --show-current
git -C <projects[].workdir> diff origin/<default-branch> -- detent.yaml
Then compare gate.required_status_checks with the check names on the current pull-request head. Do not infer a renamed or retired check from a green aggregate result; the configured names are exact gate inputs.
Fix it
For immediate recovery, put the configured working checkout on the intended default branch, update it, and make gate.required_status_checks match the checks the repository actually emits. Rerun detent doctor --port 0 before returning the item to the merge path.
The durable prevention is to set projects[].workflow_ref to a remote-tracking ref such as origin/main in Detent's global configuration after WORKFLOW.md and detent.yaml exist at that ref. Detent then reads both shared files from that commit and ignores the working-tree branch; local overlays remain working-tree inputs. Source: ref-backed project definitions.
Doctor verifies that the configured remote-tracking ref is fresh. It checks the remote without fetching, so fetch the ref when doctor reports staleness, then rerun doctor until the policy check says the ref is fresh and ignores the working-tree branch. Source: workflow-ref freshness diagnostic.