ステータス分類を公式実装に揃える (compressed flag / HTTP_1_1_REQUIRED / trailers欠落 → INTERNAL) - #28
Conversation
…INTERNAL) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
| if (call->compressed_response_seen || call->unsupported_response_encoding) return GRPC_STATUS_UNIMPLEMENTED; | ||
| /* Client-side inability to process a server message is INTERNAL per | ||
| * compression.md; UNIMPLEMENTED is reserved for the server-side case. */ | ||
| if (call->compressed_response_seen || call->unsupported_response_encoding) return GRPC_STATUS_INTERNAL; |
There was a problem hiding this comment.
この変更で圧縮未対応応答は INTERNAL に変わっていますが、docs/SPEC.md の重要前提/未決事項、docs/design/protocol-classification-boundary.md、docs/verification/compatibility-control-checklist.md が旧 UNIMPLEMENTED 前提のままです。status taxonomy は PHP-visible behavior なので、PR内で current spec/design/checklist も最終挙動に合わせて更新してください。missing trailers も checklist が STATUS_UNKNOWN のままなので合わせて更新が必要です。
There was a problem hiding this comment.
対応しました (ce5872d)。docs/SPEC.md の重要前提・未決事項、protocol-classification-boundary.md の分類表(Unsupported compression → INTERNAL に更新、Missing trailers 行を新規追加)、compatibility-control-checklist.md の missing trailers / 圧縮の期待値を最終挙動(INTERNAL)に合わせて更新しました。
| return strpprintf(0, "HTTP/2 stream reset: %u", call->stream_error_code); | ||
| } | ||
| if (call->stream_closed && call->grpc_status < 0) { | ||
| return zend_string_init("server closed the stream without sending trailers", sizeof("server closed the stream without sending trailers") - 1, 0); |
There was a problem hiding this comment.
この新規 details 文字列は C unit では通りません。missing trailers の code は tests/unit/test_status_core.c で固定されていますが、UnaryCall::wait() / ServerStreamingCall::getStatus() 経由で details が空文字や malformed gRPC response frame に戻る回帰は検出できません。50054 fixture などに clean END_STREAM without grpc-status を追加し、PHPT で unary / server streaming 両方の STATUS_INTERNAL とこの details を assert してください。
There was a problem hiding this comment.
対応しました (ce5872d)。50054 fixture に x-bench-grpc-response: no-trailers(message 送信後 grpc-status なしで clean END_STREAM)を追加し、PHPT 022 で unary / server streaming 両方について STATUS_INTERNAL と details "server closed the stream without sending trailers" を assert するようにしました。test-server 再ビルド後 PHPT 17/17 pass を確認済みです。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
敵対的レビュー(
|
…me区別 (grpc-go exact) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
敵対的レビュー3件に対応しました (f5a2f75)。 [Medium] encoding宣言のみでの拒否 → 対応
50054 fixture を拡張し(
[Design Decision] terminal frame の区別 → grpc-go exact を選択3択のうち grpc-go exact を採用しました。理由: 本 issue の変更根拠自体が grpc-go の分類であり、ext-grpc の UNKNOWN "Stream removed" は C-core transport エラーの偶発的文言で仕様意図を表さず、全 clean-close INTERNAL は公式のどちらとも一致しない独自 policy になるためです。Decision Log に記録済み。 実装: [Low] fixture inventory / verification matrix → 対応
検証
🤖 Generated with Claude Code |
dkkoma
left a comment
There was a problem hiding this comment.
敵対的・再レビュー(f5a2f75)
前回の encoding Medium は修正済み、missing-trailers の Design Decision は grpc-go exact として明示・受入済み、fixture inventory の Low も修正済みです。新規 finding は Medium 2件、Low 1件です。
[Medium] src/transport.c:2127 — NGHTTP2_HCAT_HEADERS は terminal trailers を意味しない
trailing_headers_seen は NGHTTP2_HCAT_HEADERS を受けた時点で、END_STREAM を確認せず true になります。しかし nghttp2 の category 契約では、これは「他 category に該当しない generic HEADERS」であり、1xx 後の final response HEADERS もここへ分類されます。
そのため、non-terminal generic HEADERS の後に DATA END_STREAM で status なしとなると、実際の terminal frame は DATA なのに trailing_headers_seen=true が status_core.c の INTERNAL 判定を抑止し、UNKNOWN へ落ちます。grpc-go exact policy を表す field なら、少なくとも NGHTTP2_FLAG_END_STREAM 付き HEADERS だけを terminal marker として記録してください。
raw fixture で、(a) trailing HEADERS + END_STREAM → UNKNOWN、(b) non-terminal second HEADERS 後の DATA END_STREAM → INTERNAL または先行 malformed INTERNAL、を unary / streaming で固定する必要があります。
[Medium] docs/verification/compatibility-control-checklist.md:37,62,66 — current verification gate が最終 policy と矛盾する
checklist は missing trailers 全般を STATUS_INTERNAL としていますが、f5a2f75 が採用した grpc-go exact は DATA END_STREAM のみ INTERNAL、initial / trailing HEADERS END_STREAM は UNKNOWN です。
compression の本文・表も「未対応 grpc-encoding header 宣言」自体を失敗条件として読めますが、実装と PHPT は header + Compressed-Flag=0 を成功させます。docs/SPEC.md:233 も同じ曖昧さがあります。checklist を terminal DATA / HEADERS と per-message Compressed-Flag で書き分け、SPEC・verification matrix・実行テストを同じ current model へ揃えてください。
[Low] docs/design/grpc-call-exchange-state.md:15 — field ownership map が新 state を欠いている
grpc_call の authoritative responsibility map は validation/status field を initial_headers_end_stream までしか列挙しておらず、今回追加した trailing_headers_seen がありません。nghttp2 callback が set し、status resolution が terminal DATA / HEADERS を区別するために読む call-local lifetime を同 map へ追加してください。
検証
- C static analysis: pass
- C unit: pass(3 suites)
- PHPT: 17/17 pass
- PHPUnit: 31 tests / 116 assertions pass
- Native QA: Static analysis / NTS PHPT + C coverage / Crash/UB / ZTS PHPT すべて pass
- 初回 ZTS 失敗は GitHub Actions cache export の 503 で、再実行は pass
Medium / Low が残るため、repository の protocol model review gate は現時点では未充足です。
… frame policyに整合 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
再レビュー3件に対応しました (375c3dd)。 [Medium]
|
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
第三パスレビュー2件に対応しました (093b808)。 [Medium] REVIEW-20260710-004: 不完全な1xx成功経路 → 推奨どおり分離指摘のとおり
1xx 対応は docs/issues/open/2026-07-10-informational-1xx-response-handling.md の別 PR スコープとし、issue には却下された初回実装の問題点(metadata ownership 反転の probe 結果、RFC 8297 §2)と、再実装要件(header callback 時点での block phase 確定、informational field 隔離、metadata ownership / field isolation の unary / streaming テスト)を Plan として記録しました。 [Low] REVIEW-20260710-003: PR説明の乖離 → 対応PR 本文を最終挙動に書き直しました: 項目1を Compressed-Flag=1 限定 + 「encoding 宣言 + flag=0 は成功」の明記、項目3を DATA END_STREAM → INTERNAL / HEADERS END_STREAM → UNKNOWN の書き分けに変更し、release note 対象の observable changes 一覧も本文に追加しました。 検証(revert 後)
🤖 Generated with Claude Code |
dkkoma
left a comment
There was a problem hiding this comment.
敵対的・第四パス再レビュー(093b808)
前回の Medium(不完全な1xx成功経路)と Low(PR説明)は修正済みです。
expect_final_response、early-hints fixture / PHPT / active docsはPR #28から除去済みtrailing_headers_seenのNGHTTP2_FLAG_END_STREAMgateは残り、DATA / HEADERS terminal taxonomyは維持- PR本文はCompressed-Flag=1限定、encoding宣言 + flag=0成功、DATA END_STREAMのみINTERNAL、HEADERS END_STREAMはUNKNOWNへ更新済み
source / fixture / testsには新規 finding はありません。残るのはLow 1件だけです。
[Low] docs/issues/open/2026-07-08-status-taxonomy-official-alignment.md:93-98 — Related issuesの現在のscope説明が古い
同fileの第三パスProgressは1xx実装をPR #28からrevertして別PR scopeへ移したと正しく記録していますが、Related issues節は2件とも「コードは分離せず、記録としてissue分割」と現在形で一括説明しています。
現在の境界は次の2種類です。
grpc-encodingflag=0修正: PR #28へ同梱したまま、記録だけ別issue- informational 1xx対応: code / fixture / PHPTも別issueの将来PRへ分離
Related issuesの導入文と各bulletをこの境界へ書き分けてください。Verificationの「1xxケース追加込み」も、必要なら一時導入commit 375c3dd のhistorical resultでありcurrent testではないと明示してください。実装・テストの追加は不要です。
検証
- C static analysis: pass
- C unit: pass(3 suites)
- PHPT: 17/17 pass
- PHPUnit: 31 tests / 116 assertions pass
- Native QA: Static analysis / NTS PHPT + C coverage / Crash/UB / ZTS PHPTすべてpass
git diff --check: pass
Lowが残るためprotocol model review gateは現時点では未充足ですが、runtime / compatibility findingはnoneです。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
第四パスレビューの [Low] に対応しました (e5b0982)。 work issue の Related issues 節を現在の分割境界に書き分けました: 🤖 Generated with Claude Code |
- PR #26/#27/#28/#29 でマージ済みの issue(goaway transparent retry / bin metadata unpadded base64 / status taxonomy / encoding flag=0 / deadline RST_STREAM)を Status: Closed にして docs/issues/closed/ へ移動 - PR #29 レビューサイクル(pass 4〜11)の記録 30 ファイルを docs/reviews/issues/ に追加 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
概要
docs/issues/open/2026-07-08-status-taxonomy-official-alignment.md の対応。エラー分類で公式実装(C-core / grpc-go)と食い違っていたケースのステータスコードを INTERNAL に揃える。
grpc-encodingheader 宣言のみでは失敗しないよう修正(レビュー指摘)。header は観測のみで、失敗判定は DATA parser が flag=1 を見た時点。gzip 宣言 + flag=0 の message は成功し wire status に従う(grpc-gocheckRecvPayload準拠)。記録: docs/issues/open/2026-07-10-grpc-encoding-flag0-no-reject.mdhttp2ErrConvTabに合わせた。handleData準拠)。HEADERS END_STREAM で終わる場合(headers-only 応答 / grpc-status を含まない trailing HEADERS)は UNKNOWN のまま(grpc-gooperateHeaders準拠)。terminal frame はinitial_headers_end_streamと END_STREAM 付き trailing HEADERS を記録するtrailing_headers_seenで区別する。実装メモ
trailing_headers_seenはNGHTTP2_FLAG_END_STREAM付き HEADERS のみ記録(nghttp2 では 1xx 後の final response HEADERS もHCAT_HEADERSで届くため)。検証
tools/test/check-c-unit.sh: 3本 pass(HTTP_1_1_REQUIRED / terminal frame 区別のアサーション追加)tools/test/check-phpt.sh: 17/17 pass(022 に compression / missing-status の unary / server streaming マトリクス追加)注意
grpc-encoding宣言 + flag=0: エラー → 成功🤖 Generated with Claude Code