Skip to content

fix(hip)!: read REG_FAILED's Failure Type and Reg Types as RFC 8003 lays them out (#2309) - #2336

Merged
JarryShaw merged 1 commit into
mainfrom
fix/2309-hip-reg-failed-model
Oct 26, 2026
Merged

JarryShaw merged 1 commit into
mainfrom
fix/2309-hip-reg-failed-model

Conversation

@JarryShaw

@JarryShaw JarryShaw commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner
  • Searched for similar pull requests
  • Followed the coding style
  • make test passes, and a test case covers the change
  • Changelog entry: 1.5.0.rst (breaking change)

What is the purpose of your pull request?

  • fix — bug fix

Description

Closes #2309, per the ruling (take the recommendation). Breaking: lifetime is renamed with no alias.

  • Fix: RFC 8003 §4.5 lays out REG_FAILED as a Failure Type octet followed by Reg Type octets, with no lifetime. pcapkit read the first octet as a lifetime timedelta and decoded the Reg Types through the RegistrationFailure registry.
    • The schema, data model and maker now carry failure_type (a RegistrationFailure) in place of lifetime.
    • reg_type and reg_failed decode through the Registration registry.
    • The wire octets are unchanged.
  • Tests: test_hip_roundtrip_unit pins the parsed types, parse→rebuild over Failure Types 0–255 with several Reg Types, and make→parse octets.
  • Fail-without-fix: on origin/main, 7 failed, e.g. '03a8000300030100' != '03a8000302030100'. On the head, 44 passed.

@JarryShaw JarryShaw added this to the PyPCAPKit v1.5 milestone Oct 26, 2026
@JarryShaw JarryShaw added breaking Breaks public-facing behaviour or API (apply alongside the type label) bug Issues reporting a defect (set by the bug report template; a default, not an assessment) fix Pull requests that fix a defect (fix: subject prefix) review: running A cross-review is in flight against the current head - no verdict yet labels Oct 26, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

Review: GOOD TO GO at c75c8f120 (Sonnet).

  • RFC 8003 §4.5, checked against the RFC text: REG_FAILED is a Failure Type octet followed by Reg Types, with no lifetime. failure_type uses RegistrationFailure, and reg_failed uses Registration, like REG_INFO, REG_REQUEST and REG_RESPONSE.
  • Byte-exact: parse→rebuild over Failure Types 0, 1, 2, 3, 9, 201 and 255, plus make→parse. No lifetime attribute or keyword remains, and no leftover reference was found repo-wide.
  • Changelog: a breaking-change bullet is in 1.5.0.rst and CHANGELOG.md. The PR body's changelog box now says so.
  • Fail-without-fix: on origin/main, 7 failed across both test files (4 from the round-trip file alone). On the head, 51 passed.

@JarryShaw JarryShaw added review: good-to-go Cross-review at the current head says ready; CI state is separate and removed review: running A cross-review is in flight against the current head - no verdict yet labels Oct 26, 2026
@JarryShaw JarryShaw moved this to In review in PyPCAPKit Oct 26, 2026
…ays them out (#2309)

RFC 8003 section 4.5 gives REG_FAILED a Failure Type octet followed by Reg
Type octets, and no lifetime. pcapkit read the first octet as a `lifetime`
timedelta and decoded the Reg Types with the RegistrationFailure registry.

Replace `lifetime` with `failure_type` (a RegistrationFailure) in the schema,
the data model and the maker, with no alias, and decode `reg_type` /
`reg_failed` with the Registration registry. The octets are unchanged.

Tests: test_hip_roundtrip_unit pins the parsed types, parse->rebuild over
Failure Types 0-255 with several Reg Types, and make->parse octets.
@JarryShaw
JarryShaw force-pushed the fix/2309-hip-reg-failed-model branch from c75c8f1 to 4ec3e1d Compare October 26, 2026 22:32
@JarryShaw

Copy link
Copy Markdown
Owner Author

Rebased c75c8f120 → 4ec3e1d17 onto main bfe184bd6. The patch-id is identical, so the GOOD TO GO verdict carries over to the new head.

The old head's Project tests failed on test_no_test_calls_unparse_outside_a_version_gate. That was not this PR. It came from main's #2306 scan test, which called ast.unparse outside a version gate; bfe184bd6 fixes it on main, and CI is re-running on the new head.

@github-actions

Copy link
Copy Markdown
Contributor

Coverage: 91.56% (unit tier, Python 3.15, 4ec3e1d17, Unit Tests run success)

Package Statements Missed Branches Partial Cover
pcapkit (top level) 104 4 20 2 95.16%
pcapkit/const 19599 881 2618 867 92.11%
pcapkit/corekit 2589 74 816 37 96.51%
pcapkit/dumpkit 282 3 102 3 98.44%
pcapkit/foundation 3023 23 1044 25 98.82%
pcapkit/interface 138 4 52 3 96.32%
pcapkit/protocols 17438 218 4586 185 98.15%
pcapkit/toolkit 869 36 298 10 95.20%
pcapkit/utilities 504 7 146 5 98.15%
pcapkit/vendor 4432 1988 1018 167 51.87%

Per-file detail: the coverage-html artifact of this run.

@JarryShaw
JarryShaw merged commit 9dd46d8 into main Oct 26, 2026
61 checks passed
@JarryShaw
JarryShaw deleted the fix/2309-hip-reg-failed-model branch October 26, 2026 23:44
@github-project-automation github-project-automation Bot moved this from In review to Done in PyPCAPKit Oct 26, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

Rebased 4ec3e1d17 → fa1dd3c83 onto main b7b02c0fa. The patch-id is identical to the old head, so the rebase applied every hunk — including the CHANGELOG.md/1.5.0.rst additions — with no textual conflict against #2312's entry.

The old head's CI was green (Required checks passed SUCCESS, 0 failures, KTLO clean, protocols ordering leg 1946 tests / 0 failures). On the new head: test_hip_roundtrip_unit.py, test_hip_unit.py, tests/test_docstring_contract.py and tests/test_tier_guard.py give 187 passed, and util/changelog_md.py --check passes.

The patch is unchanged and the old head was already green, so the owner can bypass checks and merge once the new head's CI completes.

@JarryShaw

Copy link
Copy Markdown
Owner Author

Correction to my own comment above: you had already merged this (as 9dd46d8d4) while I was rebasing it, so the "rebase" and the force-push after it landed on an orphan branch ref and changed nothing merged. Sorry for the noise — no action needed here.

@JarryShaw JarryShaw removed the review: good-to-go Cross-review at the current head says ready; CI state is separate label Oct 27, 2026
JarryShaw added a commit that referenced this pull request Oct 28, 2026
Problem: of the 60 pull requests merged in the #2312-#2407 range, only
#2334, #2336, #2337, #2340 and #2348 wrote a 1.5.0 changelog entry, and
#2398 and #2403 only reworded lines that were already there. Every other
user-visible change in the range -- wire-semantics fixes, maker guards,
reassembly behaviour, public-API and error-message changes -- went
unrecorded, so the entry no longer describes the release.

Fix: one entry per user-visible pull request, in each module section's
existing style and ordered by the issue it closes. Two pairs share a
bullet, since each is the direct follow-up of the other: #2393 with
#2401, and #2405 with #2407. The diff on the entry file is purely
additive.

Internal-only work is left out deliberately: dependency and action bumps
(#2387 to #2391), test-only and docs-prose passes (#2333, #2376, #2379,
#2380, #2402), the unreachable-branch removal (#2378), and the #: comment
marker the HIP Group and Packet crawlers now write (#2381). That last one
renders nothing either way: the marker lands inside the generated
_missing_ body, conf.py's exclude-members drops _missing_ from autodoc,
and a comment in a method body is not an attribute comment to begin with.

#2392 and #2403 are recorded together, under Added rather than Fixed, for
the declarations they introduce: __proto_key__ on the seven classes owning
a __proto__ registry (#2392), __proto_dest__ on the four enum registries
and Vendor.PROTO_DEST to generate it (#2403). Both PRs added the autodoc
entries, so both are rendered public attributes. #2392's rejection-message
change is deliberately not recorded as a fix: the bare "code must be ..."
text it prefixed came from _check_code, which #2193 introduced and which
is in no release tag -- absent at v1.5.0b14 -- so no released version ever
emitted it. #2403 is no longer skipped as internal because it reworded an
existing bullet to name __proto_dest__ while nothing credited the
attribute's introduction.

Four claims are corrected against the source rather than carried over:
FTP_DATA shipped in pcapkit/protocols/application/ftp.py from 1.0.0, not
1.4.0 (class FTP_DATA(Raw) is there at v1.0.0); #2365's pre-fix fallback
read cmmd.value, so a .value-carrying object was accepted unchecked
rather than raising; #2399 left the dpkt adapter and the adapters'
ModuleNotFound raises alone, so it claims no universal prefix; and
#2397's old tail did name the version it got, so the entry quotes it and
gains the :issue:`2302` it was missing. #2370's "a Section Header Block
... still fails" sentence is dropped: #2369 settles the byte order first,
and an SHB built from raw octets with ctx=None now rebuilds byte-exact in
both byte orders.

CHANGELOG.md is regenerated with util/changelog_md.py.

Test: tests/project/ in full, 0 failures, including test_changelog_md.py's
in-step and supported-subset checks; util/changelog_md.py --check reports
the two files in step; the entry parses under docutils with no structural
warning.
JarryShaw added a commit that referenced this pull request Oct 28, 2026
Problem: of the 60 pull requests merged in the #2312-#2407 range, only
#2334, #2336, #2337, #2340 and #2348 wrote a 1.5.0 changelog entry, and
#2398 and #2403 only reworded lines that were already there. Every other
user-visible change in the range -- wire-semantics fixes, maker guards,
reassembly behaviour, public-API and error-message changes -- went
unrecorded, so the entry no longer describes the release.

Fix: one entry per user-visible pull request, in each module section's
existing style and ordered by the issue it closes. Three pairs share a
bullet, since each is the direct follow-up or counterpart of the other:
#2393 with #2401, #2405 with #2407, and #2392 with #2403. The diff on the
entry file is purely additive.

Internal-only work is left out deliberately: dependency and action bumps
(#2387 to #2391), test-only and docs-prose passes (#2333, #2376, #2379,
#2380, #2402), the unreachable-branch removal (#2378), and the #: comment
marker the HIP Group and Packet crawlers now write (#2381). That last one
renders nothing either way: the marker lands inside the generated
_missing_ body, conf.py's exclude-members drops _missing_ from autodoc,
and a comment in a method body is not an attribute comment to begin with.

#2392 and #2403 are recorded together, under Added rather than Fixed, for
the declarations they introduce: __proto_key__ on each class owning a
__proto__ registry (#2392), __proto_dest__ on the enum registries and
Vendor.PROTO_DEST to generate it (#2403). The bullet names those classes
and registries rather than counting them, per the no-counted-numbers rule
for the unreleased entry. Both PRs added the autodoc entries, so both are
rendered public attributes. #2392's rejection-message
change is deliberately not recorded as a fix: the bare "code must be ..."
text it prefixed came from _check_code, which #2193 introduced and which
is in no release tag -- absent at v1.5.0b14 -- so no released version ever
emitted it. #2403 is no longer skipped as internal because it reworded an
existing bullet to name __proto_dest__ while nothing credited the
attribute's introduction.

Four claims are corrected against the source rather than carried over:
FTP_DATA shipped in pcapkit/protocols/application/ftp.py from 1.0.0, not
1.4.0 (class FTP_DATA(Raw) is there at v1.0.0); #2365's pre-fix fallback
read cmmd.value, so a .value-carrying object was accepted unchecked
rather than raising; #2399 left the dpkt adapter and the adapters'
ModuleNotFound raises alone, so it claims no universal prefix; and
#2397's old tail did name the version it got, so the entry quotes it and
gains the :issue:`2302` it was missing. #2370's "a Section Header Block
... still fails" sentence is dropped: #2369 settles the byte order first,
and an SHB built from raw octets with ctx=None now rebuilds byte-exact in
both byte orders.

CHANGELOG.md is regenerated with util/changelog_md.py.

Test: tests/project/ in full, 0 failures, including test_changelog_md.py's
in-step and supported-subset checks; util/changelog_md.py --check reports
the two files in step; the entry parses under docutils with no structural
warning.
JarryShaw added a commit that referenced this pull request Oct 28, 2026
Problem: of the 60 pull requests merged in the #2312-#2407 range, only
#2334, #2336, #2337, #2340 and #2348 wrote a 1.5.0 changelog entry, and
#2398 and #2403 only reworded lines that were already there. Every other
user-visible change in the range -- wire-semantics fixes, maker guards,
reassembly behaviour, public-API and error-message changes -- went
unrecorded, so the entry no longer describes the release.

Fix: one entry per user-visible pull request, in each module section's
existing style and ordered by the issue it closes. Three pairs share a
bullet, since each is the direct follow-up or counterpart of the other:
#2393 with #2401, #2405 with #2407, and #2392 with #2403. The diff on the
entry file is purely additive.

Internal-only work is left out deliberately: dependency and action bumps
(#2387 to #2391), test-only and docs-prose passes (#2333, #2376, #2379,
#2380, #2402), the unreachable-branch removal (#2378), and the #: comment
marker the HIP Group and Packet crawlers now write (#2381). That last one
renders nothing either way: the marker lands inside the generated
_missing_ body, conf.py's exclude-members drops _missing_ from autodoc,
and a comment in a method body is not an attribute comment to begin with.

#2392 and #2403 are recorded together, under Added rather than Fixed, for
the declarations they introduce: __proto_key__ on each class owning a
__proto__ registry (#2392), __proto_dest__ on the enum registries and
Vendor.PROTO_DEST to generate it (#2403). The bullet names those classes
and registries rather than counting them, per the no-counted-numbers rule
for the unreleased entry. Both PRs added the autodoc entries, so both are
rendered public attributes. #2392's rejection-message
change is deliberately not recorded as a fix: the bare "code must be ..."
text it prefixed came from _check_code, which #2193 introduced and which
is in no release tag -- absent at v1.5.0b14 -- so no released version ever
emitted it. #2403 is no longer skipped as internal because it reworded an
existing bullet to name __proto_dest__ while nothing credited the
attribute's introduction.

Four claims are corrected against the source rather than carried over:
FTP_DATA shipped in pcapkit/protocols/application/ftp.py from 1.0.0, not
1.4.0 (class FTP_DATA(Raw) is there at v1.0.0); #2365's pre-fix fallback
read cmmd.value, so a .value-carrying object was accepted unchecked
rather than raising; #2399 left the dpkt adapter and the adapters'
ModuleNotFound raises alone, so it claims no universal prefix; and
#2397's old tail did name the version it got, so the entry quotes it and
gains the :issue:`2302` it was missing. #2370's "a Section Header Block
... still fails" sentence is dropped: #2369 settles the byte order first,
and an SHB built from raw octets with ctx=None now rebuilds byte-exact in
both byte orders.

CHANGELOG.md is regenerated with util/changelog_md.py.

Test: tests/project/ in full, 0 failures, including test_changelog_md.py's
in-step and supported-subset checks; util/changelog_md.py --check reports
the two files in step; the entry parses under docutils with no structural
warning.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Breaks public-facing behaviour or API (apply alongside the type label) bug Issues reporting a defect (set by the bug report template; a default, not an assessment) fix Pull requests that fix a defect (fix: subject prefix)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

fix(hip): REG_FAILED reads Failure Type as a lifetime and its Reg Types as failure types

1 participant