<?xml version="1.0" encoding="US-ASCII"?>
<!-- This template is for creating an Internet Draft using xml2rfc,
    which is available here: http://xml.resource.org. -->

<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
        <!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
        <!ENTITY RFC2629 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2629.xml">
        <!ENTITY RFC3032 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3032.xml">
        <!ENTITY RFC3277 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3277.xml">
        <!ENTITY RFC3719 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3719.xml">
        <!ENTITY RFC4271 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4271.xml">
        <!ENTITY RFC5120 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5120.xml">
        <!ENTITY RFC5301 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5301.xml">
        <!ENTITY RFC5303 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5303.xml">
        <!ENTITY RFC5305 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5305.xml">
        <!ENTITY RFC5308 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5308.xml">
        <!ENTITY RFC5309 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5309.xml">
        <!ENTITY RFC5311 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5311.xml">
        <!ENTITY RFC5316 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5316.xml">
        <!ENTITY RFC5440 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5440.xml">
        <!ENTITY RFC5449 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5449.xml">
        <!ENTITY RFC5614 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5614.xml">
        <!ENTITY RFC5837 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5837.xml">
        <!ENTITY RFC5820 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5820.xml">
        <!ENTITY RFC6232 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6232.xml">
        <!ENTITY RFC7356 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7356.xml">
        <!ENTITY RFC7921 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7921.xml">
        <!ENTITY RFC8174 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8174.xml">
        <!ENTITY RFC8126 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8126.xml">
        <!ENTITY RFC8296 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8296.xml">
        ]>

<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<?rfc strict="yes" ?>
<?rfc toc="yes"?>
<?rfc tocdepth="4"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes" ?>
<?rfc compact="yes" ?>
<?rfc subcompact="no" ?>
<rfc category="exp" docName="draft-prz-lsr-ash-packets-08" ipr="trust200902">

    <!-- ***** FRONT MATTER ***** -->

    <front>

        <title>IS-IS Aggregated SNP Hash Packets</title>

        <author initials='T.' surname='Przygienda' fullname='Tony Przygienda'>
            <organization>HPE Juniper Networking</organization>
            <address>
                <email>antoni.przygienda@hpe.com</email>
            </address>
        </author>

        <author initials='T.' surname='Li' fullname='Tony Li'>
            <organization>HPE Juniper Networking</organization>
            <address>
                <email>anthony.li@hpe.com</email>
            </address>
        </author>

        <author initials='J.' surname='Halpern' fullname='Joel Halpern'>
            <organization>HPE Juniper Networking</organization>
            <address>
                <email>joel.halpern@hpe.com</email>
            </address>
        </author>
        <date/>

        <abstract>
            <t>
                The document presents an optional new type of database synchronization packet called an Aggregated
                SNP Hash (ASH). When feasible,
                it compresses
                traditional SNP exchanges into a dynamic Merkle tree-like structure, which speeds up synchronization of large
                databases and adjacency numbers while reducing the load from regular CSNP exchanges during normal
                operation. Just like CSNPs and PSNPs, ASH packets come in two flavors, called Complete ASH (CASH)
                and Partial ASH (PASH).
            </t>


        </abstract>

    </front>

    <middle>

        <section>
            <name>Introduction</name>

<!--            <t>-->
<!--                The document introduces an optional, new type of SNPs called Hierarchical SNP (ASH) that can-->
<!--                compress the traditional CSNPs exchange into a variant of merkle tree, hence-->
<!--                allowing to support fast synchronization of large databases and adjacency numbers while-->
<!--                lessening the load of periodic CSNP exchanges during steady state operation.-->

<!--                Mixture of parallel flooding, exchanging of CSNPs and a fitting ASH compression strategy-->
<!--                should lead to faster database re-synchronization-->
<!--                since only a subset of packets as compared to full scale CSNP exchange-->
<!--                is necessary to reconcile any entropy present. When using ASHs more of unnecessary flooding can be suppressed-->
<!--                while the mismatched fragments will be detected with less communication overhead as compared to-->
<!--                full CSNP exchanges.-->
<!--            </t>-->

            <t>
                The document introduces an optional new type of database synchronization packet called the Aggregated SNP Hash (ASH).
                It compresses and enhances
                traditional CSNP and SNP exchanges with a structure somewhat similar to a
                <xref target="MERKLE">dynamic Merkle tree</xref>,
                enabling faster synchronization of large
                databases and adjacency information while reducing the overhead of regular CSNP exchanges during
                steady state
                operation.

                By combining parallel flooding, SNP and ASH exchanges, database resynchronization
                can be accelerated because fewer packets (and not the entire CSNP set) are used to fix
                inconsistencies. Using ASHs also reduces unnecessary flooding and communication overhead, while still
                detecting mismatched fragments more efficiently than full CSNP exchanges.
            </t>

<!--            <t>-->
<!--                To keep the framework uniform we consider-->
<!--                the usual CSNP entries of LSPs simply a "as good as a perfect merkle hash" where we basically use lsp id, seq# and checksum-->
<!--                as "hash" and assume the 16 bits IS-IS fletcher checksum of the content never collides with other fragments. We add the PDU length-->
<!--                of the fragment for further entropy. Subsequently, we build a fletcher checksum on that data as-->
<!--                the fingerprint of the fragment and consider it its hash.-->
<!--                The hash summarizing hashes of all fragments of a node we consider as "node merkle hash". Range of such node merkle-->
<!--                hashes can be again summarized by a hash built over the according hashes.-->
<!--                We will call such hash a "node range merkle hash". For such hashes we do however-->
<!--                move away from fletcher checksums for reasons explained further in <xref target="hashfn"/>.-->

<!--            </t>-->

            <t>
                To maintain the Merkle analogy, we initially treat
                each SNP entry for an LSP as equivalent to an "as good as perfect" -
                though rather long -
                Merkle hash. In other words, the LSP ID, sequence number,
                and checksum act as a "collision-free fragment hash".
                We include the fragment's PDU length in this perfect hash to add
                more entropy in the next step.
                Lifetime is not used since it is
                not compared except in purge cases. The SNP entries then serve as the conceptual "bottom" of
                the Merkle tree.
            </t>

                <t>
                In the following step we compute a <xref target="SIPHASH"/> over the SNP entry
                data to create a shorter Merkle
                hash for each fragment. Somewhat surprisingly, these per-fragment hashes are never transmitted in packets,
                since doing so would effectively
                duplicate SNP functionality.
                However, the hash that aggregates all fragment hashes of a node becomes a "node Merkle hash". Groups
                of node hashes can then be summarized into a "node range Merkle hash" by combining the
                individual node hashes together. For the node and node range hashes,
                we switch from <xref target="SIPHASH"/> to a different hashing
                method, as explained in <xref target="hashfn"/>.
                    </t>
                <t>

                The resulting hierarchy of hashes enables large LSDB synchronizations using far fewer
                packets than CSNPs alone. Although the hashes summarize ranges recursively, the actual
                exchange resembles a <xref target="SKIP"/>-like process rather than
                maintaining a fixed tree structure, since the packets and ranges exchanged vary depending on where
                mismatches are found.
            </t>

            <t>
                This document limits itself to LSDB sizes on the order of 1E6 fragments
                and addresses considerations necessary to prevent overly
                garrulous exchanges
                of hashes covering progressively smaller sets of fragments. More details on the
                targeted IS-IS scale envelope can be found in <xref target="envelope"/>, and further
                considerations are summarized in
                <xref target="further"/>.
            </t>

            <t>
                ASH also changes the architecture of graceful restart to
                address the scaling limitations of <xref target="RFC8706"/>.
                Instead of concentrating overlapping database transfers and
                their reconciliation at the restarting router, ASH distributes
                recovery work among helpers under the restarting router's
                orchestration. This reduces redundant transfers and central
                processing as database size and the number of helpers grow,
                while retaining the existing adjacency-preservation and
                restart-signaling semantics. Additionally, it introduces an epoch based
                protection against overlapping restarts.
            </t>

            <t>
                The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>",
                "<bcp14>SHALL</bcp14>", "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>",
                "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
                "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
                described in BCP&nbsp;14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only
                when, they appear in all capitals, as shown here.
            </t>

            <section anchor="glossary">
                <name>Glossary</name>
                <t>
                    Since all confusion starts in language, we begin with
                    a precise glossary to express the solution space in
                    unambiguous terms.
                </t>
                <t>
                    CASH terminology is defined first; corresponding CSNP
                    terms refer to those definitions. Coverage, agreement,
                    terminal repair, and restart completion describe
                    separate properties.
                </t>
                <section anchor="glossary-database">
                <name>Database Objects and Scope</name>
                <dl>
                    <dt>Invalid System ID:</dt>
                    <dd>
                        The all-ones System ID (FFFF.FFFF.FFFF with the standard
                        six-octet length) is not a valid IS-IS node identifier.
                        It serves as an end marker: an all-ones End System ID
                        identifies C-CASH; an all-ones End LSP ID identifies
                        C-CSNP. Neither identifies a node to reconcile.
                        These endpoint values are distinct from the reserved
                        64-bit all-ones hash value.
                    </dd>
                    <dt>LSDB (Link State Database):</dt>
                    <dd>
                        A database of LSP fragments maintained for one IS-IS
                        level. ASH summarizes the non-purged fragments visible
                        on the circuit, using the same scope as ordinary CSNPs.
                    </dd>
                    <dt>LSP (Link State PDU):</dt>
                    <dd>
                        A link-state advertisement identified by an LSP ID.
                        Its sequence number and checksum distinguish
                        instances with the same LSP ID.
                    </dd>
                    <dt>Fragment:</dt>
                    <dd>
                        One individually identified LSP carrying part of an
                        originator's link-state information.
                    </dd>
                    <dt>System ID:</dt>
                    <dd>
                        A router identifier forming the system portion of an
                        LSP ID.
                    </dd>
                    <dt>Node:</dt>
                    <dd>
                        The ASH aggregation unit comprising all fragments
                        associated with one System ID, including its
                        pseudonodes.
                    </dd>
                    <dt>Pseudonode:</dt>
                    <dd>
                        An IS-IS representation of a broadcast network whose
                        LSPs are originated by the DIS. Its identifier
                        distinguishes it from the router's non-pseudonode
                        information under the same System ID.
                    </dd>
                    <dt>LSP ID:</dt>
                    <dd>
                        A fragment identifier consisting of a System ID,
                        pseudonode identifier, and fragment number. Unlike a
                        System ID alone, it identifies one fragment rather
                        than the whole ASH node.
                    </dd>
                    <dt>Purge:</dt>
                    <dd>
                        An LSP instance with zero remaining lifetime. Purges
                        use ordinary flooding and are excluded from ASH hash
                        computations.
                    </dd>
                    <dt>Active level:</dt>
                    <dd>
                        An IS-IS protocol level, Level 1 or Level 2,
                        participating on the adjacency. A common active level
                        is one at which both neighbors participate; database
                        summaries and reconciliation remain separate per level.
                    </dd>
                </dl>
                </section>
                <section anchor="glossary-packets">
                <name>Packets, Entries, and Capabilities</name>
                <dl>
                    <dt>PDU (Protocol Data Unit):</dt>
                    <dd>
                        A protocol packet.
                    </dd>
                    <dt>TLV (Type-Length-Value):</dt>
                    <dd>
                        A typed, length-delimited element carried within
                        a PDU.
                    </dd>
                    <dt>ASH (Aggregated SNP Hash):</dt>
                    <dd>
                        A database-reconciliation mechanism describing
                        node ranges with hashes. An ASH PDU
                        is either a CASH or a PASH.
                    </dd>
                    <dt>CASH (Complete ASH):</dt>
                    <dd>
                        An ASH PDU with Start and End System IDs delimiting
                        its coverage. Within those bounds, gaps between
                        advertised ranges indicate absence. Describing the
                        whole database may require more than one CASH PDU.
                        See <xref target="cash-format"/>. Analogous in
                        behavior to
                        CSNP.
                    </dd>
                    <dt>PASH (Partial ASH):</dt>
                    <dd>
                        An ASH PDU carrying independent node-range entries
                        without an enclosing packet coverage range. Unlike
                        CASH, gaps between its entries have no absence
                        semantics. It carries refinement hashes or terminal
                        repair directives. See <xref target="pash-format"/>.
                        Analogous in behavior to PSNP.
                    </dd>
                    <dt>SNP (Sequence Number PDU):</dt>
                    <dd>
                        An IS-IS database-reconciliation PDU describing
                        individual LSPs through LSP entries. Its two forms
                        are CSNP and PSNP.
                    </dd>
                    <dt>CSNP (Complete Sequence Number PDU):</dt>
                    <dd>
                        The SNP equivalent of CASH, describing individual
                        LSPs rather than node-range hashes. Its coverage is
                        delimited by Start and End LSP IDs. Describing the
                        whole database may require more than one CSNP PDU.
                        It is part of the existing and deployed IS-IS standard.
                    </dd>
                    <dt>PSNP (Partial Sequence Number PDU):</dt>
                    <dd>
                        The SNP equivalent of PASH, carrying individual LSP
                        entries used to request or acknowledge fragments.
                        Gaps between entries have no absence semantics.
                        It is part of the existing and deployed IS-IS standard.
                    </dd>
                    <dt>Node Range Hash Entry:</dt>
                    <dd>
                        A wire record containing inclusive Start and End
                        System IDs and a 64-bit hash field.
                    </dd>
                    <dt>Node Range Hash TLV:</dt>
                    <dd>
                        A TLV containing one or more Node Range Hash Entries.
                        A CASH or PASH can carry multiple such TLVs.
                    </dd>
                    <dt>IIH (IS-IS Hello):</dt>
                    <dd>
                        An adjacency-management PDU carrying, among other
                        information, ASH capability and restart signaling.
                        IIH is part of the existing and deployed IS-IS standard.
                    </dd>
                    <dt>ASH_RX:</dt>
                    <dd>
                        A Hello Capability flag advertising willingness
                        and ability to receive ASH. Carried in
                        <xref target="ID.draft-ginsberg-lsr-hello-capability-00"/>.
                    </dd>
                    <dt>ASH_TX:</dt>
                    <dd>
                        A Hello Capability flag advertising that the router
                        may originate ASH. It is independent of ASH_RX.
                        Carried in <xref target="ID.draft-ginsberg-lsr-hello-capability-00"/>.
                    </dd>
                </dl>
                </section>
                <section anchor="glossary-ranges">
                <name>Ranges, Hashes, and Repair</name>
                <dl>
                    <dt>Node range:</dt>
                    <dd>
                        An inclusive interval of System IDs,
                        covering all pseudonodes and fragments of each included
                        system for ASH comparison purposes.
                    </dd>
                    <dt>Singleton range:</dt>
                    <dd>
                        A node range with equal endpoints, covering exactly
                        one System ID and all its fragments for ASH comparison
                        purposes.
                    </dd>
                    <dt>More specific range:</dt>
                    <dd>
                        A proper subrange of another node range.
                    </dd>
                    <dt>Less specific range:</dt>
                    <dd>
                        A node range containing another range as a proper
                        subrange.
                    </dd>
                    <dt>Fragment Population:</dt>
                    <dd>
                        An advisory, one-octet encoded estimate of the number
                        of LSP fragments held by the sender in the advertised
                        node range. Zero denotes an empty range; nonzero
                        values give a logarithmic estimate no greater than
                        the actual population. It describes local holdings
                        independently of the advertised hash, including
                        when that hash is zero. See <xref target="cash-format"/>.
                    </dd>
                    <dt>Zero population:</dt>
                    <dd>
                        An advertised node range whose Fragment Population
                        field is zero, indicating that the sender holds no
                        LSP fragments in that range.
                    </dd>
                    <dt>Fragment hash:</dt>
                    <dd>
                        A 64-bit fingerprint computed from one fragment's
                        SNP description using <xref target="SIPHASH">siphash-1-3</xref>.
                    </dd>
                    <dt>Node hash:</dt>
                    <dd>
                        A fingerprint aggregating the fragment hashes of one
                        node (singleton range) using XOR (exclusive OR).
                    </dd>
                    <dt>Node range hash:</dt>
                    <dd>
                        A fingerprint aggregating the fragment hashes within
                        a node range using XOR. Reserved-value handling is
                        specified in <xref target="hashfn"/>.
                    </dd>
                    <dt>Merkle hash:</dt>
                    <dd>
                        The name used in this document for a node or node
                        range hash in the aggregation hierarchy.
                    </dd>
                    <dt>Zero hash (zero-hash directive):</dt>
                    <dd>
                        The hash-field value 0 in a valid Node Range Hash
                        Entry, directing terminal repair. It is a control
                        value, not a computed fingerprint: it is never
                        compared and establishes neither hash agreement nor
                        hash mismatch, even when the local range is empty.
                        On point-to-point circuits and from the DIS it
                        requests direct flooding; from a non-DIS to the DIS
                        it requests range-CSNP repair. Range validity is
                        checked before interpreting the directive.
                        See <xref target="rules"/>.
                    </dd>
                    <dt>Reserved all-ones hash:</dt>
                    <dd>
                        The 64-bit all-ones hash-field value, reserved
                        and excluded from transmission and hash comparison.
                    </dd>
                    <dt>Hash agreement:</dt>
                    <dd>
                        Equality between a valid advertised fingerprint and
                        the locally computed fingerprint for the same range,
                        after reserved-value handling. The zero-hash
                        directive is excluded from comparison.
                        During graceful restart, a matching hash for the
                        restarting router's isolated System ID retains its
                        ordinary meaning; a difference on that singleton
                        is ignored as specified in
                        <xref target="graceful-restart-procedures"/>.
                    </dd>
                    <dt>Hash mismatch:</dt>
                    <dd>
                        Inequality between a valid advertised fingerprint and
                        the locally computed fingerprint for the same range,
                        after reserved-value handling. The zero-hash
                        directive is excluded from comparison.
                        During graceful restart, a difference confined to
                        the restarting router's isolated System ID is
                        excluded from mismatch processing, as specified in
                        <xref target="graceful-restart-procedures"/>.
                    </dd>
                    <dt>Hash collision:</dt>
                    <dd>
                        Hash agreement despite different hashed contents.
                        Hash agreement therefore provides probabilistic
                        evidence of database agreement.
                    </dd>
                    <dt>Refinement:</dt>
                    <dd>
                        A reconciliation step that subdivides a mismatching
                        range into two or more more-specific ranges that
                        together cover the entire original range. Each
                        subrange is described by a hash or handled by
                        terminal repair.
                    </dd>
                    <dt>Terminal range:</dt>
                    <dd>
                        A node range selected for terminal repair following
                        a hash mismatch or a zero-hash directive.
                        It can cover any number
                        of valid System IDs.
                    </dd>
                    <dt>Terminal repair threshold:</dt>
                    <dd>
                        An implementation's criterion for selecting a
                        mismatching range as terminal.
                    </dd>
                    <dt>Terminal repair:</dt>
                    <dd>
                        A reconciliation step that resolves a terminal range
                        using ordinary IS-IS LSP and SNP procedures rather
                        than further hash subdivision. The circuit role and
                        graceful-restart helper exception determine which
                        repair actions apply. See
                        <xref target="terminal-repair"/> and
                        <xref target="broadcast-circuits"/>.
                    </dd>
                    <dt>Range CSNP (terminal-repair range CSNP):</dt>
                    <dd>
                        A CSNP, or series of CSNPs, used to repair a selected
                        terminal range. Its distinguishing property is its
                        repair purpose, not necessarily narrow coverage.
                        It does not signal a complete CSNP set for graceful
                        restart: its End LSP ID excludes the all-ones
                        complete-set marker, even when the selected range
                        includes the last valid System ID. See
                        <xref target="range-csnp-rules"/>.
                    </dd>
                    <dt>Flooding:</dt>
                    <dd>
                        Transmission of LSPs to neighbors using IS-IS
                        database-distribution procedures.
                    </dd>
                    <dt>Acknowledgement:</dt>
                    <dd>
                        Confirmation of receipt of an LSP instance.
                    </dd>
                    <dt>Retransmission:</dt>
                    <dd>
                        Repeated transmission of an unacknowledged LSP
                        instance.
                    </dd>
                </dl>
                </section>
                <section anchor="glossary-coverage">
                <name>Coverage, Trains, and Agreement</name>
                <dl>
                    <dt>CASH train:</dt>
                    <dd>
                        A set of CASHes describing the database at one
                        IS-IS level.
                    </dd>
                    <dt>C-CASH:</dt>
                    <dd>
                        A CASH with an all-ones End System ID, terminating
                        a CASH train. This name introduces no new PDU type
                        or flag bit.
                    </dd>
                    <dt>Complete CASH train:</dt>
                    <dd>
                        A CASH train whose PDU header ranges together cover
                        the entire System ID space without gaps, from the
                        all-zero Start System ID through the all-ones End
                        System ID of its closing C-CASH, including
                        unpopulated ranges.
                        Receipt of C-CASH alone does not prove receipt of
                        the complete train. Completeness describes coverage,
                        not hash agreement.
                    </dd>
                    <dt>CSNP train:</dt>
                    <dd>
                        The CSNP equivalent of a CASH train.
                    </dd>
                    <dt>C-CSNP:</dt>
                    <dd>
                        The CSNP equivalent of C-CASH, identified by an
                        all-ones End LSP ID.
                    </dd>
                    <dt>Complete CSNP train (complete CSNP set):</dt>
                    <dd>
                        The CSNP equivalent of a complete CASH train,
                        terminating with a C-CSNP.
                    </dd>
                    <dt>Database coverage:</dt>
                    <dd>
                        The portion of the System ID or LSP ID space
                        described by an advertisement at one level, including
                        unpopulated ranges. Whole-database coverage describes
                        every valid node.
                        Coverage is independent of hash agreement and of
                        whether a mismatching range is terminal.
                    </dd>
                    <dt>Complete matching CASH train:</dt>
                    <dd>
                        A complete CASH train received and compared in full,
                        whose comparisons establish agreement over every
                        covered range under the applicable procedures,
                        including the restarter singleton exception during
                        graceful restart. A zero-hash directive supplies no
                        agreement for its range.
                    </dd>
                    <dt>Inventory:</dt>
                    <dd>
                        The database contents described by a CASH train.
                        The term applies equivalently to a CSNP train.
                    </dd>
                </dl>
                </section>
                <section anchor="glossary-restart">
                <name>Adjacency Roles and Restart State</name>
                <dl>
                    <dt>DIS (Designated Intermediate System):</dt>
                    <dd>
                        The router elected per level on a broadcast circuit
                        to originate the pseudonode LSP, periodic CASH
                        advertisements, and terminal-repair range CSNPs.
                    </dd>
                    <dt>Non-DIS:</dt>
                    <dd>
                        Any other router on that broadcast circuit at
                        that level.
                    </dd>
                    <dt>GR (Graceful Restart):</dt>
                    <dd>
                        The IS-IS restart procedure of
                        <xref target="RFC8706"/>, preserving adjacencies
                        while the restarting router recovers protocol state.
                    </dd>
                    <dt>ASH graceful restart:</dt>
                    <dd>
                        The point-to-point GR variant defined here, using
                        CASH trains and helper snapshot completion.
                    </dd>
                    <dt>Restarting router (restarter):</dt>
                    <dd>
                        The router rebuilding its database during a restart
                        exchange.
                    </dd>
                    <dt>Helper:</dt>
                    <dd>
                        A neighbor retaining its database and providing
                        assistance to a restarting router.
                    </dd>
                    <dt>RR (Restart Request):</dt>
                    <dd>
                        The Restart TLV flag requesting restart assistance.
                        It is defined in <xref target="RFC8706"/> and retains
                        its semantics under ASH graceful restart.
                    </dd>
                    <dt>RA (Restart Acknowledgement):</dt>
                    <dd>
                        The Restart TLV flag acknowledging a restart request.
                        It is defined in <xref target="RFC8706"/> and retains
                        its semantics under ASH graceful restart.
                    </dd>
                    <dt>SA (Suppress Adjacency):</dt>
                    <dd>
                        The Restart TLV flag requesting suppression of
                        adjacency advertisement. ASH graceful restart here
                        applies to RR with SA clear.
                    </dd>
                    <dt>Restart epoch:</dt>
                    <dd>
                        A four-bit identifier associating restart signaling
                        and successive CASH trains with one restart exchange.
                    </dd>
                    <dt>ASH GR Suggested Epoch TLV:</dt>
                    <dd>
                        The IIH TLV carrying the restart epoch alongside
                        RR or RA.
                    </dd>
                    <dt>GR Control octet:</dt>
                    <dd>
                        The CASH header field carrying the restart epoch and
                        S bit. See <xref target="graceful-restart-wire"/>.
                    </dd>
                    <dt>S (Snapshot Served):</dt>
                    <dd>
                        The GR Control bit indicating that the helper's
                        snapshot has been served and its first CASH train
                        has finished. See
                        <xref target="graceful-restart-wire"/>.
                    </dd>
                    <dt>Helper snapshot:</dt>
                    <dd>
                        The logical set of LSPs captured by a helper when
                        acknowledging restart, per adjacency and level,
                        excluding fragments originated under the restarter's
                        System ID. It defines the helper's assistance work.
                    </dd>
                    <dt>Snapshot obligation:</dt>
                    <dd>
                        The requirement for a helper to transmit a snapshot
                        LSP toward the restarter or obtain validated evidence
                        that the restarter holds it. Queuing the LSP does not
                        satisfy the obligation.
                    </dd>
                    <dt>Snapshot sealing:</dt>
                    <dd>
                        Finalization of the helper's snapshot obligation
                        accounting when its first complete CASH train has
                        been transmitted. Sealing does not establish that
                        the obligations have been satisfied.
                    </dd>
                    <dt>Recovering database:</dt>
                    <dd>
                        The restarter's changing LSDB as it acquires LSPs
                        from its helpers and ordinary flooding.
                    </dd>
                    <dt>Snapshot served (snapshot completion):</dt>
                    <dd>
                        The helper-side condition in which every snapshot
                        obligation has been satisfied.
                    </dd>
                    <dt>Initial handshake completion:</dt>
                    <dd>
                        The restart stage requiring both RA and receipt of a
                        complete CASH train or complete CSNP set for every
                        active level. A complete CASH train can satisfy receipt
                        despite hash mismatches; a range CSNP cannot.
                        This stage permits RR to clear
                        but does not establish synchronization or end helper
                        assistance.
                    </dd>
                    <dt>Restart synchronization completion:</dt>
                    <dd>
                        The restart stage requiring the reconciliation
                        conditions on every participating adjacency and level.
                        For ASH, a complete matching helper train or valid S
                        supplies the reconciliation condition, without bypassing
                        the initial handshake; ordinary CSNP fallback follows
                        <xref target="RFC8706"/>. It is distinct from both
                        train receipt and a single helper's snapshot completion.
                        See <xref target="graceful-restart-procedures"/>.
                    </dd>
                    <dt>T1:</dt>
                    <dd>
                        The <xref target="RFC8706"/> timer governing
                        restart-request retransmission and the initial
                        handshake.
                    </dd>
                    <dt>T2:</dt>
                    <dd>
                        The <xref target="RFC8706"/> timer bounding database
                        resynchronization.
                    </dd>
                    <dt>T3:</dt>
                    <dd>
                        The <xref target="RFC8706"/> timer bounding adjacency
                        retention during restart.
                    </dd>
                </dl>
                </section>
            </section>
        </section>

        <section anchor="startexample">
            <name>Examples</name>
            <section anchor="example-plain-ash">
            <name>Plain ASH</name>
            <t>
                Before diving into precise technical details,
                an example will help introduce the concepts
                involved and demonstrate the behavior of an exchange.
            </t>
            <t> The exchange consists of initial CASH packets (analogous to CSNPs but carrying node range hashes)
                followed by
                PASH packets (analogous to PSNPs) that omit matching ranges and exchange hashes
                over progressively smaller ranges. Once a range reaches an implementation's terminal
                repair threshold, a range CSNP (or, when the node holds nothing in the
                range, a zero-hash PASH directive) synchronizes the databases in the
                traditional IS-IS manner, see <xref target="terminal-repair"/>. On broadcast
                circuits, the DIS sends the range CSNP, with non-DIS systems requesting it
                using a zero-hash PASH as specified in <xref target="broadcast-circuits"/>.
                A terminal range can
                cover one or more system IDs. ASH operates
                at the resolution of a system ID (including its pseudonodes), not individual fragments.
            </t>
            <t>
            The details of packet formats are provided later in <xref target="pash-format"/> and
            <xref target="cash-format"/>, and the procedures are defined in <xref target="rules"/>,
                but the example can be understood intuitively without those details.
                For the sake of readability the example encompasses only a database of roughly 3000 fragments
                over 100 nodes with about 10% of the database not synchronized on start. Details of PSNP packets
                exchanged are omitted for the same reason. The exact fragment counts shown are
                explanatory annotations; the wire format carries low-balling encoded population
                estimates as specified in <xref target="cash-format"/>.
            </t>

            <t>Initially, both nodes generate and exchange a CASH packet. Node 1 sends to Node 2 the CASH shown in
                <xref target="n1-cash"/>, containing
            node range hashes, some of which will disagree with the peer. An asterisk marks a range whose
            hash differs from the peer's.</t>

            <figure anchor="n1-cash">
                <artwork align="left" name="" type="" alt=""><![CDATA[
Node1->Node2 (initial CASH) -> 1 CASH packet(s)
Pkt   1 [0000.0000.0000 - FFFF.FFFF.FFFF] (  35 hashes):
1010.0000.0000 - 1010.0000.0001:   47 frags, hash=$ED6174261B52A218
1010.0000.0002 - 1010.0000.0002:  150 frags, hash=$BA8EC0FA6F86557A
1010.0000.0003 - 1010.0000.0006:   87 frags, hash=$2A7D5B4045D54F14
1010.0000.0007 - 1010.0000.0008:   34 frags, hash=$B15068FC7C4F044B
1010.0000.0009 - 1010.0000.000A:   85 frags, hash=$4396112BEAB62D20
1010.0000.000B - 1010.0000.000E:   88 frags, hash=$CCA15999A8BAA5E8 *
1010.0000.000F - 1010.0000.0014:   91 frags, hash=$04CA3A21161464F9 *
1010.0000.0015 - 1010.0000.0017:   79 frags, hash=$82039367F94F611C *
1010.0000.0018 - 1010.0000.001A:   61 frags, hash=$65D4C194A433D2A7
1010.0000.001B - 1010.0000.001C:   92 frags, hash=$5F8701B08AE39C2C
1010.0000.001D - 1010.0000.001F:   75 frags, hash=$0123DD370E42720C *
1010.0000.0020 - 1010.0000.0021:   39 frags, hash=$9CFF63C97F8C86D0
1010.0000.0022 - 1010.0000.0022:  155 frags, hash=$D1513B30C1F1D21D
1010.0000.0023 - 1010.0000.0026:   91 frags, hash=$51B443F4FE1B20DA *
1010.0000.0027 - 1010.0000.0029:   83 frags, hash=$44CEC7E1452B1855
1010.0000.002A - 1010.0000.002E:   86 frags, hash=$8F1B907E974094F3
1010.0000.002F - 1010.0000.0032:   89 frags, hash=$E2A31EC91DB1C4C3 *
1010.0000.0033 - 1010.0000.0036:   85 frags, hash=$E4D0AF41BA0BBDF1 *
1010.0000.0037 - 1010.0000.003B:   82 frags, hash=$13A40B0A950D7694
1010.0000.003C - 1010.0000.003C:   23 frags, hash=$DA7335371FB231CD
1010.0000.003D - 1010.0000.003D:   99 frags, hash=$D14266119B1003CD
1010.0000.003E - 1010.0000.003E:   34 frags, hash=$91D8522BD2EB0523
1010.0000.003F - 1010.0000.003F:   91 frags, hash=$9F206FAF8432046E
1010.0000.0040 - 1010.0000.0040:   88 frags, hash=$79441DDEE60A1F89
1010.0000.0041 - 1010.0000.0044:   87 frags, hash=$ED7F3899858D61EE
1010.0000.0045 - 1010.0000.0046:   22 frags, hash=$382CF99A031E42DE
1010.0000.0047 - 1010.0000.0047:  101 frags, hash=$10B9E7D282B7B8EF
1010.0000.0048 - 1010.0000.004B:   83 frags, hash=$AC0C721830474E1C
1010.0000.004C - 1010.0000.004D:   25 frags, hash=$501B59AE9A65ABC9 *
1010.0000.004E - 1010.0000.004E:  166 frags, hash=$4EF46668F1DD1A7B
1010.0000.004F - 1010.0000.0054:   90 frags, hash=$64362751D60995DA
1010.0000.0055 - 1010.0000.0059:   87 frags, hash=$2771634B6A78AACE
1010.0000.005A - 1010.0000.005C:   91 frags, hash=$E3F65D19CC13C7ED
1010.0000.005D - 1010.0000.0060:   84 frags, hash=$C3205BB177BB816E
1010.0000.0061 - 1010.0000.0063:   52 frags, hash=$D3500D0875EC4B66
]]></artwork>
            </figure>

            <t>Analogously, Node 2 sends an initial CASH with 33 hashes as shown in <xref target="n2-cash"/>.
                It may seem counter-intuitive that the ranges do not align, but this is natural since
                the databases themselves differ. <xref target="noderanges"/> addresses this effect in more
                detail.
            </t>

            <figure anchor="n2-cash">
                <artwork align="left" name="" type="" alt=""><![CDATA[
Node2->Node1 (initial CASH) -> 1 CASH packet(s)
Pkt   1 [0000.0000.0000 - FFFF.FFFF.FFFF] (  33 hashes):
1010.0000.0000 - 1010.0000.0001:   47 frags, hash=$ED6174261B52A218
1010.0000.0002 - 1010.0000.0002:  150 frags, hash=$B312CA61CDDAF08F
1010.0000.0003 - 1010.0000.0006:   87 frags, hash=$2A7D5B4045D54F14
1010.0000.0007 - 1010.0000.0008:   34 frags, hash=$B15068FC7C4F044B
1010.0000.0009 - 1010.0000.000A:   85 frags, hash=$134574F1DF91FBE5
1010.0000.000B - 1010.0000.000E:   88 frags, hash=$41DA43916CC90C52 *
1010.0000.000F - 1010.0000.0014:   91 frags, hash=$866969306096FD29 *
1010.0000.0015 - 1010.0000.0017:   79 frags, hash=$C2CEDFBA88080A3B *
1010.0000.0018 - 1010.0000.001A:   61 frags, hash=$65D4C194A433D2A7
1010.0000.001B - 1010.0000.001C:   92 frags, hash=$0BA9276510EE03CB
1010.0000.001D - 1010.0000.0021:   92 frags, hash=$4F5A632B673697BA *
1010.0000.0022 - 1010.0000.0022:  155 frags, hash=$6EDDFD41D8C4E0A6
1010.0000.0023 - 1010.0000.0026:   91 frags, hash=$2C2B89EF96A7C7C8 *
1010.0000.0027 - 1010.0000.0029:   83 frags, hash=$878C86D658B81FAD
1010.0000.002A - 1010.0000.002E:   86 frags, hash=$8F1B907E974094F3
1010.0000.002F - 1010.0000.0034:   81 frags, hash=$2684E1CAA3FB8EB7 *
1010.0000.0035 - 1010.0000.0038:   90 frags, hash=$6D1FAC454620D6BB
1010.0000.0039 - 1010.0000.003C:   67 frags, hash=$ADB300A6365F6360
1010.0000.003D - 1010.0000.003D:   99 frags, hash=$CDF517B289695626
1010.0000.003E - 1010.0000.003E:   34 frags, hash=$0365ED0461CA3EDC
1010.0000.003F - 1010.0000.003F:   91 frags, hash=$1EA9199FB3A12017
1010.0000.0040 - 1010.0000.0040:   88 frags, hash=$761D4D297B4BFA45
1010.0000.0041 - 1010.0000.0044:   87 frags, hash=$1C97513E233AD431
1010.0000.0045 - 1010.0000.0046:   22 frags, hash=$382CF99A031E42DE
1010.0000.0047 - 1010.0000.0047:  101 frags, hash=$022CA678714C04D5
1010.0000.0048 - 1010.0000.004B:   83 frags, hash=$AC0C721830474E1C
1010.0000.004C - 1010.0000.004D:   25 frags, hash=$AA9C89D8384E152E *
1010.0000.004E - 1010.0000.004E:  166 frags, hash=$D82B8A40F2F6B75D
1010.0000.004F - 1010.0000.0054:   90 frags, hash=$64362751D60995DA
1010.0000.0055 - 1010.0000.0059:   87 frags, hash=$2771634B6A78AACE
1010.0000.005A - 1010.0000.005C:   91 frags, hash=$10DAD5C8C452DDCB
1010.0000.005D - 1010.0000.0060:   84 frags, hash=$9316E89831EE599B
1010.0000.0061 - 1010.0000.0063:   52 frags, hash=$D3500D0875EC4B66
]]></artwork>
            </figure>

        <t>At this point both nodes take the range mismatches they detected and split them
            into smaller ranges. Ranges selected for terminal repair are resolved using
            range CSNPs and ordinary PSNP and LSP processing, or the zero-hash
            directive when locally empty, as specified in <xref target="terminal-repair"/>.
            This synchronization
            proceeds in parallel, independent of any further ASH exchanges.
            <xref target="n1-pash"/> shows an excerpt of a PASH that subdivides
            Node 2's mismatching range 1010.0000.001D through 1010.0000.0021.
            The two subranges cover that entire range; other refinement
            branches and terminal repairs are omitted.
        </t>


        <figure anchor="n1-pash">
            <artwork align="left" name="" type="" alt=""><![CDATA[
Node1 -> Node2 (after cuts) -> 1 PASH packet(s)
1010.0000.001D - 1010.0000.001F:   75 frags, hash=$0123DD370E42720C *
1010.0000.0020 - 1010.0000.0021:   39 frags, hash=$9CFF63C97F8C86D0
]]></artwork>
        </figure>

<t>
    Further mismatches are refined until they match or reach terminal repair.
    A singleton mismatch requires terminal repair because ASH cannot subdivide
    a System ID into individual fragments.
</t>
            <t>
                Only mismatching ranges require further exchange; matching ranges
                need no per-fragment inventory. The number of repair packets depends
                on the selected terminal ranges and their fragment populations.
            </t>
            </section>
            <section anchor="example-ash-gr">
            <name>ASH GR</name>
            <t>
                This example shows the simplest form of ASH graceful restart,
                with one restarting router Restarter and two helpers
                Helper1 and Helper2, each on a point-to-point adjacency
                with Restarter and with ASH
                fully negotiated. The helpers hold the same database:
                sixteen systems, each with one non-purged LSP fragment.
                Restarter's System ID is 0000.0000.0002.
                We assume no packet loss or
                database changes during the exchange. Restarter's System ID is
                isolated as specified in <xref target="graceful-restart"/>.
                Many optimizations in ASH GR are possible but not discussed or shown
                here for the sake of simplicity.
            </t>
            <t>
                Restarter sends an IIH with RR set, SA clear, and its restart epoch.
                Each helper acknowledges with RA and the same epoch and
                captures its helper snapshot. The example uses epoch 3.
                RR, RA, and the epoch signaling are explained in
                <xref target="graceful-restart-wire"/>.
                Each CASH train fits in one
                PDU with header bounds 0000.0000.0000 through
                FFFF.FFFF.FFFF; with that each PDU is also a C-CASH.
            </t>
            <t>
                Each helper sends its first complete CASH train with S
                clear. Sending its closing C-CASH seals that helper's
                snapshot obligation accounting, as explained in
                <xref target="graceful-restart-snapshot-service"/>. The S
                (Snapshot Served) bit is explained in
                <xref target="graceful-restart-wire"/>. In this example, both
                helpers queue their remaining snapshot LSPs for normal
                flooding and begin transmitting them to Restarter. Receipt of RA
                and a complete train from each helper satisfies Restarter's initial
                handshake requirements, but the mismatching hashes do not
                establish synchronization; these separate conditions are
                defined in <xref target="graceful-restart-procedures"/>.
                PEER MISMATCH below marks a hash differing from Restarter's local
                inventory. NO COMPARE marks Restarter's isolated System ID, whose
                hash difference is ignored during restart.
            </t>
            <figure>
                <artwork><![CDATA[
Helper1 -> Restarter: CASH / C-CASH, epoch=3, S=0
Header range: 0000.0000.0000 .. FFFF.FFFF.FFFF
Start           End             Hash
0000.0000.0001  0000.0000.0001   $8C3A6D21F907B45E  PEER MISMATCH
0000.0000.0002  0000.0000.0002   $52E8A1C73B9046DF  NO COMPARE
0000.0000.0003  0000.0000.0004   $6EB348F808C9AE4E  PEER MISMATCH
0000.0000.0005  0000.0000.0006   $A72D193C54E60B81  PEER MISMATCH
0000.0000.0007  0000.0000.0008   $D18F42A76C0935BE  PEER MISMATCH
0000.0000.0009  0000.0000.000A   $39C6B871E2A40F5D  PEER MISMATCH
0000.0000.000B  0000.0000.000D   $B4057E2D9A61C38F  PEER MISMATCH
0000.0000.000E  0000.0000.0010   $71DA03F6C82B954E  PEER MISMATCH
]]></artwork>
            </figure>
            <t>
                Restarter initially holds only its own fragment and sends the
                following nearly empty complete CASH train to each helper.
                Gaps within the CASH header bounds describe absent
                inventory, as specified in <xref target="cash-format"/>;
                no entries for the other systems are needed.
            </t>
            <figure>
                <artwork><![CDATA[
Restarter -> Helper1, Helper2: CASH / C-CASH, epoch=3, S=0
Header range: 0000.0000.0000 .. FFFF.FFFF.FFFF
Start           End             Hash
0000.0000.0002  0000.0000.0002   $E94B60D28A173CF5  NO COMPARE
]]></artwork>
            </figure>
            <t>
                Restarter's own hash differs from the helpers' copy. The difference
                is confined to Restarter's isolated singleton range, so neither
                side treats it as a mismatch requiring repair or preventing
                agreement analogous to normal GR. The other fifteen systems are absent at Restarter and
                remain subject to ordinary reconciliation. Repair requests
                for LSPs already queued by a helper add no further flooding
                work; helper-side terminal repair is explained in
                <xref target="graceful-restart-snapshot-service"/>.
            </t>
            <t>
                While flooding continues, Restarter receives the fragments for
                systems 0003 through 0006 from Helper1 and systems 0007 through
                000A from Helper2.
                In this simple example, Restarter has drained its own pending
                reconciliation work toward each helper and sends another periodic CASH,
                without waiting for the helpers' flooding to finish, as specified in
                <xref target="reconciliation-pacing"/>. This
                train describes its recovering database:
            </t>
            <figure>
                <artwork><![CDATA[
Restarter -> Helper1, Helper2: CASH / C-CASH, epoch=3, S=0
Header range: 0000.0000.0000 .. FFFF.FFFF.FFFF
Start           End             Hash
0000.0000.0002  0000.0000.0002   $E94B60D28A173CF5  NO COMPARE
0000.0000.0003  0000.0000.0006   $C99E51C45C2FA5CF  PEER MATCH
0000.0000.0007  0000.0000.000A   $E849FAD68EAD3AE3  PEER MATCH
]]></artwork>
            </figure>
            <t>
                At Helper1, the hash for systems 0007 through 000A now matches, although
                Helper1 has not yet transmitted those fragments to Restarter. This
                evidence of possession satisfies their snapshot obligations
                and cancels Helper1's pending flooding for them. Likewise, Helper2
                can cancel pending copies of systems 0003 through 0006.
                Satisfaction of snapshot obligations by evidence of
                possession is explained in
                <xref target="graceful-restart-snapshot-service"/>.
                The differences for system 0001 and systems 000B through
                0010 still require
                repair, but their LSPs are already queued. Their existing
                transmission resolves those terminal ranges.
                LSP acknowledgements and any required retransmissions
                follow ordinary IS-IS procedures.
            </t>
            <t>
                Once Helper1 transmits its last required snapshot LSP, all its
                snapshot obligations have been satisfied by transmission
                or evidence of possession. Helper1 sends a CASH notification
                with S set and the same restart epoch. Helper2 likewise signals
                S when its snapshot obligations have been satisfied.
                Neither helper waits for acknowledgements or retransmissions
                to finish before signaling Snapshot Served. Restarter accepts each
                helper's S and considers that adjacency synchronized.
                Restarter sends each helper a complete CASH train describing its
                database for final reconciliation.
                Helper's S signaling and the final CASH response are explained in
                <xref target="graceful-restart-wire"/> and
                <xref target="graceful-restart-final-response"/>, respectively.
            </t>
            <figure>
                <artwork><![CDATA[
Helper1 -> Restarter: CASH / C-CASH, epoch=3, S=1
Header range: 0000.0000.0000 .. FFFF.FFFF.FFFF
Start           End             Hash
0000.0000.0001  0000.0000.0001   $8C3A6D21F907B45E
0000.0000.0002  0000.0000.0002   $52E8A1C73B9046DF  NO COMPARE
0000.0000.0003  0000.0000.0004   $6EB348F808C9AE4E
0000.0000.0005  0000.0000.0006   $A72D193C54E60B81
0000.0000.0007  0000.0000.0008   $D18F42A76C0935BE
0000.0000.0009  0000.0000.000A   $39C6B871E2A40F5D
0000.0000.000B  0000.0000.000D   $B4057E2D9A61C38F
0000.0000.000E  0000.0000.0010   $71DA03F6C82B954E
]]></artwork>
            </figure>
            </section>
        </section>
        <!--
        <section anchor="partition">
            <name>Dynamic Partitioning</name>

            <t>
                In practical terms, the most interesting problem
                is figuring out how to divide the database into groups of leaf
                nodes (each representing a set of fragments) that both compress the data effectively compared to
                standard CSNPs and remain as stable as possible. If the fragment boundaries within each hash keep
                changing, neighboring systems will need to recalculate their hashes instead of reusing cached ones from
                their own Merkle tree, which adds unnecessary computation.

                The subdivision should also create enough "bins" to handle any distribution of fragment IDs across the
                network. This helps avoid pathological cases where all fragments might end up in a single hash, such as
                when e.g. a hashing function degrades. Ideally, when a hash mismatch occurs, it should take only one or
                two packets, with hashes for smaller fragment groups or regular CSNPs, to fix the difference.
                Reducing I/O and/or computation directly improves how quickly the systems synchronize.
            </t>

///            <t>
///                Practically speaking, the most interesting problem we encounter is the correct subdivision of the database into
///                collections of leaf nodes (set of fragments contained by such nodes)
///                that on one hand will provide a good compression vs. standard CSNPs,
///                on the other hand it changes as little as possible. In case the boundaries of fragments covered by
///                a hash change all the time, the neighbors receiving the
///                information
///                may have to recompute the hashes rather than relying on a cache representing its own merkle tree of such hashes.
///                The generated subdivision should also produce enough "bins" no matter the distribution of the fragment IDs
///                in the network. This is important to prevent such things as packing of all the fragments into a single hash when
///                e.g. a particular hash function degenerates. And ideally, a hash mismatch should produce not more than a
///                single packet or two with hashes covering less fragments or ultimately, CSNPs.
///                Rather obviously, minimizing necessary I/O and computation will improve re-convergence performance.
///            </t>


            <t>
                To begin, in IS-IS networks we can fit just under 100 SNP entries into the typical 1500-byte MTU frame.
                This is the consequence of each SNP entry including the Node ID, Fragment number, Sequence number, Checksum, and
                Lifetime fields - totaling 7 + 1 + 4 + 2 + 2 = 16 bytes per entry.
            </t>

///            <t>
///                To start our considerations, in IS-IS networks
///                we can fit into the prevailing 1500 bytes somewhat less than 100 of
///                PSNP entries for the foreseeable future. This is the consequence of
///                CSNP entries consuming Node ID + Fragment# + Seq# + CSUM + Lifetime
///                length which
///                amounts to 7 + 1 + 4 + 2 + 2 = 16 bytes each.
///            </t>


///            <t> Subsequently, fletcher hashes will occupy (as shown in <xref target="cash-format"/>) the length
///                of 6 + 6 + 6 = 18 bytes
///                per hash
///                and hence around 70 of those hashes fit into a packet. Deeper considerations how the
///                48-bits fletcher checksum and subsequent hashes size has been chosen can be found in
///                <xref target="collisions"/>.
///            </t>

            <t>
                <xref target="SIPHASH"/> hashes, as shown in <xref target="cash-format"/>, take up
                6 + 6 + 8 = 20 bytes each, which means that
                about 70 such hashes fit into a single packet. A more detailed explanation of why a 64-bit
                <xref target="SIPHASH"/> and the resulting hash sizes were chosen is provided in <xref target="collisions"/>.
            </t>

            <t>These limits form the basis for the recommended partitioning and packing strategies discussed later.</t>

            <t>
                At the lowest compression level, it is optimal to generate a single SNP packet on a mismatch in
                a hash. To achieve this, the first-level hashes should initially group about 80 LSP fragments
                together, with exceptions handled later. There is no need to maximize this initial packing.
                </t>

            <t>

                As the LSDB grows, it is better to leave some flexibility ("slack") in how fragments are grouped. This
                increases the likelihood that both sides of an adjacency will maintain the same leaf-level packing, even
                during flooding transitions, and prevents the ranges from shifting constantly.


///                At "lowest" compression level, it is desirable to produce one CSNP packet on a miss on the merkle hash
///                and hence such "first level" hashes should  pack initially 80
///                LSP fragments with exceptions following later. There is no need to maximize such "initial packing".
///                LSDB may grow and to
///                maximize the chances of the same "leaf packing" ranges on both sides
///                of an adjacency, even during flooding transitions, some
///                "slack" is advisable so the ranges don't move all the time.
            </t>

            <t>
///                The packing will always put all fragments of a system and its pseudonodes
///                into the same node range (which of course can exceed
///                the advisable 80 fragments sometimes) and a first order leaf will be considered "full" if addition
///                of next System ID fragments would exceed this size (except obviously, when the leaf is empty).
///                At such point the range may be included into a hash of a less specific range which however on
///                mismatch will force disaggregation and sending of less specific ranges.

                The packing process always places all fragments belonging to the same system and its pseudonodes within
                a single node Merkle hash. This hash may occasionally exceed the recommended size of 80 fragments. When
                it comes to node range hashes a
                hash is considered "full" when adding the next system's fragments would go beyond this
                limit. Unless, of course, the leaf is still empty.
                </t>
            <t>

                At that point, any range hash can be folded into a higher-level, less specific range hash. However,
                whenever a mismatch
                occurs at any level, the process must disaggregate the hash and send the corresponding smaller, more
                specific range or node hash instead as defined in <xref target="rules"/>.
            </t>
        
        -->

            <section anchor="noderanges">
            <name>Node Ranges</name>
<!--                <t>-->
<!--                    Instead or in addition to the "first level" packing a system can decide to pack "more densely".-->
<!--                    In such a mode, the ASH may include hashes that cover a much larger range than the-->
<!--                    first-level hashes. How this denser packing is implemented is left up to the specific implementation.-->
<!--                    </t>-->

<!--                <t>-->
<!--                    A good general approach is to increase packing density in parts of the database that have not changed,-->
<!--                    where no hash mismatches have been observed, or when it is reasonable to assume that the-->
<!--                    neighbor already holds a mostly synchronized database.-->
<!--                </t>-->

                <t>



                    When nodes advertise node range hashes to each other, it
                    would obviously be useful for cache-based implementations to agree on which ranges
                    to use, as this would make caching much more
                    effective. However, while this seems viable in theory, implementing it across many
                    interfaces would effectively require a global synchronization protocol - something impractical in a
                    network where nodes constantly add, remove, and update fragments asynchronously. These
                    ongoing changes continually shift what the "optimal" hash ranges are, and with enough churn, such
                    a range negotiation protocol might never converge.

                    </t>



                <t>
                    Alternatively, providing a fast way to reconstruct the Merkle hash for a "mismatched" range
                    reduces the need for perfect range alignment. Since hashes are built on system ID boundaries,
                    maintaining a Merkle hash per system ID allows a node to quickly
                    recompute the required hashes whenever received ranges differ from cached ones.

                </t>

<!--                <t>-->
<!--                    It is still highly preferable for advertised Merkle hash ranges to align on system ID boundaries as-->
<!--                    much as possible - especially at the top level. Under stable conditions, these top-level Merkle hashes-->
<!--                    significantly reduce the amount of CSNP exchange required, minimizing both packet volume and-->
<!--                    processing overhead.-->
<!--                </t>-->

                <t>As a second consideration, even though a fully stable network could in theory be represented by a single hash covering the
                    entire LSDB, doing so is neither desirable nor beneficial. Since an ASH packet must be sent anyway,
                    it is much better to fill it with as many range hashes as possible. This limits the
                    work required when a collision occurs within one of the ranges and also reduces the risk of
                    hash collisions, as discussed in <xref target="collisions"/>.

                    </t>


                <t>
                    In summary, a node should avoid compressing beyond the point where a single CASH covers the entire
                    database. Ideally, one ASH should contain at most about (MTU / Node Range Hash Entry Size)
                    hashes to keep collision probabilities low, as described in <xref target="collisions"/>.
                    Due to the efficiency of recomputing node range hashes on the fly, there is no need
                    to negotiate or agree on ranges with peers.
                </t>


                <!--
                <t>
                    To attempt to settle on the same ranges in ASHs an implementation of the suggested packing should let a
                    leaf that
                    drops under 50% occupancy "start robbing" system IDs from "left" of the next leaf until the current
                    leaf meets the "full condition". This is of course a recursive action that may ultimately generate
                    less leaves, remove some and in a recursive fashion lead to the same "greedy robbery from the left"
                    in the next level up. The "left" is colloquial here for starting with lowest System IDs under
                    normal sorting criteria.
                    On the other end of the spectrum a leaf that holds more than 150% of usual capacity (i.e. 80 * 1.5 LSPs or 60 * 1.5 Hashes)
                    should be preferably split into two leaves unless it holds a single System ID with more than 80 fragments.
                    Splitting the leaves may cause a repacking at a higher
                    level again in a recursive fashion.

                </t>
Claude (Anthropic) assisted in reviewing the draft specification, identifying ambiguities in zero-hash semantics, overlap handling, and PDU header-to-entry range
 relationships
                <t>
                    The rebalancing of ranges to agree across all nodes and hence reduce hashing load
                    is a trade-off in terms of possibly large recomputation vs. suffering a penalty of
                    recomputing some hashes on disagreeing ranges on every exchange. Other solutions are
                    of course possible such as internal caches that keep the recomputed hashes for the
                    neighbor's ranges.
                </t>

                <t>
                    Precise splitting/merging algorithms agreed upon increase the likelihood of nodes ending up on
                    precisely same ranges. A possibly
                    simpler idea to discuss is to simply "repack" the whole thing on some balance violations or
                    periodically. As example, the optimal dynamic programming algorithm for the problem of
                    optimal partitioning into capacity limited segments is well known.
                    Another idea is to simply use IS-IS fragment sliding but this may lead in worst
                    case to first level checksumming a single fragment over time.
</t>
                <t>
                    Overall, different partitioning and packing approaches are possible but if system ID
                    as natural partition is not used, this will likely change the packet
                    format since the partition boundaries will necessarily reflect which of the fragments are
                    covered by the hashes. Although, given that ordering of fragments has to be preserved it is hard to
                    imagine anything else but start and end consisting of fragment IDs.
                </t>

                -->

            </section>

        <section>
            <name>Hash Functions</name>
        <section>
            <name>Hash Function for a Fragment</name>
            <t>
                Each fragment generates a 64-bit <xref target="SIPHASH">siphash-1-3</xref> from
                its full SNP description. The salt key
                is given in <xref target="refcode"/>.

            </t>

            <t>
                If a fragment hash computes to zero or to the 64-bit all-ones value, the value
                <bcp14>MUST</bcp14> be replaced with the constant 1.
            </t>

            <t>
                To validate implementation correctness, a reference hash is provided in
                <xref target="reference-hash"/>.
            </t>

            <figure anchor="reference-hash">
                <artwork align="left" name="" type="" alt=""><![CDATA[
Hash Variant: Siphash-1-3:64Bits
Fragment ID: 0101:0101:0000.01-01
Seq# $0001
Csum: $0001
Len: 0512
Hash $6EB348F808C9AE4E
]]></artwork>
            </figure>

        </section>

        <section anchor="hashfn">
            <name>Fast, Incremental, Self-Inverse Hashing Function for Ranges</name>
            <t>
                Since large-scale deployments must compute significant numbers of hashes over sets of frequently changing
                fragments, it is highly desirable to use a specialized hash function that supports fast incremental
                updates when fragments are added, removed, or when their checksums change.
                </t>
            <t>
                Once hashes are built over sets of fragments, it is also beneficial to support very fast splitting and merging
                of such sets, especially when two hashes differ in which fragments they contain.
            </t>

            <t>
            Further discussion of such hashes can be found in
            <xref target="HASHES"/>,
            but the design space is
            simplified here since cryptographic security is not a concern.
            </t>


            <t>
                The hash for a set of fragments is computed by XOR'ing their individual fragment hashes. This makes
                it straightforward and very fast
                to update the hash when a fragment is added, removed, or its checksum changes. As a
                result, less specific ranges can quickly derive their raw aggregate by
                XOR'ing the raw aggregates of disjoint more specific ranges that
                together cover them, when those are available.

<!--                The hash function for sets of fragments is a very fast XOR operation of their fletcher hashes.-->
<!--                This allows to update the hash when adding, removing a leaf or-->
<!--                changing its checksum-->
<!--                in a very fast and simple manner. This also implies that less specific ranges can very quickly-->
<!--                compute their hash by XOR'ing all included more specific ranges if such hashes are available.-->
            </t>

            <!--
            <t>
                Ultimately, and fairly obviously, third order hash uses second order hash logic to keep its hash.
                This all means that every time a first order leaf changes the
                contained system IDs for
                some reason the merkle hashes will have to be readjusted recursively in according 2nd and third
                order leaves. This is in itself nothing
                particular since
                <em>any</em>
                change on first order leaf hash forces change on second order and consequently third order leaf hash.
                This is how Merkle
                trees work after all.
            </t>
            -->

            <t>
                Each fragment hash has already undergone reserved-value replacement.
                XOR'ing such hashes can nevertheless produce zero or all-ones,
                so the completed range hash requires a separate replacement step.
            </t>
            <t>
                Range aggregation, splitting, and incremental updates
                <bcp14>MUST</bcp14> use raw XOR aggregates of the fragment
                hashes defined above, before range-level reserved-value replacement.
                The replacement below applies only to the final range value
                used for comparison or advertisement. A remapped node or range
                value <bcp14>MUST NOT</bcp14> be used in place of its raw
                aggregate when computing another range.
            </t>
            <t>
                For a non-empty range, if a node range hash computes to zero or to the 64-bit
                all-ones value, the value <bcp14>MUST</bcp14> be replaced with the constant 1.
                Zero is reserved for the terminal wire directive described in
                <xref target="rules"/>. The all-ones value is reserved and
                <bcp14>MUST NOT</bcp14> be transmitted.
            </t>
        </section>
    </section>

        <section>
            <name>Procedures</name>
            <section>
            <name>ASH Support Negotiation</name>
                <t>
                    Rather than defining a new, dedicated IIH TLV, support for ASH is negotiated
                    using the generic Hello Capability TLV defined in <xref target="ID.draft-ginsberg-lsr-hello-capability-00"/>.
                    This document requests allocation of two bits (Bits TBD) from the "IS-IS Bit
                    Values for Hello Capability TLV Flags" registry created by that document; see
                    <xref target="IGP_IANA"/>:
                </t>
                <t>
                    <list style="symbols">
                        <t><spanx style="strong">ASH_RX</spanx> ("ASH Reception Capable"): the
                        advertising node is willing and able to receive and process CASH/PASH
                        packets on this adjacency in place of CSNPs/PSNPs.</t>
                        <t><spanx style="strong">ASH_TX</spanx> ("ASH Transmission Capable"): the
                        advertising node may originate CASH/PASH packets on this adjacency in
                        place of CSNPs/PSNPs.</t>
                    </list>
                </t>
                <t>
                    A single combined "ASH capable" bit was considered and rejected in favor of
                    these two independent bits: implementations commonly wish to enable ASH
                    asymmetrically, for example decoding and verifying received ASH packets from
                    a peer while still originating ordinary CSNPs/PSNPs itself (a conservative or
                    "canary" rollout of newly written decode logic), or the converse. A single bit
                    cannot convey to the peer which direction(s) are actually safe or expected,
                    whereas two independent bits let each side advertise exactly what it will
                    accept and what it may send.
                </t>
                <t>
                    A node <bcp14>MUST NOT</bcp14> originate CASH/PASH packets on an adjacency
                    unless the peer has most recently advertised <spanx style="strong">ASH_RX</spanx>
                    on that adjacency. A node <bcp14>MUST</bcp14> treat an adjacency as not ASH
                    capable for reception and fall back to ordinary CSNP/PSNP processing
                    whenever it has not itself advertised <spanx style="strong">ASH_RX</spanx>,
                    regardless of what the peer sends. Receipt of a CASH/PASH packet while
                    <spanx style="strong">ASH_RX</spanx> is not being advertised is anomalous input
                    and <bcp14>MUST NOT</bcp14> be treated as fatal to the adjacency. The
                    implementation <bcp14>SHOULD</bcp14> log the event and fall back to requesting a full
                    CSNP/LSP resynchronization on that adjacency. Loss of the peer's Hello
                    Capability TLV (adjacency restart, or a peer that does not implement
                    <xref target="ID.draft-ginsberg-lsr-hello-capability-00"/> at all) is
                    equivalent to both bits being clear.
                </t>
                <t>
                    On broadcast circuits, each level's IIH is a distinct PDU, so the two bits are
                    advertised, and can differ, independently per level. On point-to-point
                    circuits a single IIH is shared by whichever levels are enabled on that
                    circuit; the Hello Capability TLV of
                    <xref target="ID.draft-ginsberg-lsr-hello-capability-00"/> is not level-scoped,
                    so on a point-to-point circuit running both Level 1 and Level 2,
                    <spanx style="strong">ASH_RX</spanx> and <spanx style="strong">ASH_TX</spanx>
                    necessarily apply identically to both levels; an implementation
                    <bcp14>MUST NOT</bcp14> attempt to advertise or negotiate them differently per
                    level on such a circuit.
                </t>
                <t>
                    No additional capability information (sub-TLVs) is defined by this document
                    at this time; future extensions may make use of the sub-TLV mechanism of
                    <xref target="ID.draft-ginsberg-lsr-hello-capability-00"/> to advertise
                    additional ASH-related capability information.
                </t>
            </section>

            <section>
            <name>Advertising and Receiving CASHes</name>
                <t>
                    Advertising of standard CSNPs is extended or replaced
                    with CASH advertisements when this feature is supported. Analogous to CSNPs,
                    CASHes are sent periodically at a configured interval.
                    Since
                    both CSNPs and CASHes carry range information in their headers, they can be freely mixed, depending
                    on which level of fragment "compression" best fits the situation. In practice, sufficiently specific
                    range mismatches will naturally fall back to SNP exchanges or flooding to resolve remaining
                    differences.
<!--                    -->
<!--                    Advertising normal CSNPs is augmented with advertisement of ASHs when this feature is supported.-->
<!--                    Since both CSNP and ASHs advertise "range" in their headers they can even be-->
<!--                    randomly mixed depending what level of "compression" of fragments is best suited to the situation-->
<!--                    and range mismatches specific enough will end up to CSNP exchanges or flooding.-->
                </t>





<!--                    -->
<!--                    The node sending such an entry SHOULD send according CSNPs before the according ASH packet.-->
<!--                    Observe that in the case the receiving node computed the "real" XOR'ed ASH hash of the fragments of such-->
<!--                    range as resulting in a 0 value, it MUST still treat the received ASH hash as "mismatch" to prevent-->
<!--                    a stable "hole" in the database on the peer.-->


<!--                    Any node IDs not covered by ranges in the packet either due to "holes" between the advertised-->
<!--                    ranges or holes between contained ranges and the Start and End System ID of the ASH MUST be considered-->
<!--                    as missing.-->
<!--                    Consequently, in case a node detects that it holds Merkle hashes for LSPs that are not covered by the-->
<!--                    received ASH, it MUST trigger the same behavior as triggered by CSNP with this condition,-->
<!--                    i.e. flood the missing LSPs.-->


<!--                    -->
<!--                    As is the case with CSNPs the ASH containing in its first range the first node of the-->
<!--                    database MUST indicate in its packet range 0000.0000.0000 as start system ID to-->
<!--                    allow detection of missing nodes. Analogous behavior applies to ASH carrying hash-->
<!--                    covering the last node of the database.-->


<!--                <t>-->
<!--                    When a node receives ASHs with Merkle hash ranges, it MUST either compute-->
<!--                    and verify the hashes for the indicated ranges and in case of mismatch -->
<!--                    send more specific hashes for that range - in other-->
<!--                    words, "disaggregate". Disaggregation is less preferable, however, because if both sides repeatedly-->
<!--                    do this for wide mismatched ranges, it can lead to a ping-pong effect that ultimately falls back to-->
<!--                    full CSNP exchanges.-->
<!--                    -->
<!--                    In case a node receives ASHs where the merkle hash ranges are not the same, the node MUST-->
<!--                    either compute and verify the hashes over the ranges indicated or-->
<!--                    send more specific hashes for the range or in other words "disaggregate". The disaggregation is-->
<!--                    less preferred since in case of  mismatches over wide ranges both sides-->
<!--                    using this strategy end up ultimately in a 'ping-pong' ending with CSNPs.-->
<!--                </t>-->




            </section>

            <section>
            <name>Advertising and Receiving PASHes</name>
                <t>Where PSNPs are used, PASHes may extend or substitute the exchange as long as the rules of
                    <xref target="rules"/> are followed.
                </t>
            </section>

            <section anchor="rules">
            <name>Refinement Rules</name>
            <t>
                ASH exchanges are per-level, analogous to CSNP/PSNP exchanges.  CASH and PASH
                packets are scoped to the IS-IS level (Level 1 or Level 2) of the adjacency on which they
                are sent, just as CSNPs are.
            </t>
            <t>
                Fragments in purge state (remaining lifetime of zero) are NOT included in ASH hash
                computations, consistent with the treatment of purges in CSNP exchanges.  Purges are
                handled through normal IS-IS flooding procedures independently of ASH.
            </t>
            <t>
                The set of fragments covered by the ASHes sent on a circuit <bcp14>MUST</bcp14> be
                the same set that a CSNP sent on that circuit would describe.  An implementation that
                restricts per circuit which LSPs it floods and advertises in CSNPs (e.g., by area
                address) <bcp14>MUST</bcp14> either compute the ASHes over that restricted set or
                <bcp14>MUST NOT</bcp14> send ASHes on that circuit.
            </t>
            <t>
                When a node receives an ASH where any of the contained hashes
                does not match after recomputation or comparison, it <bcp14>MUST</bcp14>
                 send PASHes with Merkle hashes covering the mismatched ranges. These new hashes <bcp14>MUST</bcp14> be
                more specific than the range where the mismatch occurred.
            </t>
            <t>

                Alternatively, instead of more specific PASH hashes,
                a node <bcp14>MAY</bcp14> treat the mismatched range as a terminal range and
                repair it immediately as specified in <xref target="terminal-repair"/>. This may be
                preferable when the mismatch affects only a small number of LSPs.

                </t>
            <t>
                When refinement reaches a range that has no matching non-purged fragments in the local
                database, silence is not sufficient: independently selected range boundaries can prevent
                the remote node from reaching the same terminal range. The node <bcp14>MUST</bcp14>
                therefore send a PASH entry for the valid, non-inverted range with its hash set to zero
                on a point-to-point circuit. Broadcast circuits instead follow the role-directed
                procedures in <xref target="broadcast-circuits"/>.
            </t>
            <t>
                A zero hash in a CASH or PASH entry is a terminal repair directive, not a hash mismatch to refine
                further. Range validity is checked before interpreting the hash: an entry whose Range End
                is smaller than its Range Start <bcp14>MUST</bcp14> be discarded even when its hash is
                zero. For a valid zero-hash entry, a receiver <bcp14>MUST NOT</bcp14> compare or subdivide
                the range.
                If it holds non-purged fragments in the indicated range, it <bcp14>MUST</bcp14>
                send every such fragment using normal IS-IS flooding procedures. It
                <bcp14>MUST NOT</bcp14> answer the directive only with a PSNP, because that would add a
                redundant request/response round before the same fragments are flooded. If it holds no
                such fragments, it <bcp14>MUST</bcp14> silently ignore the directive: it
                <bcp14>MUST NOT</bcp14> answer with a PASH entry for the range, including a zero-hash
                entry, and <bcp14>MUST NOT</bcp14> refine the range further. It <bcp14>MAY</bcp14>
                instead send an empty range CSNP covering the range, following
                <xref target="range-csnp-rules"/>. On broadcast circuits, a zero-hash entry from
                a non-DIS to the DIS is a range-CSNP request instead, handled as specified in
                <xref target="broadcast-circuits"/>.
            </t>
            <t>
                The value zero is reserved and <bcp14>MUST NOT</bcp14> be emitted as the result of any
                fragment-hash computation or any non-empty range-hash computation. In a valid Node Range
                Hash Entry, zero is a terminal repair directive, never a computed hash. On a
                point-to-point circuit, and when sent by the DIS on a broadcast circuit, it
                requests direct flooding by the receiver, independently of the sender's
                holdings indicated by Fragment Population. When sent by a
                non-DIS to the DIS, it requests range-CSNP repair as specified in
                <xref target="broadcast-circuits"/>, regardless of the non-DIS's holdings.
                It does not make an otherwise malformed range valid.
            </t>
            <t>
                The all-ones value is reserved and <bcp14>MUST NOT</bcp14> be transmitted.
            </t>

            <!--                <t>-->
            <!--                    -->
            <!--                    A node receiving an ASH where any of the hashes received does not match on recomputation or-->
            <!--                    comparison the result of its own hash-->
            <!--                    MUST send immediately ASHs with Merkle hashes covering the-->
            <!--                    ranges where the hash mismatch was detected. The sent hashes MUST be more specific than-->
            <!--                    the range where the collison occurred.-->
            <!--                    Alternately, a node MAY choose to-->
            <!--                    immediately send according CSNPs, PSNPs or flood the LSPs that have been detected-->
            <!--                    as not matching the merkle hashes. Sending CSNPs or immediate flooding-->
            <!--                    may be preferable if the mismatch-->
            <!--                    covers relatively few LSPs. </t>-->

            <t>
                An implementation <bcp14>MAY</bcp14> stop refinement when a mismatching range
                contains sufficiently few locally held fragments, even when the range covers more than
                one system ID. Broadcast circuits follow <xref target="broadcast-circuits"/>.
                On a point-to-point circuit, if it holds none of the fragments in that terminal range, it
                <bcp14>MUST</bcp14> send the zero-hash directive specified above. If it holds
                fragments in the range, it <bcp14>MUST</bcp14> repair the range as specified in
                <xref target="terminal-repair"/>.

                <!--                        In case of mismatch or no computation available for a hash covering only a single node-->
                <!--                        (with its pnodes) or mismatch on a hash covering less than a CSNP PDU full of fragments,-->
                <!--                        a CSNP MUST be sent or alternately the node MAY choose to flood those fragments.-->
            </t>

            <section anchor="terminal-repair">
            <name>Terminal Range Repair on Point-to-Point Circuits</name>
            <t>
                On a point-to-point circuit, when a valid received CASH or PASH entry
                explicitly advertises zero Fragment Population for a
                mismatching range, the receiver <bcp14>MAY</bcp14> omit
                the range CSNP and directly flood its locally held,
                non-purged fragments within that range. The peer has no
                inventory to contribute for the advertised range. This
                exception does not apply to broadcast circuits or to
                ranges outside the advertised boundaries. A zero
                population accompanied by a nonzero hash
                <bcp14>MUST</bcp14> be treated as a zero hash, and the
                receiver <bcp14>SHOULD</bcp14> report the inconsistency.
                This exception does not suppress required ordinary
                flooding, acknowledgements, or retransmissions.
            </t>
            <t>
                A gap within valid CASH header bounds supplies the same
                empty-inventory information implicitly, as specified in
                <xref target="cash-format"/>. It receives the same
                zero-hash directive processing; no explicit wire entry is
                needed to trigger direct flooding.
            </t>
            <t>
                An empty-population advertisement does not satisfy
                graceful-restart snapshot obligations. If repair omits the range
                CSNP and directly floods local fragments, every required
                snapshot LSP <bcp14>MUST</bcp14> still have actually been
                transmitted toward the restarter, or be covered by validated
                evidence of possession, before the helper signals Snapshot
                Served (S). Neither the empty advertisement nor merely queuing
                the resulting flood is such evidence. The restart epoch and
                completion requirements in <xref target="graceful-restart"/>
                remain unchanged.
            </t>
            <t>
                These procedures apply except for the helper-side
                graceful-restart exception in <xref target="graceful-restart"/>.
            </t>
            <t>
                Only one neighbor may select a range for terminal repair, so
                its action must reconcile both directions. Except for an
                explicitly empty peer range as specified above, a range CSNP reveals
                locally absent fragments as well as those held; PSNPs or
                flooding alone do not.
            </t>
            <t>
                When a node performs terminal repair for a range in which it
                holds non-purged fragments, it <bcp14>MUST</bcp14> send a
                range CSNP covering the terminal range and listing every non-purged fragment it
                holds in that range, unless it uses the zero-population
                entry exception above. Otherwise, it <bcp14>MUST NOT</bcp14> repair such a range with PSNPs or by
                flooding its own fragments alone. It <bcp14>MAY</bcp14> additionally flood its
                fragments in the range. If it holds none, it
                <bcp14>MUST</bcp14> send the zero-hash PASH directive
                specified in <xref target="rules"/>.
            </t>
            <t anchor="range-csnp-rules">
                The following rules apply to range CSNPs:
            </t>
            <ul>
                <li>
                    The Start and End LSP IDs <bcp14>MUST</bcp14> lie within, or on the boundaries
                    of, the terminal range: the first LSP ID of its lowest system ID through the last LSP
                    ID of its highest system ID. When the listed fragments do not fit into one PDU, the
                    range is covered by a series of CSNPs with consecutive, non-overlapping LSP ID
                    ranges, as for periodic CSNPs.
                </li>
                <li>
                    A node <bcp14>MAY</bcp14> combine terminal ranges that are contiguous or overlapping
                    into one range CSNP or series. It <bcp14>SHOULD NOT</bcp14> extend a range CSNP over
                    system IDs outside the ranges found mismatching.
                </li>
                <li>
                    A sender <bcp14>MUST NOT</bcp14> use C-CSNP for terminal
                    repair. If the range reaches the all-ones End LSP ID, it
                    ends at the preceding LSP ID instead and directly floods
                    the excluded fragment if held. A receiver
                    <bcp14>MUST NOT</bcp14> treat a range CSNP as completing
                    the <xref target="RFC8706"/> database-summary receipt
                    requirement.
                </li>
                <li>
                    Range CSNPs are sent only on adjacencies using ASH and
                    processed using ordinary IS-IS CSNP procedures.
                </li>
            </ul>
            <t>
                Broadcast circuits follow <xref target="broadcast-circuits"/>.
            </t>
            </section>
            <section anchor="reconciliation-pacing">
            <name>Reconciliation Pacing and Amplification Avoidance</name>
                <t>
                    A node that detects a mismatch in a received CASH refines the disputed range with
                    progressively more specific PASHes until the hashes match or refinement reaches a
                    range that requires normal SNP exchange or flooding (see <xref target="rules"/>).
                    The PASH refinement and the subsequent repair form one reconciliation attempt.
                    For a sender, a reconciliation remains pending while it has PASHes
                    or PSNPs to send to that peer, or while its own LSP transmissions
                    or retransmissions toward that peer resulting from that reconciliation
                    remain outstanding.
                </t>
                <t>
                    A new periodic CASH sent while a previous reconciliation remains pending typically
                    rediscovers the same disagreement and starts an overlapping refinement. Two overlapping
                    attempts can produce roughly twice the PASH, PSNP, and LSP traffic of one; additional
                    attempts increase the traffic further without a natural bound. In a
                    ~6,700-fragment/40-node experiment, overlapping attempts generated PSNP requests equal
                    to roughly five times the total fragment count, with the count still increasing when
                    observed. The amplification resulted from overlapping reconciliation attempts rather
                    than from the topology scale or hash function.
                </t>
                <t>
                    For each peer and level, a node <bcp14>MUST</bcp14> limit reconciliation to one attempt at a time.
                    The node <bcp14>MUST NOT</bcp14> send a new periodic CASH while its own PASHes or PSNPs from the previous
                    attempt remain to be sent to that peer, or while its own LSP transmissions or retransmissions toward
                    that peer resulting from that attempt remain outstanding. The next periodic CASH can start after all such local work
                    has completed. This rule applies equally to helpers and restarters during
                    graceful restart. It does not require the sender to determine whether
                    the peer has pending work or to wait for the peer's flooding to finish.
                    This requirement bounds the traffic caused by each divergence while
                    delaying only a redundant probe.
                </t>
                <!--
                <t>
                    During an ordinary point-to-point initial exchange,
                    a node <bcp14>MUST</bcp14> arrange one fresh
                    follow-up CASH train after completing transmission of its first
                    CASH train. It arms a non-rearming timer shorter than the periodic
                    interval without waiting for any response or local work. On expiry,
                    the follow-up waits for local reconciliation work to abate. If the
                    next periodic exchange becomes due first, that exchange overrides
                    this local-work wait and satisfies the follow-up obligation.
                    This exception does not interrupt an active CASH train or bypass
                    normal transmission pacing, and does not apply during graceful restart.
                    A fresh periodic train may satisfy the obligation instead of an
                    additional train. Received CASHes or PASHes <bcp14>MUST NOT</bcp14>
                    rearm the initial follow-up.
                </t>
                -->
                <t>
                    Before a peer session completes its initial full-coverage CASH exchange, a node
                    <bcp14>MAY</bcp14> use ordinary CSNP framing as a conservative fallback. After that exchange
                    completes, deferring a periodic CASH does not require the node to introduce a CSNP.
                    Implementations <bcp14>SHOULD</bcp14> expose a counter for deferred CASH cycles. Such a counter
                    identifies peers that do not complete reconciliation and helps determine whether the
                    periodic interval is shorter than the time required to exchange the necessary PASHes,
                    PSNPs, and LSPs.
                </t>
                <t>
                    When refinement reaches a range that requires normal SNP exchange or flooding, the node
                    <bcp14>MUST</bcp14> initiate that repair without waiting for another periodic CASH.
                    Transitioning from PASH refinement to SNP exchange or flooding does not complete the
                    reconciliation attempt; completion occurs only after the required PASHes, PSNPs, and
                    resulting LSP transmissions and retransmissions have completed.
                </t>
                <t>
                    ASH repair can generate a large number of PSNP entries while received repair LSPs
                    simultaneously require acknowledgment. When an implementation schedules both classes
                    of entry through the same PSNP transmission mechanism, it <bcp14>SHOULD</bcp14> transmit
                    acknowledgments for received LSPs before PSNP entries generated to request or describe
                    further reconciliation. Delaying those acknowledgments behind a reconciliation backlog
                    can cause the sender's retransmission timer to expire, adding duplicate LSP traffic and
                    extending convergence. A PSNP can use any space remaining after the acknowledgments for
                    reconciliation entries.
                </t>
            </section>
            </section>

            <section anchor="broadcast-circuits">
            <name>Broadcast Circuit Operation</name>
                <t>
                    Graceful restart on broadcast circuits uses traditional
                    procedures, not ASH, as specified in
                    <xref target="graceful-restart"/>.
                </t>
                <t>
                    On a broadcast circuit, only the Designated Intermediate System (DIS) for a
                    level <bcp14>MAY</bcp14> originate periodic CASHes for that level. The DIS
                    <bcp14>MUST NOT</bcp14> replace a CSNP with a CASH unless every Up
                    adjacency at that level has advertised
                    <spanx style="strong">ASH_RX</spanx>. Otherwise it
                    <bcp14>MUST</bcp14> send an ordinary CSNP.
                </t>
                <t>
                    PASH refinement on a broadcast circuit is performed between the DIS and the
                    non-DIS systems. The DIS processes PASHes originated by non-DIS systems. A
                    non-DIS processes PASHes originated by the current DIS, but
                    <bcp14>MUST NOT</bcp14> process a PASH originated by another non-DIS.
                </t>
                <t>
                    PASHes that would generate the same SNP requests or flooding
                    <bcp14>MAY</bcp14> be reconciled by the DIS before it reacts.
                </t>
                <t>
                    Terminal repair on a broadcast circuit has the same requirement as
                    point-to-point repair: flooding locally held fragments or listing them in
                    PSNPs alone cannot reveal fragments held only by the other system.
                    The other system need not independently reach the same terminal range.
                    Only the DIS originates the range CSNPs used for this repair; a non-DIS
                    <bcp14>MUST NOT</bcp14> originate a range CSNP.
                </t>
                <t>
                    When the DIS decides that a received mismatching range is terminal,
                    it <bcp14>MUST</bcp14> send a range CSNP covering that range and listing
                    its locally held non-purged fragments. It <bcp14>MUST</bcp14> do so
                    even when it holds no such fragments: an empty range CSNP makes
                    non-DIS systems flood fragments they hold in that range.
                </t>
                <t>
                    When a non-DIS decides that a received mismatching range is terminal,
                    it <bcp14>MUST</bcp14> schedule its locally held non-purged fragments in
                    that range for normal flooding and send a zero-hash PASH entry for
                    the same range to the DIS. It <bcp14>MUST</bcp14> send this entry
                    even when it holds no such fragments. In this direction the zero
                    hash requests a range CSNP from the DIS; it does not assert that
                    the non-DIS has an empty database in the range.
                </t>
                <t>
                    On receiving a valid zero-hash CASH or PASH entry from the DIS, a non-DIS
                    <bcp14>MUST</bcp14> schedule its locally held non-purged fragments in
                    that range for normal flooding. It <bcp14>MUST NOT</bcp14> answer the
                    directive with a PASH entry for the range, including a zero-hash entry,
                    and <bcp14>MUST NOT</bcp14> refine the range further. When it holds no
                    such fragments it ignores the directive. A non-DIS
                    <bcp14>MUST NOT</bcp14> send a range CSNP in either case.
                </t>
                <t>
                    On receiving a valid zero-hash CASH or PASH entry from a non-DIS, the DIS
                    <bcp14>MUST</bcp14> schedule its locally held non-purged fragments in
                    the range for normal flooding and send a range CSNP covering the
                    range, even when the range is locally empty. It <bcp14>MUST NOT</bcp14>
                    return a zero-hash PASH directive in response. The range CSNP
                    exposes fragments held only by a non-DIS and allows non-DIS systems
                    to request fragments held only by the DIS through normal PSNP
                    processing. This is role-directed terminal repair, not another
                    hash comparison or subdivision step, and does not create directive loops.
                </t>
                <t>
                    Range CSNP coverage, segmentation, and merging follow
                    <xref target="range-csnp-rules"/>. A range CSNP is processed by all
                    receiving systems using normal broadcast-circuit CSNP procedures,
                    including systems that did not participate in the PASH exchange.
                </t>
                <t>
                    When the DIS on a broadcast circuit changes, every system on that
                    circuit <bcp14>MUST</bcp14> discard any in-flight CASH origination
                    state and any PASH refinement state associated with the prior DIS
                    for that level, and the new DIS <bcp14>MUST</bcp14> begin CASH
                    origination afresh rather than resuming a sequence started by its
                    predecessor. A PASH received from a system after that system has
                    ceased to be the current DIS <bcp14>MUST NOT</bcp14> be processed,
                    consistent with the role rules above.
                </t>
                <t>
                    A DIS change <bcp14>MUST NOT</bcp14> by itself be treated as
                    invalidating database synchronization already achieved for ranges
                    other than the pseudonode LSP whose content changes as a result of
                    the election. In particular, a DIS change alone is not sufficient
                    reason to re-run terminal repair, or to fall back to a full CSNP
                    exchange of the entire node-ID space, for ranges where CASH/PASH
                    refinement had already converged; an implementation
                    <bcp14>SHOULD</bcp14> resume refinement from a clean, empty
                    CASH/PASH state rather than discarding and recomputing
                    synchronization status for the whole circuit.
                </t>
            </section>

            <section anchor="graceful-restart">
            <name>Graceful Restart on Point-to-Point Circuits</name>
                <t>
                    On a point-to-point adjacency eligible for graceful restart
                    under <xref target="RFC8706"/>, ASH negotiation is
                    complete when both neighbors advertise both ASH_RX and
                    ASH_TX and have ASH transmission and reception enabled
                    at every common active level, with at least one common
                    active level. When ASH negotiation is complete, both
                    neighbors <bcp14>MUST</bcp14> use ASH graceful restart
                    on that adjacency. Otherwise, both neighbors
                    <bcp14>MUST</bcp14> use traditional graceful restart
                    as specified in <xref target="RFC8706"/> and
                    <bcp14>MUST NOT</bcp14> use ASH graceful restart
                    on that adjacency. An ineligible adjacency does not
                    participate in graceful restart. ASH graceful restart
                    is inherent in ASH support, with no separate capability.
                    Adjacency preservation, restart acknowledgement, and
                    remaining holding time retain their meanings from
                    <xref target="RFC8706"/>.
                </t>
                <t>
                    These procedures are initiated by a restarting router
                    sending RR set and Suppress Adjacency (SA) clear.
                    They do not change the
                    procedures for SA or planned restart in
                    <xref target="RFC8706"/>. Broadcast circuits continue to
                    use the graceful-restart procedures of that specification.
                    On a broadcast circuit, the restarter and its helpers
                    <bcp14>MUST</bcp14> use traditional CSNP, PSNP, and LSP
                    procedures for the restart exchange, regardless of ASH
                    capabilities. They <bcp14>MUST NOT</bcp14> substitute
                    CASH or PASH for required restart inventory or repair,
                    or use ASH signaling to establish restart state or
                    satisfy restart completion conditions. ASH-specific
                    restart signaling <bcp14>MUST</bcp14> be ignored on
                    broadcast circuits.
                </t>
                <section anchor="graceful-restart-theory">
                <name>Theory of Operation</name>
                    <t>
                        The restarting router requests complete CASH trains
                        instead of complete CSNP sets from its helpers.
                        Only helpers set the S (Snapshot Served) bit.
                        The restarter <bcp14>MUST NOT</bcp14> set S in any
                        CASH PDU it sends for this restart exchange.
                        A helper <bcp14>MUST</bcp14> ignore the value of S
                        in every CASH PDU received from the restarter.
                    </t>
                    <section anchor="graceful-restart-initiation">
                    <name>Initiation and Snapshot Capture</name>
                    <t>
                        The restarting router conveys its restart epoch with
                        RR, and each helper echoes it in its CASH trains.
                        Successive trains and repeated RR hellos belonging
                        to the same restart retain that epoch.
                    </t>
                    <t>
                        The restarter <bcp14>MAY</bcp14> store the epoch in
                        persistent memory and increment it on restart.
                        If no epoch history is available, the restarter
                        <bcp14>MUST</bcp14> choose it uniformly at random on restart.
                        When recent epoch history is available, it
                        <bcp14>SHOULD</bcp14> avoid reusing a recent value.
                    </t>
                    <t>
                        Epoch validation follows
                        <xref target="graceful-restart-epoch-mismatch"/>.
                        Epoch matching does not
                        by itself establish train completeness or database
                        synchronization, and does not replace authentication.
                    </t>
                    <t>
                        On receipt of RR, a helper <bcp14>MUST</bcp14> respond with a
                        complete CASH train for each active level on the
                        adjacency, with the epoch indicated by the Suggested
                        Epoch TLV accompanying RR. This requirement also
                        applies to repeated RR hellos with the same epoch;
                        an in-progress train <bcp14>MAY</bcp14> serve that request.
                        It <bcp14>MUST</bcp14> acknowledge RR with RA
                        according to <xref target="RFC8706"/>. CASH
                        reconciliation replaces the complete CSNP set and
                        unconditional setting of SRMflags in Section 3.2.1
                        of that specification: the helper
                        <bcp14>MUST NOT</bcp14> initiate a full database
                        flood solely because it received RR.
                    </t>
                    <t>
                        Each helper captures its helper snapshot when
                        acknowledging the restart with RA. Its live database
                        and ordinary flooding continue independently.
                    </t>
                    </section>
                    <section anchor="graceful-restart-reconciliation">
                    <name>Restarter Reconciliation</name>
                    <t>
                        As ASH packets arrive, the restarting router
                        <bcp14>MUST</bcp14> compare
                        their advertised hashes with its recovering database.
                        To reconcile differences, it <bcp14>MUST</bcp14> use
                        PASHes and/or terminal repair to solicit missing or
                        mismatched LSPs from the helper.
                    </t>
                    <t>
                        The restarting router <bcp14>SHOULD</bcp14> send a
                        complete CASH train describing its recovering database
                        when requesting restart with RR.
                    </t>
                    <t>
                        The restarter's own LSPs can legitimately differ
                        from the pre-restart copies held by helpers.
                        Both the helper and the restarter
                        <bcp14>MUST</bcp14> isolate the restarter's System ID
                        as a separate singleton range in CASH and PASH
                        hash advertisements covering that ID throughout
                        the restart exchange. A hash mismatch confined to
                        that singleton <bcp14>MUST NOT</bcp14> trigger
                        refinement or terminal repair, or prevent CASH
                        agreement. All other System IDs remain subject
                        to ordinary comparison and reconciliation.
                        This exemption applies only to a hash mismatch on
                        that exact singleton, not to a wider range containing
                        it. Matching hashes and zero-hash repair directives
                        retain their ordinary meanings.
                        The helper's own System ID requires no special
                        isolation.
                    </t>
                    <t>
                        The restarting router <bcp14>SHOULD</bcp14> periodically
                        advertise its recovering database in CASH trains.
                        These advertisements
                        let helpers learn which fragments the restarting router
                        has already acquired, including those supplied by other
                        helpers, rather than all continuing to flood the same
                        fragments. It <bcp14>MUST</bcp14> pace these
                        advertisements according to
                        <xref target="reconciliation-pacing"/> and
                        <bcp14>MUST NOT</bcp14> substitute a full-database
                        CSNP of its partially recovered database for a deferred
                        CASH advertisement. Terminal-repair range CSNPs
                        remain permitted.
                    </t>
                    </section>
                    <section anchor="graceful-restart-snapshot-service">
                    <name>Helper Snapshot Service</name>
                    <t>
                        Completion of the helper's first full CASH train
                        transmission seals its snapshot obligation accounting
                        at that level. Snapshot sealing does not establish
                        that the snapshot has been served. When sending a complete CASH train,
                        the helper <bcp14>SHOULD</bcp14> queue its remaining
                        snapshot LSPs for normal flooding. The helper
                        <bcp14>MUST NOT</bcp14> infer possession from silence
                        or the omission of a range from a PASH.
                        On receiving a CASH or PASH from the restarter,
                        the helper <bcp14>MUST</bcp14> process mismatching
                        ranges through refinement or terminal repair.
                        Terminal repair uses ordinary IS-IS CSNP, PSNP, and
                        LSP flooding procedures, subject to the helper-side
                        exception below; resulting LSP transmissions
                        <bcp14>MUST</bcp14> be queued without requiring
                        receipt of a complete CASH train from the restarter.
                    </t>
                    <t>
                        During this exchange, a helper performing terminal
                        repair <bcp14>MAY</bcp14> send its locally held
                        non-purged fragments in the terminal range directly,
                        without sending a range CSNP or an empty-range
                        directive to solicit the restarter's inventory.
                        This is an exception to
                        <xref target="terminal-repair"/> for the helper only.
                        The restarter continues to use ordinary terminal
                        repair. Neither this exception nor snapshot completion
                        suppresses required LSP acknowledgements or
                        retransmissions.
                    </t>
                    <t>
                        While a snapshot LSP still awaits transmission or
                        validated evidence of possession by the restarter,
                        a newer accepted instance of that LSP
                        <bcp14>MUST</bcp14> replace the version required by
                        the snapshot. Transmission or validated possession
                        of that version, or a newer one, satisfies the
                        snapshot obligation for that LSP.
                    </t>
                    <t>
                        Once that obligation has been satisfied, a later
                        instance of the same LSP is ordinary flooding work:
                        it <bcp14>MUST NOT</bcp14> reopen the satisfied
                        obligation or delay snapshot completion. New LSP IDs
                        likewise <bcp14>MUST NOT</bcp14> extend the snapshot.
                        These rules bound restart assistance to the snapshot; they
                        <bcp14>MUST NOT</bcp14> suppress ordinary flooding,
                        acknowledgements, or required retransmissions of
                        newer or newly learned LSPs toward the restarter.
                    </t>
                    <t>
                        Once a helper has completed the reconciliation work
                        resulting from that exchange, it <bcp14>MUST</bcp14>
                        present its database again in another complete CASH
                        train, without requiring a CASH advertisement from
                        the restarter first. The restarter compares it
                        against its recovering database and continues
                        reconciliation as needed.
                    </t>
                    <t>
                        Helpers <bcp14>MUST</bcp14> continue periodic CASH
                        advertisements and required reconciliation responses
                        while providing restart assistance, including after
                        RR clears. Clearing RR indicates completion of the
                        initial handshake, not database synchronization.
                    </t>
                    </section>
                    <section anchor="graceful-restart-final-response">
                    <name>Snapshot Completion and Final Response</name>
                    <t>
                        Before signaling snapshot completion, each required LSP
                        <bcp14>MUST</bcp14> have actually been transmitted,
                        unless validated evidence demonstrates that the
                        restarter already possesses it. Queuing or scheduling
                        does not satisfy this requirement, and deferred
                        refinement does not remove fragments from it.
                        Acknowledgements and retransmissions need not have
                        completed. Subsequent flooding does not delay snapshot
                        completion. The helper signals completion with S
                        as specified in <xref target="graceful-restart-wire"/>.
                    </t>
                    <t>
                        For example, a helper can transmit version 1 of a
                        snapshot LSP, satisfying its obligation, and then
                        learn version 2 and flood it normally. A CASH
                        comparison made between those events can mismatch.
                        Such a mismatch does not invalidate the served
                        snapshot or prevent completion through the helper's
                        S indication, subject to the initial handshake
                        requirements in
                        <xref target="graceful-restart-procedures"/>.
                        S does not assert that version 2 has been received;
                        its delivery remains ordinary flooding and
                        retransmission work.
                    </t>
                    <t>
                        On receiving a complete matching helper CASH train,
                        the restarter <bcp14>SHOULD</bcp14> respond
                        with a complete CASH train describing its recovering
                        database at that level, even if it has already
                        accepted that helper as synchronized.
                    </t>
                    <t>
                        When the restarter accepts an S indication from a
                        helper for the current restart epoch, it
                        <bcp14>MUST</bcp14> send that helper a complete CASH
                        train describing its database at that level, even
                        if it already considers the helper synchronized.
                        Every CASH PDU in this train <bcp14>MUST</bcp14>
                        carry the epoch of that restart exchange.
                        The restarter may use one such train to answer
                        repeated S indications from the same helper on the
                        same adjacency and level for that epoch.
                        This transmission <bcp14>MUST NOT</bcp14> delay
                        graceful restart completion. If restart completes
                        before the train has been fully sent, the restarter
                        <bcp14>MUST</bcp14> still finish sending it.
                        Adjacency teardown, withdrawal of ASH negotiation,
                        or a subsequent restart cancels this transmission
                        requirement for the old exchange.
                    </t>
                    <t>
                        Completion is determined independently for each
                        adjacency and active level by the conditions in
                        <xref target="graceful-restart-procedures"/>.
                    </t>
                    </section>
                </section>
                <section anchor="graceful-restart-wire">
                <name>Restart Signaling and CASH Encoding</name>
                    <t>
                        The Restart TLV (Type 211) remains unchanged from
                        <xref target="RFC8706"/>. A router with ASH transmission
                        and reception enabled at every locally active level
                        on a point-to-point circuit <bcp14>MUST</bcp14>
                        accompany its RR with an ASH GR Suggested Epoch TLV,
                        without waiting to learn its neighbor's capabilities.
                        This separate IIH TLV has Type TBD-ASH-GR, Length 1,
                        and the following Value:
                    </t>
                    <figure>
                        <artwork type="ascii-art"><![CDATA[
                                           No. of octets
             +---------------------------+
             | Reserved (4) | Epoch (4)  |     1
             +---------------------------+
]]></artwork>
                    </figure>
                    <t>
                        The TLV applies only to RR or RA in the Restart TLV
                        in the same IIH, irrespective of TLV order. Senders
                        <bcp14>MUST NOT</bcp14> include it without RR or RA.
                        A receiver <bcp14>MUST NOT</bcp14> infer a restart
                        request or acknowledgement from this TLV alone.
                    </t>
                    <t>
                        The low-order four bits of the Epoch octet encode
                        the restart epoch, with all values 0 through 15
                        valid. Its high-order four bits are reserved:
                        senders <bcp14>MUST</bcp14> transmit them as zero
                        and receivers <bcp14>MUST</bcp14> ignore them.
                        The restarter <bcp14>MUST</bcp14> put its current
                        epoch in the TLV accompanying RR. A helper accepting
                        ASH graceful restart <bcp14>MUST</bcp14> echo that
                        epoch in the TLV accompanying RA. The RA
                        <bcp14>MUST</bcp14> identify the restarter as required
                        by <xref target="RFC8706"/>. Selection and validation
                        <bcp14>MUST</bcp14> follow IIH authentication and
                        account for all Hello Capability TLVs, independently
                        of their order. For a selected ASH
                        exchange, missing, malformed, or duplicate Suggested
                        Epoch TLVs, an invalid or duplicate Restart TLV,
                        or an RA with a mismatched target,
                        <bcp14>MUST</bcp14> cause the associated restart
                        signaling to be ignored without restart-related
                        state changes or fallback to ordinary restart
                        processing of that signaling; other IIH contents are
                        processed normally.
                        An RA with a mismatched epoch is handled as specified
                        in <xref target="graceful-restart-epoch-mismatch"/>.
                    </t>
                    <t>
                        The Suggested Epoch TLV offers ASH graceful restart;
                        it does not by itself select it. If the eligibility
                        rule above is not met, a receiver
                        <bcp14>MUST</bcp14> ignore this TLV and process the
                        unchanged Restart TLV using ordinary procedures,
                        including RA and a complete CSNP set when eligible.
                        Such an RA does not echo the Suggested Epoch TLV.
                        The restarter
                        <bcp14>MUST</bcp14> accept that ordinary exchange
                        rather than requiring CASH or an epoch-bearing RA.
                        Peers unaware of the new TLV can ignore it without
                        encountering a modified Type 211 format.
                    </t>
                    <t>
                        The formerly reserved octet at offset 6 in the
                        CASH fixed header is the GR Control octet:
                    </t>
                    <figure>
                        <artwork type="ascii-art"><![CDATA[
                7   6   5   4   3   2   1   0
              +---------------+-----------+---+
              | Restart Epoch | Reserved  | S |
              +---------------+-----------+---+
]]></artwork>
                    </figure>
                    <t>
                        Bits 7 through 4 carry the epoch, using the same
                        numeric value as the Suggested Epoch TLV. Bit 0 is S
                        (Snapshot Served). Bits 3 through 1 are reserved and
                        <bcp14>MUST</bcp14> be transmitted as zero and
                        ignored on receipt. Except for retained completion
                        signaling described below, the octet
                        <bcp14>MUST</bcp14> be zero outside a restart exchange.
                        It <bcp14>MUST NOT</bcp14> establish restart state
                        on receipt. The corresponding
                        PASH octet remains reserved and is transmitted as zero.
                    </t>
                    <t>
                        Each CASH in an active exchange <bcp14>MUST</bcp14>
                        carry its restart epoch. The restarter
                        <bcp14>MUST</bcp14> transmit S clear; only a helper
                        can signal snapshot completion. Every PDU in the helper's
                        first CASH train for a new restart exchange
                        <bcp14>MUST</bcp14> have S clear, even if the snapshot
                        is served before that train finishes. The helper
                        <bcp14>MUST NOT</bcp14> set S merely because the
                        snapshot's LSPs have been queued. It
                        <bcp14>MUST</bcp14> set S only after the snapshot
                        transmission work has drained onto the wire as
                        specified in <xref target="graceful-restart-final-response"/>
                        and the first CASH train has finished, and send a
                        paced CASH notification. It
                        <bcp14>MUST</bcp14> retain S on subsequent CASH for
                        that exchange and <bcp14>MAY</bcp14> continue sending
                        S with the completed epoch until the next restart
                        request; it need not determine when the restarter
                        finishes. A new exchange starts with S clear.
                        Clearing RR or receiving S clear
                        <bcp14>MUST NOT</bcp14> revoke accepted completion.
                    </t>
                    <t>
                        A receiver <bcp14>MUST</bcp14> validate and
                        authenticate the CASH and associate it with the
                        current neighbor, adjacency, level, and epoch before
                        accepting S. An indication received before initial
                        inventory completion <bcp14>MAY</bcp14> be retained
                        for that same exchange. A repeated RR with
                        the same epoch <bcp14>MUST NOT</bcp14> reset the
                        snapshot or its earned completion indication.
                        Adjacency replacement, exchange timeout, or abort
                        <bcp14>MUST</bcp14> invalidate pending receiver
                        completion state; retained helper signaling does not
                        create a new exchange. Numerical epoch values do not
                        establish ordering; reuse of a four-bit value can
                        make delayed signaling indistinguishable from the
                        current exchange.
                    </t>
                </section>
                <section anchor="graceful-restart-epoch-mismatch">
                <name>Epoch Mismatch</name>
                    <t>
                        During an active exchange, a receiver
                        <bcp14>MUST</bcp14> discard any CASH whose epoch
                        differs from that exchange's epoch, including its
                        S indication. It <bcp14>MUST NOT</bcp14> compare
                        the hashes, initiate repair, or update inventory or
                        completion state from that CASH.
                    </t>
                    <t>
                        The restarter <bcp14>MUST</bcp14> ignore restart
                        acknowledgement signaling in an RA carrying a
                        different epoch, without falling back to ordinary
                        restart processing of that signaling. Other IIH
                        contents are processed normally.
                    </t>
                    <t>
                        A wrong-epoch helper response <bcp14>MUST NOT</bcp14>
                        change the restarter's current exchange, reset its
                        restart timers, or revoke previously accepted
                        synchronization. The restarter continues waiting
                        for valid responses under the existing restart
                        timers. Timer expiry and unsuccessful restart follow
                        <xref target="RFC8706"/>.
                    </t>
                    <t>
                        When a helper accepts RR from the restarting router
                        with an epoch different from the exchange it is
                        currently assisting, it <bcp14>MUST</bcp14> replace
                        that exchange with the new one and invalidate the
                        previous exchange's pending completion indications.
                    </t>
                </section>
                <section anchor="graceful-restart-procedures">
                <name>Initial Handshake and Synchronization Completion</name>
                    <t>
                        For T1 processing, receipt of either a complete CASH
                        train or a complete CSNP set satisfies the initial
                        database-summary receipt requirement for that level.
                        The restarting router <bcp14>MUST</bcp14> receive both
                        RA and either a complete CASH train or a complete
                        CSNP set from the helper
                        for every active level before considering the initial
                        handshake complete. A complete CASH train satisfies
                        this receipt requirement even if its hashes mismatch.
                        Receipt does not require retaining a separate inventory
                        or snapshot at the restarting router and does not by
                        itself establish database synchronization.
                        A range CSNP used for terminal repair does not satisfy
                        this requirement, regardless of the size of the range
                        being repaired. It cannot be a C-CSNP because it
                        excludes the complete-set end marker as specified
                        in <xref target="range-csnp-rules"/>.
                    </t>
                    <t>
                        The initial database-summary receipt and synchronization requirements
                        <bcp14>MUST</bcp14> apply to every participating ASH
                        adjacency and active level, independently of whether
                        a CASH has arrived from that helper. Silence or a
                        lost train <bcp14>MUST NOT</bcp14> remove a helper's
                        requirement.
                        A detected mismatch <bcp14>MUST</bcp14> prevent
                        agreement for that train even when its repair is
                        deferred.
                    </t>
                    <t>
                        The restarting router <bcp14>MUST</bcp14> receive either a
                        complete matching CASH train from the helper or
                        the helper's S indication for the
                        current restart epoch at each active level
                        before considering that adjacency synchronized.
                        The S indication
                        <bcp14>MUST NOT</bcp14> bypass the initial database-summary
                        receipt or the RA handshake requirement. If a helper
                        falls back to a complete CSNP set, synchronization
                        with that helper follows the ordinary procedures of
                        <xref target="RFC8706"/>; receipt of the set alone
                        does not establish synchronization.
                        The restarting router <bcp14>MUST</bcp14> satisfy
                        this reconciliation condition on all required ASH
                        graceful-restart adjacencies and active levels,
                        together with the synchronization conditions of any
                        participating ordinary graceful-restart adjacencies,
                        before declaring restart synchronization complete.
                        The T2 and T3 limits and unsuccessful-restart
                        procedures of <xref target="RFC8706"/> continue to
                        apply. Repeated RR hellos or additional CASH trains
                        <bcp14>MUST NOT</bcp14> extend the restart holding
                        period.
                    </t>
                </section>
            </section>

        </section>


        <section anchor="cash-format">
            <name>CASH PDU Format</name>
            <t>
<!--                ASH PDU Format follows closely CSNP format where instead of CSNP entries the according merkle-->
<!--                hashes are propagated, i.e. the hashes incorporate strictly the same-->
<!--                fragments that are being incorporated in-->
<!--                CSNP packets. Start and End System IDs do not include pseudo node bytes as those are subsumed-->
<!--                implicitly.-->

                The CASH PDU format closely follows the CSNP format. Instead of CSNP entries, it carries the
                corresponding Merkle hashes - which cover exactly the same fragments that would appear in CSNP packets.
                The Start and End System IDs exclude pseudonode bytes, as those are implicitly included within the
                ranges.
            </t>

            <figure>
            <artwork align="left" name="" type="" alt=""><![CDATA[
                                       No. of Octets
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Intradomain Routing Protocol        |     1
| Discriminator                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length Indicator                    |     1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Version/Protocol ID Extension (1)   |     1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ID Length                           |     1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| R R R   PDU Type                    |     1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Version (1)                         |     1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| GR Control                          |     1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Max Area Addresses                  |     1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| PDU Length                          |     2
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source ID                           |  ID Length + 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Start System ID                     |  ID Length
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| End System ID                       |  ID Length
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Node Range Hash TLVs                |  Variable
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
]]></artwork>
            </figure>

            <t>
                The Start and End System IDs use the standard ID length and indicate the range of fragments covered by
                the ASH, just like CSNPs do. The key difference is that all pseudonodes of the systems within this
                range are implicitly included (implying as well that all fragments of the range are included).
                Both the Start and End System IDs are inclusive, meaning fragments from
                both endpoints are part of the range.  All Node Range Hash Entries
                <bcp14>MUST</bcp14> fall within the bounds defined by the header's Start and End System IDs.


<!--                Start and End System IDs are or the usual ID Length and indicate, just like CSNP do,-->
<!--                the range of fragments that the ASH covers with the difference that all pnodes of-->
<!--                the systems are implied in the range. Start and End System ID are inclusive, i.e.-->
<!--                the fragments of both the start and the end system ID are included.-->
            </t>

            <t>
                Unlike CSNPs, which place LSP Entries directly in a dedicated LSP Entries TLV
                (type 9) whose value is itself just a flat sequence of entries, ASH packets carry
                their Node Range Hash Entries inside a new Node Range Hash TLV (type TBD), following
                the standard IS-IS TLV convention of a 1-octet Type, 1-octet Length, and Value:
            </t>

        <figure>
            <artwork align="left" name="" type="" alt=""><![CDATA[
                                       No. of Octets
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type = Node Range Hash TLV (TBD)    |     1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length                              |     1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Node Range Hash Entries             |  Variable
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
]]></artwork>
        </figure>

            <t>
                The Value of a Node Range Hash TLV is a sorted sequence of Node Range Hash Entries
                in the following format.
            </t>
            <t>
                A CASH <bcp14>MAY</bcp14> contain no Node Range Hash TLVs.
                In that case, its entire header range describes absent inventory,
                and the receiver processes that absence as specified below.
                An empty database is described by one such CASH with an all-zero
                Start System ID and an all-ones End System ID. Other required
                TLVs, including authentication, remain present. No zero-hash
                entry is needed: a zero hash is a terminal repair directive,
                not an empty-database fingerprint.
            </t>

        <figure>
            <artwork align="left" name="" type="" alt=""><![CDATA[
                                       No. of Octets
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Range Start System ID               |  ID Length
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Range End System ID                 |  ID Length
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Merkle Hash                         |     8
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Fragment Population                 |     1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
]]></artwork>
        </figure>

            <t>The range of fragments included in the hash. Range Start and Range End System IDs are inclusive, i.e.
                fragments of both the start and the end system ID are contained within the range.</t>
            <t>
                The Merkle hash field is 8 octets containing the 64-bit computed hash of all fragments covered
                by the range. A computed value <bcp14>MUST NOT</bcp14> be zero. In both
                CASH and PASH entries, zero is the terminal
                repair directive specified in <xref target="rules"/>, including the
                role-directed broadcast behavior in <xref target="broadcast-circuits"/>.
                The all-ones value is reserved
                and <bcp14>MUST NOT</bcp14> be transmitted.
            </t>

            <t>
                The Fragment Population field encodes the number N of LSP fragments in the inclusive
                range in the sender's local database. A sender <bcp14>MUST</bcp14> encode an empty range
                as zero. For a nonempty range, it <bcp14>MUST</bcp14> low-ball N
                by encoding the highest possible represented value not exceeding N.
                To read a nonzero wire code C, subtract one and split the result
                into the four exponent bits E and four fraction bits F shown below.
                The represented value is 2^E * 2^(F/16); the receiver
                <bcp14>MUST</bcp14> decode it as floor(2^E * 2^(F/16)).
                Codes 1, 17, 97, and 129 represent 1, 2, 64, and 256 fragments.
                Code 0xff is the last available step and decodes to 60096;
                it also represents larger populations.
                This field is advisory and, except for the inconsistent
                zero-population/nonzero-hash handling in <xref target="terminal-repair"/>,
                does not alter hash comparison or the meaning of a zero hash.
                It <bcp14>MUST</bcp14> describe the
                sender's local population even when the Merkle Hash field is zero.
            </t>

            <figure>
                <artwork><![CDATA[
For nonzero wire code C, let L = C - 1:

       7   6   5   4   3   2   1   0
     +---------------+---------------+
 L = | Integer part E| Fraction F    |
     +---------------+---------------+

       represented value   = 2^E * 2^(F/16)
       population estimate = floor(2^E * 2^(F/16))

Wire code 0 means empty; the split above applies to C - 1,
not directly to C.
]]></artwork>
            </figure>

            <t>
                With the standard ID Length of 6, each entry is 6 + 6 + 8 + 1 = 21 octets. Since a TLV's Length field
                is a single octet, a single Node Range Hash TLV can carry at most 12 entries (12 * 21 = 252 octets,
                leaving room within the 255-octet maximum TLV value size). Since Node Range Hash Entries are treated
                as a single logical sequence regardless of which TLV they appear in, a CASH or PASH PDU <bcp14>MAY</bcp14>, and
                typically will, carry multiple Node Range Hash TLVs to fit the roughly 70 entries that fit into a
                standard 1500-byte MTU, exactly as CSNPs carry multiple LSP Entries TLVs when needed.
            </t>


            <t>
                The ranges in a CASH <bcp14>MUST</bcp14> be sorted by Range Start System ID across the concatenation of all Node
                Range Hash TLVs in the PDU, in the order the TLVs appear. The ranges <bcp14>MUST NOT</bcp14> overlap.
                A receiver encountering overlapping ranges <bcp14>MUST</bcp14> treat the union of those
                ranges as a single range with a zero hash. Its Fragment Population
                <bcp14>MUST</bcp14> be obtained by adding the decoded populations
                of the contributing entries, without subtracting for overlap,
                and encoding the sum using the Fragment Population encoding above,
                including saturation at the largest code.
                Any range exceeding the CASH header bounds
                <bcp14>MUST</bcp14> be clamped to fit within the CASH range and treated as a zero hash.
                Clamping <bcp14>MUST NOT</bcp14> change its Fragment Population.
                A range whose end equals its start is valid and covers the fragments of that single system ID.
                Any range whose end is smaller than its start <bcp14>MUST</bcp14> be discarded.
                A node <bcp14>SHOULD</bcp14> log such events since they most likely indicate
                protocol implementation problems or attacks.
            </t>

            <t>
                Any node IDs that are not covered by the ranges in a CASH - either because there are gaps between
                the advertised ranges, or between those ranges and the ASH's Start and End System IDs - <bcp14>MUST</bcp14> be
                treated as missing. Consequently, if a node detects that it holds Merkle hashes for LSPs that are
                not covered by a received CASH, it <bcp14>MUST</bcp14> behave as it would in the same situation with a CSNP, namely
                by flooding the missing LSPs.
            </t>
            <t>
                A gap within the CASH header bounds is therefore semantically
                equivalent to an implicit entry covering that gap with hash zero
                and Fragment Population zero. An explicit zero-hash entry requests
                the same terminal repair but can advertise a nonzero population;
                the directive alone does not assert empty inventory. Neither
                form provides hash agreement. Ranges outside the CASH header
                bounds are not described by that PDU.
            </t>

            <t>
                As with CSNPs, a CASH whose first range covers the first node in the database <bcp14>MUST</bcp14> use
                0000.0000.0000 as the start system ID in its packet header so that missing nodes can be detected. The
                same rule applies at the other end: a CASH whose range covers the last node <bcp14>MUST</bcp14>
                indicate this so that any missing trailing nodes are detectable.
            </t>

            <t>
                As with PASHes (<xref target="pash-format"/>), deployments combining ASH with
                <xref target="RFC9681"/> fast flooding <bcp14>SHOULD</bcp14> reserve sufficient
                space within the PDU for a Flooding Parameters TLV, along with any other TLVs
                that may need to coexist in the same PDU, when computing how many Node Range
                Hash TLVs and entries fit within the MTU, as described in
                <xref target="envelope"/> and <xref target="max-coverage"/>.
            </t>

        </section>

        <section anchor="pash-format">
            <name>PASH PDU Format</name>
            <t>
                PASH uses the CASH format in <xref target="cash-format"/>,
                with the PASH PDU Type for the applicable level and without
                the Start and End System ID header fields. The octet
                corresponding to CASH's GR Control remains reserved:
                it <bcp14>MUST</bcp14> be transmitted as zero and ignored
                on receipt.
            </t>
            <t>
                Node Range Hash TLV and entry encoding, Fragment Population,
                and reserved hash values are the same as for CASH.
                Additional TLVs and PDU space reservation follow
                <xref target="additional-tlvs"/>.
            </t>

            <t>PASHes are equivalent to PSNPs in that entries are treated independently:
                gaps between entries have no semantics, entries need not be sorted, and may overlap.
                Unlike CASH gaps, PASH gaps do not imply zero-hash,
                zero-population entries.
                A range whose end equals its start is valid and covers the fragments of that single system ID.
                Any range whose end is smaller than its start <bcp14>MUST</bcp14> be discarded before its
                hash is interpreted, including when the hash is zero. A node <bcp14>SHOULD</bcp14> log such
                events since they most likely indicate protocol implementation problems or attacks.
            </t>

        </section>

        <section anchor="additional-tlvs">
            <name>Additional TLVs in CASH and PASH PDUs</name>
            <t>
                A CASH replaces a CSNP and a PASH replaces a PSNP; neither may be less capable than the
                PDU it replaces. Except for the LSP Entries TLV (type 9),
                whose inventory representation is replaced by Node Range Hash TLVs,
                every TLV type that an implementation supports in CSNPs
                <bcp14>MUST</bcp14> equally be supported in CASHes, and every TLV type it supports in
                PSNPs <bcp14>MUST</bcp14> equally be supported in PASHes, with the same semantics, the
                same configuration and the same receive processing. This includes, but is not limited to,
                the Authentication TLV (<xref target="RFC5304"/>, <xref target="RFC5310"/>), the Checksum
                TLV, the Instance Identifier TLV, and the Flooding Parameters TLV of
                <xref target="RFC9681"/>. Deployments therefore do not have to give up any of these
                features, and in particular do not have to disable SNP authentication, in order to use ASH.
                Senders <bcp14>MUST NOT</bcp14> include an LSP Entries TLV in
                CASH or PASH; receivers <bcp14>MUST</bcp14> ignore such a TLV
                if present.
            </t>
            <t>
                Such TLVs <bcp14>MAY</bcp14> appear anywhere in the PDU, before, between or after the
                Node Range Hash TLVs, exactly as they may in CSNPs/PSNPs. A receiver <bcp14>MUST</bcp14>
                ignore their position when collecting Node Range Hash Entries.
            </t>
            <t>
                Where a TLV is computed over the PDU, it is computed over the complete CASH or PASH PDU,
                in the same order and with the same field treatment as for CSNPs/PSNPs. In particular
                the authentication digest of <xref target="RFC5304"/> and <xref target="RFC5310"/> covers
                the whole PDU including all Node Range Hash TLVs, and is computed with the PDU Length
                field already carrying the final length. The authentication configuration (keys, key
                chains, algorithms and any per PDU type exemptions) that applies to CSNPs
                <bcp14>MUST</bcp14> apply to CASHes, and the one that applies to PSNPs
                <bcp14>MUST</bcp14> apply to PASHes.
            </t>
            <t>
                A receiver <bcp14>MUST</bcp14> perform the same validation of these TLVs that it
                performs for a CSNP (for a CASH) or a PSNP (for a PASH), and <bcp14>MUST</bcp14> do so
                before any Node Range Hash Entry is compared or triggers any PASH, PSNP or flooding. A PDU failing that validation <bcp14>MUST</bcp14>
                be discarded exactly as a CSNP/PSNP failing it would be.
            </t>
            <t>
                The space these TLVs need <bcp14>MUST</bcp14> be reserved when computing how many Node
                Range Hash TLVs and entries fit within the MTU (<xref target="envelope"/>,
                <xref target="max-coverage"/>), so that adding them never requires dropping or
                re-splitting entries. If the space needed on a circuit exceeds what the implementation
                has reserved, it <bcp14>MUST NOT</bcp14> send CASHes or PASHes without those TLVs on
                that circuit; it <bcp14>MUST</bcp14> instead fall back to CSNPs/PSNPs there until
                sufficient space is reserved.
            </t>
        </section>

        <section toc="default" anchor="further">
            <name>Further Considerations</name>

            <section anchor="gr-epoch-reuse">
                <name>Graceful Restart Epoch Reuse</name>
                <t>
                    The four-bit ASH graceful-restart epoch distinguishes
                    exchanges with different epoch values, but its sixteen
                    values can be reused. A sufficiently delayed packet from
                    an earlier exchange with the same epoch can then be
                    indistinguishable from current signaling, even after
                    the neighbor, adjacency, level, and authentication checks
                    succeed. In particular, an old Snapshot Served indication
                    could be accepted for the current exchange. Authentication
                    alone does not establish freshness.
                </t>
                <t>
                    The epoch-selection and state-invalidation rules in
                    <xref target="graceful-restart"/> reduce this exposure
                    but do not eliminate it. This is a residual risk accepted
                    by this design for viable ASH graceful-restart operation,
                    not a guarantee against arbitrarily delayed or replayed
                    signaling.
                </t>
                <t>
                    Traditional graceful restart in <xref target="RFC8706"/>
                    does not carry an explicit per-restart epoch in its
                    Restart TLV or CSNP exchange. Its adjacency, timer, and
                    database-synchronization procedures provide other checks,
                    but do not supply an equivalent exchange identifier for
                    rejecting old signaling solely because it belongs to an
                    earlier restart. ASH adds that discrimination for
                    different epochs; finite epoch reuse remains a limitation.
                    This comparison does not imply identical completion
                    procedures or failure consequences in the two protocols.
                </t>
            </section>

            <section toc="default" anchor="envelope">
            <name>IS-IS Scale Envelope</name>
<!--            <t>-->
<!--                As first, obvious observation, ASHs are of negligible value on small networks of tens of nodes-->
<!--                and hundreds of fragments. Arguably, perfectly correctly implemented flooding is enough at any size (which is-->
<!--                a very optimistic assumption historically speaking) and CSNPs are unnecessary overhead built into-->
<!--                the protocol although practically speaking they contributed largely to the stability of the protocol-->
<!--                deployments over years.-->
<!--                The larger the network becomes the higher the cost of link flap or node restart and the higher-->
<!--                the steady state cost of issuing periodic CSNPs and hence ASH feature can stretch the scale of IS-IS-->
<!--                by a significant degree.-->
<!--                </t>-->

            <t>
                ASHs provide negligible benefit in small networks with only tens of nodes and hundreds of fragments.
                Perfect flooding would theoretically suffice at any scale (though history shows this is too optimistic),
                and CSNPs under such assumptions represent
                protocol overhead only - yet they have significantly contributed to IS-IS stability in real
                deployments.
                </t>
            <t>
                As networks grow larger, the costs of link flaps, node restarts, and periodic CSNP exchanges increase
                substantially. ASHs can significantly extend IS-IS scalability in these scenarios.
            </t>



<!--            <t>-->
<!--                If we start from the assumption that we want to push IS-IS to its practical limit we realize-->
<!--                that in deployment we have to contend with the limit of what comprises practically viable-->
<!--                flooding rate generated by fragment refreshes and database synchronization.-->
<!--                Path computations still play a role but-->
<!--                they can be much better deferred and take advantage of techniques like dampening and parallelization so-->
<!--                we disregard their impact here unless we deal with pathological cases of 1E6 nodes in a chain-->
<!--                with 1 fragment-->
<!--                each. -->
<!--                Hence, with more realistic assumption of something like 50E3 nodes and 1E6 fragments-->
<!--                we are at maximum configured lifetime in the realms of-->
<!--                1E6/2^16 fragments being refreshed per second and thus generating about 15 packets per-->
<!--                second load per interface (disregarding any flood reduction attempts using techniques like-->
<!--                <xref target="ID.draft-ietf-lsr-distoptflood-11"/>). Additionally, 1E6 fragments generate-->
<!--                about 10E3 CSNP packets on prevalent interface MTUs and thus during LSDB synchronization, to-->
<!--                achieve something in the order of relatively lame 120 seconds LSDB sync up we would have to contend with a-->
<!--                flooding rate of roughly 80 CSNPs per seconds. Multiplied that by an envelope of 16E3 desirable interfaces-->
<!--                we look at a sustained peak flooding rate to the control plane of somewhere around 1.5E6 packets-->
<!--                per second in the system, something that is at least an order of magnitude outside the envelope of any fast flooding-->
<!--                technique and power available for a on-system distributed control plane. Assuming maximum compression-->
<!--                using ASH we are however in the order of one additional packet on top of the flooding caused by-->
<!--                refreshes. This leaves the 15 * 16E3 ~ 2.4E5 flooding rate to be shouldered by reduction and-->
<!--                fast flooding techniques. Not an easy task but within the realm of the possible.-->

            <t>
                To push IS-IS to its practical limits, we must account for flooding rates driven by fragment refreshes
                and LSDB synchronization. Path computation impacts can be deferred - barring pathological scenarios -
                through dampening and parallelization,
                so we focus on realistic scenarios on the order of 50,000 nodes and 1 million fragments. We assume
                an outer envelope of 16K peers, which provides some margin over the largest deployments realized today.
            </t>
            <t>
                At maximum configured lifetime of 65K seconds, this generates ~15 packets/second per interface from refreshes (1M/65K
                fragments/second), plus periodically ~10,000 CSNP packets for full LSDB sync.
            </t>
            <t>
                Achieving sync within a modest 120 seconds
                requires ~80 CSNPs/second, and across 16,000 interfaces this represents a peak of 1.5 million
                packets/second - far
                beyond current fast-flooding capabilities.
                We disregard here techniques like <xref target="ID.draft-ietf-lsr-distoptflood-11"/>,
                especially since they do not improve CSNP scale.
            </t>

            <t>

                With maximum ASH compression, however, sync overhead drops to roughly one additional packet beyond
                refresh flooding, leaving ~250,000 packets/second (15 * 16K) to be handled by fast flooding and
                flood reduction
                techniques - a challenging but feasible target.
            </t>


            <t>
                The above makes it clear that combining fast flooding, flood reduction, and ASH
                will be essential for extending IS-IS scalability as deployments continue to grow.

<!--                With the above considerations it should become clear that a mixture of fast flooding, flood reduction-->
<!--                and ASH features will be critical to extend the deployable envelope of IS-IS given the ever-increasing-->
<!--                deployment of the protocol.-->
            </t>

            </section>

            <section anchor="max-coverage">
            <name>Maximum Advisable Hash Coverage</name>
                <t>
<!--                Although the mechanism can be applied to the point where a single merkle hash represents-->
<!--                an arbitrarily large database, such a single hash is not advisable. Limiting hash coverage-->
<!--                to the point where at maximum a single full ASH packet is far more preferable.-->

                    Although the mechanism can theoretically use a single Merkle hash to represent an arbitrarily large
                    database, such an approach is not advisable. Instead, it is far preferable to limit hash coverage so
                    that at minimum one full ASH packet is required.
                </t>

                <t>
                    In practice, limiting compression so that a maximum of about a dozen ASH packets covers the entire
                    database is usually sufficient. For example, a single maximally compressed ASH packet for a
                    10,000 - fragment database covers ~140 fragments per hash. Allowing for more ASH packets (e.g., 10 instead of
                    100 CSNPs) still provides a 10x compression factor, reduces disaggregation needs during LSDB changes, and
                    further lowers the already negligible collision risk (which in 10K sized LSDB is however
                    vanishingly small with a single hash already).


<!--                    Generally, limiting compression to the point where maximum of a dozen ASH packets cover the database-->
<!--                    can be practically speaking better than enough. As practical example a single ASH packet on-->
<!--                    a 1E3 fragments database compressed to maximum extent-->
<!--                    covers with each hash ~140 fragments. Allowing more ASH packets will lead to less disaggregation-->
<!--                    on LSDB changes obviously, lower collision possibility further (which in 1E3 sized LSDB is however-->
<!--                    vanishingly small with a single hash already) and e.g.-->
<!--                    10 ASH packets compared to 100 CSNP packets covering the LSDB normally-->
<!--                    is a compression factor of 10x already.-->
                </t>
            </section>

            <section anchor="collisions">
            <name>Hash Collision Probabilities</name>
<!--                <t>-->
<!--                    As first observation it is worth noting that even with CSNPs or PSNPs IS-IS does-->
<!--                    harbor a corner case where LSDB may not end up synchronized, especially on a node restart.-->
<!--                    In simple terms, issuing a fragment with the same sequence number and checksum'ed content that-->
<!--                    collides with a previously sent fragment with a dissimilar content that generates however-->
<!--                    the same 16 bit fletcher checksum will go undetected until the fragment lifetime expires.-->
<!--                    The likelihood of such an event is largely determined by the assumptions as to likelihood-->
<!--                    of a fletcher checksum colliding. A simple assumption we will work from is that values of-->
<!--                    fletcher-->
<!--                    checksums are uniformly likely, even if the content varies by relatively few bytes.-->
<!--                    With that assumption, the-->
<!--                    likelihood of such event is simply 1/2^16 or 0.001%. This will allow for further-->
<!--                    comparisons with ASH fletcher collision likelihood.-->
<!--                    </t>-->
                <t>


                    Even with CSNPs or PSNPs, IS-IS has a corner case where LSDB synchronization can fail - particularly
                    during node restarts. In simple terms, if a new fragment has the same sequence number and
                    different content but an identical 16-bit Fletcher
                    checksum, the collision goes undetected until the fragment expires.
                </t>
                <t>
                    Assuming Fletcher checksums are uniformly distributed (even with minor content changes), the
                    collision probability for that case is 1/2**16 ~ 0.0015%. This baseline enables meaningful
                    comparisons with ASH hash collision probabilities.

                </t>
                <t>
<!--                    ASH generates 48 bit fletcher checksums over what is basically PSNP data of a fragment-->
<!--                    and IS-IS length of the fragment.-->
<!--                    We will be concerned about the likelihood of two fragments being at the same time generating-->
<!--                    the same fletcher checksum while they are covered by the same ASH since such a constellation-->
<!--                    will make both fragments "disappear" due to the nature of the XOR checksum. Any collision-->
<!--                    that is not the in the node range hash is irrelevant.-->

                    ASH uses 64-bit <xref target="SIPHASH"/> over what is essentially PSNP data for a fragment plus its
                    IS-IS PDU length. One concern is the probability that two fragments covered by the same
                    hash produce identical hashes simultaneously. This would cause both fragments to
                    "cancel out" due to the XOR nature. Collisions between fragments in
                    different node range hashes are irrelevant.

                </t>
                <t>
                    Distinct sets of fragment hashes can also produce the same XOR
                    even when no individual fragment hashes collide. Hash agreement
                    therefore remains probabilistic, including for singleton ranges
                    containing multiple fragments. The simulations below examine
                    individual fragment-hash collisions, not all possible aggregate
                    collisions.
                    </t>
<!--                <t>-->
<!--                    One could further argue that XOR'ing several hashes can produce the same value as another-->
<!--                set of XOR'ed hashes but the likelihood of the sets having the same combination of modulo-->
<!--                1 sums on all of the 48 bits is so small (somewhere in the order of 1E-15)-->
<!--                    that we don't consider it further.-->
<!--                </t>-->

                <t>
                    Collision probability analysis is complex for the general case, though the birthday paradox gives a
                    rough estimate of 0.18% collision likelihood for 48-bit hashes in a 1M-sized set. For 64-bit
                    hashes this reduces to ~0.000,002,7%. Rather than
                    relying solely on statistical assumptions, we use extensive simulations that
                    mirror real-world conditions.
</t>
                <t>
                    These simulations model 50,000-node networks with 1M fragments, assuming node IDs differ by only 3
                    bytes, maximum fragment lifetimes, random protocol checksums on fragment refresh, and packet length changes
                    in just 5% of refreshes to reflect network stability. Results are derived from 32 networks running
                    for 2 years each.
                   </t>

<!--                <t>-->
<!--                    Probability statistics in not trivial to deal with the generic case of collisions (though it delivers based on-->
<!--                    birthday paradox first ballpark number of 0.18% collision likelihood in-->
<!--                    48 bit numbers colliding in 1E6 sized set, i.e. a single hash). Intuitively we would expect that using-->
<!--                    64 bit numbers with resulting birthday paradox probability of 0.0000027% would be necessary.-->
<!--                    But with intention of mirroring operational realities as close as possible, we fall on extensive-->
<!--                    simulations of refreshes on a vast network of 50E3 nodes with 1E6 fragments under assumptions-->
<!--                    of node IDs differing in 3 bytes only, maximum fragment lifetime and protocol checksums-->
<!--                    on each sequence number refresh being a random value. We change the length of the packet in-->
<!--                    5% of all refreshes only to mirror a rather stable network. 32 networks, each running for 2 years-->
<!--                    are used to derive the numbers.-->
<!--                </t>-->
                <t>
                    Across 64 years of simulated time and the resulting
                    36E9 fragment refreshes, we observed 142 collisions for the 48-bit variant of
                    <xref target="SIPHASH"/> across the whole set, or roughly ~0.000,000,4% - much lower than the birthday paradox
                    prediction.
                    However, assuming a single maximum-size
                    ASH packet covering the entire database, only 3 of those collisions matter
                    - a probability of ~0.000,000,008%,
                    or roughly 1 occurrence per 20 years. These collisions have an average lifetime of about 10 hours.
                    The rates are orders of magnitude lower than birthday paradox predictions, likely because node
                    IDs act as a consistent "salt" that effectively pre-partitions the probability space. This is
                    arguably "good enough" by a wide margin.

<!--                    The absolute number of collisions in 36E9 refreshes over set of all fragments-->
<!--                    is in the order of 200-300 collisions or-->
<!--                    6E-9 probability or expressed otherwise about 3 occurrences a year. Lifetime of such a-->
<!--                    collision shows on simulations as average of about 10 hours. The 6E-9 being significantly-->
<!--                    lower than the 1E-3 predicted by birthday paradox is likely to be attributed to the fact-->
<!--                    that node id can be seen as an always differing "salt" to the checksums and hence "pre-partitioning"-->
<!--                    the space of probabilities.-->
                </t>

                <t>
                    Nevertheless, further investigation using the standard 64-bit SipHash 1-3 variant
                    over the same scenario produces *no* detectable collisions. Measuring the CPU
                    cost of the 48-bit variant vs. the 64-bit variant (or even 64-bit traditional Fletcher checksum)
                    shows negligible differences of low single-digit percent with modern implementation
                    techniques. Thus, 64-bit <xref target="SIPHASH"/> 1-3 has been chosen and should provide
                    a very safe margin even for much larger databases.
                </t>

<!--                <t>-->
<!--                    The situation becomes more practically relevant when considering collisions within a single-->
<!--                    highest-compression packet containing 70 hashes. This roughly halves the collision rate, leading to-->
<!--                    about 1 collision per year in such a large network. If compression is instead limited to 70 ASH-->
<!--                    packets (rather than maximum compression), the rate drops further to approximately 1 collision per-->
<!--                    10 years.-->
<!--                    </t>-->

<!--                <t>-->
<!--                    The situation becomes more interesting and practically relevant-->
<!--                    once we start to consider how many collision occur in-->
<!--                    the highest compression packet with 70 hashes. This roughly halves the amount of collisions-->
<!--                    so we can expect in such a large network about 1 collision per year. Once we go to the assumption-->
<!--                    that we don't use maximum compression but limit it to 70 ASH packets we end up with about 1 collision-->
<!--                    per 10 years.-->
<!--                </t>-->

<!--                <t>-->
<!--                    Surprisingly, switching to 64-bit hashes reduces total collisions by only about 50%, and under-->
<!--                    maximum compression (single full ASH packet), the results are actually measurably worse. This-->
<!--                    appears to be because 64-bit collisions tend to cluster more closely together in the database - a-->
<!--                    phenomenon we currently lack an explanation for.-->

<!--&lt;!&ndash;                Surprisingly enough, going to 64 bit drops the total number of collisions by about 50% but under the&ndash;&gt;-->
<!--&lt;!&ndash;                assumptions of a single full ASH packet the outcome is measurably worse. This is based on the fact&ndash;&gt;-->
<!--&lt;!&ndash;                taht 64 bit collision hashes occur much "closer together" on the database, something for which we lack an explanation.&ndash;&gt;-->
<!--                </t>-->

                <t>
                    Ultimately, a highly conservative (not to say paranoid) implementation can simply monitor the LSDB for colliding
                    fragment hashes and exclude them from the same ASH hash. This forces receiving
                    nodes to compare separate range hashes instead, where System ID
                    boundaries permit. Such an approach reduces the risk of synchronization
                    misses to the highest extent possible with this partitioning.
                    It does not eliminate collisions: distinct sets of fragment hashes can
                    have the same XOR, and fragments belonging to one System ID cannot
                    be separated into different ASH ranges.
                </t>

<!--                <t>Obviously, a very, very conservative, not to say paranoid implementation can easily-->
<!--                monitor the LSDB for presence of colliding fletcher hashes on the fragments and simply prevent-->
<!--                such fragments being included in a single ASH hash which will force the receiving node-->
<!--                to consider separate hashes without a collision in them. This is sufficient to prevent-->
<!--                any kind of "misses" when using ASH to synchronize the databases.</t>-->
                <t>
                    Other techniques are possible, such as slowly walking the database and sending CSNPs. However, for a
                    1M-fragment database that generates 10,000 such CSNP packets, the chance of this detecting a collision
                    during its 10-hour window is rather unlikely.
<!--                    -->
<!--                    Other techniques are obviously possible like walking the database at slow speed and sending-->
<!--                    CSNPs. Given a 1E6 fragments database generates 10E3 such packets the chance of this preventing a-->
<!--                    collision during its 10 hours time is probably extremely small.-->
                </t>
            </section>

            <section>
            <name>Impact of Packet Losses</name>
                <t>
                    Hashes covering large numbers of fragments are more vulnerable to packet losses, as each lost packet
                    affects a much larger portion of the LSDB during synchronization. Implementations can choose ASH
                    node ranges freely, but should balance maximum compression against "good enough" compression that
                    reduces both collision risk and vulnerability to possible packet drops.

<!--                    Hashes covering large numbers of fragments will be more susceptible to packet losses since each loss-->
<!--                    covers a much larger part of the LSDB during synchronization. An implementation can choose the-->
<!--                    node ranges covered by ASHs in any way it desires but a consideration should be a balance-->
<!--                    between maximum reduction and a compression "good enough" that is less prone to collisions and-->
<!--                    unavoidable packet losses.-->
                </t>
            </section>

            <section>
            <name>Decompression and Caching/Comparison Optimizations</name>
                <t>
<!--                    As mentioned above a node may apply many strategies to speed up decompression.-->
<!--                    E.g. LSPs missing in ASHs as not covered by ranges are clearly "missing in action" and can-->
<!--                    be reflooded. As another example,-->
<!--                    small ranges where merkle mismatched can generate CSNPs, PSNPs or lead to flooding immediately.-->

                    As mentioned earlier, nodes can use various strategies to accelerate decompression. For example,
                    LSPs missing from CASHes (those not covered by any ranges) are clearly absent and can be immediately
                    reflooded. Similarly, small mismatched ranges can trigger immediate CSNPs, PSNPs, or direct
                    flooding.

                </t>
                <t>
<!--                    Caching of hashes can be applied at many levels since the merkle hashes suggested here are-->
<!--                    easily computed. Obviously keeping a hash on all fragments of a node and its pnodes is the-->
<!--                    simplest and most relevant candidate but other resolutions are easily achievable.-->
<!--                    Even if certain elements must be removed e.g. on receiving a-->
<!--                    range &lt;A &#45;&#45; B&gt; while the node already holds &lt; A &#45;&#45; B &amp; next-after-B&gt; the hash can be simply-->
<!--                    adjusted by removing 'next-after-B' node merkle hash from the cached result.-->

                    Caching of hashes can be applied at many levels. The
                    simplest and most useful approach is maintaining a raw XOR aggregate for all fragments of a node and its
                    pseudonodes, though other granularities work equally well. Even when adjusting for changes - such as
                    receiving a range &lt; A - B &gt; while having cached &lt; A - B &amp; next-after-B &gt;
                    - the cached hash can be quickly updated by
                    simply XOR'ing out the next-after-B node's raw aggregate.
                    Range-level reserved-value replacement is applied only to the final
                    comparison or advertisement value, as specified in <xref target="hashfn"/>,
                    not to the cached aggregates used for this calculation.

                </t>
                <t>
                    Implementations that adapt ASH compression from observed comparison results should distinguish
                    positive evidence from negative evidence. A matching range hash is strong evidence that every
                    node covered by that range matched and can therefore justify maintaining or increasing
                    compression for those nodes. In contrast, a mismatching coarse range proves only that at least
                    one covered node differs; it does not identify which node or nodes caused the mismatch.
                    Implementations should therefore avoid assigning that negative result to every node in the
                    range. Instead, they should use progressively finer PASH comparisons, and ultimately SNP
                    comparison or flooding, to obtain sufficiently specific evidence before reducing compression
                    for individual nodes. Otherwise, a small localized change can incorrectly drive an entire
                    coarse range toward little or no compression.
                </t>
            </section>

        </section>


        <section toc="default">
            <name>Security Considerations</name>

            <t>ASH security relies on the same mechanisms protecting IS-IS PDU integrity.
                As required in <xref target="additional-tlvs"/>, CASHes and PASHes are authenticated
                with the same mechanisms (<xref target="RFC5304"/>, <xref target="RFC5310"/>) and
                configuration as the CSNPs and PSNPs they replace, so enabling ASH neither weakens nor
                removes SNP authentication.
            </t>
            <t>
                A received hash drives more work than a received CSNP entry: a mismatch triggers
                further PASHes, PSNPs and flooding. Validating authentication before any of this happens
                is therefore required, so that an unauthenticated PDU cannot trigger that work.
            </t>

        </section> <!-- end of security considerations -->

        <section anchor="IGP_IANA">
            <name>IANA Considerations</name>
            <t>
                IANA is requested to allocate Type TBD-ASH-GR from the
                "IS-IS TLV Codepoints" registry for the ASH GR Suggested
                Epoch TLV, permitted in point-to-point IIHs as defined in
                <xref target="graceful-restart-wire"/>.
            </t>
            <t>
                IANA is requested to allocate two bits from the "IS-IS Bit Values for Hello
                Capability TLV Flags" registry defined in <xref target="ID.draft-ginsberg-lsr-hello-capability-00"/>,
                named "ASH_RX" and "ASH_TX", indicating respectively that the advertising node
                is willing to receive and process, and/or may originate, ASH (CASH/PASH) packets
                on that adjacency in place of CSNPs/PSNPs.
            </t>
            <t>
                IANA is requested to allocate a codepoint (type TBD) from the "IS-IS TLV
                Codepoints" registry for the Node Range Hash TLV, valid within CASH and PASH
                PDUs as defined in <xref target="cash-format"/> and <xref target="pash-format"/>.
            </t>
            <t>
                IANA is requested to allocate four new codepoints from the "PDU Types" registry
                under "Intermediate System to Intermediate System (IS-IS) Parameters", one for
                each combination of CASH or PASH and Level 1 or Level 2, analogous to the existing Level 1 and
                Level 2 Complete/Partial SNP codepoints, as follows:
            </t>
            <table>
                <thead>
                    <tr>
                        <th align="center">Value</th>
                        <th align="left">Description</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td align="center">TBD1</td>
                        <td align="left">Level 1 CASH</td>
                    </tr>
                    <tr>
                        <td align="center">TBD2</td>
                        <td align="left">Level 2 CASH</td>
                    </tr>
                    <tr>
                        <td align="center">TBD3</td>
                        <td align="left">Level 1 PASH</td>
                    </tr>
                    <tr>
                        <td align="center">TBD4</td>
                        <td align="left">Level 2 PASH</td>
                    </tr>
                </tbody>
            </table>
            <t>
                As with existing SNP PDU types, separate Level 1 and Level 2 codepoints are
                requested for both CASH and PASH so that the PDU Type field alone identifies both
                the packet's function and the level it applies to.
            </t>
        </section>

        <!-- 2 -->
        <section toc="default">
            <name>Contributors</name>

            <t>TBD</t>

        </section> <!-- end of contributors -->

        <!-- 2 -->
        <section toc="default">
            <name>Acknowledgement</name>
            <t>

                People have been talking about "compressing CSNPs" for a very long time, reportedly going back to when
                Radia Perlman and an insomniac Dave Katz were walking the halls discussing it. Recent attempts to scale
                the protocol much further have made it worthwhile to turn this idea into a standardized, practical
                engineering solution.
            </t>
            <t>
                Les Ginsberg identified several unresolved issues and contributed alternative ideas to the draft.
            </t>
            <t>
                Job Snijders initiated the discussion of <xref target="SIPHASH"/> as a likely better solution than
                traditional Fletcher checksumming of fragments.
            </t>
            <t>
                <xref target="CLAUDE">Claude (Anthropic)</xref> and
                <xref target="GPT">GPT (OpenAI)</xref>
                assisted in reviewing the draft specification, identifying
                ambiguities in zero-hash semantics, overlap handling, PDU header-to-entry range
                relationships, and many intricacies of ASH GR.
            </t>

        </section> <!-- end of contributors -->

    </middle>

    <back>

        <references title="Normative References">

            <reference anchor="RFC2119">
                <front>
                    <title>Key words for use in RFCs to Indicate Requirement Levels</title>
                    <author initials="S." surname="Bradner" fullname="S. Bradner"/>
                    <date month="March" year="1997"/>
                </front>
                <seriesInfo name="BCP" value="14"/>
                <seriesInfo name="RFC" value="2119"/>
                <seriesInfo name="DOI" value="10.17487/RFC2119"/>
            </reference>

            <reference anchor="RFC8174">
                <front>
                    <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
                    <author initials="B." surname="Leiba" fullname="B. Leiba"/>
                    <date month="May" year="2017"/>
                </front>
                <seriesInfo name="BCP" value="14"/>
                <seriesInfo name="RFC" value="8174"/>
                <seriesInfo name="DOI" value="10.17487/RFC8174"/>
            </reference>

            <reference anchor="RFC5304">
                <front>
                    <title>IS-IS Cryptographic Authentication</title>
                    <author initials="T." surname="Li" fullname="T. Li"/>
                    <author initials="R." surname="Atkinson" fullname="R. Atkinson"/>
                    <date month="October" year="2008"/>
                </front>
                <seriesInfo name="RFC" value="5304"/>
                <seriesInfo name="DOI" value="10.17487/RFC5304"/>
            </reference>

            <reference anchor="RFC5310">
                <front>
                    <title>IS-IS Generic Cryptographic Authentication</title>
                    <author initials="M." surname="Bhatia" fullname="M. Bhatia"/>
                    <author initials="V." surname="Manral" fullname="V. Manral"/>
                    <author initials="T." surname="Li" fullname="T. Li"/>
                    <author initials="R." surname="Atkinson" fullname="R. Atkinson"/>
                    <author initials="R." surname="White" fullname="R. White"/>
                    <author initials="M." surname="Fanto" fullname="M. Fanto"/>
                    <date month="February" year="2009"/>
                </front>
                <seriesInfo name="RFC" value="5310"/>
                <seriesInfo name="DOI" value="10.17487/RFC5310"/>
            </reference>

            <reference anchor="SIPHASH" target="https://131002.net/siphash/">
                <front>
                    <title>SipHash: A Fast Short-Input PRF</title>
                    <author initials="J.-P." surname="Aumasson" fullname="Jean-Philippe Aumasson"/>
                    <author initials="D. J." surname="Bernstein" fullname="Daniel J. Bernstein"/>
                    <date year="2012"/>
                </front>
                <seriesInfo name="Lecture Notes in Computer Science" value="Vol. 7668, INDOCRYPT 2012, pp. 489-508"/>
            </reference>

            <reference anchor="ID.draft-ginsberg-lsr-hello-capability-00" target="https://www.ietf.org/id/draft-ginsberg-lsr-hello-capability-00.txt">
                <front>
                    <title>IS-IS Hello Capability</title>
                    <author initials="L." surname="Ginsberg et al.">
                        <organization/>
                    </author>
                    <date month="Aug" year="2026"/>
                </front>
            </reference>

            <reference anchor="RFC8706">
                <front>
                    <title>Restart Signaling for IS-IS</title>
                    <author initials="L." surname="Ginsberg et al.">
                        <organization/>
                    </author>
                    <date month="February" year="2020"/>
                </front>
                <seriesInfo name="RFC" value="8706"/>
                <seriesInfo name="DOI" value="10.17487/RFC8706"/>
            </reference>

        </references> <!-- end of normative references -->

        <references title="Informative References">


            <reference anchor="MERKLE">
                <front>
                    <title>A Digital Signature Based on a Conventional Encryption Function</title>
                    <author initials="R.C." surname="Merkle">
                    </author>
                    <date year="1988"/>
                    <keyword>Advances in Cryptology &ndash; CRYPTO '87</keyword>
                </front>
            </reference>

            <reference anchor="HASHES">
                <front>
                    <title>Security considerations for incremental hash functions based on pair block chaining</title>
                    <author initials="C.-W." surname="Phan">
                    </author>
                    <date year="2006"/>
                    <keyword>Computers and Security 25</keyword>

                </front>
            </reference>

            <reference anchor="SKIP">
                <front>
                    <title>Skip lists: A probabilistic alternative to balanced trees</title>
                    <author initials="W." surname="Pugh">
                    </author>
                    <date year="1990"/>
                    <keyword>Communications of the ACM</keyword>

                </front>
            </reference>

            <reference anchor="CLAUDE" target="https://www.anthropic.com/claude">
                <front>
                    <title>Claude: AI Assistant</title>
                    <author>
                        <organization>Anthropic</organization>
                    </author>
                    <date year="2025"/>
                </front>
            </reference>

            <reference anchor="GPT" target="https://arxiv.org/abs/2303.08774">
                <front>
                    <title>GPT-4 Technical Report</title>
                    <author>
                        <organization>OpenAI</organization>
                    </author>
                    <date month="March" year="2023"/>
                </front>
                <seriesInfo name="arXiv" value="2303.08774"/>
                <seriesInfo name="DOI" value="10.48550/arXiv.2303.08774"/>
            </reference>

            <reference anchor="ID.draft-ietf-lsr-distoptflood-11" target="https://www.ietf.org/id/draft-ietf-lsr-distoptflood-11.txt">
                <front>
                    <title>IS-IS Distributed Flooding Reduction</title>
                    <author initials="R." surname="White et al.">
                        <organization/>
                    </author>
                    <date month="Oct" year="2025"/>
                </front>
            </reference>

            <reference anchor="RFC9681">
                <front>
                    <title>IS-IS Fast Flooding</title>
                    <author initials="B." surname="Decraene et al.">
                        <organization/>
                    </author>
                    <date month="November" year="2024"/>
                </front>
                <seriesInfo name="RFC" value="9681"/>
                <seriesInfo name="DOI" value="10.17487/RFC9681"/>
            </reference>

        </references> <!-- end of informative references -->

        <section anchor="refcode">
            <name>Reference Implementation of SIP Fragment Hashing</name>

            <figure>
            <artwork align="center" name="" type="" alt=""><![CDATA[
<CODE BEGINS>
pub fn fragment_hash(
    fragmentid: &SharedFragmentID,
    fragmentcontent: &FragmentContent,
) -> ASHHash {
    let nid = fragmentid.node.node_id().0;
    let pnodebe = fragmentid.pnode.0.to_be_bytes();
    let seqnrbe = fragmentcontent.seqnr.0.to_be_bytes();
    let fragmentnrbe = fragmentid.fragmentnr.0.to_be_bytes();
    let csumbe = fragmentcontent.isis_checksum.0.to_be_bytes();
    let lenbe = fragmentcontent.isis_pdu_length.0.to_be_bytes();

    let rotate_in_primary = nid.iter().chain(
        csumbe.iter().chain(
            seqnrbe.iter().chain(
                fragmentnrbe
                    .iter()
                    .chain(lenbe.iter().chain(pnodebe.iter())),
            ),
        ),
    );

    let key = [
        1, 2, 3, 4, 5, 6, 7, 8,
        9, 10, 11, 12, 13, 14, 15, 16u8,
    ];
    let mut hasher = SipHasher13::new_with_key(&key);
    let mut sl = [0u8; 16];
    rotate_in_primary
        .copied()
        .collect_slice_checked(&mut sl[..]);
    hasher.write(&sl);
    let hash = ASHHash(hasher.finish());

    if hash == EMPTY_ASHHASH || hash == ASHHash(u64::MAX) {
        ASHHash(1)
    } else {
        hash
    }
}
<CODE ENDS>
]]></artwork>
            </figure>
        </section>

    </back>

</rfc>
