Partial

RFC 7854 - BGP Monitoring Protocol (BMP)

Every requirement this repository extracted from RFC 7854, the tests bound to it, and what a reader has verified about them. This summary is enrolled and gated by ./le rfc check.

Overview

Positive

what Ze has

Tested both ways79.5%31 of 39 gated MUSTs

a positive test proves Ze does what the requirement demands and a negative one proves it refuses what the requirement forbids

One polarity plus reason20.5%8 of 39 gated MUSTs

the requirement admits no counter-case, so one polarity plus a recorded reason is the whole proof available for it

One polarity, unexcused0.0%0 of 39 gated MUSTs

one direction is tested, the other is neither tested nor excused, and nothing states which

Partial proof; remaining gap0.0%0 of 39 gated MUSTs

scoped tests exist; the remaining obligation is unmet or unproven, with zero whole-requirement credit

No test at all0.0%0 of 39 gated MUSTs

no test carries the requirement id, whether or not a gap states why

Proven by a recorded break53.5%53 of 99 tagged units

a red was observed once under a recorded procedure, and the unit, the claim and the producer it rested on still hash to what was recorded. The break is not re-run. A test pair is not a proof until one has been observed

Audit verdicts43of 39 gated MUSTs judged

0 weak, wrong or unimplemented, 0 no longer current. Each is named below under its own requirement id

Neutral

measures that are neither good news nor bad

Gated MUSTs39of 48 this summary declares

MUST-level requirements the gate HOLDS. A population, not a result: the shares beside it are what says how Ze stands

Out of scope0of 39 gated MUSTs

an obligation that does not bind Ze. A {not-applicable} annotation says it never bound; a {feature-declined} annotation says its condition is an optional feature Ze does not offer, and quotes the RFC sentence that makes it optional. Scope, not coverage: it stays in the denominator every share on this page is taken over

Not applicable0.0%0 of 39 gated MUSTs

a {not-applicable} annotation says the obligation does not bind Ze, so no test is owed for it. It stays in the denominator every share here is taken over

Met below Ze0.0%0 of 39 gated MUSTs

a {lower-layer} annotation says a layer under Ze performs the behavior, on state Ze installs into that layer, and names the producer that installs it. The obligation binds Ze and is met; Ze proves none of it, because its own boundary carries no value the behavior reads

Optional feature declined0.0%0 of 39 gated MUSTs

a {feature-declined} annotation says the obligation is conditional on a feature the RFC makes optional and Ze does not offer, and it quotes the sentence that makes it optional. The condition is false, so nothing is owed and nothing is missing. It stays in the denominator every share here is taken over

The 8 shares marked as a part above are the whole of the 39 gated MUSTs: they add to 100%. Proven by a recorded break is a share of TAGGED UNITS, a different population, so it is not one of them.

How to read the colors

A color names what the measure MEANS, not how well Ze scores on it. Green is a good outcome at any value, red is a bad one, and neither a population nor a scope count is an outcome, so both take no color. The number under the label is what says how far Ze has got.

CardTone hereWhy that color
Gated MUSTs neutral no color: a population is a scale, and a larger one is neither good news nor bad. It is the accounting total
Out of scope neutral no color: an obligation that never bound Ze is neither an achievement nor a failure, and counting it either way would be a claim
Tested both ways ok green at every value: a test pair is the outcome this gate exists to produce, and the share under the label is what says how far Ze has got
One polarity plus reason ok green at every value: where no counter-case exists, one polarity IS the complete answer, and a recorded reason is what the gate demands beside it
One polarity, unexcused ok green at zero, RED above it: half a proof with no reason for the other half
Partial proof; remaining gap ok green at zero, RED above it: a tested clause cannot prove the whole requirement
No test at all ok green at zero, RED above it: a binding obligation nothing exercises is a claim with nothing behind it, whether or not a reason is stated
Not applicable neutral no color: an obligation that never bound Ze is neither an achievement nor a failure, and counting it either way would be a claim
Met below Ze neutral no color: an obligation met below Ze is neither a test Ze wrote nor work Ze owes, and the two green shares above are what says how much Ze proves itself
Optional feature declined neutral no color: an obligation whose condition Ze never meets is neither an achievement nor a failure. The absent FEATURE is disclosed on the RFC's own status row, as an implementation gap a later scope decision can revisit
Proven by a recorded break ok green at every value: an observed break is the outcome the discrimination gate exists to produce. The denominator is TAGGED UNITS, not obligations, so this share is not one of the parts above
Audit verdicts ok RED on the first weak, wrong or unimplemented verdict, amber while a verdict is no longer current or a gated MUST is unjudged, green when every one is judged sound and current

At a glance

FieldValue
Public status Partial
Enrolment Enrolled
Requirements 48
Gated MUST-level 39
Not applicable, so out of scope 0
Declared gaps 0
Declared gaps a test demonstrates 0
Gated with no test 0
Nightly-only evidence 0
Test tags 99
Tagged units 99
Recorded audit verdicts 43
Discrimination records 53
Summary rfc/short/rfc7854.md
Requirement shard rfc/requirements/rfc7854.md
RFC text rfc/full/rfc7854.txt

Enrolment

Enrolled: Ze implements the BMP sender and receiver under internal/component/bgp/plugins/bmp. Wire-message and session carriers cover the common and per-peer headers, OPEN exchange, current per-peer replay and completion, identity, ordered information, termination and statistics. Requirement coverage and discrimination remain subject to the current gate result.

What the public ledger says

Status: Partial

What the ledger says is covered
  • BMP receiver and sender, peer lifecycle, current per-NLRI replay with per-family End-of-RIB, received and sent route monitoring, CLI and configuration. Initiation carries the administrative system identity
  • receiver information strings retain order and duplicates. Sender shutdown carries Reason 0 and closes
  • bounded transmit queues reset stalled sessions.
What the ledger says remains Focused execution, producer discrimination and third-party pmacct acceptance of the current changes remain unrun. Loc-RIB monitoring is defined under RFC 9069 and Adj-RIB-Out under RFC 8671. Post-policy Adj-RIB-In monitoring, the optional view with the L flag set on received routes, is not offered: the route-monitoring-policy post-policy choice streams the Adj-RIB-Out.

Coverage

BucketCountWhat it counts
Positive and negative tests 31 one part of the gated population
Annotated (including scoped evidence) 8 one part of the gated population
One polarity only 0 one part of the gated population
No test and no annotation 0 one part of the gated population
Partial proof; remaining gap (subset of annotated; zero whole-requirement credit) 0 an overlay: each of these is also counted by the part it falls in
Evidence that runs nightly only 0 an overlay: each of these is also counted by the part it falls in
Derived from other rows 0 outside the gated population: each asserts nothing and derives its state from the rows it names, which the parts above already count
Gated MUST-level requirements39every gated MUST falls in exactly one bucket above

Positive and negative tests (31): RFC7854-x-1, RFC7854-x-2, RFC7854-x-3, RFC7854-x-5, RFC7854-x-8, RFC7854-4.9-1, RFC7854-4.5-2, RFC7854-x-18, RFC7854-3.2-1, RFC7854-3.2-2, RFC7854-3.3-1, RFC7854-4.1-1, RFC7854-4.2-1, RFC7854-4.3-2, RFC7854-4.4-1, RFC7854-4.4-2, RFC7854-4.4-3, RFC7854-4.5-1, RFC7854-4.5-3, RFC7854-4.5-4, RFC7854-4.7-1, RFC7854-4.7-2, RFC7854-4.7-3, RFC7854-4.8-1, RFC7854-4.8-2, RFC7854-4.8-3, RFC7854-4.10-1, RFC7854-5-1, RFC7854-5-2, RFC7854-5-4, RFC7854-8.2-1

Annotated (including scoped evidence) (8): RFC7854-x-4, RFC7854-x-6, RFC7854-x-7, RFC7854-x-9, RFC7854-x-10, RFC7854-x-12, RFC7854-4.5-5, RFC7854-5-6

Requirements

RequirementLevelSectionTests
RFC7854-x-1This is set to '3' for all messages defined in this specification. (§4.1, Common Header)
MUST 4.1
RFC7854-x-2Version (1 byte): Indicates the BMP version. This is set to '3' for all messages defined in this specification. ('1' and '2' were used by draft versions of this document.) Version 0 is reserved and MUST NOT be sent. o Message Length (4 bytes): Length of the message in bytes (including headers, data, and encapsulated messages, if any). o Message Type (1 byte): This identifies the type of the BMP message. (§4.1, Common Header)
MUST 4.1
RFC7854-x-3The per-peer header follows the common header for most BMP messages. (§4.2, Per-Peer Header)
MUST 4.2
RFC7854-x-4If a 16-bit AS number is stored in this field [RFC6793], it should be padded with zeroes in the 16 most significant bits. (§4.2, Per-Peer Header)
MUST 4.2
positiveunit/verifyTestBMPPeerHeaderDecode
positiveunit/verifyTestBMPPeerHeaderEncode
negativeno testno negative test

{single-polarity}: the Peer AS is unconditionally a 4-octet field on every encode and decode, so there is no shorter-AS variant to reject and no negative case to construct

RFC7854-x-5It is 4 bytes long if an IPv4 address is carried in this field (with the 12 most significant bytes zero-filled) and 16 bytes long if an IPv6 address is carried in this field. (§4.2, Per-Peer Header)
MUST 4.2
positiveunit/verifyTestParseIPIntoIPv4
negativeunit/verifyTestParseIPIntoIPv6
RFC7854-x-6An initiation message MUST be sent as the first message after the TCP session comes up. (§4.3, Initiation Message)
MUST 4.3
positiveunit/verifyTestBMPSenderConnects
negativeno testno negative test

{single-polarity}: the sender always emits Initiation as the first message on a fresh connection, so there is no valid session in which another message precedes it to reject

RFC7854-x-7The sysDescr and sysName Information TLVs MUST be sent, any others are optional. (§4.3, Initiation Message)
MUST 4.3
positiveunit/verifyTestBMPSenderInitiation
negativeno testno negative test

{single-polarity}: the Initiation the sender builds always includes the sysName TLV, so there is no valid Initiation omitting it to assert against

RFC7854-x-8Sent OPEN Message: The full OPEN message transmitted by the monitored router to its peer. o Received OPEN Message: The full OPEN message received by the monitored router from its peer. (§4.10, Peer Up Notification)
MUST 4.10
positiveunit/verifyTestBMPSenderPeerUp
positiveunit/verifyTestHandleSenderStatePeerUp
RFC7854-x-9Following the common BMP header and per-peer header is a BGP Update PDU. (§4.6, Route Monitoring)
MUST 4.6
positiveunit/verifyTestBMPSenderRouteMonitoring
negativeno testno negative test

{single-polarity}: Route Monitoring is only ever constructed around a complete BGP UPDATE PDU, so there is no valid Route Monitoring lacking one to reject

RFC7854-x-10Reason indicates why the session was closed. (§4.9, Peer Down Notification)
MUST 4.9
positiveunit/verifyTestBMPSenderPeerDown
negativeno testno negative test

{single-polarity}: Peer Down is always written with a reason byte, so there is no valid Peer Down without one to assert against

RFC7854-x-11The router MAY send a Termination message prior to closing the session. (§3.3, Lifecycle of a BMP Session)
MAY 3.3
positiveunit/verifyTestBMPSenderTermination
negativeno testno negative test

{single-polarity}: Termination is produced unconditionally when the session is torn down, so there is no valid shutdown that omits it to reject

RFC7854-x-12No BMP message is ever sent from the monitoring station to the monitored router. (§3.2, Connection Establishment and Termination)
MUST 3.2
negativeno testno negative test

{single-polarity}: the receiver loop (internal/component/bgp/plugins/bmp/bmp.go:441-492) issues only reads and the sender hold-loop (sender.go:207-237) reads only to detect close, so neither role writes toward the monitored router on a valid session and there is no reject case to construct

RFC7854-4.9-1Reason 1: The local system closed the session. Following the Reason is a BGP PDU containing a BGP NOTIFICATION message that would have been sent to the peer. o Reason 2: The local system closed the session. No notification message was sent. Following the reason code is a 2-byte field containing the code corresponding to the Finite State Machine (FSM) Event that caused the system to close the session (see Section 8.1 of [RFC4271]). Two bytes both set to 0 are used to indicate that no relevant Event code is defined. o Reason 3: The remote system closed the session with a notification message. Following the Reason is a BGP PDU containing the BGP NOTIFICATION message as received from the peer. (§4.9, Peer Down Notification)
MUST 4.9
RFC7854-4.5-2Likewise, the monitoring station MUST close the TCP session after receiving a termination message. (§4.5, Termination Message)
MUST 4.5
RFC7854-x-13Exponential backoff with a default initial backoff of 30 seconds and a maximum of 720 seconds is suggested. (§3.2, Connection Establishment and Termination)
SHOULD 3.2
positiveno testno positive test
negativeno testno negative test
RFC7854-x-14Exponential backoff with a default initial backoff of 30 seconds and a maximum of 720 seconds is suggested. (§3.2, Connection Establishment and Termination)
SHOULD 3.2
positiveno testno positive test
negativeno testno negative test
RFC7854-x-15It MAY periodically send Stats Reports or even new Initiation messages, according to configuration. (§3.3, Lifecycle of a BMP Session)
MAY 3.3
RFC7854-x-16It subsequently sends a Peer Up message over the BMP session for each of its monitored BGP peers that is in the Established state. (§3.3, Lifecycle of a BMP Session)
SHOULD 3.3
RFC7854-x-17It subsequently sends a Peer Up message over the BMP session for each of its monitored BGP peers that is in the Established state. It follows by sending the contents of its Adj- RIBs-In (pre-policy, post-policy, or both, see Section 5) encapsulated in Route Monitoring messages. (§3.3, Lifecycle of a BMP Session)
SHOULD 3.3
RFC7854-x-18The sysDescr and sysName Information TLVs MUST be sent, any others are optional. (§4.3, Initiation Message)
MUST 4.3
RFC7854-x-19Information: Information about the peer, using the Information TLV (Section 4.4) format. Only the string type is defined in this context; it may be repeated. Inclusion of the Information field is OPTIONAL. (§4.10, Peer Up Notification)
MAY 4.10
positiveno testno positive test
negativeno testno negative test
RFC7854-x-20Route Mirroring messages are used for verbatim duplication of messages as received. A possible use for mirroring is exact mirroring of one or more monitored BGP sessions, without state compression. (§4.7, Route Mirroring)
MAY 4.7
positiveno testno positive test
negativeno testno negative test
RFC7854-3.2-1Retries MUST be subject to some variety of backoff. (§3.2, Connection Establishment and Termination)
MUST 3.2
RFC7854-3.2-2The router MUST also restrict the rate at which sessions may be established. (§3.2, Connection Establishment and Termination)
MUST 3.2
RFC7854-3.3-1Once it has sent all the routes for a given peer, it MUST send an End-of-RIB message for that peer (§3.3, Lifecycle of a BMP Session, and restated in the Route Monitoring section)
MUST 3.3
RFC7854-4.1-1A BMP implementation MUST ignore unrecognized message types upon receipt. (§4.1, Common Header)
MUST 4.1
RFC7854-4.2-1The remaining bits are reserved for future use. They MUST be transmitted as 0 and their values MUST be ignored on receipt. (§4.2, Per-Peer Header)
MUST 4.2
RFC7854-4.3-1The string TLV MAY be included multiple times. (§4.3, Initiation Message)
MAY 4.3
positiveno testno positive test
negativeno testno negative test
RFC7854-4.3-2The initiation message consists of the common BMP header followed by two or more Information TLVs (Section 4.4) containing information about the monitored router. (§4.3, Initiation Message)
MUST 4.3
RFC7854-4.4-1If multiple strings are included, their ordering MUST be preserved when they are reported. (§4.4, Information TLV)
MUST 4.4
RFC7854-4.4-2Type = 1: sysDescr. The Information field contains an ASCII string whose value MUST be set to be equal to the value of the sysDescr MIB-II [RFC1213] object. (§4.4, Information TLV)
MUST 4.4
RFC7854-4.4-3Type = 2: sysName. The Information field contains an ASCII string whose value MUST be set to be equal to the value of the sysName MIB-II [RFC1213] object. (§4.4, Information TLV)
MUST 4.4
RFC7854-4.5-1Once the router has sent a termination message, it MUST close the TCP session without sending any further messages. (§4.5, Termination Message)
MUST 4.5
RFC7854-4.5-3Type = 1: Reason. The Information field contains a 2-byte code indicating the reason that the connection was terminated. Some reasons may have further TLVs associated with them. Inclusion of this TLV is REQUIRED. (§4.5, Termination Message)
MUST 4.5
RFC7854-4.5-4The termination message consists of the common BMP header followed by one or more TLVs containing information about the reason for the termination (§4.5, Termination Message)
MUST 4.5
RFC7854-4.5-5Although use of this message is RECOMMENDED, a monitoring station must always be prepared for the session to terminate with no message. (§4.5, Termination Message)
MUST 4.5
negativeno testno negative test

{single-polarity}: a router that closes with no Termination message sends no non-compliant input, because the sentence permits exactly that close, so the station has nothing to refuse. TestBMPReceiverEndsTheSessionWhenTheRouterLeavesWithoutTermination proves the station clause and TestSenderStopSendsTerminationToCollector proves the RECOMMENDED clause on the router side

RFC7854-4.7-1If the BGP Message TLV occurs in the Route Mirroring message, it MUST occur last in the list of TLVs. (§4.7, Route Mirroring)
MUST 4.7
RFC7854-4.7-2Code = 0: Errored PDU. The contained message was found to have some error that made it unusable, causing it to be treated-as- withdraw [RFC7606]. A BGP Message TLV MUST also occur in the TLV list. (§4.7, Route Mirroring)
MUST 4.7
RFC7854-4.7-3Following the common BMP header and per-peer header is a set of TLVs that contain information about a message or set of messages. (§4.7, Route Mirroring)
MUST 4.7
RFC7854-4.8-1A BMP implementation MUST ignore unrecognized stat types on receipt, and likewise MUST ignore unexpected data in the Stat Data field. (§4.8, Stats Reports)
MUST 4.8
RFC7854-4.8-2However, if an SR message is transmitted, at least one statistic MUST be carried in it. (§4.8, Stats Reports)
MUST 4.8
RFC7854-4.8-3Following the common BMP header and per-peer header is a 4-byte field that indicates the number of counters in the stats message where each counter is encoded as a TLV. (§4.8, Stats Reports)
MUST 4.8
RFC7854-4.10-1Following the common BMP header and per-peer header is the following (§4.10, Peer Up Notification)
MUST 4.10
RFC7854-5-1Pre-policy routes MUST have their L flag clear in the BMP header (see Section 4), post-policy routes MUST have their L flag set. (§5, Route Monitoring)
MUST 5
RFC7854-5-2If the implementation is able to provide information about when routes were received, it MAY provide such information in the BMP Timestamp field. Otherwise, the BMP Timestamp field MUST be set to 0, indicating that time is not available. (§5, Route Monitoring)
MUST 5
RFC7854-5-4The withdraw MUST have its L flag set to correspond to that of any previous announcement (§5, Route Monitoring)
MUST 5
RFC7854-5-6When a change occurs to a route, such as an attribute change, the router must update the monitoring station with the new attribute. (§5, Route Monitoring)
MUST 5
negativeno testno negative test

{single-polarity}: every received UPDATE that changes a route is compliant input to the router, so the sender holds no refusal path. TestRFC7854ChangedAttributesCanReturnToEarlierValue asserts one Route Monitoring message for each ORIGIN change, including the return to an earlier value

RFC7854-8.2-1Since in this case no transport session actually exists, the Local and Remote Port fields of the Peer Up message MUST be set to 0. (§8.2, Peer Up Notification)
MUST 8.2

Gaps and untested MUSTs

RFC 7854 declares no gap, and every gated MUST it carries has a test bound to it.

Proof state

A tagged unit reads unproven where no discrimination record exists for it: nothing in this tree has been observed to break it, so the claim its tag makes is unproven.

RFC7854-x-1

This is set to '3' for all messages defined in this specification. (§4.1, Common Header)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-29. rfc7854_wire_header_test.go::TestRFC7854EveryTransmittedMessageCarriesVersion3AndItsTotalLength builds all seven types through the writers the sender calls (writeRouteMonitoring, writeStatisticsReport, writePeerDown, writePeerUp, writeInitiation, writeTermination, writeRouteMirroring) into a 0xA5-patterned buffer and requires octet 0 == 3 on each, so a writer that emits another version or leaves the octet unset goes red. The sentence binds the sender and no input can make it send another version; the negatives (header_test decode table #2, session_test TestBMPMalformedHeaderDrops) are the receiver refusing a version-2 header, the same rule read at the other end. The old decode-table positive stays tagged and proves only decode.

PolarityTestKind and tierProof state
negative TestBMPCommonHeaderDecode unit/verify unproven
negative TestBMPMalformedHeaderDrops unit/verify unproven
positive TestBMPCommonHeaderDecode unit/verify unproven
positive TestRFC7854EveryTransmittedMessageCarriesVersion3AndItsTotalLength unit/verify revert, verified

RFC7854-x-2

Version (1 byte): Indicates the BMP version. This is set to '3' for all messages defined in this specification. ('1' and '2' were used by draft versions of this document.) Version 0 is reserved and MUST NOT be sent. o Message Length (4 bytes): Length of the message in bytes (including headers, data, and encapsulated messages, if any). o Message Type (1 byte): This identifies the type of the BMP message. (§4.1, Common Header)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-29. TestRFC7854EveryTransmittedMessageCarriesVersion3AndItsTotalLength reads the transmitted octets of all seven types: octet 0 == 3 (so never the reserved 0), octets 1-4 == the whole message computed independently from the case's own inputs (common header + per-peer header where present + data) and equal to the octets the writer produced, and octet 5 == the type. Each clause of the quoted definition is asserted on a sent message. The tagged negative (header_test, a 3-octet buffer refused) is thin, but the clauses are sender field definitions with no input to refuse; the positive discriminates every one.

PolarityTestKind and tierProof state
negative TestBMPCommonHeaderDecode unit/verify unproven
positive TestBMPCommonHeaderEncode unit/verify unproven
positive TestRFC7854EveryTransmittedMessageCarriesVersion3AndItsTotalLength unit/verify revert, verified

RFC7854-x-3

The per-peer header follows the common header for most BMP messages. (§4.2, Per-Peer Header)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-29. rfc7854_wire_header_test.go::TestRFC7854PerPeerHeaderFollowsTheCommonHeader writes all seven types and decodes a per-peer header at octet 6 of Route Monitoring, Statistics Report, Peer Down, Peer Up and Route Mirroring, requiring it to equal the header the writer was given (4-octet AS 4200000001); for Initiation and Termination it requires the first TLV (type 1, length 2) at octet 6 and a message too short to hold a per-peer header, which is the 'most' of the sentence. The older TestHasPeerHeader tags stay: hasPeerHeader has no non-test caller, so those two tags prove a helper table only.

PolarityTestKind and tierProof state
negative TestHasPeerHeader unit/verify unproven
negative TestRFC7854PerPeerHeaderFollowsTheCommonHeader unit/verify revert, verified
positive TestHasPeerHeader unit/verify unproven
positive TestRFC7854PerPeerHeaderFollowsTheCommonHeader unit/verify revert, verified

RFC7854-x-4

If a 16-bit AS number is stored in this field [RFC6793], it should be padded with zeroes in the 16 most significant bits. (§4.2, Per-Peer Header)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-29. rfc7854_wire_header_test.go::TestRFC7854PeerASIsFourOctetsWithTheShortASZeroPadded writes a Peer Down (writePeerHeader) into a patterned buffer and reads per-peer octets 26-29 raw: 65001 must be 00 00 FD E9 (the 16 most significant bits zero) and 4200000001 must be FA 56 EA 01, so a 2-octet field, a lost padding or a misplaced AS goes red. {single-polarity: positive} holds: the field is a fixed 4-octet encode with no shorter variant to refuse.

PolarityTestKind and tierProof state
positive TestBMPPeerHeaderDecode unit/verify unproven
positive TestBMPPeerHeaderEncode unit/verify unproven
positive TestRFC7854PeerASIsFourOctetsWithTheShortASZeroPadded unit/verify revert, verified

RFC7854-x-5

It is 4 bytes long if an IPv4 address is carried in this field (with the 12 most significant bytes zero-filled) and 16 bytes long if an IPv6 address is carried in this field. (§4.2, Per-Peer Header)

Audit verdict: enforced (the tests do what the requirement demands), fresh. IPv4 lands in octets 12..15 with 0..11 zero; the IPv6 negative keeps its full address

PolarityTestKind and tierProof state
negative TestParseIPIntoIPv6 unit/verify unproven
positive TestParseIPIntoIPv4 unit/verify unproven

RFC7854-x-6

An initiation message MUST be sent as the first message after the TCP session comes up. (§4.3, Initiation Message)

Audit verdict: enforced (the tests do what the requirement demands), fresh. collector reads the first message off a live TCP connection and asserts type Initiation; single-polarity marker

PolarityTestKind and tierProof state
positive TestBMPSenderConnects unit/verify unproven

RFC7854-x-7

The sysDescr and sysName Information TLVs MUST be sent, any others are optional. (§4.3, Initiation Message)

Audit verdict: enforced (the tests do what the requirement demands), fresh. live Initiation carries sysName equal to the system identity and a sysDescr; single-polarity marker

PolarityTestKind and tierProof state
positive TestBMPSenderInitiation unit/verify unproven

RFC7854-x-8

Sent OPEN Message: The full OPEN message transmitted by the monitored router to its peer. o Received OPEN Message: The full OPEN message received by the monitored router from its peer. (§4.10, Peer Up Notification)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-13 after the RFC 7854 Section 3.3 guard (no Peer Down for a peer never reported up). Positives unchanged: TestHandleSenderStatePeerUp and TestBMPSenderPeerUp echo both cached OPENs byte for byte. Negative TestPeerUpOnCacheMissNeverReachesTheCollector: up event with no OPEN cached, down event, then a Route Monitoring sentinel on the same FIFO queue; the first message read must be the sentinel, and a Peer Up is a named failure. Owner-approved marker change (sentinel replaces the Peer Down, which Section 3.3 no longer owes). Reviewer observed red with the guard removed (first message became the Peer Down), so the test still sees the whole queue head; a Peer Up emitted without both OPENs would be read first and fail.

PolarityTestKind and tierProof state
negative TestPeerUpOnCacheMissNeverReachesTheCollector unit/verify unproven
positive TestHandleSenderStatePeerUp unit/verify unproven
positive TestBMPSenderPeerUp unit/verify unproven

RFC7854-x-9

Following the common BMP header and per-peer header is a BGP Update PDU. (§4.6, Route Monitoring)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Route Monitoring wraps the body in a full RFC 4271 header of type UPDATE; single-polarity marker

PolarityTestKind and tierProof state
positive TestBMPSenderRouteMonitoring unit/verify unproven

RFC7854-x-10

Reason indicates why the session was closed. (§4.9, Peer Down Notification)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-18 (independent auditor, after 4ef90497c6). Section 4.9: "Reason indicates why the session was closed." The earlier finding (no unit tied a Reason to the cause, and peerDownFor never emitted reason 4) is fixed and now proven at both decision points. Reactor: TestPeerCloseNamesTheTransportLoss drops TCP under a running Peer and asserts rpc.ReasonTCPFailure with Event 18; TestPeerCloseNamesTheCongestionTeardownLocal drives congestionTeardownPeer and asserts rpc.ReasonLocalClose with Event 18, so ze closing the transport itself is not reported as the remote doing it. BMP: TestRFC7854PeerDownTransportLossIsReason4 asserts Reason 4 ("This includes any unexpected termination of the transport session") with no Data for rpc.ReasonTCPFailure. TestHandleSenderStatePeerDown (reason 2 for a NOTIFICATION close with no cached PDU) and TestBMPSenderPeerDown (round-trips a chosen byte) remain weak on their own. Seam not covered by a tagged unit: apiStateObserver.OnPeerClosed and server/events.go copying the reason and CloseFSMEvent into the StructuredEvent. Single-polarity annotation holds: every Peer Down is written with a reason byte.

PolarityTestKind and tierProof state
positive TestHandleSenderStatePeerDown unit/verify unproven
positive TestRFC7854PeerDownTransportLossIsReason4 unit/verify revert, verified
positive TestBMPSenderPeerDown unit/verify unproven
positive TestPeerCloseNamesTheCongestionTeardownLocal unit/verify revert, verified
positive TestPeerCloseNamesTheTransportLoss unit/verify revert, verified

RFC7854-x-11

The router MAY send a Termination message prior to closing the session. (§3.3, Lifecycle of a BMP Session)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-29: the stale unit TestSenderStopSendsTerminationToCollector changed only by an added RFC7854-4.5-5 tag comment; body unchanged. It still requires the collector to read a Termination through stop() racing holdConnection, and the writeTerminationLocked break recorded under RFC7854-4.5-5 on this same unit was observed red. sender_test.go::TestBMPSenderTermination covers the encoder, no record. {single-polarity: positive} holds for a MAY that ze always exercises.

PolarityTestKind and tierProof state
positive TestSenderStopSendsTerminationToCollector unit/verify unproven
positive TestBMPSenderTermination unit/verify unproven

RFC7854-x-12

No BMP message is ever sent from the monitoring station to the monitored router. (§3.2, Connection Establishment and Termination)

Audit verdict: enforced (the tests do what the requirement demands), fresh. receiver loop driven with Initiation and Termination writes zero bytes toward the router end; single-polarity marker

PolarityTestKind and tierProof state
positive TestBMPReceiverUnidirectional unit/verify unproven

RFC7854-4.9-1

Reason 1: The local system closed the session. Following the Reason is a BGP PDU containing a BGP NOTIFICATION message that would have been sent to the peer. o Reason 2: The local system closed the session. No notification message was sent. Following the reason code is a 2-byte field containing the code corresponding to the Finite State Machine (FSM) Event that caused the system to close the session (see Section 8.1 of [RFC4271]). Two bytes both set to 0 are used to indicate that no relevant Event code is defined. o Reason 3: The remote system closed the session with a notification message. Following the Reason is a BGP PDU containing the BGP NOTIFICATION message as received from the peer. (§4.9, Peer Down Notification)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-18 (independent auditor, after ecba2d9147). Section 4.9: "Reason 2: The local system closed the session. No notification message was sent. Following the reason code is a 2-byte field containing the code corresponding to the Finite State Machine (FSM) Event that caused the system to close the session", and the figure gives "Data (present if Reason = 1, 2 or 3)". The two data units now feed the close reasons the reactor sends: TestRFC7854PeerDownCarriesTheDataItsReasonRequires feeds rpc.ReasonNotification with a sent and a received NOTIFICATION and asserts reasons 1 and 3 with Data equal to the exact NOTIFICATION PDU, and rpc.ReasonLocalClose on FSMEvent 18 and asserts reason 2 with Data 0012, red if peerDownFor (bmp_events.go) writes constant zero octets or drops the event. TestRFC7854PeerDownOmitsDataWhereTheReasonHasNone asserts reason 5 for rpc.ReasonPeerRemoved and reason 4 for rpc.ReasonTCPFailure on event 18, each with no Data, so an encoder that always appends the event code goes red; its tag claim names reason 5 only and the body proves more. TestRFC7854PeerDownLocalCloseCarriesTheFSMEvent is unchanged. Residual seam as before: which event closed the session is the reactor's answer (sessionCloseFor), and the copy of CloseFSMEvent into StructuredEvent.FSMEvent (server/events.go) has no unit; these units set FSMEvent directly.

PolarityTestKind and tierProof state
negative TestRFC7854PeerDownOmitsDataWhereTheReasonHasNone unit/verify revert, verified
positive TestRFC7854PeerDownLocalCloseCarriesTheFSMEvent unit/verify revert, verified
positive TestRFC7854PeerDownCarriesTheDataItsReasonRequires unit/verify revert, verified

RFC7854-4.5-2

Likewise, the monitoring station MUST close the TCP session after receiving a termination message. (§4.5, Termination Message)

Audit verdict: enforced (the tests do what the requirement demands), fresh. receiver closes after reading a Termination with the router end held open (well under the read deadline) and drops the router; without a Termination two valid messages leave the session open

PolarityTestKind and tierProof state
negative TestBMPReceiverKeepsSessionWithoutTermination unit/verify unproven
positive TestBMPReceiverClosesAfterTermination unit/verify unproven

RFC7854-x-15

It MAY periodically send Stats Reports or even new Initiation messages, according to configuration. (§3.3, Lifecycle of a BMP Session)

Audit verdict: enforced (the tests do what the requirement demands), fresh. statistics-timeout 1 through the reload rail yields two reports about one interval apart; statistics-timeout 0 yields none

PolarityTestKind and tierProof state
negative TestRFC7854StatisticsTimeoutZeroSendsNoReport unit/verify revert, verified
positive TestRFC7854StatisticsTimeoutSendsPeriodicReports unit/verify revert, verified

RFC7854-x-16

It subsequently sends a Peer Up message over the BMP session for each of its monitored BGP peers that is in the Established state. (§3.3, Lifecycle of a BMP Session)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-29. The wrong tags on TestConcurrentDumpsStayAddressedToTheirOwnCollector are gone. rfc7854_session_opening_test.go::TestRFC7854SessionPeerUpOnlyForEstablishedPeers primes a new collector (primeSender) over one Established peer and one peer that exchanged OPENs and sent an UPDATE but never reported Up; it counts Peer Ups per address on the collector's bytes: exactly 1 for the Established peer, 0 for the other, and the first message is the Peer Up. A producer that announced every peer with cached OPENs, or none, goes red.

PolarityTestKind and tierProof state
negative TestRFC7854SessionPeerUpOnlyForEstablishedPeers unit/verify revert, verified
positive TestRFC7854SessionPeerUpOnlyForEstablishedPeers unit/verify revert, verified

RFC7854-x-17

It subsequently sends a Peer Up message over the BMP session for each of its monitored BGP peers that is in the Established state. It follows by sending the contents of its Adj- RIBs-In (pre-policy, post-policy, or both, see Section 5) encapsulated in Route Monitoring messages. (§3.3, Lifecycle of a BMP Session)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-29. rfc7854_session_opening_test.go::TestRFC7854SessionDumpsAdjRIBInAfterThePeerUp reads the same two-peer session in order: no Route Monitoring before the Peer Up, the Established peer's received route (exact UPDATE body announceBody(1)) arrives as a pre-policy Route Monitoring (L clear, the default pre-policy selection), and nothing is dumped for the peer that never reached Established. Order, content and scope of the Adj-RIB-In dump are each asserted.

PolarityTestKind and tierProof state
negative TestRFC7854SessionDumpsAdjRIBInAfterThePeerUp unit/verify revert, verified
positive TestRFC7854SessionDumpsAdjRIBInAfterThePeerUp unit/verify revert, verified

RFC7854-x-18

The sysDescr and sysName Information TLVs MUST be sent, any others are optional. (§4.3, Initiation Message)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-29. Both clauses now hold both polarities. Sender: rfc7854_test.go TestRFC7854InitiationCarriesSysDescr and the new rfc7854_session_opening_test.go::TestRFC7854InitiationCarriesSysName decode the Initiation sendInitiation writes and require exactly one sysName (type 2) and a sysDescr (type 1). Receiver: TestRFC7854InitiationMissingSysDescrEndsSession and TestBMPInitiationMissingSysNameEndsSession (tag added) each send an Initiation missing one TLV and require the session closed (decodeInitiation checks each independently); TestRFC7854InitiationEmptyIdentityValuesAccepted keeps presence, not length, as the test.

PolarityTestKind and tierProof state
negative TestBMPInitiationMissingSysNameEndsSession unit/verify revert, verified
negative TestRFC7854InitiationMissingSysDescrEndsSession unit/verify unproven
positive TestRFC7854InitiationEmptyIdentityValuesAccepted unit/verify unproven
positive TestRFC7854InitiationCarriesSysName unit/verify revert, verified
positive TestRFC7854InitiationCarriesSysDescr unit/verify revert, verified

RFC7854-3.2-1

Retries MUST be subject to some variety of backoff. (§3.2, Connection Establishment and Termination)

Audit verdict: enforced (the tests do what the requirement demands), fresh. nextReconnectWait doubles and caps at reconnectMax; a refused dial is not retried before the base wait even when the port reopens early

PolarityTestKind and tierProof state
negative TestRFC7854RetryNotBeforeBackoff unit/verify revert, verified
positive TestRFC7854RetryBackoffDoubles unit/verify revert, verified

RFC7854-3.2-2

The router MUST also restrict the rate at which sessions may be established. (§3.2, Connection Establishment and Termination)

Audit verdict: enforced (the tests do what the requirement demands), fresh. after the collector closes a session the sender reconnects, and not before the base wait since the first session

PolarityTestKind and tierProof state
negative TestRFC7854SessionEstablishmentRateLimited unit/verify revert, verified
positive TestRFC7854SessionEstablishmentRateLimited unit/verify revert, verified

RFC7854-3.3-1

Once it has sent all the routes for a given peer, it MUST send an End-of-RIB message for that peer (§3.3, Lifecycle of a BMP Session, and restated in the Route Monitoring section)

Audit verdict: enforced (the tests do what the requirement demands), fresh. after reconnect Peer Up precedes the surviving route and each family gets EOR after its routes; an incremental UPDATE and another collector's reconnect produce no EOR, and an incomplete snapshot never emits EOR

PolarityTestKind and tierProof state
negative TestRFC7854AdjReplayCompletionIsSessionScoped unit/verify unproven
negative TestRFC7854IncompleteAdjReplayCannotClaimCompletion unit/verify unproven
positive TestRFC7854AdjReplayEndsEachFamily unit/verify unproven

RFC7854-4.1-1

A BMP implementation MUST ignore unrecognized message types upon receipt. (§4.1, Common Header)

Audit verdict: enforced (the tests do what the requirement demands), fresh. type 200 is skipped and the following Termination is consumed; a malformed Peer Up still ends the session

PolarityTestKind and tierProof state
negative TestRFC7854MalformedKnownTypeStillEndsSession unit/verify revert, verified
positive TestRFC7854UnrecognizedMessageTypeIgnored unit/verify revert, verified

RFC7854-4.2-1

The remaining bits are reserved for future use. They MUST be transmitted as 0 and their values MUST be ignored on receipt. (§4.2, Per-Peer Header)

Audit verdict: enforced (the tests do what the requirement demands), fresh. transmitted Route Monitoring on both directions has reserved bits 0; a Peer Up with every reserved bit set is accepted and its defined flags decode unchanged

PolarityTestKind and tierProof state
negative TestRFC7854ReservedFlagsIgnoredOnReceipt unit/verify revert, verified
positive TestRFC7854ReservedFlagsTransmittedAsZero unit/verify revert, verified

RFC7854-4.3-2

The initiation message consists of the common BMP header followed by two or more Information TLVs (Section 4.4) containing information about the monitored router. (§4.3, Initiation Message)

Audit verdict: enforced (the tests do what the requirement demands), fresh. First verdict 2026-09-29. Positive rfc7854_message_layout_test.go::TestRFC7854InitiationIsTheCommonHeaderThenTwoOrMoreTLVs reads the octets sender.go::sendInitiation writes off a pipe, checks type 4 and walks TLVs by hand from octet 6 to exactly the end, requiring >= 2. Negative (R1(a)) ::TestRFC7854InitiationWithFewerThanTwoTLVsIsRefused: a one-TLV Initiation is refused by the receiver. The refusal comes from decodeInitiation's sysName-presence check (RFC7854-x-18), not a count check, but every one-TLV Initiation lacks sysName or sysDescr, so no one-TLV input is accepted; the buffer is otherwise valid.

PolarityTestKind and tierProof state
negative TestRFC7854InitiationWithFewerThanTwoTLVsIsRefused unit/verify revert, verified
positive TestRFC7854InitiationIsTheCommonHeaderThenTwoOrMoreTLVs unit/verify revert, verified

RFC7854-4.4-1

If multiple strings are included, their ordering MUST be preserved when they are reported. (§4.4, Information TLV)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Initiation and Peer Up strings reach the command output in transmitted order, with duplicates kept

PolarityTestKind and tierProof state
negative TestRFC7854InitiationStringsKeepDuplicates unit/verify unproven
negative TestRFC7854PeerUpStringsKeepDuplicates unit/verify unproven
positive TestRFC7854InitiationStringsReportedInOrder unit/verify unproven
positive TestRFC7854PeerUpStringsReportedInOrder unit/verify unproven

RFC7854-4.4-2

Type = 1: sysDescr. The Information field contains an ASCII string whose value MUST be set to be equal to the value of the sysDescr MIB-II [RFC1213] object. (§4.4, Information TLV)

Audit verdict: enforced (the tests do what the requirement demands), fresh. sysDescr carries the running build and uname sysname, release and machine, the MIB-II sysDescr content; it changes when the build identity changes

PolarityTestKind and tierProof state
negative TestRFC7854InitiationDescriptionChangesWithBuild unit/verify unproven
positive TestRFC7854InitiationDescribesRunningSystem unit/verify unproven

RFC7854-4.4-3

Type = 2: sysName. The Information field contains an ASCII string whose value MUST be set to be equal to the value of the sysName MIB-II [RFC1213] object. (§4.4, Information TLV)

Audit verdict: enforced (the tests do what the requirement demands), fresh. sysName is the configured host.domain FQDN, the MIB-II sysName convention, survives rollback, and follows a configuration change

PolarityTestKind and tierProof state
negative TestRFC7854InitiationSystemNameChanges unit/verify unproven
positive TestRFC7854InitiationUsesConfiguredSystemName unit/verify unproven

RFC7854-4.5-1

Once the router has sent a termination message, it MUST close the TCP session without sending any further messages. (§4.5, Termination Message)

Audit verdict: enforced (the tests do what the requirement demands), fresh. after stop() the collector reads the Termination then EOF; a Peer Up afterwards is refused with errNotConnected

PolarityTestKind and tierProof state
negative TestRFC7854TerminationThenCloseAndSilence unit/verify revert, verified
positive TestRFC7854TerminationThenCloseAndSilence unit/verify revert, verified

RFC7854-4.5-3

Type = 1: Reason. The Information field contains a 2-byte code indicating the reason that the connection was terminated. Some reasons may have further TLVs associated with them. Inclusion of this TLV is REQUIRED. (§4.5, Termination Message)

Audit verdict: enforced (the tests do what the requirement demands), fresh. live shutdown Termination carries exactly one two-octet Reason; absent, empty, short and long Reason TLVs fail decode and end the session

PolarityTestKind and tierProof state
negative TestRFC7854TerminationRequiresTwoByteReason unit/verify unproven
positive TestRFC7854SenderTerminationCarriesReason unit/verify unproven

RFC7854-4.5-4

The termination message consists of the common BMP header followed by one or more TLVs containing information about the reason for the termination (§4.5, Termination Message)

Audit verdict: enforced (the tests do what the requirement demands), fresh. First verdict 2026-09-29. Positive rfc7854_message_layout_test.go::TestRFC7854TerminationIsTheCommonHeaderThenTLVs reads the octets the sender's Termination path writes, walks TLVs from octet 6 to exactly the end, requires at least one and exactly one Reason TLV. Negative ::TestRFC7854TerminationWithNoTLVIsRefused: a 6-octet header-only Termination is refused (decodeTermination's missing-Reason branch, which any zero-TLV body reaches).

PolarityTestKind and tierProof state
negative TestRFC7854TerminationWithNoTLVIsRefused unit/verify revert, verified
positive TestRFC7854TerminationIsTheCommonHeaderThenTLVs unit/verify revert, verified

RFC7854-4.5-5

Although use of this message is RECOMMENDED, a monitoring station must always be prepared for the session to terminate with no message. (§4.5, Termination Message)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Station clause: termination_absent_test.go::TestBMPReceiverEndsTheSessionWhenTheRouterLeavesWithoutTermination sends Initiation + Peer Up, confirms one router and one peer held, closes the pipe with no Termination, and requires handleSession to return with zero routers and zero peers (record: removeRouter break observed red). RECOMMENDED clause: sender_queue_test.go::TestSenderStopSendsTerminationToCollector reads a Termination on the collector side through stop() racing holdConnection (record: writeTerminationLocked break observed red). {single-polarity: positive} holds: the sentence permits the no-message close, so no non-compliant router input exists for the station to refuse.

PolarityTestKind and tierProof state
positive TestSenderStopSendsTerminationToCollector unit/verify revert, verified
positive TestBMPReceiverEndsTheSessionWhenTheRouterLeavesWithoutTermination unit/verify revert, verified

RFC7854-4.7-1

If the BGP Message TLV occurs in the Route Mirroring message, it MUST occur last in the list of TLVs. (§4.7, Route Mirroring)

Audit verdict: enforced (the tests do what the requirement demands), fresh. transmitted Route Mirroring ends with the BGP Message TLV; Information then BGP Message is accepted, BGP Message then Information ends the session

PolarityTestKind and tierProof state
negative TestRFC7854MirrorBGPMessageNotLastEndsSession unit/verify unproven
positive TestRFC7854ErroredMirrorWithPDUAccepted unit/verify unproven
positive TestRFC7854RouteMirroringBGPMessageTLVLast unit/verify revert, verified

RFC7854-4.7-2

Code = 0: Errored PDU. The contained message was found to have some error that made it unusable, causing it to be treated-as- withdraw [RFC7606]. A BGP Message TLV MUST also occur in the TLV list. (§4.7, Route Mirroring)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Errored PDU with a BGP Message TLV is accepted; Errored PDU without one ends the session

PolarityTestKind and tierProof state
negative TestRFC7854ErroredMirrorWithoutPDUEndsSession unit/verify unproven
positive TestRFC7854ErroredMirrorWithPDUAccepted unit/verify unproven

RFC7854-4.7-3

Following the common BMP header and per-peer header is a set of TLVs that contain information about a message or set of messages. (§4.7, Route Mirroring)

Audit verdict: enforced (the tests do what the requirement demands), fresh. First verdict 2026-09-29. Positive rfc7854_message_layout_test.go::TestRFC7854RouteMirroringIsThePerPeerHeaderThenTLVs: writeRouteMirroring output decodes a per-peer header equal to the input at octet 6, then TLVs walked by hand from octet 48 to exactly the end, same types and values in order. Negative ::TestRFC7854RouteMirroringWhoseBodyIsNotTLVsIsRefused: the valid message is first accepted, then a 3-octet tail that is no TLV (length fixed up) is refused, so only the not-TLVs body differs.

PolarityTestKind and tierProof state
negative TestRFC7854RouteMirroringWhoseBodyIsNotTLVsIsRefused unit/verify revert, verified
positive TestRFC7854RouteMirroringIsThePerPeerHeaderThenTLVs unit/verify revert, verified

RFC7854-4.8-1

A BMP implementation MUST ignore unrecognized stat types on receipt, and likewise MUST ignore unexpected data in the Stat Data field. (§4.8, Stats Reports)

Audit verdict: enforced (the tests do what the requirement demands), fresh. unknown stat type 60000 and a 3-octet counter are consumed and the session survives; a stat length past the report end still ends it

PolarityTestKind and tierProof state
negative TestRFC7854TruncatedStatEndsSession unit/verify revert, verified
positive TestRFC7854UnrecognizedStatTypeIgnored unit/verify revert, verified

RFC7854-4.8-2

However, if an SR message is transmitted, at least one statistic MUST be carried in it. (§4.8, Stats Reports)

Audit verdict: enforced (the tests do what the requirement demands), fresh. a transmitted report carries one statistic; an empty report is refused before it reaches the collector

PolarityTestKind and tierProof state
negative TestRFC7854SenderRefusesEmptyStatistics unit/verify unproven
positive TestRFC7854StatsReportCarriesAStatistic unit/verify revert, verified

RFC7854-4.8-3

Following the common BMP header and per-peer header is a 4-byte field that indicates the number of counters in the stats message where each counter is encoded as a TLV. (§4.8, Stats Reports)

Audit verdict: enforced (the tests do what the requirement demands), fresh. First verdict 2026-09-29. Positive rfc7854_message_layout_test.go::TestRFC7854StatsReportCountNamesTheCountersThatFollow: the 4-octet count at octet 48 equals 3 and exactly three counter TLVs, walked by hand, run to the end with the input types and values. Negative ::TestRFC7854StatsReportCountDisagreeingWithItsCountersIsRefused: the valid report is first accepted, then count+1 (truncated entry) and count-1 (trailing data) are each refused by decodeStatisticsReport.

PolarityTestKind and tierProof state
negative TestRFC7854StatsReportCountDisagreeingWithItsCountersIsRefused unit/verify revert, verified
positive TestRFC7854StatsReportCountNamesTheCountersThatFollow unit/verify revert, verified

RFC7854-4.10-1

Following the common BMP header and per-peer header is the following (§4.10, Peer Up Notification)

Audit verdict: enforced (the tests do what the requirement demands), fresh. First verdict 2026-09-29. The row's sentence is the lead-in to the §4.10 figure, the only statement of the Peer Up layout, so the obligation judged is that figure: Local Address (16), Local Port, Remote Port, Sent OPEN, Received OPEN after the per-peer header (Information TLVs are RFC7854-x-19, the OPEN contents RFC7854-x-8). Positive rfc7854_message_layout_test.go::TestRFC7854PeerUpIsThePerPeerHeaderThenTheFixedFieldsAndBothOPENs reads each field raw at its offset from writePeerUp output and the exact total length. Negative ::TestRFC7854PeerUpShorterThanItsFixedFieldsIsRefused: a valid Peer Up is accepted, the same cut 10 octets into the fixed fields is refused (decodePeerUp short check).

PolarityTestKind and tierProof state
negative TestRFC7854PeerUpShorterThanItsFixedFieldsIsRefused unit/verify revert, verified
positive TestRFC7854PeerUpIsThePerPeerHeaderThenTheFixedFieldsAndBothOPENs unit/verify revert, verified

RFC7854-5-1

Pre-policy routes MUST have their L flag clear in the BMP header (see Section 4), post-policy routes MUST have their L flag set. (§5, Route Monitoring)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-29 (the negative unit gained the RFC7854-5-4 tag line only; assertions unchanged). rfc7854_test.go::TestRFC7854LFlagFollowsPolicy: received announce and withdraw leave with L clear, sent with L set. ::TestRFC7854LFlagNotDecidedByBody: one body streamed on both sides leaves L clear received and L set sent, so the flag follows the direction (policy stage) and not the message. Ze sends no post-policy Adj-RIB-In; its L-set stream is the RFC 8671 Adj-RIB-Out (O and L set, peerHeaderFromEvent).

PolarityTestKind and tierProof state
negative TestRFC7854LFlagNotDecidedByBody unit/verify revert, verified
positive TestRFC7854LFlagFollowsPolicy unit/verify revert, verified

RFC7854-5-2

If the implementation is able to provide information about when routes were received, it MAY provide such information in the BMP Timestamp field. Otherwise, the BMP Timestamp field MUST be set to 0, indicating that time is not available. (§5, Route Monitoring)

Audit verdict: enforced (the tests do what the requirement demands), fresh. replayed routes and EORs with unknown receipt time carry 0.0; a known receipt time survives replay exactly

PolarityTestKind and tierProof state
negative TestRFC7854KnownRouteTimeSurvivesReplay unit/verify unproven
positive TestRFC7854UnknownRouteTimeIsZero unit/verify unproven

RFC7854-5-4

The withdraw MUST have its L flag set to correspond to that of any previous announcement (§5, Route Monitoring)

Audit verdict: enforced (the tests do what the requirement demands), fresh. First verdict 2026-09-29 (first clause of the §5 sentence; the twice-sent-withdraw clause left with retired RFC7854-5-3). Producer peerHeaderFromEvent sets L only on the sent direction, so a route's announcement and its withdraw take their L from the same direction. Positive rfc7854_test.go::TestRFC7854LFlagFollowsPolicy: a received withdraw carries L clear like a received announce, a sent withdraw L set like a sent announce. Negative ::TestRFC7854LFlagNotDecidedByBody: the same withdraw body on both sides gets L clear and L set, so a withdraw cannot carry the other side's flag. Both observed red under the peerHeaderFromEvent break. The test does not pair one announce with its own withdraw by prefix; the direction is the only input L reads, so no pairing can diverge.

PolarityTestKind and tierProof state
negative TestRFC7854LFlagNotDecidedByBody unit/verify revert, verified
positive TestRFC7854LFlagFollowsPolicy unit/verify revert, verified

RFC7854-5-6

When a change occurs to a route, such as an attribute change, the router must update the monitoring station with the new attribute. (§5, Route Monitoring)

Audit verdict: enforced (the tests do what the requirement demands), fresh. rfc7854_replay_test.go::TestRFC7854ChangedAttributesCanReturnToEarlierValue receives one prefix three times with ORIGIN IGP, INCOMPLETE, IGP and requires exactly three Route Monitoring messages, each body byte-equal to the UPDATE carrying that ORIGIN, so a sender that suppresses or dedupes the return to an earlier value fails (record: handleSenderUpdate break observed red). One attribute (ORIGIN) samples 'such as an attribute change'. {single-polarity: positive} holds: every route change is compliant input to the router, which has no refusal path.

PolarityTestKind and tierProof state
positive TestRFC7854ChangedAttributesCanReturnToEarlierValue unit/verify revert, verified

RFC7854-8.2-1

Since in this case no transport session actually exists, the Local and Remote Port fields of the Peer Up message MUST be set to 0. (§8.2, Peer Up Notification)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Loc-RIB instance Peer Up carries ports 0/0; a BGP peer's Peer Up carries its real 179/40000

PolarityTestKind and tierProof state
negative TestRFC7854BGPPeerUpCarriesTransportPorts unit/verify revert, verified
positive TestRFC7854LocRIBPeerUpPortsZero unit/verify revert, verified

Extraction sign-off

FieldValue
Reviewer claude
Signed off 2026-09-29
Register prose
Source rfc/full/rfc7854.txt
Source fingerprint b32c6bf7d6b5d67a
Record rfc/extraction/rfc7854.json
Mapped sentences 24
Declined as scope 15
Relocated to a spec, which Ze OWES 0
Unclassified 0

Sections

SectionNameSitesDispositionReason
front not stated 1 walked not stated
1 not stated 0 walked not stated
1.1 not stated 0 walked not stated
2 not stated 0 walked not stated
3 not stated 0 walked not stated
3.1 not stated 0 walked not stated
3.2 not stated 2 walked not stated
3.3 not stated 2 walked not stated
4 not stated 0 walked not stated
4.1 not stated 2 walked not stated
4.2 not stated 1 walked not stated
4.3 not stated 2 walked not stated
4.4 not stated 3 walked not stated
4.5 not stated 4 walked not stated
4.6 not stated 0 walked not stated
4.7 not stated 2 walked not stated
4.8 not stated 3 walked not stated
4.9 not stated 0 walked not stated
4.10 not stated 0 walked not stated
5 not stated 6 walked not stated
6 not stated 0 walked not stated
7 not stated 0 walked not stated
8 not stated 0 walked not stated
8.1 not stated 0 walked not stated
8.2 not stated 2 walked not stated
9 not stated 0 walked not stated
10 not stated 0 walked not stated
10.1 not stated 1 walked not stated
10.2 not stated 1 walked not stated
10.3 not stated 0 walked not stated
10.4 not stated 1 walked not stated
10.5 not stated 1 walked not stated
10.6 not stated 1 walked not stated
10.7 not stated 1 walked not stated
10.8 not stated 1 walked not stated
10.9 not stated 1 walked not stated
10.10 not stated 1 walked not stated
11 not stated 0 walked not stated
12 not stated 0 walked not stated
12.1 not stated 0 walked not stated
12.2 not stated 0 walked not stated

Excluded sentences

SiteExcluded kindReasonQuote
front:1 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
Front-matter boilerplate the extractor did not strip: the IETF Trust Legal Provisions notice binds whoever extracts Code Components from the RFC document, not a BMP router or monitoring station. The lowercase must is the license condition of the copyright notice. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.
3.3:1 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
Restates the obligation section 4.3 states at the site this walk maps to RFC7854-x-6: 'An initiation message MUST be sent as the first message after the TCP session comes up.' Section 3.3 states it as the first step of the session lifecycle; section 4.3 states it as the rule of the message itself. It MUST begin by sending an Initiation message.
4.8:2 cross-document
never bound Ze
the obligation belongs to another document that this one only cites
The sentence is the 64-bit Gauge definition that section 4.8 adopts from Section 4 of RFC 2856 (the section says the stats types are defined after the examples in Section 3.2.3.3 of RFC 1155 and Section 4 of RFC 2856). The lowercase shall describes the semantics of that data type as RFC 2856 defines it; section 4.8 states its own obligations on stats reports at the sites this walk maps to RFC7854-4.8-1 and RFC7854-4.8-2. 64-bit Gauge: A non-negative integer that may increase or decrease, but shall never exceed a maximum value, nor fall below a minimum one.
5:1 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
Restates the per-peer End-of-RIB obligation section 3.3 states at the site this walk maps to RFC7854-3.3-1: 'Once it has sent all the routes for a given peer, it MUST send an End-of-RIB message for that peer'. Section 5 adds only where the marker is defined (Section 2 of RFC 4724) and that it carries the BMP encapsulation header. When the initial dump is completed for a given peer, this MUST be indicated by sending an End-of-RIB marker for that peer (as specified in Section 2 of [RFC4724], plus the BMP encapsulation header).
5:6 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
The prose scanner matched the ordinary English required in (Route mirroring (Section 6) is provided if this is required.), which describes when an operator uses Route Mirroring, and the lowercase should attempt to generate updates promptly, which the same paragraph relaxes: it is acceptable that the router generate the final state of that prefix. Neither states an obligation on the router; RFC 7854 invokes RFC 2119 for the capitalized keywords only. (Route mirroring (Section 6) is provided if this is required.) While the router should attempt to generate updates promptly, there is a finite time that could elapse between reception of an update, the generation an RM message, and its transmission to the monitoring station.
8.2:1 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
The prose scanner matched the ordinary English Some consideration is required, which introduces section 8.2 and states no obligation. The section obligation on locally originated routes is the next site, mapped to RFC7854-8.2-1. Some consideration is required for routes originated into BGP by the local router, whether as a result of redistribution from another protocol or for some other reason.
10.1:1 binds-another-role
never bound Ze
the obligation is addressed to a role Ze never acts as
Presumed wrong until justified: Ze rarely implements one side of a protocol, so the reason beside this row must name the role, show Ze never acts as it, and cite the producer that would.
Binds IANA, the registry the section addresses: the sentence sets the allocation policy ('Standards Action', 'Specification Required' under RFC 5226) IANA applies when it assigns a value from this registry. Ze holds no code that acts as IANA and could hold none: the role is the registry itself, not a party on the BMP wire. Ze's BMP encoder and decoder (internal/component/bgp/plugins/bmp) read and write the values the registry already holds; nothing in the repository allocates one. Type values 0 through 127 MUST be assigned using the "Standards Action" policy, and values 128 through 250 using the "Specification Required" policy defined in [RFC5226].
10.2:1 binds-another-role
never bound Ze
the obligation is addressed to a role Ze never acts as
Presumed wrong until justified: Ze rarely implements one side of a protocol, so the reason beside this row must name the role, show Ze never acts as it, and cite the producer that would.
Binds IANA, the registry the section addresses: the sentence sets the allocation policy ('Standards Action', 'Specification Required' under RFC 5226) IANA applies when it assigns a value from this registry. Ze holds no code that acts as IANA and could hold none: the role is the registry itself, not a party on the BMP wire. Ze's BMP encoder and decoder (internal/component/bgp/plugins/bmp) read and write the values the registry already holds; nothing in the repository allocates one. Peer Type values 0 through 127 MUST be assigned using the "Standards Action" policy, and values 128 through 250 using the "Specification Required" policy, defined in [RFC5226].
10.4:1 binds-another-role
never bound Ze
the obligation is addressed to a role Ze never acts as
Presumed wrong until justified: Ze rarely implements one side of a protocol, so the reason beside this row must name the role, show Ze never acts as it, and cite the producer that would.
Binds IANA, the registry the section addresses: the sentence sets the allocation policy ('Standards Action', 'Specification Required' under RFC 5226) IANA applies when it assigns a value from this registry. Ze holds no code that acts as IANA and could hold none: the role is the registry itself, not a party on the BMP wire. Ze's BMP encoder and decoder (internal/component/bgp/plugins/bmp) read and write the values the registry already holds; nothing in the repository allocates one. Stat Type values 0 through 32767 MUST be assigned using the "Standards Action" policy, and values 32768 through 65530 using the "Specification Required" policy, defined in [RFC5226].
10.5:1 binds-another-role
never bound Ze
the obligation is addressed to a role Ze never acts as
Presumed wrong until justified: Ze rarely implements one side of a protocol, so the reason beside this row must name the role, show Ze never acts as it, and cite the producer that would.
Binds IANA, the registry the section addresses: the sentence sets the allocation policy ('Standards Action', 'Specification Required' under RFC 5226) IANA applies when it assigns a value from this registry. Ze holds no code that acts as IANA and could hold none: the role is the registry itself, not a party on the BMP wire. Ze's BMP encoder and decoder (internal/component/bgp/plugins/bmp) read and write the values the registry already holds; nothing in the repository allocates one. Information type values 0 through 32767 MUST be assigned using the "Standards Action" policy, and values 32768 through 65530 using the "Specification Required" policy, defined in [RFC5226].
10.6:1 binds-another-role
never bound Ze
the obligation is addressed to a role Ze never acts as
Presumed wrong until justified: Ze rarely implements one side of a protocol, so the reason beside this row must name the role, show Ze never acts as it, and cite the producer that would.
Binds IANA, the registry the section addresses: the sentence sets the allocation policy ('Standards Action', 'Specification Required' under RFC 5226) IANA applies when it assigns a value from this registry. Ze holds no code that acts as IANA and could hold none: the role is the registry itself, not a party on the BMP wire. Ze's BMP encoder and decoder (internal/component/bgp/plugins/bmp) read and write the values the registry already holds; nothing in the repository allocates one. Information type values 0 through 32767 MUST be assigned using the "Standards Action" policy, and values 32768 through 65530 using the "Specification Required" policy, defined in [RFC5226].
10.7:1 binds-another-role
never bound Ze
the obligation is addressed to a role Ze never acts as
Presumed wrong until justified: Ze rarely implements one side of a protocol, so the reason beside this row must name the role, show Ze never acts as it, and cite the producer that would.
Binds IANA, the registry the section addresses: the sentence sets the allocation policy ('Standards Action', 'Specification Required' under RFC 5226) IANA applies when it assigns a value from this registry. Ze holds no code that acts as IANA and could hold none: the role is the registry itself, not a party on the BMP wire. Ze's BMP encoder and decoder (internal/component/bgp/plugins/bmp) read and write the values the registry already holds; nothing in the repository allocates one. Information type values 0 through 32767 MUST be assigned using the "Standards Action" policy, and values 32768 through 65530 using the "Specification Required" policy, defined in [RFC5226].
10.8:1 binds-another-role
never bound Ze
the obligation is addressed to a role Ze never acts as
Presumed wrong until justified: Ze rarely implements one side of a protocol, so the reason beside this row must name the role, show Ze never acts as it, and cite the producer that would.
Binds IANA, the registry the section addresses: the sentence sets the allocation policy ('Standards Action', 'Specification Required' under RFC 5226) IANA applies when it assigns a value from this registry. Ze holds no code that acts as IANA and could hold none: the role is the registry itself, not a party on the BMP wire. Ze's BMP encoder and decoder (internal/component/bgp/plugins/bmp) read and write the values the registry already holds; nothing in the repository allocates one. Information type values 0 through 32767 MUST be assigned using the "Standards Action" policy, and values 32768 through 65530 using the "Specification Required" policy, defined in [RFC5226].
10.9:1 binds-another-role
never bound Ze
the obligation is addressed to a role Ze never acts as
Presumed wrong until justified: Ze rarely implements one side of a protocol, so the reason beside this row must name the role, show Ze never acts as it, and cite the producer that would.
Binds IANA, the registry the section addresses: the sentence sets the allocation policy ('Standards Action', 'Specification Required' under RFC 5226) IANA applies when it assigns a value from this registry. Ze holds no code that acts as IANA and could hold none: the role is the registry itself, not a party on the BMP wire. Ze's BMP encoder and decoder (internal/component/bgp/plugins/bmp) read and write the values the registry already holds; nothing in the repository allocates one. Information type values 0 through 32767 MUST be assigned using the "Standards Action" policy, and values 32768 through 65530 using the "Specification Required" policy, defined in [RFC5226].
10.10:1 binds-another-role
never bound Ze
the obligation is addressed to a role Ze never acts as
Presumed wrong until justified: Ze rarely implements one side of a protocol, so the reason beside this row must name the role, show Ze never acts as it, and cite the producer that would.
Binds IANA, the registry the section addresses: the sentence sets the allocation policy ('Standards Action', 'Specification Required' under RFC 5226) IANA applies when it assigns a value from this registry. Ze holds no code that acts as IANA and could hold none: the role is the registry itself, not a party on the BMP wire. Ze's BMP encoder and decoder (internal/component/bgp/plugins/bmp) read and write the values the registry already holds; nothing in the repository allocates one. Information type values 0 through 32767 MUST be assigned using the "Standards Action" policy, and values 32768 through 65530 using the "Specification Required" policy, defined in [RFC5226].

Superseded

No document obsoletes RFC 7854, so its obligations are stated where they were written.