fix: apply Max-Forwards to pg-erd intermediary - #106
seonghobae merged 34 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (10)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughpg-erd가 공유 RFC 9110 ChangesMax-Forwards 정책 통합
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~30 minutes Change: Bug fix Sequence Diagram(s)sequenceDiagram
participant Client
participant MigrationGatewayProxy
participant http_intermediary_policy
participant Backend
Client->>MigrationGatewayProxy: OPTIONS with Max-Forwards
MigrationGatewayProxy->>http_intermediary_policy: classify after admission
http_intermediary_policy-->>MigrationGatewayProxy: FinalRecipient or Forward(1)
MigrationGatewayProxy-->>Client: 501 for zero-hop request
MigrationGatewayProxy->>Backend: forwarded OPTIONS with Max-Forwards: 1
Merge Risk: ⚪ Minimal · up to The Max-Forwards behavior is consistently applied and covered by the described listener contract. No merge-blocking issue was identified. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 57.69% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 26 functions across 5 files. (5 skipped: 5 unsupported.)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. Comment |
|
@coderabbitai review Please review current exact head |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== checked-out commit =='
git rev-parse HEAD
git status --short
printf '%s\n' '== PR metadata =='
gh pr view 106 --repo ContextualWisdomLab/pingora-gateway --json number,title,isDraft,baseRefName,headRefName,commits,files --jq '{number,title,isDraft,baseRefName,headRefName,commits:[.commits[].oid],files:[.files[].path]}'
printf '%s\n' '== parent commits and changed files =='
git log --oneline --decorate -8
git diff --name-status HEAD~1..HEAD
printf '%s\n' '== stat =='
git diff --stat HEAD~1..HEADLength of output: 2200 🏁 Script executed: #!/bin/bash
set -euo pipefail
base_ref="fix/generic-forwarding-header-sanitization-v1"
merge_base=$(git merge-base HEAD "$base_ref")
printf '== merge base ==\n%s\n' "$merge_base"
printf '%s\n' '== aggregate changed files =='
git diff --name-status "$merge_base"...HEAD
printf '%s\n' '== Rust outlines =='
ast-grep outline src/http_intermediary_policy.rs --items all || true
ast-grep outline src/gateway_proxy.rs --items all || true
ast-grep outline src/migration_proxy.rs --items all || true
ast-grep outline tests/pg_erd_max_forwards_traffic.rs --items all || true
printf '%s\n' '== aggregate source and test diff =='
git diff --find-renames --find-copies --unified=80 "$merge_base"...HEAD -- \
src/http_intermediary_policy.rs src/gateway_proxy.rs src/migration_proxy.rs src/lib.rs \
tests/pg_erd_max_forwards_traffic.rsLength of output: 1215 🏁 Script executed: #!/bin/bash
set -euo pipefail
base_sha=$(gh pr view 106 --repo ContextualWisdomLab/pingora-gateway --json baseRefOid --jq .baseRefOid)
printf '== base SHA ==\n%s\n' "$base_sha"
printf '%s\n' '== base object and ancestry =='
git cat-file -t "$base_sha" || true
git merge-base --is-ancestor "$base_sha" HEAD && echo 'base is an ancestor of HEAD' || echo 'base is not an ancestor of HEAD'
printf '%s\n' '== files changed from base to head =='
git diff --name-status "$base_sha"...HEAD
printf '%s\n' '== Rust outlines =='
ast-grep outline src/http_intermediary_policy.rs --items all || true
ast-grep outline src/gateway_proxy.rs --items all || true
ast-grep outline src/migration_proxy.rs --items all || true
ast-grep outline tests/pg_erd_max_forwards_traffic.rs --items all || true
printf '%s\n' '== aggregate Rust source and fixture diff =='
git diff --find-renames --find-copies --unified=100 "$base_sha"...HEAD -- \
src/http_intermediary_policy.rs src/gateway_proxy.rs src/migration_proxy.rs src/lib.rs \
tests/pg_erd_max_forwards_traffic.rsLength of output: 57137 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== all ProxyHttp implementations =='
rg -n -C 5 'impl\s+ProxyHttp\s+for\s+' src tests
printf '%s\n' '== Max-Forwards policy call sites =='
rg -n -C 5 '\b(max_forwards_action|apply_max_forwards_before_forward|MaxForwardsAction)\b' src tests
printf '%s\n' '== pg-erd binary/startup and route references =='
rg -n -C 5 'cwl-pingora-pg-erd-migration|/api/max-forwards|/api/plain|MigrationGatewayProxy' \
Cargo.toml src tests
printf '%s\n' '== integration-test configuration =='
sed -n '1,260p' Cargo.toml
printf '%s\n' '== complete migration callback and tests =='
sed -n '60,430p' src/migration_proxy.rs
printf '%s\n' '== complete listener fixture =='
sed -n '1,280p' tests/pg_erd_max_forwards_traffic.rs
printf '%s\n' '== changed contract documentation =='
base_sha=38dab48f910f7078c3dfd37764a6fdc229bd513e
git diff --unified=40 "$base_sha"...HEAD -- API_CONFIG_CONTRACT.md CHANGELOG.md SECURITY.md TEST_STRATEGY.md TRD.mdLength of output: 126102 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '== pg-erd composition root =='
ast-grep outline src/bin/cwl-pingora-pg-erd-migration.rs --items all || true
sed -n '1,260p' src/bin/cwl-pingora-pg-erd-migration.rs
printf '%s\n' '== compiled route profile =='
rg -n -C 6 'RouteRule|RouteMatch|/api|backend|frontend' src/migration_admin.rs src/migration_plan.rs
printf '%s\n' '== patch whitespace check =='
base_sha=38dab48f910f7078c3dfd37764a6fdc229bd513e
git diff --check "$base_sha"...HEAD
printf '%s\n' '== exact source locations of new migration control flow =='
nl -ba src/http_intermediary_policy.rs | sed -n '1,120p'
nl -ba src/migration_proxy.rs | sed -n '120,330p'
nl -ba tests/pg_erd_max_forwards_traffic.rs | sed -n '110,230p'Length of output: 27802
I found no actionable issues in the requested areas.
I performed a static review only. I did not build or execute the repository. This review does not change the Draft status or establish merge readiness. ✅ Action performedReview finished.
|
|
Fresh parent-drift finding: current #15 moved to This is a repair finding, not a close condition. The behind commit is #15's test/traffic coverage repair and overlaps the generic/migration proxy test surfaces refactored here into shared |
|
Parent-state correction: #15 current exact moved to |
seonghobae
left a comment
There was a problem hiding this comment.
Current-parent reconciliation review found two concrete repair requirements before this lane can be restacked onto integrated #15 840b03873d8e25ebd960438183884ea609b173ff.
-
Admission precedence is currently wrong in the historical pg-erd implementation. In
MigrationGatewayProxy::request_filter,max_forwards_action(session.req_header())?runs beforereject_oversize_declared_body(...). That means a TRACE/OPTIONS request with both an oversized declared body and malformed/duplicateMax-Forwardsreturns 400 before the parent's body-admission contract can return 413. The PR body explicitly requires preserving integrated #15's declared-body 413 precedence. During reconciliation, classifyMax-Forwardsonly after the in-flight lease and declared-body check; add an executable regression where oversizedContent-Lengthplus malformed/duplicateMax-Forwardsremains 413 and no origin contact occurs. -
The new real-listener fixture reintroduces the exact startup-evidence defect already repaired in the current parent stack.
reserve_loopback()returns only the address and drops itsTcpListener, creating a bind-steal window;wait_until_listening()then credits a bare TCP connect as readiness. Current parent evidence now keeps traffic/metrics reservations alive through config construction and requires application-level HTTP readiness. Reconciletests/pg_erd_max_forwards_traffic.rsonto that pattern rather than replaying this historical helper. Require real/readyzHTTP 200 (and the metrics listener's HTTP 200 where that fixture depends on metrics readiness), with reservations released only immediately before process spawn.
These are repair findings, not reasons to close the PR. Keep Draft, adopt the integrated parent ordinary/non-force, preserve the valid shared http_intermediary_policy extraction, and reacquire exact-head CI/Supply/traffic/coverage/review. No predecessor receipt should transfer.
seonghobae
left a comment
There was a problem hiding this comment.
Current-exact technical review after integrated-parent reconciliation. I re-read the effective diff against 840b038..., the shared intermediary policy, both adapter call orders, real-listener pg-erd fixture, and code-current contract/security/test docs. The prior 413-precedence and listener-evidence findings are repaired: pg-erd now acquires the ordinary lease, enforces declared-body admission, and only then classifies Max-Forwards; the fixture preserves port reservations until spawn, uses HTTP readiness, requires oversized+malformed/duplicate to return 413 before origin contact, and exits gracefully so compiled-child coverage can flush. Generic TRACE-content, forwarding/Via, runtime-isolation and current parent behavior are retained while generic and pg-erd consume one parser/decrement authority. No additional writer-safe source finding found on f8df1246e19780614fc2a2399bcb3da700b1aee0. This is COMMENT-only review, not approval; exact-head hosted formatting/compile/test/Clippy/rustdoc/coverage/OCI/Supply evidence is still required before integration.
seonghobae
left a comment
There was a problem hiding this comment.
Current-exact technical review after hosted formatter RCA. Predecessor f8df124 fully ran: Supply, OCI and load were GREEN; test failed only at Rust 1.98.0 cargo fmt before compile/test. The fetched hosted log contained deterministic layout deltas in exactly src/http_intermediary_policy.rs and tests/pg_erd_max_forwards_traffic.rs. Ordinary commits 4fa238c and 7962100 apply only those rustfmt changes. Max-Forwards parsing/decrement, 413-before-400 admission precedence, zero-hop 501/no-origin-contact behavior, listener reservations, HTTP readiness, graceful shutdown and supplier/runtime boundaries are unchanged. Compare remains ahead 18 / behind 0 from integrated #15 with #15 as merge-base. Fresh CI/Supply must settle independently. COMMENT only; no approval or merge credit.
seonghobae
left a comment
There was a problem hiding this comment.
Current-exact technical review after #16 integration reconciliation: effective diff is again limited to the ten Max-Forwards-owned paths, live-base compare is ahead 19 / behind 0 with merge-base exactly bf38bc571dbb7c75e651bcaccdc66904c8c92dab, and the #16 runtime-isolation file/CLAUDE delta is inherited rather than replayed or overwritten. I do not find a new source-level boundary regression in the reconciled range. This COMMENT is review evidence only, not self-approval; integration still requires fresh exact CI/Supply and the stated traffic/coverage/OCI gates.
Preserve the validated Max-Forwards tree as first-parent state while recording integrated #119 as the additional parent. The parent-only refused-origin fixture/docs are composed in follow-up ordinary commits; no force-push or destructive rebase.
seonghobae
left a comment
There was a problem hiding this comment.
Current-exact technical review on dbecf6e43372e52d8af46e734fb74df83d63399d (COMMENT only; not approval). Live parent is integrated #119 40e10607601bf9722d642d4a4bb18f02806c20cc; merge-base is exactly that parent and behind is 0. Effective delta is again the ten Max-Forwards-owned paths only. Parent refused-origin fixture is inherited unchanged; CHANGELOG.md / TEST_STRATEGY.md compose both authorities rather than dropping either. Max-Forwards ordering/zero-hop/malformed/duplicate behavior is unchanged, #61-owned baseline/TRACEABILITY remain untouched, and no product auth/business logic, Keyverse/Wardnet/EgressWeave authority, service discovery, or WebSocket authority is added. Previous exact 40dd054... Supply GREEN does not transfer. Fresh CI 35449030706 and Supply 35449030601 are queued.
seonghobae
left a comment
There was a problem hiding this comment.
Current-parent reconciliation review for 1fb5f514411414bff7a738fb64f3327263024a0d against live parent fix/pg-erd-listener-wildcard-collision-v1@7417e7551a496bffee711375171ea7816cfac81a: compare remains diverged (ahead 28 / behind 35, merge-base c78a296a87972845f8f9724e2cf2072d95a7df34) and the effective child range is exactly ten Max-Forwards paths. The parent delta is not ancestry-only: #104 introduced compiler-enforced private-production rustdoc and meaningful private-item documentation. Five child paths overlap that authority (CHANGELOG.md, TEST_STRATEGY.md, src/gateway_proxy.rs, src/lib.rs, src/migration_proxy.rs). A valid ordinary/non-force reconciliation therefore must semantically compose those parent rustdoc/lint changes with the child intermediary-policy refactor; merely creating a two-parent commit with the current child tree would silently regress #104 even though ancestry becomes behind=0. Non-overlap child paths (API_CONFIG_CONTRACT.md, SECURITY.md, TRD.md, src/http_intermediary_policy.rs, tests/pg_erd_max_forwards_traffic.rs) can be preserved verbatim. Keep this PR Draft until the five overlap paths are composed and fresh exact lint/rustdoc/coverage/traffic/Supply evidence runs. This COMMENT is merge-planning evidence only, not approval or GREEN.
seonghobae
left a comment
There was a problem hiding this comment.
Current-head reconciliation review on 18c768b50aebaf5bf9ef39d07c03c0599a5b38f0: parent compare is ahead 34 / behind 0 with exactly the intended ten Max-Forwards paths. The pre-reconciliation causal-fix exact 1fb5f514... → current-head compare contains no functional deletions: overlap changes are one CHANGELOG replacement, one TEST_STRATEGY replacement, +5 private rustdoc lines in gateway_proxy, +1 crate lint line in lib, +7 private rustdoc lines in migration_proxy, plus #104's twelve parent-only documentation additions. The Max-Forwards implementation/test/coverage repair blobs are therefore retained while #104's private-production rustdoc contract is inherited. This is COMMENT-only technical evidence, not self-approval. Fresh exact CI/Supply 35494556815 / 35494556785 are newly materialized and must settle successfully before integration.
045acb2
into
fix/pg-erd-listener-wildcard-collision-v1
Scope
Writer-safe successor for #105. This lane owns only shared HTTP intermediary
Max-Forwardspolicy and bounded pg-erd consumption. It does not add product auth/business logic, Keyverse identity, Wardnet/EgressWeave authority, service discovery, WebSocket authority, or request-selected upstream destinations.Historical RED
84a75125...proved pg-erd forwardedOPTIONS ... Max-Forwards: 0instead of terminating locally. #15, #16, refused-origin successor #119, and read-stall #18 are already integrated ancestry.Valid RED and causal repair — 2026-09-20
After #18 reconciliation, exact
5f87459ea78c6e9f5dfe98ec38ffa70550f14626preserved the intended ten-path Max-Forwards scope. Supply Chain35468678900, load-contract, OCI runtime, compile/test, Clippy and rustdoc all succeeded, but CI35468678908failed the owned-production 100% region gate. Coverage artifact10596611208(sha256:cb4616ba20c1d65cda642d1205353ebbb1d6513f51e9a676a9c21db5085ec6e7) identified exactly one uncovered region atsrc/migration_proxy.rs:163: the error continuation generated byself.apply_response_headers(&mut response)?in the zero-hop pg-erd final-recipient path. Line coverage remained 100%.ResponseHeaderPolicy::try_newalready validates admitted response-header names/values before activation, and the local literal headers in this path are invariant assertions. Ordinary fast-forward commit1fb5f514411414bff7a738fb64f3327263024a0dreplaces only that structurally impossible?continuation with an invariantexpect. It changes no HTTP behavior, coverage denominator, exclusion, routing/auth authority, or gate.#104 semantic reconciliation completed
Sibling quality lane #104 completed full exact GREEN and normally merged into this PR's base branch as
7417e7551a496bffee711375171ea7816cfac81a. This lane did not solve that movement with a child-tree ancestry merge.The five overlap paths were first composed explicitly:
cf1977a79fe6df81a1aabbf8e52ae011f0a59951:src/lib.rskeeps the shared privatehttp_intermediary_policymodule and inherits test: enforce private production rustdoc contract #104's non-testclippy::missing_docs_in_private_itemsgate.9414c40e481b36ea853046ae92d9bc190a6c3174:TEST_STRATEGY.mdkeeps test: enforce private production rustdoc contract #104's warnings-denied/private-production rustdoc acceptance and this lane's real-listener Max-Forwards contract.4b1a5cc82c20fda2a969edb98d2b1a9a5d67f2cf:CHANGELOG.mdkeeps the Max-Forwards entry and replaces the stale public-only rustdoc claim with test: enforce private production rustdoc contract #104's compiler-enforced private-production contract.d45f807b0c06fb5af8d15f85910a54734aa2f519:src/gateway_proxy.rskeeps the shared Max-Forwards refactor while restoring meaningful private request/proxy-field rustdoc.10a229dcd16e18feca8380930d3b25c73175338f:src/migration_proxy.rskeeps the Max-Forwards implementation and coverage repair while restoring private context/proxy/forwarding-helper rustdoc.Final ordinary two-parent reconciliation commit
18c768b50aebaf5bf9ef39d07c03c0599a5b38f0has first parent10a229d...and second parent7417e755.... Its tree is built from the exact #104 parent tree and overlays only this lane's ten verified effective paths. Compare from #104 is ahead 34 / behind 0, merge-base exactly7417e755..., with exactly these ten paths:API_CONFIG_CONTRACT.mdCHANGELOG.mdSECURITY.mdTEST_STRATEGY.mdTRD.mdsrc/gateway_proxy.rssrc/http_intermediary_policy.rssrc/lib.rssrc/migration_proxy.rstests/pg_erd_max_forwards_traffic.rsThe inverse verification from pre-merge child
10a229d...to18c768b...shows only #104's twelve parent-only private-rustdoc source files added, with none of the ten Max-Forwards blobs altered. A direct1fb5f514...→ current-head compare likewise shows no functional deletions: the reconciliation adds/replaces only documentation/lint-contract text around the already-repaired Max-Forwards implementation. This rules out the earlier invalidbehind 0shape that would have silently dropped parent quality contracts.Draft synchronize runs CI
35494531904and Supply Chain35494531888are SKIPPED and are not GREEN. After exact ancestry/tree verification, #106 was returned to Ready and a COMMENT-only current-head review5259799275was recorded without self-approval. Fresh exact CI35494556815subsequently completed SUCCESS on unchanged18c768b...: load-contract, formatting, compile/test, Clippy, warnings-denied rustdoc, complete owned-production coverage, resolved-lock verification, and least-privilege OCI runtime all passed. Supply Chain35494556785also completed SUCCESS, including dependency audit, SPDX SBOM, exact candidate image scans, and source binding. With no review threads and no remaining lane-local blocker, the PR normally merged with expected-head protection as045acb2675788e15fd98175deebcc4fec2f042a8on 2026-09-21 KST.The Max-Forwards behavior remains unchanged: positive TRACE/OPTIONS values decrement and cap at 255; zero terminates locally; malformed/duplicate values fail closed; other methods retain the field; pg-erd keeps application admission and declared-body checks before Max-Forwards classification, preserving 413 precedence. Zero-hop traffic returns bounded empty 501 without origin contact and retains characterized response-security fields.
Repository-wide
docs/product-technical-gap-baseline.mdand TRACEABILITY remain #61 authority. Merge045acb2675788e15fd98175deebcc4fec2f042a8is dependency-branch integration only. No protected-main promotion, immutable release, canary/shadow, rollback, cutover, or legacy-removal credit is claimed.