a positive test proves Ze does what the requirement demands and a negative one proves it refuses what the requirement forbids
RFC 7311 - The Accumulated IGP Metric Attribute for BGP
Every requirement this repository extracted from RFC 7311, 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
the requirement admits no counter-case, so one polarity plus a recorded reason is the whole proof available for it
one direction is tested, the other is neither tested nor excused, and nothing states which
scoped tests exist; the remaining obligation is unmet or unproven, with zero whole-requirement credit
no test carries the requirement id, whether or not a gap states why
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
Neutral
measures that are neither good news nor bad
MUST-level requirements the gate HOLDS. A population, not a result: the shares beside it are what says how Ze stands
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
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
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
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 22 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.
| Card | Tone here | Why 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 | warn | 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
| Field | Value |
|---|---|
| Public status | Partial |
| Enrolment | Enrolled |
| Requirements | 26 |
| Gated MUST-level | 22 |
| 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 | 81 |
| Tagged units | 81 |
| Recorded audit verdicts | 12 |
| Discrimination records | 53 |
| Summary | rfc/short/rfc7311.md |
| Requirement shard | rfc/requirements/rfc7311.md |
| RFC text | rfc/full/rfc7311.txt |
Enrolment
Enrolled: Ze implements AIGP validation, per-session policy, configured origination, forwarding accumulation and best-path selection. Recursive metric changes reach retained advertisements and the selecting RIB, including its subprocess transport. Requirement identities follow the mappings in `rfc/extraction/rfc7311.json`; the legacy RFC7311-3.2-1 identity maps to the origination prohibition in Section 3.4.1, not a separate propagation rule in Section 3.2.
What the public ledger says
Status: Partial
What the ledger says is covered:
- Attribute codec and presentation
- receive validation
- per-session enablement
- configured origination
- next-hop-self accumulation
- retained-generation re-advertisement
- native and forked best-path reselection.
What the ledger says remains:
Automatic origination policies are not enabled. Origination accepts explicitly configured metrics and remains subject to the domain and next-hop restrictions in Section 3.4.1.Coverage
| Bucket | Count | What it counts |
|---|---|---|
| Positive and negative tests | 22 | one part of the gated population |
| Annotated (including scoped evidence) | 0 | 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 requirements | 22 | every gated MUST falls in exactly one bucket above |
Positive and negative tests (22): RFC7311-3-1, RFC7311-3-2, RFC7311-3-3, RFC7311-3.2-4, RFC7311-3.2-1, RFC7311-3.2-5, RFC7311-3.2-6, RFC7311-3.3-1, RFC7311-3.3-2, RFC7311-3.3-3, RFC7311-3.3-4, RFC7311-3.4.1-1, RFC7311-3.4.1-2, RFC7311-3.4.1-3, RFC7311-3.4.3-1, RFC7311-3.4.3-2, RFC7311-3.4.3-3, RFC7311-3.4.3-4, RFC7311-3.4.3-5, RFC7311-3.4.3-6, RFC7311-3.4.3-7, RFC7311-4.1-1
Requirements
| Requirement | Level | Section | Tests |
|---|---|---|---|
RFC7311-3-1 | The AIGP TLV is encoded as follows: - Type: 1 - Length: 11 - Value: Accumulated IGP Metric. The value field of the AIGP TLV is always 8 octets long (§3) | ||
| MUST | 3 | ||
RFC7311-3-2 | The value field of the AIGP attribute is defined here to be a set of elements encoded as "Type/Length/Value" (i.e., a set of TLVs). (§3) | ||
| MUST | 3 | ||
RFC7311-3-3 | Any other AIGP TLVs in the AIGP attribute MUST be passed along unchanged if the AIGP attribute is passed along. (§3) | ||
| MUST | 3 | ||
RFC7311-3.2-4 | If a BGP path attribute is received that has the AIGP attribute codepoint but also has the transitive bit set, the attribute MUST be considered to be a malformed AIGP attribute and MUST be discarded as specified in this section. (§3.2) | ||
| MUST | 3.2 | ||
RFC7311-3.2-1 | A BGP speaker MUST NOT add the AIGP attribute to any route whose path leads outside the AIGP administrative domain to which the BGP speaker belongs (§3.4.1) | ||
| MUST NOT | 3.4.1 | ||
RFC7311-3.2-5 | When receiving a BGP Update message containing a malformed AIGP attribute, the attribute MUST be treated exactly as if it were an unrecognized non-transitive attribute. That is, it "MUST be quietly ignored and not passed along to other BGP peers" (§3.2) | ||
| MUST | 3.2 | ||
RFC7311-3.2-2 | If an AIGP attribute is received and its first AIGP TLV contains the maximum value 0xffffffffffffffff, the attribute SHOULD be considered to be malformed and SHOULD be discarded (§3.2) | ||
| SHOULD | 3.2 | positive
no testno positive testnegative
no testno negative test |
|
RFC7311-3.2-6 | Note that an AIGP attribute MUST NOT be considered to be malformed because it contains more than one TLV of a given type or because it contains TLVs of unknown types. (§3.2) | ||
| MUST NOT | 3.2 | ||
RFC7311-3.3-1 | An implementation that supports the AIGP attribute MUST support a per-session configuration item, AIGP_SESSION, that indicates whether the attribute is enabled or disabled for use on that session (§3.3) | ||
| MUST | 3.3 | ||
RFC7311-3.3-2 | - For all other External BGP (EBGP) sessions, the default value of AIGP_SESSION MUST be "disabled". (§3.3) | ||
| MUST | 3.3 | ||
RFC7311-3.3-3 | The AIGP attribute MUST NOT be sent on any BGP session for which AIGP_SESSION is disabled (§3.3) | ||
| MUST NOT | 3.3 | ||
RFC7311-3.3-4 | If an AIGP attribute is received on a BGP session for which AIGP_SESSION is disabled, the attribute MUST be treated exactly as if it were an unrecognized non-transitive attribute (§3.3) | ||
| MUST | 3.3 | ||
RFC7311-3.4.1-1 | An implementation that supports the AIGP attribute MUST support a configuration item, AIGP_ORIGINATE, that enables or disables its creation and attachment to routes (§3.4.1) | ||
| MUST | 3.4.1 | ||
RFC7311-3.4.1-2 | The default value of AIGP_ORIGINATE MUST be "disabled" (§3.4.1) | ||
| MUST | 3.4.1 | ||
RFC7311-3.4.1-3 | A BGP speaker R MUST NOT add the AIGP attribute to any route for which R does not set itself as the next hop (§3.4.1) | ||
| MUST NOT | 3.4.1 | ||
RFC7311-3.4.3-1 | If R1 does not change the next hop of the route, then R1 MUST NOT change the AIGP attribute value of the route (§3.4.3) | ||
| MUST NOT | 3.4.3 | ||
RFC7311-3.4.3-2 | In all the computations discussed in this section, the AIGP value MUST be capped at its maximum unsigned value 0xffffffffffffffff. (§3.4.3) | ||
| MUST | 3.4.3 | ||
RFC7311-3.4.3-3 | Increasing the AIGP value MUST NOT cause the value to wrap around (§3.4.3) | ||
| MUST NOT | 3.4.3 | ||
RFC7311-3.4.3-4 | If R1's route to R2 is either (a) an IGP-learned route or (b) a static route that does not require recursive next hop resolution, then R1 MUST increase the value of the AIGP TLV by adding to A the distance from R1 to R2. (§3.4.3) | ||
| MUST | 3.4.3 | ||
RFC7311-3.4.3-5 | A MUST be increased by a non-zero amount (§3.4.3) | ||
| MUST | 3.4.3 | ||
RFC7311-3.4.3-6 | Then, when R1 changes the next hop of a route from R2 to R1, the AIGP TLV value MUST be increased by a non-zero amount. (§3.4.3) | ||
| MUST | 3.4.3 | ||
RFC7311-3.4.3-7 | Any change due to (a) in any of these values MUST trigger a new AIGP computation for that route. (§3.4.3) | ||
| MUST | 3.4.3 | ||
RFC7311-4.1-1 | Assuming that the BGP decision process invokes the tie-breaking procedures, the procedures in this section MUST be executed BEFORE any of the tie-breaking procedures described in [BGP], Section 9.1.2.2 are executed. (§4.1) | ||
| MUST | 4.1 | ||
RFC7311-3.3-5 | For Internal BGP (IBGP) sessions, and for External BGP (EBGP) sessions between members of the same BGP Confederation [BGP-CONFED], the default value of AIGP_SESSION SHOULD be "enabled". (§3.3) | ||
| SHOULD | 3.3 | positive
no testno positive testnegative
no testno negative test |
|
RFC7311-3.1-1 | This document only considers the use of the AIGP attribute in networks where each router uses tunneling of some sort to deliver a packet to its BGP next hop. Use of the AIGP attribute in other scenarios is outside the scope of this document. (§3.1) | ||
| MAY | 3.1 | positive
no testno positive testnegative
no testno negative test |
|
RFC7311-3.4.1-4 | The AIGP attribute may be added only to routes that satisfy one of the following conditions: - The route is a static route, not leading outside the AIGP administrative domain, that is being redistributed into BGP; - The route is an IGP route that is being redistributed into BGP; - The route is an IBGP-learned route whose AS_PATH attribute is empty; or - The route is an EBGP-learned route whose AS_PATH contains only ASes that are in the same AIGP administrative domain as the BGP speaker. (§3.4.1) | ||
| MAY | 3.4.1 | positive
no testno positive testnegative
no testno negative test |
|
Gaps and untested MUSTs
RFC 7311 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.
RFC7311-3-1
The AIGP TLV is encoded as follows: - Type: 1 - Length: 11 - Value: Accumulated IGP Metric. The value field of the AIGP TLV is always 8 octets long (§3)
Audit verdict: enforced (the tests do what the requirement demands), fresh. Judge 2026-09-30. TestRFC7311AIGPTLVLengthIsEleven: + WriteTo emits 01 000b and 8 value octets and ParseAIGP reads the metric back; - Type-1 TLVs of Length 12 and 10 are refused by ParseAIGP, the registered parser. Forbidden: accepting a Type-1 TLV whose Length is not 11. Records observed red (AIGPMetricOffset).
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestParseAIGPMalformedMetricWrongLength |
unit/verify | unproven |
| negative | TestRFC7311AIGPTLVLengthIsEleven |
unit/verify | revert, verified |
| positive | TestParseAIGP |
unit/verify | unproven |
| positive | TestRFC7311AIGPTLVLengthIsEleven |
unit/verify | revert, verified |
RFC7311-3-2
The value field of the AIGP attribute is defined here to be a set of elements encoded as "Type/Length/Value" (i.e., a set of TLVs). (§3)
Audit verdict: enforced (the tests do what the requirement demands), fresh. Judge 2026-09-30. TestRFC7311AIGPValueIsWholeTLVSet: + a value of two whole TLVs parses into exactly those two; - one, two or three trailing octets that do not form a TLV are refused. Forbidden: accepting a value that is not a whole set of TLVs.
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestParseAIGPMalformedTruncatedValue |
unit/verify | unproven |
| negative | TestRFC7311AIGPValueIsWholeTLVSet |
unit/verify | revert, verified |
| positive | TestParseAIGPMultipleTLVs |
unit/verify | unproven |
| positive | TestRFC7311AIGPValueIsWholeTLVSet |
unit/verify | revert, verified |
RFC7311-3-3
Any other AIGP TLVs in the AIGP attribute MUST be passed along unchanged if the AIGP attribute is passed along. (§3)
Audit verdict: enforced (the tests do what the requirement demands), fresh. RFC 7311 Section 3: 'Any other AIGP TLVs in the AIGP attribute MUST be passed along unchanged if the AIGP attribute is passed along.' Re-read all four tagged units. TestRFC7311OtherAIGPTLVsPassedAlongUnchanged compares the complete trailing second Type-1 and unknown Type-9 TLVs byte-for-byte at the final socket for unchanged next hop and next-hop-self, despite a policy replacement that drops them; it separately asserts first metric 100/130. TestRFC7311OtherAIGPTLVsSurviveTheCodec supplies conforming complete-byte roundtrip and first-TLV selection, supplemented by TestParseAIGPMultipleTLVs and TestAIGPWriteToMultipleTLVs. Valid lengths isolate preservation, not malformed-input rejection. Producers attribute.ParseAIGP/AIGP.WriteTo and reactor.applyFactsAIGP preserve all received bytes and modify only the first metric; fwdBatchHandler reaches Session.writeUpdateBody with AIGP enabled. Dropping, rewriting or accumulating the second metric would fail the exact assertions. The ownership fixture establishes admissible forwarded identity, not the RFC verdict; the socket octets establish the conditional whole obligation. Producer-halt records alone were not used as semantic proof.
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestRFC7311OtherAIGPTLVsPassedAlongUnchanged |
unit/verify | revert, verified |
| negative | TestAIGPWriteToMultipleTLVs |
unit/verify | unproven |
| positive | TestRFC7311OtherAIGPTLVsPassedAlongUnchanged |
unit/verify | revert, verified |
| positive | TestParseAIGPMultipleTLVs |
unit/verify | unproven |
| positive | TestRFC7311OtherAIGPTLVsSurviveTheCodec |
unit/verify | revert, verified |
RFC7311-3.2-4
If a BGP path attribute is received that has the AIGP attribute codepoint but also has the transitive bit set, the attribute MUST be considered to be a malformed AIGP attribute and MUST be discarded as specified in this section. (§3.2)
Audit verdict: enforced (the tests do what the requirement demands), fresh. Forbidden: keeping or passing along an AIGP whose transitive bit is set. TestRFC7606AIGPTransitiveIsDiscarded asserts Action==AttributeDiscard on code 26 with DiscardReasonMalformedValue and require.False(found) for AIGP after ApplyAttrDiscard, with ORIGIN, AS_PATH, NEXT_HOP intact; TestRFC7311AIGPTransitiveDiscardedOnReceive asserts the same through enforceRFC7606 with no error (discard, not reset). Positives with flags 0x80 assert RFC7606ActionNone and the AIGP bytes unchanged, so a codepoint-only check goes red.
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestRFC7606AIGPTransitiveIsDiscarded |
unit/verify | revert, verified |
| negative | TestRFC7311AIGPTransitiveDiscardedOnReceive |
unit/verify | revert, verified |
| positive | TestRFC7606AIGPNonTransitiveIsKept |
unit/verify | revert, verified |
| positive | TestRFC7311AIGPNonTransitiveKeptOnReceive |
unit/verify | revert, verified |
RFC7311-3.2-1
A BGP speaker MUST NOT add the AIGP attribute to any route whose path leads outside the AIGP administrative domain to which the BGP speaker belongs (§3.4.1)
Audit verdict: not audited: no reader has judged these tests
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestAIGPConfiguredOriginationRejectsOutsideDomain |
unit/verify | unproven |
| positive | TestAIGPConfiguredOriginationRejectsOutsideDomain |
unit/verify | unproven |
RFC7311-3.2-5
When receiving a BGP Update message containing a malformed AIGP attribute, the attribute MUST be treated exactly as if it were an unrecognized non-transitive attribute. That is, it "MUST be quietly ignored and not passed along to other BGP peers" (§3.2)
Audit verdict: enforced (the tests do what the requirement demands), fresh. Forbidden: acting on, or passing along, a malformed AIGP, or escalating beyond ignoring it. TestAIGPReceiveValidatesEveryTLV (IBGP, AIGP enabled) appends a truncated trailing TLV and asserts require.Equal(!malformed, present) on the payload leaving enforceRFC7606 (the bytes passed along), require.NoError (quietly, no session reset) and the NLRI kept (route not withdrawn). The well-formed half (unknown TLV plus duplicate metric) keeps the metric, so a blanket AIGP strip goes red.
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestAIGPReceiveValidatesEveryTLV |
unit/verify | unproven |
| positive | TestAIGPReceiveValidatesEveryTLV |
unit/verify | unproven |
RFC7311-3.2-6
Note that an AIGP attribute MUST NOT be considered to be malformed because it contains more than one TLV of a given type or because it contains TLVs of unknown types. (§3.2)
Audit verdict: enforced (the tests do what the requirement demands), fresh. Forbidden: judging an AIGP malformed for a repeated TLV type or an unknown TLV type. TestRFC7311DuplicateAndUnknownTLVsAreWellFormed parses two Type-1 TLVs and a Type-200 TLV with require.NoError, so rejecting either shape goes red; ParseAIGP and the receive validator validateAIGPAttr share AIGPMetricOffset. TestRFC7311MalformedVerdictIsForLengthOnly shows the malformed verdict exists (ErrMalformedValue on a Type-1 TLV of Length 8) and is lifted when only the length is repaired.
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestRFC7311MalformedVerdictIsForLengthOnly |
unit/verify | revert, verified |
| positive | TestRFC7311DuplicateAndUnknownTLVsAreWellFormed |
unit/verify | revert, verified |
RFC7311-3.3-1
An implementation that supports the AIGP attribute MUST support a per-session configuration item, AIGP_SESSION, that indicates whether the attribute is enabled or disabled for use on that session (§3.3)
Audit verdict: not audited: no reader has judged these tests
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestAIGPSessionReceiveBoundary |
unit/verify | unproven |
| positive | TestAIGPSessionReceiveBoundary |
unit/verify | unproven |
RFC7311-3.3-2
- For all other External BGP (EBGP) sessions, the default value of AIGP_SESSION MUST be "disabled". (§3.3)
Audit verdict: enforced (the tests do what the requirement demands), fresh. Forbidden: an EBGP (non-confederation) session defaulting AIGP_SESSION to enabled. TestAIGPSessionReceiveBoundary case external-default (peer AS 65002, local 65001, AIGPSession nil) asserts require.Equal(false, present) for AIGP after enforceRFC7606, which goes red on an enabled default; external-enabled shows the item is honoured when set; internal-default keeps AIGP, so the check is not a blanket strip.
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestAIGPSessionReceiveBoundary |
unit/verify | unproven |
| positive | TestAIGPSessionReceiveBoundary |
unit/verify | unproven |
RFC7311-3.3-3
The AIGP attribute MUST NOT be sent on any BGP session for which AIGP_SESSION is disabled (§3.3)
Audit verdict: not audited: no reader has judged these tests
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestAIGPFinalWriterBoundary |
unit/verify | revert, verified |
| positive | TestAIGPFinalWriterBoundary |
unit/verify | revert, verified |
RFC7311-3.3-4
If an AIGP attribute is received on a BGP session for which AIGP_SESSION is disabled, the attribute MUST be treated exactly as if it were an unrecognized non-transitive attribute (§3.3)
Audit verdict: not audited: no reader has judged these tests
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestAIGPSessionReceiveBoundary |
unit/verify | unproven |
| positive | TestAIGPSessionReceiveBoundary |
unit/verify | unproven |
RFC7311-3.4.1-1
An implementation that supports the AIGP attribute MUST support a configuration item, AIGP_ORIGINATE, that enables or disables its creation and attachment to routes (§3.4.1)
Audit verdict: not audited: no reader has judged these tests
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestAIGPOriginationControlsReachWire |
unit/verify | unproven |
| positive | TestAIGPOriginationControlsReachWire |
unit/verify | unproven |
RFC7311-3.4.1-2
The default value of AIGP_ORIGINATE MUST be "disabled" (§3.4.1)
Audit verdict: not audited: no reader has judged these tests
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestAIGPOriginationControlsReachWire |
unit/verify | unproven |
| positive | TestAIGPOriginationControlsReachWire |
unit/verify | unproven |
RFC7311-3.4.1-3
A BGP speaker R MUST NOT add the AIGP attribute to any route for which R does not set itself as the next hop (§3.4.1)
Audit verdict: not audited: no reader has judged these tests
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestAIGPOriginationControlsReachWire |
unit/verify | unproven |
| positive | TestAIGPOriginationControlsReachWire |
unit/verify | unproven |
RFC7311-3.4.3-1
If R1 does not change the next hop of the route, then R1 MUST NOT change the AIGP attribute value of the route (§3.4.3)
Audit verdict: not audited: no reader has judged these tests
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestAIGPForwardedMetricsReachFinalWire |
unit/verify | revert, verified |
| positive | TestAIGPForwardedMetricsReachFinalWire |
unit/verify | revert, verified |
RFC7311-3.4.3-2
In all the computations discussed in this section, the AIGP value MUST be capped at its maximum unsigned value 0xffffffffffffffff. (§3.4.3)
Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-12 (independent auditor). SHIFTED by 4e731b2d96 (owner-approved lint-only reactor test edits). The tagged unit is byte-identical (gate-verified); the file-level changes are comment punctuation, slices.Concat over the same bytes, joined appends, strings.SplitSeq, newDefaultOriginatePeer taking its fixed addresses from constants with the same values, and registerTypeLenRecognizer losing a lo every caller passed as 1, none of which changes what a helper this unit calls produces. Verdict stands. independently re-read RFC7311 §3.4.3, “In all the computations discussed in this section, the AIGP value MUST be capped at its maximum unsigned value 0xffffffffffffffff”; the four-carrier composition covers each accumulation site rather than merely testing Add—TestRFC7311DirectLinkCostNeverWrapsOrDisappears and TestAIGPForwardedMetricsReachFinalWire cover finite/overflowing source additions through applyFactsAIGP and the final writer, TestAIGPRecursiveDistanceUsesReceivedMetrics covers BGP-hop accumulation in igpcost.Resolve with exact finite 330/530 and overflowing maximum, and the corrected recursive-wire carrier covers terminal accumulation at MaxUint64−5 plus 7, source-only overflow at MaxUint64−50 plus 7 plus received 100, and exact 507 recovery after each; execution evidence inspected is Main's after.sh and job-aigp-wire-readiness-after-race20-bfa85e8a.log, showing controlled-overlay root20 plus ordinary changed-root20 and received-recursive-root20 with both depth subcases passing and status 0, while the original full-reactor census remains 2446 roots, 48919 passes and one failure—not a green full run The corrected controlled-schedule carrier passed twenty race iterations, and the ordinary corrected carrier and received-recursive companion each passed twenty race iterations in job-aigp-wire-readiness-after-race20-bfa85e8a.log. Native job-aigp-wire-readiness-native-renewals-391566bc.log successfully renews both polarities of both changed claims: Resolve for RFC7311-3.4.3-2 and readvertiseAIGP for RFC7311-3.4.3-7. These producer-halting bindings are distinct from the controlled-schedule synchronization proof. The original full-reactor run remains red; no whole-corpus freshness or terminal-IGP threshold implementation is claimed.
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestRFC7311DirectLinkCostNeverWrapsOrDisappears |
unit/verify | revert, verified |
| negative | TestAIGPForwardedMetricsReachFinalWire |
unit/verify | revert, verified |
| negative | TestRFC7311RecursiveAIGPChangeReachesWire |
unit/verify | revert, verified |
| negative | TestAIGPRecursiveDistanceUsesReceivedMetrics |
unit/verify | revert, verified |
| positive | TestRFC7311DirectLinkCostNeverWrapsOrDisappears |
unit/verify | revert, verified |
| positive | TestAIGPForwardedMetricsReachFinalWire |
unit/verify | revert, verified |
| positive | TestRFC7311RecursiveAIGPChangeReachesWire |
unit/verify | revert, verified |
| positive | TestAIGPRecursiveDistanceUsesReceivedMetrics |
unit/verify | revert, verified |
RFC7311-3.4.3-3
Increasing the AIGP value MUST NOT cause the value to wrap around (§3.4.3)
Audit verdict: not audited: no reader has judged these tests
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestAIGPForwardedMetricsReachFinalWire |
unit/verify | revert, verified |
| positive | TestAIGPForwardedMetricsReachFinalWire |
unit/verify | revert, verified |
RFC7311-3.4.3-4
If R1's route to R2 is either (a) an IGP-learned route or (b) a static route that does not require recursive next hop resolution, then R1 MUST increase the value of the AIGP TLV by adding to A the distance from R1 to R2. (§3.4.3)
Audit verdict: enforced (the tests do what the requirement demands), fresh. RFC 7311 Section 3.4.3: 'If R1's route to R2 is either (a) an IGP-learned route or (b) a static route that does not require recursive next hop resolution, then R1 MUST increase the value of the AIGP TLV by adding to A the distance from R1 to R2.' Read in its preceding next-hop-self condition and following policy-distance sentence. All three tagged units were re-read. TestAIGPForwardedMetricsReachFinalWire's interior case asserts final metric 130 from received 100 plus resolved 30 and asserts the announcement NLRI; its unchanged-next-hop case pins 100 despite policy replacement. TestAIGPRecursiveDistanceUsesReceivedMetrics proves actual resolver terminal metric 30 is counted once rather than following its gateway or importing BGP MED; TestAIGPRecursiveStaticDistance separately asserts nonrecursive static distance 25, recursive static distance 30 and unresolved refusal. Producers nhResolver.IGPMetric -> igpcost.Resolve and applyFactsAIGP -> aigpIncrement compose the resolved distance with the received metric; final forwarding writer keeps AIGP on an enabled session. The mocked distance in the socket carrier is not credited as resolver proof: the separately tagged actual-RIB tests supply it. Exact finite values, valid TLVs and transparent control isolate and discriminate both route classes and the conditional whole obligation.
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestAIGPForwardedMetricsReachFinalWire |
unit/verify | revert, verified |
| negative | TestAIGPRecursiveDistanceUsesReceivedMetrics |
unit/verify | unproven |
| negative | TestAIGPRecursiveStaticDistance |
unit/verify | unproven |
| positive | TestAIGPForwardedMetricsReachFinalWire |
unit/verify | revert, verified |
| positive | TestAIGPRecursiveDistanceUsesReceivedMetrics |
unit/verify | unproven |
| positive | TestAIGPRecursiveStaticDistance |
unit/verify | unproven |
RFC7311-3.4.3-5
A MUST be increased by a non-zero amount (§3.4.3)
Audit verdict: not audited: no reader has judged these tests
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestAIGPForwardedMetricsReachFinalWire |
unit/verify | revert, verified |
| positive | TestAIGPForwardedMetricsReachFinalWire |
unit/verify | revert, verified |
RFC7311-3.4.3-6
Then, when R1 changes the next hop of a route from R2 to R1, the AIGP TLV value MUST be increased by a non-zero amount. (§3.4.3)
Audit verdict: enforced (the tests do what the requirement demands), fresh. RFC 7311 Section 3.4.3: 'Then, when R1 changes the next hop of a route from R2 to R1, the AIGP TLV value MUST be increased by a non-zero amount.' Read with the preceding directly linked EBGP-neighbor/no-IGP condition. All four tagged units were re-read. TestRFC7311DirectLinkCostNeverWrapsOrDisappears and TestAIGPForwardedMetricsReachFinalWire assert configured-link sum 107 and a real withdrawal, not an attribute-free announcement, when no increment exists. TestRFC7311SourceLinkCostReachesRecipient exercises general ForwardUpdate and RS cached forwarding with source costs 7/19 versus destination cost 43; final AIGP bytes, next-hop-self bytes and exact NLRI pin 107/119, while transparent controls preserve 100. TestRFC7311UnknownCostWithdrawsUntilMetricRecovers asserts exact recipient withdrawal for missing/zero cost, both initially and after prior advertisement, then recovery as 111 from received 100 plus known 11. Producers sourceAIGPLinkMetric, forwardUpdateSection, aigpIncrement and applyFactsAIGP select the received-next-hop link, require nonzero direct cost and withhold rather than invent distance; final writer propagates their result. Fixtures rule out an IGP route for configured-link cases. Exact recipient outputs would fail omitted or destination-derived increments. The absent-cost withdrawal is the implementation's safe refusal, not an RFC mandate to withdraw; the required nonzero increment is proven on actual advertisements.
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestRFC7311DirectLinkCostNeverWrapsOrDisappears |
unit/verify | revert, verified |
| negative | TestAIGPForwardedMetricsReachFinalWire |
unit/verify | revert, verified |
| negative | TestRFC7311SourceLinkCostReachesRecipient |
unit/verify | revert, verified |
| negative | TestRFC7311UnknownCostWithdrawsUntilMetricRecovers |
unit/verify | revert, verified |
| positive | TestRFC7311DirectLinkCostNeverWrapsOrDisappears |
unit/verify | revert, verified |
| positive | TestAIGPForwardedMetricsReachFinalWire |
unit/verify | revert, verified |
| positive | TestRFC7311SourceLinkCostReachesRecipient |
unit/verify | revert, verified |
| positive | TestRFC7311UnknownCostWithdrawsUntilMetricRecovers |
unit/verify | revert, verified |
RFC7311-3.4.3-7
Any change due to (a) in any of these values MUST trigger a new AIGP computation for that route. (§3.4.3)
Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-12 (independent auditor) after owner-approved lint-only edits in 96ec49327b and 4e731b2d96; the row text is unchanged and each changed unit was re-read diff by diff. TestRFC7311ReceivedRecursiveAIGPChangeReachesWire joins two appends of the LOCAL_PREF and AIGP attribute headers into one append of the same bytes in the same order. No assertion changed. Verdict stands. independently re-read the whole requirement in RFC7311 §3.4.3, “Any change due to (a) in any of these values MUST trigger a new AIGP computation for that route”; the seven-carrier composition remains intact—TestAIGPDistanceChangeReselectsRetainedRoutes covers retained selection and unchanged-distance control, TestAIGPReadvertisesFromReceivedGeneration covers source retention beyond cache eviction and automatic terminal-distance replay, TestRFC7311RecursiveZeroCostRemainsAnnounced covers resolved-zero announcements, TestRFC7311ExtendedNextHopCostRecovery covers retained 16/32-octet next-hop recovery, TestAIGPRecursiveDistanceUsesReceivedMetrics covers actual recursive-resolution changes, the corrected TestRFC7311RecursiveAIGPChangeReachesWire covers automatic Loc-RIB-to-wire saturation/recovery from received 100, and TestRFC7311ReceivedRecursiveAIGPChangeReachesWire connects real received UPDATEs through registered plugins and rib_bestchange.go::checkRouteBestChange to that replay consumer, checking immediate/deeper-hop changes, unchanged received attributes, and the unrelated single-advertisement control; replayAIGP retains original received bytes, reactor_api_forward.go carries its replay identity, and forward_pool.go::fwdBatchHandler explicitly validates that identity before writing; no terminal-IGP threshold implementation or broader RFC completion is claimed. The corrected controlled-schedule carrier passed twenty race iterations, and the ordinary corrected carrier and received-recursive companion each passed twenty race iterations in job-aigp-wire-readiness-after-race20-bfa85e8a.log. Native job-aigp-wire-readiness-native-renewals-391566bc.log successfully renews both polarities of both changed claims: Resolve for RFC7311-3.4.3-2 and readvertiseAIGP for RFC7311-3.4.3-7. These producer-halting bindings are distinct from the controlled-schedule synchronization proof. The original full-reactor run remains red; no whole-corpus freshness or terminal-IGP threshold implementation is claimed.
RFC7311-4.1-1
Assuming that the BGP decision process invokes the tie-breaking procedures, the procedures in this section MUST be executed BEFORE any of the tie-breaking procedures described in [BGP], Section 9.1.2.2 are executed. (§4.1)
Audit verdict: enforced (the tests do what the requirement demands), fresh. Forbidden: running a Section 9.1.2.2 tie-breaker before the AIGP step. TestAIGPSelectsStoredRoutesBeforeASPath gives peer B the lower AIGP sum (20 plus 10) and the longer AS_PATH (3 versus 1); require.Equal(nhB, winner.NextHop) goes red if AS_PATH length, the first 9.1.2.2 tie-breaker, runs first. Negatives assert LOCAL_PREF (Section 9.1.1, not a tie-breaker) still wins before AIGP and that a missing AIGP is not metric zero.
| Polarity | Test | Kind and tier | Proof state |
|---|---|---|---|
| negative | TestAIGPSelectsStoredRoutesBeforeASPath |
unit/verify | unproven |
| positive | TestAIGPSelectsStoredRoutesBeforeASPath |
unit/verify | unproven |
Extraction sign-off
| Field | Value |
|---|---|
| Reviewer | claude |
| Signed off | 2026-09-21 |
| Register | rfc2119 |
| Source | rfc/full/rfc7311.txt |
| Source fingerprint | cfedbb96c63b8a55 |
| Record | rfc/extraction/rfc7311.json |
| Mapped sentences | 20 |
| Declined as scope | 2 |
| Relocated to a spec, which Ze OWES | 0 |
| Unclassified | 0 |
Sections
| Section | Name | Sites | Disposition | Reason |
|---|---|---|---|---|
front |
not stated | 0 | walked | not stated |
1 |
not stated | 0 | walked | not stated |
2 |
not stated | 0 | walked | not stated |
3 |
not stated | 1 | walked | not stated |
3.1 |
not stated | 0 | walked | not stated |
3.2 |
not stated | 4 | walked | not stated |
3.3 |
not stated | 5 | walked | not stated |
3.4 |
not stated | 0 | walked | not stated |
3.4.1 |
not stated | 4 | walked | not stated |
3.4.2 |
not stated | 0 | walked | not stated |
3.4.3 |
not stated | 7 | walked | not stated |
4 |
not stated | 0 | walked | not stated |
4.1 |
not stated | 1 | walked | not stated |
4.2 |
not stated | 0 | walked | not stated |
5 |
not stated | 0 | walked | not stated |
6 |
not stated | 0 | walked | not stated |
7 |
not stated | 0 | walked | not stated |
8 |
not stated | 0 | walked | not stated |
9 |
not stated | 0 | walked | not stated |
9.1 |
not stated | 0 | walked | not stated |
9.2 |
not stated | 0 | walked | not stated |
Excluded sentences
| Site | Excluded kind | Reason | Quote |
|---|---|---|---|
3.2:2 |
duplicate-ofnever bound Ze the same obligation is already captured under another requirement id |
The sentence opens "That is," and restates the preceding MUST of the same paragraph, quoting [BGP] Section 5; site 3.2:1 already maps that obligation. | That is, it "MUST be quietly ignored and not passed along to other BGP peers" (see [BGP], Section 5). |
3.3:5 |
duplicate-ofnever bound Ze the same obligation is already captured under another requirement id |
The sentence opens "That is," and restates the preceding MUST of the same paragraph, quoting [BGP] Section 5; site 3.3:4 already maps that obligation. | That is, it "MUST be quietly ignored and not passed along to other BGP peers" (see [BGP], Section 5). |
Superseded
No document obsoletes RFC 7311, so its obligations are stated where they were written.