Skip to content

fix(gateway): keep a selected peer fence through deploy recovery - #5634

Merged
devantler merged 2 commits into
mainfrom
claude/gateway-fence-selected-recovery-5448
Oct 31, 2026
Merged

devantler merged 2 commits into
mainfrom
claude/gateway-fence-selected-recovery-5448

Conversation

@devantler

Copy link
Copy Markdown
Contributor

🤖 Generated by the Agentic Engineer

Why

Email recovery needs the physical-peer fence selected before the proxy transport can be turned on, but every deploy currently removes that fence and then fails unless it is absent. Selecting it today would undo itself or evict its own pull request.

What

The deploy's restore and verify steps now follow what the checked-out source selects: unselected keeps today's behaviour, selected writes nothing and requires the reviewed fence to be live. The fence stays unselected here, so public routes do not change; selecting it is the next change.

Part of #5448

restore-disabled and verify assumed the fence is never selected, so the first
revision selecting it would have had its fence removed or its deploy failed.
Both now follow the checked-out source, and an unreadable selection fails
without a write. The fence stays unselected, so nothing changes on live routes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor
Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between aa73bf4 and a102a19.

Files selected for processing: 5
  • docs/operations/gateway-receiver-boundary.md
  • scripts/gateway-receiver-binding/main.go
  • scripts/gateway-receiver-binding/selected.go
  • scripts/gateway-receiver-binding/selected_test.go
  • scripts/gateway-receiver-binding/verify.go

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Recent review details
Context from checks skipped due to timeout: 1
  • GitHub Check: CodeRabbit
Additional context used
golangci-lint (2.14.0)
scripts/gateway-receiver-binding/selected.go

[error] 44-44: comparing with == will fail on wrapped errors. Use errors.Is to check for a specific error

(errorlint)

scripts/gateway-receiver-binding/selected_test.go

[medium] 81-81: G304: Potential file inclusion via variable

(gosec)

[medium] 96-96: G204: Subprocess launched with variable

(gosec)

LanguageTool
docs/operations/gateway-receiver-boundary.md

[style] ~90-~90: To elevate your writing, try using more formal phrasing here.
Context: ...cted, so a listener that lost the fence keeps failing verify until something rewrites it. B...

(CONTINUE_TO_VB)

Additional comments: 6
scripts/gateway-receiver-binding/selected.go: 1

1-174: LGTM!

scripts/gateway-receiver-binding/selected_test.go: 1

1-284: LGTM!

scripts/gateway-receiver-binding/main.go: 2

181-189: LGTM!

Also applies to: 198-209

190-193: Data Integrity & Integration

No affected stdout consumer is identified.

The deployment workflow runs both commands directly and relies on their exit status. It does not inspect these stdout markers. The proposed compatibility failure is unsupported.

scripts/gateway-receiver-binding/verify.go: 1

52-52: LGTM!

Also applies to: 66-66

docs/operations/gateway-receiver-boundary.md: 1

77-95: LGTM!

Walkthrough

The receiver-binding commands now render the configured layer and use its fence selection to determine restoration and verification behavior. Selected layers require matching bindings and an active receiver fence. Unselected layers require absent bindings and a disabled receiver state. Tests cover rendered selection, live-state checks, and restoration. The operations guide documents these conditions and the limits on activation and recovery.

Possibly related PRs

Merge Risk: Minimal · up to a102a

The documented selected and unselected behaviors are consistent, and no blocking issue is established.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly identifies the main change: preserving the selected peer fence during gateway deployment recovery.
Description check Passed The description directly explains the restore and verify changes for selected and unselected peer-fence states and matches the changeset.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 16 functions across 4 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

A single key in one kustomization missed a selection made from a parent
overlay, which would have removed a selected fence. An independent review
reproduced that with real renders. The render also has to contain the prepared
policies, so reading the wrong source fails instead of reading as unselected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor
Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Readiness record at a102a19edc046db39ea417341138ed60b4669b6e.

  • Tested: CI run 41234258718 succeeded at this head. Locally the helper's 69 tests pass. Three mutations of the first revision's checks were each caught: dropping the every-chain check, dropping the marker check, and removing the skip for a selected fence.
  • Reviewed: CodeRabbit reported no actionable comments at this head (summary verdict GREEN, 19:56Z), with no unresolved threads. Before that, an independent local reader found one real P1: the first revision read one YAML key, so a fence selected from a parent overlay read as unselected and would have been removed. This head reads the rendered layer instead, with a test that uses real renders of a parent selection. The reader's two notes are now in the runbook: a selected recovery does not rewrite a listener that lost the fence, and both steps still refuse an active PROXY listener.
  • Tried as a user, and what could not be: the agent host has no admin@prod context, so I cannot run either step against production. I ran the selection read against the real Hetzner infrastructure layer, which reports unselected. The unselected path first runs for real in this PR's merge-group deploy, where the log must show GATEWAY_RECEIVER_SOURCE=VERIFIED public_probes=4 fence_selected=false. The selected path has tests only and cannot run live until the activation PR. No check reaches it before then, which is why this PR leaves the fence unselected.
  • If the deploy fails: a failed render or check stops without a write, the queue evicts this PR, and the heal restores from main with the current helper.

@devantler
devantler marked this pull request as ready for review October 31, 2026 19:57
@devantler
devantler added this pull request to the merge queue Oct 31, 2026
Merged via the queue into main with commit 4b19379 Oct 31, 2026
47 checks passed
@devantler
devantler deleted the claude/gateway-fence-selected-recovery-5448 branch October 31, 2026 20:28
@github-project-automation github-project-automation Bot moved this from 🫴 Ready to ✅ Done in 🌊 Project Board Oct 31, 2026
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Correction to the readiness record above. It said the unselected path would first run for real in this PR's merge-group deploy. That was wrong: in run 41238112849 the Deploy to Prod job was skipped, so this PR merged without running the new helper against production. The live check is still owed. The next deploy from main has to show GATEWAY_RECEIVER_SOURCE=VERIFIED public_probes=4 fence_selected=false, and I am reading that from the deploy of #5635, which is queued now. Until then, this change's production behaviour is unverified.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

The live check owed above is done. The merge-group deploy of #5635 (run 41239030101), which is one commit ahead of this merge, ran the new helper against production and logged GATEWAY_RECEIVER_DISABLED=VERIFIED bindings=0 and GATEWAY_RECEIVER_SOURCE=VERIFIED public_probes=4 fence_selected=false. Platform health reads OK afterwards. This proves the unselected path only; the selected path still has tests only until the activation PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

1 participant