Skip to main content

PALA-1: A Tamper-Evident Audit Record Format for Constrained and Disconnected Deployments
draft-sparysh-pala-audit-01

Document Type Active Internet-Draft (individual)
Authors Andrii Sparysh , Oleksandr Verteletskyi
Last updated 2026-10-02
RFC stream (None)
Intended RFC status (None)
Formats
Stream Stream state (No stream defined)
Consensus boilerplate Unknown
RFC Editor Note (None)
IESG IESG state I-D Exists
Telechat date (None)
Responsible AD (None)
Send notices to (None)
draft-sparysh-pala-audit-01
Network Working Group                                         A. Sparysh
Internet-Draft                                           O. Verteletskyi
Intended status: Informational                        Assault Consulting
Expires: 5 April 2027                                     2 October 2026

    PALA-1: A Tamper-Evident Audit Record Format for Constrained and
                        Disconnected Deployments
                      draft-sparysh-pala-audit-01

Abstract

   This document describes PALA-1 -- version 1 of the Portable Append-
   only Log for Audit -- a compact binary record format for tamper-
   evident audit trails produced by AI inference runtimes and robotic
   control systems.  It is designed for a class of deployment defined by
   three constraints that hold together: the hardware is computationally
   modest and its cycles are reserved for the workload and the power
   budget rather than for the audit trail; no external witness is
   reachable, whether because policy forbids outbound contact or because
   the platform operates beyond connectivity, so a witness is
   unavailable by rule or by physics rather than by circumstance; and
   the right to verify the trail is separated from the right to read
   what it records.

   Records form an append-only hash chain.  Integrity verification
   requires no key material of any kind, inspects no record bodies, and
   costs one hash per record rather than one signature.  The format
   distinguishes three separately answerable questions -- internal
   consistency, completeness against an external anchor, and existence
   at a point in time against an external witness -- and states which of
   the three a given trail actually supports rather than implying all
   three.

   The format is frozen at version 1.0 and is described here as it is.
   This document presents an existing wire format; it does not revise
   one.  Where a deployment does permit an external witness, a chain
   head may be published to a transparency service such as that of the
   Supply Chain Integrity, Transparency, and Trust architecture (SCITT,
   RFC 9943); that path is described but is not part of the hashing
   contract.

Status of This Memo

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

Sparysh & Verteletskyi    Expires 5 April 2027                  [Page 1]
Internet-Draft            PALA-1 Audit Records              October 2026

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF).  Note that other groups may also distribute
   working documents as Internet-Drafts.  The list of current Internet-
   Drafts is at https://datatracker.ietf.org/drafts/current/.

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   This Internet-Draft will expire on 5 April 2027.

Copyright Notice

   Copyright (c) 2026 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents (https://trustee.ietf.org/
   license-info) in effect on the date of publication of this document.
   Please review these documents carefully, as they describe your rights
   and restrictions with respect to this document.

Table of Contents

   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   3
     1.1.  The constraints . . . . . . . . . . . . . . . . . . . . .   3
     1.2.  What the constraints force  . . . . . . . . . . . . . . .   4
     1.3.  On COSE . . . . . . . . . . . . . . . . . . . . . . . . .   5
     1.4.  Scope . . . . . . . . . . . . . . . . . . . . . . . . . .   6
     1.5.  A note on regulation  . . . . . . . . . . . . . . . . . .   6
     1.6.  Terminology . . . . . . . . . . . . . . . . . . . . . . .   6
   2.  Record layout . . . . . . . . . . . . . . . . . . . . . . . .   7
     2.1.  Fixed header -- 156 bytes . . . . . . . . . . . . . . . .   7
     2.2.  TLV extensions  . . . . . . . . . . . . . . . . . . . . .   8
     2.3.  body_len -- exactly what it counts  . . . . . . . . . . .  10
     2.4.  File container  . . . . . . . . . . . . . . . . . . . . .  10
   3.  Record types  . . . . . . . . . . . . . . . . . . . . . . . .  11
     3.1.  Spans are two records . . . . . . . . . . . . . . . . . .  11
     3.2.  AGGREGATE body schema . . . . . . . . . . . . . . . . . .  12
     3.3.  SHED is in the never-shed class . . . . . . . . . . . . .  13
     3.4.  Profiles  . . . . . . . . . . . . . . . . . . . . . . . .  13
   4.  Recording at the dispatch boundary  . . . . . . . . . . . . .  14
   5.  Chain rules . . . . . . . . . . . . . . . . . . . . . . . . .  15
     5.1.  Linking . . . . . . . . . . . . . . . . . . . . . . . . .  15
     5.2.  Genesis and boots . . . . . . . . . . . . . . . . . . . .  15
     5.3.  Merkle aggregation  . . . . . . . . . . . . . . . . . . .  16
     5.4.  Bodies, encryption and crypto-shredding . . . . . . . . .  17

Sparysh & Verteletskyi    Expires 5 April 2027                  [Page 2]
Internet-Draft            PALA-1 Audit Records              October 2026

   6.  Time  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  18
   7.  Assurance tiers . . . . . . . . . . . . . . . . . . . . . . .  19
   8.  Relationship to transparency services . . . . . . . . . . . .  19
   9.  Verification  . . . . . . . . . . . . . . . . . . . . . . . .  22
     9.1.  Header-only chain verification  . . . . . . . . . . . . .  22
     9.2.  Completeness against an anchor  . . . . . . . . . . . . .  24
     9.3.  Existence against a witness . . . . . . . . . . . . . . .  24
     9.4.  Semantic checks . . . . . . . . . . . . . . . . . . . . .  25
     9.5.  Body verification (needs the key) . . . . . . . . . . . .  25
     9.6.  Forward compatibility . . . . . . . . . . . . . . . . . .  25
   10. Test vectors  . . . . . . . . . . . . . . . . . . . . . . . .  26
   11. Related work  . . . . . . . . . . . . . . . . . . . . . . . .  29
   12. Relationship to the agent auditing architecture . . . . . . .  31
   13. Implementation status . . . . . . . . . . . . . . . . . . . .  33
   14. Security considerations . . . . . . . . . . . . . . . . . . .  36
   15. IANA considerations . . . . . . . . . . . . . . . . . . . . .  37
   16. References  . . . . . . . . . . . . . . . . . . . . . . . . .  37
     16.1.  Normative References . . . . . . . . . . . . . . . . . .  37
     16.2.  Informative References . . . . . . . . . . . . . . . . .  38
   Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . .  42
   Changes from draft-sparysh-pala-audit-00  . . . . . . . . . . . .  42
   Contributors  . . . . . . . . . . . . . . . . . . . . . . . . . .  42
   Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  43

1.  Introduction

   An AI inference runtime executing on a workstation, an edge device,
   or a robot produces a sequence of events that someone may later need
   to reconstruct: what was asked, what was answered, which tools were
   dispatched, what came back, and what the operator did about it.

   A growing body of work addresses this by making a record transparent:
   the producer signs a statement, registers it with an external service
   maintaining an append-only log, and receives a receipt proving
   registration [RFC9943].  Where that construction is available it
   answers questions this format cannot answer alone, and this document
   describes how to reach it (Section 8).

   It presupposes two things: that cycles are available to sign each
   record, and that a witness is reachable.  This document addresses the
   deployments where neither holds.

1.1.  The constraints

   Three constraints defined this format.  They are stated first because
   every subsequent decision follows from them, and a reader who rejects
   them will reject the format.

Sparysh & Verteletskyi    Expires 5 April 2027                  [Page 3]
Internet-Draft            PALA-1 Audit Records              October 2026

   *C1 -- the hardware is modest, and its cycles are reserved for the
   workload and the power budget.* The target is a control system or an
   inference runtime on commodity or embedded hardware, frequently one
   that carries its own power.  A trail that writes thousands of records
   in a session cannot spend an asymmetric signature on each one: that
   cost is taken directly from the workload the device exists to run,
   and on a self-powered platform it is taken from endurance as well.
   The usual answer to a compute constraint -- provision a faster
   processor -- does not resolve the second of those, since a faster
   processor draws more.  Integrity therefore has to come from hashing a
   chain, not from signing a record.

   *C2 -- no external witness is reachable.* This is not a network that
   happens to be down.  It is either a regime under which reaching an
   external service is not permitted, or a platform operating beyond
   connectivity by the nature of its task; in both cases the witness is
   unavailable *by rule or by physics*, and no engineering effort
   changes it.  The distinction from C1 matters: C1 is a constraint that
   better hardware partly relaxes over time, while C2 does not relax at
   all.  Any design that requires a service to be reachable before a
   record is trustworthy is inapplicable here, not merely inconvenient.

   *C3 -- the right to verify is separated from the right to read.* An
   auditor may be entitled to establish that a trail is intact and
   complete while holding no clearance for what the trail records.  This
   is an access regime, not a privacy preference, and it makes
   "verification requires reading the records" an unsatisfiable
   requirement rather than an acceptable cost.

1.2.  What the constraints force

   Each of the following is a consequence, not a preference.

   From C1: the chain hash covers a fixed-length record header, one hash
   per record, no asymmetric operation on the write path.

   From C1 and C3 together: because there is no per-record signature,
   there is no per-record signature to check, and integrity verification
   consequently needs no key material at all.  A verifier reads headers,
   reports that a million records contain no break, and has read none of
   the bodies.  The header is fixed-length so that it can be scanned and
   sought without parsing a variable structure.

   From C3: bodies are bound into the chain by a digest carried inside
   the header, so a body may be encrypted, or its key destroyed, while
   the chain continues to verify.  Key destruction is an ordinary
   lifecycle operation in such a deployment rather than an exceptional
   one.

Sparysh & Verteletskyi    Expires 5 April 2027                  [Page 4]
Internet-Draft            PALA-1 Audit Records              October 2026

   From C2: existence in time is never asserted by the format on its own
   authority.  Where a deployment does permit publication, the claim is
   made after the fact by a record naming an explicit range and a
   witness, and a verifier reports the witnessed range and the
   unwitnessed remainder separately (Section 8).  A trail that has never
   been witnessed says so.

   And from all three: the format is binary and has no canonicalisation
   step, because a canonicalisation step is a place where two conforming
   implementations can disagree about the bytes being hashed.  A JSON
   canonicalisation such as [RFC8785] serialises numbers through double
   semantics, and a nanosecond wall-clock value exceeds the largest
   integer a double represents exactly, so its canonical form is lossy.
   The available workarounds -- the value as a string, truncation to
   milliseconds -- each trade the property JSON was chosen for against
   the one property this format cannot trade: byte-exact agreement
   between independent implementations.  Inspectability is recovered by
   a converter, which is a tool and not part of the hashing contract.

1.3.  On COSE

   The question this section exists to answer is why the records are not
   COSE_Sign1 [RFC9052] structures, given that CBOR encodes a nanosecond
   integer exactly and is not subject to the objection above.

   The objection above is to JSON canonicalisation, and it does not
   apply to CBOR.  A CBOR encoding could carry the same chain semantics
   this document defines, and an implementer who values ecosystem
   alignment over the constraints of Section 1.1 should consider that a
   reasonable design.

   What C1 and C3 exclude is not the encoding but the envelope.
   COSE_Sign1 places a signature on each record and a verification key
   in the hands of anyone checking one.  Both are intrinsic to what a
   single-signer signature envelope is, not parameters of it, and both
   are the two properties C1 and C3 rule out.  A signature per record is
   the cost C1 forbids; a key required to verify is the dependency C3
   forbids.

   The trade-off applies in both directions and is stated here rather
   than left for a reader to find.  A COSE_Sign1 record is self-
   sufficient: it carries its own evidence, and one such record proves
   something on its own.  A PALA-1 record proves nothing on its own --
   the sequence is what carries the evidence, and a single record
   removed from its chain is inert.  For deployments that write few
   records, are not compute-constrained, and need per-record self-
   sufficiency, the envelope is the better choice and this format is the
   wrong tool.

Sparysh & Verteletskyi    Expires 5 April 2027                  [Page 5]
Internet-Draft            PALA-1 Audit Records              October 2026

   Where the two meet is Section 8: a chain head expressed as a Signed
   Statement is a COSE_Sign1 structure, so the envelope is used exactly
   where its cost is paid once rather than per record.

1.4.  Scope

   In scope: the byte layout of a record, the rules linking records into
   a chain, the aggregation of record digests, the encoding of assurance
   claims, and a normative verification procedure any party can
   implement from this document alone.

   Out of scope: agent-to-agent protocols, authorization decisions,
   policy evaluation, transport, and the internal protocol of any
   witness.  This document records what a runtime did.  It does not
   decide what a runtime may do, and it makes no claim about the honesty
   of the runtime at the moment of recording (Section 14).

1.5.  A note on regulation

   The constraints of Section 1.1 arose in deployments that are also
   subject to record-keeping, data-minimisation and erasure obligations,
   and those obligations shaped what the format was required to support:
   that a trail can be verified without disclosing its contents, and
   that a record's content can be destroyed without falsifying the trail
   it sits in.

   No claim is made that this format satisfies any legal obligation.
   Regulations of this kind do not prescribe formats, and a format
   cannot discharge a duty that falls on an operator.  The relationship
   is only that a set of obligations produced a set of technical
   requirements, and this document specifies a format meeting them.

1.6.  Terminology

   PALA stands for Portable Append-only Log for Audit. _Portable_: a
   PALA-1 log verifies on any machine, offline, with no key material.
   _Append-only_: records are only ever added to a hash chain. _For
   audit_: that is its purpose.  The expansion is descriptive and has no
   normative effect.

   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
   "OPTIONAL" in this document are to be interpreted as described in
   BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
   capitals, as shown here.

Sparysh & Verteletskyi    Expires 5 April 2027                  [Page 6]
Internet-Draft            PALA-1 Audit Records              October 2026

2.  Record layout

   A record is header || body.  The body may be empty.

2.1.  Fixed header -- 156 bytes

     +========+======+================+=======+=====================+
     | Offset | Size | Field          | Type  | Notes               |
     +========+======+================+=======+=====================+
     |      0 |    4 | magic          | bytes | PALA (0x50 0x41     |
     |        |      |                |       | 0x4C 0x41)          |
     +--------+------+----------------+-------+---------------------+
     |      4 |    2 | format_version | u16   | 1                   |
     +--------+------+----------------+-------+---------------------+
     |      6 |    2 | header_len     | u16   | 156 + TLV bytes.    |
     |        |      |                |       | Total header        |
     |        |      |                |       | length.             |
     +--------+------+----------------+-------+---------------------+
     |      8 |    2 | record_type    | u16   | Section 3           |
     +--------+------+----------------+-------+---------------------+
     |     10 |    1 | assurance_tier | u8    | Section 7           |
     +--------+------+----------------+-------+---------------------+
     |     11 |    1 | time_trust     | u8    | Section 6           |
     +--------+------+----------------+-------+---------------------+
     |     12 |    8 | seq            | u64   | Monotonic within a  |
     |        |      |                |       | chain.  Never       |
     |        |      |                |       | reused.             |
     +--------+------+----------------+-------+---------------------+
     |     20 |   16 | boot_id        | bytes | Opaque, unique per  |
     |        |      |                |       | boot                |
     +--------+------+----------------+-------+---------------------+
     |     36 |   32 | prev_hash      | bytes | record_hash of the  |
     |        |      |                |       | previous record     |
     +--------+------+----------------+-------+---------------------+
     |     68 |   16 | span_id        | bytes | Zero if not span-   |
     |        |      |                |       | scoped              |
     +--------+------+----------------+-------+---------------------+
     |     84 |   16 | parent_span_id | bytes | Zero = root         |
     +--------+------+----------------+-------+---------------------+
     |    100 |    8 | monotonic_ns   | u64   | Since boot.  Never  |
     |        |      |                |       | wall-clock.         |
     +--------+------+----------------+-------+---------------------+
     |    108 |    8 | wall_clock_ns  | i64   | Nanoseconds since   |
     |        |      |                |       | Unix epoch, or 0    |
     +--------+------+----------------+-------+---------------------+
     |    116 |    4 | key_id         | u32   | 0 = no body, or a   |
     |        |      |                |       | cleartext body.     |
     |        |      |                |       | Section 5.4         |

Sparysh & Verteletskyi    Expires 5 April 2027                  [Page 7]
Internet-Draft            PALA-1 Audit Records              October 2026

     +--------+------+----------------+-------+---------------------+
     |    120 |    4 | body_len       | u32   | Section 2.3         |
     +--------+------+----------------+-------+---------------------+
     |    124 |   32 | body_digest    | bytes | SHA-256 [FIPS180-4] |
     |        |      |                |       | of the body bytes,  |
     |        |      |                |       | or 32 zero bytes if |
     |        |      |                |       | body_len = 0        |
     +--------+------+----------------+-------+---------------------+

                                 Table 1

   All multi-byte integers little-endian.  No padding. header_len MUST
   be >= 156 and MUST equal the actual number of header bytes.

2.2.  TLV extensions

   Immediately after the fixed header, until header_len is reached:

   type: u16 | length: u16 | value: <length> bytes

   A TLV item MUST NOT overrun header_len.  The last item MUST end
   exactly at header_len.

   *Unknown TLV types MUST be hashed and MUST NOT cause rejection.* They
   are opaque bytes to a verifier that does not know them.  This is what
   makes Section 9.5 possible.

Sparysh & Verteletskyi    Expires 5 April 2027                  [Page 8]
Internet-Draft            PALA-1 Audit Records              October 2026

     +========+======================+===============================+
     | Type   | Name                 | Value                         |
     +========+======================+===============================+
     | 0x0001 | ORIGIN_ROLE          | UTF-8 role of the emitting    |
     |        |                      | component, e.g. planner.main; |
     |        |                      | vocabularies are profile-     |
     |        |                      | defined (Section 3.4)         |
     +--------+----------------------+-------------------------------+
     | 0x0002 | ORIGIN_MODEL_DIGEST  | 32 bytes                      |
     +--------+----------------------+-------------------------------+
     | 0x0003 | ORIGIN_CONFIG_DIGEST | 32 bytes                      |
     +--------+----------------------+-------------------------------+
     | 0x0011 | MERKLE_TREE_HASH     | 32 bytes                      |
     +--------+----------------------+-------------------------------+
     | 0x0012 | MERKLE_LEAF_COUNT    | u32                           |
     +--------+----------------------+-------------------------------+
     | 0x0020 | SHED_CLASS           | u16                           |
     +--------+----------------------+-------------------------------+
     | 0x0021 | SHED_COUNT           | u32                           |
     +--------+----------------------+-------------------------------+
     | 0x0022 | SHED_WINDOW_NS       | u64                           |
     +--------+----------------------+-------------------------------+
     | 0x0030 | WITNESS_KIND         | u16 -- 1 = transparency log,  |
     |        |                      | 2 = [RFC3161] TSA             |
     +--------+----------------------+-------------------------------+
     | 0x0031 | WITNESS_RANGE_LO     | u64                           |
     +--------+----------------------+-------------------------------+
     | 0x0032 | WITNESS_RANGE_HI     | u64                           |
     +--------+----------------------+-------------------------------+
     | 0x0033 | WITNESS_RECEIPT      | opaque                        |
     +--------+----------------------+-------------------------------+
     | 0x0040 | SHRED_KEY_ID         | u32                           |
     +--------+----------------------+-------------------------------+
     | 0x0050 | ANCHOR_HEAD          | 32 bytes -- the head written  |
     |        |                      | to the anchor store.          |
     |        |                      | Section 9.2                   |
     +--------+----------------------+-------------------------------+

                                  Table 2

   *TLV type numbers and record type numbers are separate namespaces.*
   TLV 0x0011 MERKLE_TREE_HASH and record type 0x0020 MERKLE both
   concern Merkle aggregation and are different numbers in different
   spaces.  The names are kept distinct for that reason; do not read one
   table with the other's numbers.

Sparysh & Verteletskyi    Expires 5 April 2027                  [Page 9]
Internet-Draft            PALA-1 Audit Records              October 2026

   *origin is three TLVs, not a name.* (ORIGIN_ROLE,
   ORIGIN_MODEL_DIGEST, ORIGIN_CONFIG_DIGEST) -- because the first
   question after an incident is which weights produced an output, and a
   component name alone does not answer it.  A model update is a
   different origin and the chain shows it.

2.3.  body_len -- exactly what it counts

      *body_len is the total number of bytes following the header, up to
      the start of the next record.* A reader that consumes body_len
      bytes after header_len has consumed the whole body and nothing
      else.

   For an encrypted body (Section 5.4) that total covers nonce ||
   ciphertext || tag -- the nonce is *inside* the count, not additional
   to it. body_digest is taken over exactly those body_len bytes.

   This is stated explicitly because it is the most likely implementer
   error: a reader that treats the 12-byte nonce as a prefix outside
   body_len truncates the GCM tag, fails to decrypt, and attributes the
   failure to the cipher.

2.4.  File container

   A log file is records *concatenated back-to-back, with no file
   header, no framing, and no trailing metadata*. The first record
   starts at byte 0.

   A reader finds record boundaries from the records themselves: read
   the fixed header at the current offset, confirm magic, take
   header_len and body_len, and the next record begins at offset +
   header_len + body_len.  A file whose final record ends exactly at
   end-of-file is well-formed; anything else is a truncated tail and
   MUST be reported as such (it is not a chain break at any earlier
   record).

   There is deliberately nothing else at file level.  A file header
   would be one more thing to version, and the records are already self-
   delimiting; rotation, segmentation and naming are storage concerns
   outside this format -- a segment boundary is invisible to the chain,
   which continues across files exactly as it continues across boots.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 10]
Internet-Draft            PALA-1 Audit Records              October 2026

3.  Record types

    +========+============+==============+===========================+
    | Value  | Name       | Class        | Meaning                   |
    +========+============+==============+===========================+
    | 0x0001 | GENESIS    | never-shed   | Chain origin.             |
    |        |            |              | Section 5.2               |
    +--------+------------+--------------+---------------------------+
    | 0x0002 | BOOT       | never-shed   | New boot.  Its prev_hash  |
    |        |            |              | *is* the cross-boot link. |
    +--------+------------+--------------+---------------------------+
    | 0x0010 | SPAN_START | normal       | Opens a span              |
    +--------+------------+--------------+---------------------------+
    | 0x0011 | SPAN_END   | normal       | Closes it.  Section 3.1   |
    +--------+------------+--------------+---------------------------+
    | 0x0012 | EVENT      | normal       | Point event.  Payload     |
    |        |            |              | semantics are profile-    |
    |        |            |              | defined (Section 3.4).    |
    +--------+------------+--------------+---------------------------+
    | 0x0020 | MERKLE     | sheddable    | Digest aggregation over a |
    |        |            |              | window.  Section 5.3      |
    +--------+------------+--------------+---------------------------+
    | 0x0021 | AGGREGATE  | sheddable    | Tier 0 statistics over a  |
    |        |            |              | window.  Section 3.2      |
    +--------+------------+--------------+---------------------------+
    | 0x0030 | SHED       | *never-shed* | Records that records were |
    |        |            |              | dropped.  Section 3.3     |
    +--------+------------+--------------+---------------------------+
    | 0x0040 | SAFETY     | *never-shed* | Written by the safety     |
    |        |            |              | path; the audit only      |
    |        |            |              | observes                  |
    +--------+------------+--------------+---------------------------+
    | 0x0050 | ANCHOR     | never-shed   | Local anchor written.     |
    |        |            |              | Section 9.2               |
    +--------+------------+--------------+---------------------------+
    | 0x0051 | WITNESS    | never-shed   | External witness receipt. |
    |        |            |              | Section 7                 |
    +--------+------------+--------------+---------------------------+
    | 0x0060 | KEY_SHRED  | never-shed   | A key was destroyed.      |
    |        |            |              | Section 5.4               |
    +--------+------------+--------------+---------------------------+

                                 Table 3

3.1.  Spans are two records

   SPAN_START and SPAN_END are separate chained records.  Duration is
   derived at read time.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 11]
Internet-Draft            PALA-1 Audit Records              October 2026

   The alternative -- one record written on close -- loses exactly the
   case that crashed. *A crash must leave a visibly unclosed span*,
   because that is the evidence.

   This also fixes the limit of the whole design: the audit *cannot*
   guarantee a record precedes the action it describes -- that would
   require blocking, which the architecture forbids.  It guarantees only
   that *absence is visible*: the property provided is detectable
   absence, not write-ahead semantics.

3.2.  AGGREGATE body schema

   Tier 0 statistics are not personal data, so an AGGREGATE body SHOULD
   be cleartext (key_id = 0).  Encrypting it would only make the post-
   market monitoring export useless to the party entitled to read it.

   The body is a TLV sequence, encoded exactly as Section 2.2, in its
   *own type namespace*. The core defines the window framing; the
   measured quantities are profile-defined:

    +=========+===================+===================================+
    | Type    | Name              | Value                             |
    +=========+===================+===================================+
    | 0x0001  | AGG_WINDOW_NS     | u64 -- length of the aggregation  |
    |         |                   | window. *Core.*                   |
    +---------+-------------------+-----------------------------------+
    | 0x0002  | AGG_SAMPLE_COUNT  | u32 -- samples folded into this   |
    |         |                   | record. *Core.*                   |
    +---------+-------------------+-----------------------------------+
    | 0x0003+ | _profile-defined_ | Allocated upward from 0x0003 by   |
    |         |                   | the chain's profile (Section 3.4) |
    +---------+-------------------+-----------------------------------+

                                  Table 4

   A reader treats body tags it does not know as opaque -- reported,
   never rejected -- the same posture Section 9.6 takes for the header.
   Because one chain follows exactly one profile (Section 3.4), profile
   allocations cannot collide within a chain.

   *Milli-units, not floats -- a constraint on profiles.* A float in a
   body reintroduces exactly the cross-implementation disagreement
   Section 1.1 rejects JSON for -- and it would do so in the one record
   type whose whole purpose is being comparable across versions and
   vendors.  A profile MUST express fractional quantities as fixed-point
   integers (milli-, micro-).  Fixed-point integers carry no cross-
   implementation ambiguity.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 12]
Internet-Draft            PALA-1 Audit Records              October 2026

   The framing is defined here rather than left to implementations
   because AGGREGATE is the PMM instrument: a wholly undefined body
   means two conformant implementations produce incomparable exports,
   which defeats the record type.  The core fixes the window; each
   profile fixes the quantities -- so two implementations of the _same
   profile_ are comparable.  The robotics profile published with the
   specification [PALA-SPEC] defines optical-flow statistics at
   0x0003-0x0005.

3.3.  SHED is in the never-shed class

   The audit never blocks the execution path.  Therefore records are
   dropped under saturation, and *which* records is a design decision,
   not an accident.

   A dropped record is survivable.  A *silently* dropped record is a log
   that misrepresents by omission, which is worse than no log.  SHED
   carries class, count and window, and it is never itself shed.

3.4.  Profiles

   The envelope must outlive any one domain, so the split is structural:
   this document defines everything a verifier needs -- layout, chain,
   tiers, time, cryptography, the three questions -- and *profiles*
   define what the records are _about_. A profile is a companion
   document that fixes, for one domain:

   *  *EVENT payload semantics* -- what lives in the bodies;

   *  *AGGREGATE quantities* -- body tags from 0x0003 upward
      (Section 3.2);

   *  *MERKLE leaf source* -- what the aggregated digests are digests
      _of_, and at what rate (Section 5.3);

   *  *ORIGIN_ROLE vocabulary* -- the component names that appear in
      headers.

   *One chain follows exactly one profile.* Which profile is a property
   of the deployment, stated by the emitting system's documentation; the
   format does not carry a profile identifier in version 1 (a chain's
   ORIGIN_ROLE vocabulary makes it evident in practice, and adding a
   field is a v1.0 freeze decision, not a retrofit).  Mixing profiles
   within one chain is out of scope.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 13]
Internet-Draft            PALA-1 Audit Records              October 2026

   *Verification is profile-independent.* Every check in Section 9 reads
   the envelope only; a verifier needs no profile knowledge to answer
   the three questions, and profile content it does not understand is
   opaque bytes -- reported, never rejected (Section 3.2, Section 9.6).

   Two profiles are published with the specification [PALA-SPEC]: a
   robotics profile -- the first, and the one the committed test vectors
   follow -- and an inference profile, under which the reference
   implementation audits its own serving loop.

4.  Recording at the dispatch boundary

   This section is informative and describes an emitter obligation that
   the record types of this document are shaped to support.

   A hash chain constrains the relationship between records.  On its own
   it does not constrain _when_ a record was written relative to the
   event it describes.  A producer could execute an entire session and
   afterwards emit a chain that is internally consistent, verifies
   correctly, and records only what the producer chose to say about
   itself.  Such a trail is conformant and evidentially weak, and the
   distinction matters wherever the question is whether a control
   actually operated.

   The record types here are designed so that a conforming emitter does
   not have that freedom in the one place it matters most: the tool-
   dispatch boundary, where an inference runtime causes an effect
   outside itself.

   A tool call is recorded when the call is handed to its executor,
   before any result is known.  The result is recorded as a separate
   record bound by digest to the call it answers, so an attempt cannot
   be presented as a completion.  On shutdown, a call with no recorded
   outcome is explicitly cancelled in the chain, so a reader never
   encounters a dispatch whose fate is unstated.  Span-structured events
   are two records -- one at open, one at close -- for the same reason.

   The consequence a verifier can rely on: for every dispatch in a
   conforming trail there is a record written before the outcome
   existed, and every such record has a stated fate.  What no format can
   supply is an assurance that the emitter obeyed this.  That is a
   property of the implementation, which is why the verification
   procedure treats an unpaired dispatch as an advisory finding to be
   surfaced rather than silently tolerated, and why independent
   implementations of this document are the evidence that matters
   (Section 13).

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 14]
Internet-Draft            PALA-1 Audit Records              October 2026

   A second limit is stated for the same reason.  An emitter can record
   only the dispatches it mediates as structured data.  A client that
   negotiates tool use with the model in free text and executes the
   result locally produces no dispatch at the emitter's boundary, and
   therefore no record; the reference implementation measured this with
   a widely used agent client and documents it as a visibility limit
   rather than concealing it (Section 13).  A trail's silence about tool
   use is evidence of what the emitter observed, not of what the client
   did.

5.  Chain rules

5.1.  Linking

   record_hash(r)  = SHA-256(header_bytes(r))
   r.prev_hash     = record_hash(previous record)

   seq MUST increase by exactly 1 within a chain. *A gap in seq is a
   break, whether or not the hashes link*, and a verifier MUST report it
   as one (Section 9.1).

   The rule is not redundant with the hash link.  An actor holding the
   key can rebuild a shorter, perfectly linked chain that omits a range
   of seq; the hashes will chain and only the gap reveals it.

5.2.  Genesis and boots

   *  GENESIS has prev_hash = 32 zero bytes *and* record_type = GENESIS.
      A distinguished type is required so that _"no predecessor"_ and
      _"predecessor removed"_ are distinguishable. prev_hash = 0 alone
      is not sufficient.

   *  A verifier MUST report as a *violation* any chain whose first
      record is not a GENESIS (the record is the wrong kind; the links
      around it may be perfectly sound), and MUST report a GENESIS at
      any position other than the first as a violation.  Defining the
      type and then not checking it adds nothing.

   *  *A BOOT record's prev_hash is the previous boot's head.* The chain
      is continuous across power cycles; a deleted segment leaves a head
      nothing references.

   *What this does not fix -- stated in the format, not hidden in
   prose:* an owner with the key can start a _new_ GENESIS and present
   the device as new.  Chain continuity cannot prove device continuity.
   Only Section 7 addresses that, and only partly.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 15]
Internet-Draft            PALA-1 Audit Records              October 2026

5.3.  Merkle aggregation

   High-rate digests are aggregated per window into one MERKLE record --
   the digest *source* and rate are profile-defined (Section 3.4): the
   robotics profile folds a second of sensor-frame digests into one
   record; an inference profile might fold a batch of token or KV-
   operation digests.  The tree is the same either way.

   [RFC6962] tree hash, domain-separated:

   leaf(d)        = SHA-256(0x00 || d)
   node(l, r)     = SHA-256(0x01 || l || r)
   empty          = SHA-256("")

   *An unpaired node is PROMOTED, never duplicated.* Duplicating the
   last node is the CVE-2012-2459 mistake: two distinct leaf sets
   collapse to the same root.

   An *inclusion proof* for a leaf is the list of sibling hashes on the
   path from that leaf to the root, each tagged with the side the
   sibling occupies: an entry ["L", s] means the sibling is the *left*
   operand of node() -- the step computes node(s, h) -- and ["R", s]
   computes node(h, s).  Folding the leaf's leaf() hash through the
   entries in order MUST reproduce the tree hash.  This is the encoding
   the published vectors use for the inclusion proof [PALA-VECTORS].

   Two constructions are in circulation and they agree, which is worth
   stating so an implementer does not go looking for a discrepancy: RFC
   6962 defines the tree recursively, splitting at the largest power of
   two below n; the iterative bottom-up form that promotes an unpaired
   node yields the same root.  Either may be implemented.

   This provides *selective disclosure*: one leaf can be proven with
   about log2(n) hashes without revealing the other n-1 -- one moment,
   without the rest of the window.

   *The count is a commitment, verified against the leaves -- never in
   the header.* MERKLE_LEAF_COUNT states how many leaves the root
   covers.  Because the MERKLE record does not carry the leaves, only a
   party that has them -- checking a disclosure, or holding the full set
   -- can confirm it, and such a verifier SHOULD check that the number
   of leaves equals MERKLE_LEAF_COUNT and reject a disclosure whose
   count disagrees.  A mismatch is a defect of that disclosure, not a
   chain violation: the header and its chain are intact; what was
   revealed is inconsistent with what was committed.  A header-only
   verifier (Section 9.1) neither has the leaves nor checks the count.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 16]
Internet-Draft            PALA-1 Audit Records              October 2026

5.4.  Bodies, encryption and crypto-shredding

   A body is one of two shapes, and key_id says which:

              +========+====================================+
              | key_id | Body                               |
              +========+====================================+
              | 0      | Absent (body_len = 0), or          |
              |        | *cleartext*: body is the raw bytes |
              +--------+------------------------------------+
              | != 0   | *Encrypted*: body = nonce (12)     |
              |        | \|\| ciphertext \|\| tag (16)      |
              +--------+------------------------------------+

                                  Table 5

   In both cases body_digest = SHA-256(body_bytes) over exactly body_len
   bytes.  The digest does not know which shape it covered -- which is
   why crypto-shredding does not disturb it.

   Body encryption is *AES-256-GCM* [SP800-38D].

   nonce      = 4 zero bytes || seq (u64 LE)
   aad        = seq (u64 LE) || boot_id (16) || record_type (u16 LE)
   ciphertext = AES-256-GCM(K[key_id], nonce, plaintext, aad)
   body       = nonce || ciphertext || tag
   body_digest= SHA-256(body)

   The AAD binds the ciphertext to its position in the chain: bodies
   cannot be swapped between records.

   *The nonce is derived from seq, not random.* A random 96-bit nonce is
   not safe past ~2^32 records under one key -- a horizon a sustained
   high-rate writer actually reaches within the ten-year lifetime this
   format must survive (a 30 Hz emitter crosses it in under five years;
   higher rates get there sooner).  A seq-derived nonce is unique per
   record by construction -- seq never repeats within a chain
   (Section 5.1) -- and its only leak is the record's position, which
   the cleartext header states anyway.  A key MUST NOT be reused across
   chains with independent seq spaces.

   *Order of operations is normative* (it is otherwise circular): 1.
   encrypt -> 2. compute body_digest -> 3. fill the header -> 4.
   record_hash.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 17]
Internet-Draft            PALA-1 Audit Records              October 2026

   *Crypto-shredding.* Keys live outside the log, addressed by key_id.
   Erasure = destroying K[key_id]; a KEY_SHRED record notes it.  The
   body becomes noise, body_digest stays, the chain still verifies.  A
   verifier reports _"record exists, body unreadable"_ -- a reported
   condition, not a gap in the chain.

   *Shred granularity equals key granularity, and that is a deployment
   decision, not a format one.* Per subject, per session, per day -- the
   format only requires that key_id exists and that destroying a key
   breaks nothing structural.

   *key_id scope is one device.* 2^32 keys is ample per device and
   ambiguous across a fleet: two devices may both use key_id = 7 for
   unrelated keys.  A fleet key-management layer MUST qualify key_id
   with a device identity of its own; the format does not carry one.

6.  Time

   A device without a battery-backed real-time clock boots with its wall
   clock at the Unix epoch, and network time synchronisation is
   unavailable under C2.  Therefore:

   *  *monotonic_ns and seq are authoritative for ordering.* Always
      present.

   *  *wall_clock_ns is advisory* and always accompanied by time_trust:

     +============+=================================================+
     | time_trust | Meaning                                         |
     +============+=================================================+
     | 0          | UNKNOWN -- wall_clock_ns MUST be 0              |
     +------------+-------------------------------------------------+
     | 1          | UNSYNCED -- free-running, no external reference |
     +------------+-------------------------------------------------+
     | 2          | HW_RTC -- battery-backed clock, unverified      |
     +------------+-------------------------------------------------+
     | 3          | NTP_SYNCED -- externally synchronised           |
     +------------+-------------------------------------------------+

                                 Table 6

   Values above 3 are undefined in version 1.  A verifier MUST report a
   record whose time_trust is UNKNOWN with a non-zero wall_clock_ns as a
   violation (Section 9.1): an unenforced requirement is not a
   requirement, and this one separates an explicit statement that the
   time is unknown from a timestamp that cannot be justified.  The first
   can be defended; the second cannot.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 18]
Internet-Draft            PALA-1 Audit Records              October 2026

7.  Assurance tiers

   The format states how much it can be trusted.  It does not overstate.

    +======+==============+========================+=================+
    | Tier | Mechanism    | Proves                 | Does not prove  |
    +======+==============+========================+=================+
    | *A*  | Chain +      | A record was modified; | Everything else |
    | = 0  | local anchor | with the anchor, that  |                 |
    |      |              | nothing was truncated  |                 |
    +------+--------------+------------------------+-----------------+
    | *B*  | + hardware   | Device identity        | *Fresh genesis* |
    | = 1  | root of      |                        | -- a TPM signs  |
    |      | trust        |                        | any chain       |
    +------+--------------+------------------------+-----------------+
    | *B+* | + monotonic  | Counter never returns  | Platform-bound  |
    | = 2  | NV counter   | to zero -> fresh       |                 |
    |      | bound to seq | genesis visible        |                 |
    +------+--------------+------------------------+-----------------+

                                 Table 7

   *Tier C is deliberately not a header value.*

   Tier C -- periodic publication of the chain head to a transparency
   log or an [RFC3161] TSA -- proves *existence at time T*, which is the
   guarantee that actually defeats a fresh genesis.  But a header cannot
   honestly claim to have been witnessed _before the witness exists_.

   So tier C is asserted *after the fact*, by a WITNESS record covering
   a seq range.  A verifier reads:

      _records 0-9: externally witnessed at 2026-07-16T10:00Z records
      10-...: tier A, no existence claim_

   *C is strictly stronger than B here*, because fresh genesis is a
   question of existence, not identity.  Its cost is one published hash,
   not data: the model of Certificate Transparency applied to an audit
   trail.

8.  Relationship to transparency services

   This section is informative.  It adds no requirement and changes no
   byte.

   The strongest question this format cannot answer from its own bytes
   is existence at a point in time.  A chain proves that its records
   have not been altered relative to one another.  It does not prove

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 19]
Internet-Draft            PALA-1 Audit Records              October 2026

   that the chain was not created wholesale after the fact, because a
   producer in possession of its own keys can construct a consistent
   history at any time.  Defeating that requires a party other than the
   producer to have observed a commitment, and the observation has to
   have happened.

   PALA-1 handles this by deferring the claim rather than asserting it.
   A witness record covers an explicit range of sequence numbers and
   states that the head of that range was published externally.  The
   record is itself chained, so the claim cannot be inserted
   retroactively without breaking the chain, and a verifier reports the
   witnessed range and the unwitnessed remainder separately.  The
   protocol by which the external publication is verified is the
   witness's own and is out of scope here.

   A SCITT transparency service [RFC9943] is one such witness, and a
   natural one where a deployment permits it.  A producer takes the
   chain head, expresses it as a Signed Statement -- a COSE_Sign1
   [RFC9052] whose payload commits to the head by digest -- registers it
   with a transparency service, and attaches the returned Receipt -- a
   COSE Receipt [RFC9942] -- to the statement's unprotected header,
   producing what [RFC9943] calls a Transparent Statement, which is then
   carried in the evidence the producer exports.  What the producer
   publishes is one digest, not the trail: no record body, no personal
   data, no model output leaves the device.  The envelope's cost is paid
   once per published head rather than once per record (Section 1.3),
   which is what makes it affordable under C1.

   The construction published with the specification [PALA-INTEROP] is
   stated here so that it can be checked rather than assumed.  The
   statement's protected header carries the algorithm, the payload's
   content type, a key identifier, and CWT claims for issuer and subject
   under the header label registered by [RFC9597].

   Two of those values are digests, and they are treated differently on
   purpose.  The subject names the *full* chain head: a transparency
   service indexes by the subject, distinct chains must not collide
   under it, and a truncated digest collides at the birthday bound of
   whatever length is kept.  The key identifier is the COSE Key
   Thumbprint of the verification key [RFC9679] *truncated to its first
   20 bytes*, which is not a thumbprint and is not claimed to be one.
   The asymmetry is deliberate: kid is a hint for locating a key and
   [RFC9052] places no collision-resistance duty on it, since presenting
   the wrong key simply fails the signature check, whereas the subject
   is the identifier by which a relying party decides that two
   statements concern the same thing, and nothing downstream catches a
   collision there.  Truncation is acceptable exactly where a collision
   is self-correcting and unacceptable where it is not.  The payload is

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 20]
Internet-Draft            PALA-1 Audit Records              October 2026

   attached -- a CBOR map of the head, the sequence range and the format
   identifier, encoded as CBOR [RFC8949] -- so that the statement is
   readable offline, without the service.  Section 6 of [RFC9943]
   requires the kid header parameter when neither x5t nor x5chain is
   present in the protected header; its initial omission was found by a
   reproduction of the statement performed under a stated contamination
   boundary and was corrected before any registration took place
   (Section 13).

   Two properties of the envelope bear on what such a statement can be
   said to be.  First, byte-for-byte reproduction of a statement by an
   independent implementation is achievable only when the signature is
   deterministic: EdDSA [RFC8032] provides that by construction, whereas
   an ECDSA signature is deterministic only as a per-library choice, so
   two conforming implementations may emit different signature bytes
   over identical input.  The published vector therefore uses EdDSA, and
   a vector over ECDSA could claim that a statement verifies, not that
   it reproduces.  Second, a valid signature and the published bytes are
   two different facts: content in the unprotected header, the presence
   or absence of the outer CBOR tag, a detached payload, or a non-
   canonical Ed25519 scalar each yield an artifact with different bytes
   over which the signature still verifies.  An auditor comparing an
   artifact to a published one compares bytes; an auditor accepting a
   statement checks the signature; the two checks are not substitutes
   for each other.  [PALA-INTEROP] enumerates these cases with
   executable expectations.

   Under C2 this path is closed -- by policy or by the absence of any
   reachable service -- and the format is designed so that its closure
   costs nothing structural: a trail that is never witnessed is still
   verifiable for internal consistency and, against a local anchor, for
   completeness.  It simply does not claim the third question, and says
   so.

   Two properties of this arrangement are worth stating plainly, because
   the difference between them is the difference between a claim and a
   proof.

   A verifier that has checked a Receipt against a log key it trusts may
   report the covered range as externally witnessed.  A verifier that
   has not checked one MUST NOT, whatever the trail says about itself.
   The overclaim rule that governs every assurance field in this
   document governs this one.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 21]
Internet-Draft            PALA-1 Audit Records              October 2026

   And the guarantee itself is bounded.  A Receipt establishes that a
   commitment was registered, and therefore bounds when the trail can
   have been constructed and makes later substitution or omission
   detectable.  It does not establish that the recorded content is true.
   That boundary is not peculiar to this format; it applies to every
   construction of this kind, including the transparency service's own.

9.  Verification

   Verification answers three questions, and they MUST NOT be collapsed
   into one boolean.  Each needs different inputs and each fails
   differently.

   +=============================+==============+======================+
   | Question                    | Needs        | Answers              |
   +=============================+==============+======================+
   | *Section 9.1 Is what I hold | Nothing      | Modification,        |
   | internally consistent?*     |              | reordering,          |
   |                             |              | seq gaps             |
   +-----------------------------+--------------+----------------------+
   | *Section 9.2 Is what I hold | An anchor,   | Truncation,          |
   | all of it?*                 | from outside | replacement,         |
   |                             | the log      | rollback             |
   +-----------------------------+--------------+----------------------+
   | *Section 9.3 Did this       | A witness    | Fresh genesis        |
   | history exist at time T?*   | receipt      |                      |
   +-----------------------------+--------------+----------------------+

                                  Table 8

   A verifier that reports only Section 9.1 as "ok" is misleading,
   because Section 9.1 cannot see a truncated tail: dropping the last N
   records leaves a perfectly linked chain with a different head and no
   other trace.

9.1.  Header-only chain verification

   Requires no key.  Touches no bodies.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 22]
Internet-Draft            PALA-1 Audit Records              October 2026

   prev     := unset                          # no link expectation yet
   expected := unset
   for index, header h in file order:
       MUST h.magic == "PALA"                         else break, stop
       MUST h.header_len == actual header bytes       else violation
       if index == 0:
           MUST h.record_type == GENESIS              else violation
           if h.record_type == GENESIS:
               MUST h.prev_hash == 32 zero bytes      else violation
       else:
           MUST h.record_type != GENESIS              else violation
       if prev is set and h.prev_hash != prev:  report break at h.seq
       if expected is set and h.seq != expected:  report gap at h.seq
       expected := h.seq + 1
       if h.format_version unknown or h.record_type unknown:
           report uninterpretable at h.seq    # not a break; see below
       else:
           run semantic checks                # violations, not breaks
       prev := SHA-256(h.header_bytes)
   report: count, breaks, gaps, violations, uninterpretable, head = prev

   chain_ok is true iff breaks, gaps and violations are all empty.  It
   means *internally consistent*, nothing more.

   A chain whose first record is not a GENESIS yields exactly *one*
   violation -- the wrong _kind_ of first record.  Per Section 5.2, the
   links around it may be perfectly sound: the zero-prev_hash
   requirement applies only when the first record _is_ a GENESIS, and
   the break check compares only records that have a predecessor in the
   file.  (Aligned at the final pre-freeze verification run: read
   literally, the earlier pseudocode produced two violations and a
   spurious break on this case, contradicting this section's own prose
   above and Section 5.2.  The published missing-GENESIS demonstration
   had not discriminated the two readings -- its input satisfied both --
   until that run constructed the discriminating case; the demo input
   was strengthened accordingly, with its published outputs unchanged.)

   breaks and gaps are reported at the record's seq.  Violations from
   per-record checks are likewise keyed by seq; the chain-does-not-
   start-with-GENESIS violation is reported at position 0, because it is
   a property of the chain, not of any record's seq.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 23]
Internet-Draft            PALA-1 Audit Records              October 2026

9.2.  Completeness against an anchor

   The anchor is the head this chain is supposed to have, obtained from
   *outside the log*: the _current_ head held in the local anchor store
   (an OS keychain entry), or the head covered by the newest WITNESS
   receipt.  An in-chain ANCHOR record with its ANCHOR_HEAD TLV *records
   a store write at the time it occurred* -- a historical note, not the
   anchor itself.  Because a writer may append records after a store
   write, the newest ANCHOR record's head can lag the store's current
   head; a completeness check therefore uses the *store's current head*,
   not any in-chain ANCHOR record's TLV.

   Given an anchor A and a computed head H:

      +================+===========================================+
      | Condition      | Report                                    |
      +================+===========================================+
      | A == H         | Complete to the anchor                    |
      +----------------+-------------------------------------------+
      | A is the       | *Unanchored tail*: anchor_lag = N records |
      | record_hash of | past the anchored head.  A crash between  |
      | some record in | write and anchoring, or an anchor-store   |
      | the chain      | outage -- or records appended by a writer |
      |                | without anchor access.                    |
      +----------------+-------------------------------------------+
      | A names no     | *Replaced, rolled back, or truncated.*    |
      | record in the  | This is not the history that was          |
      | chain          | anchored.                                 |
      +----------------+-------------------------------------------+

                                 Table 9

   Both non-matching cases are failures; the diagnosis differs, and the
   diagnosis is what an auditor acts on.  Without an anchor a verifier
   MUST report completeness as _not checked_ -- never as passing.

9.3.  Existence against a witness

   A WITNESS record asserts that the head of records [RANGE_LO,
   RANGE_HI] was published to an external log at some time.
   Verification is out of scope for this document -- it follows the
   witness's own protocol (a COSE Receipt [RFC9942], a Rekor inclusion
   proof, an [RFC3161] token).  What this format guarantees is only that
   the claim is _in_ the chain, is itself chained, and names its range
   explicitly.

   A verifier SHOULD report the witnessed range and the unwitnessed
   remainder separately (Section 7).

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 24]
Internet-Draft            PALA-1 Audit Records              October 2026

9.4.  Semantic checks

   On records whose version and type are known -- *GENESIS and BOOT
   included*. The position checks Section 9.1 makes at index 0 (the
   record is a GENESIS, its prev_hash is zero) are _in addition to_
   these, not in place of them: a GENESIS with time_trust = UNKNOWN and
   a non-zero wall_clock_ns is as much a violation as any other record.

   The checks:

   *  time_trust == UNKNOWN => wall_clock_ns == 0 (Section 6)

   *  time_trust <= 3 (Section 6)

   *  body_len == 0 if and only if body_digest == 32 zero bytes
      (Section 2.1)

   *  key_id != 0 and body_len > 0 => body_len >= 28 (nonce + tag,
      Section 5.4)

   *  TLV items parse and end exactly at header_len (Section 2.2)

   These are violations, not breaks: the record is defective, the chain
   around it may be sound.  They MUST be reported distinctly.

   MERKLE_LEAF_COUNT is deliberately *not* among these checks.  A MERKLE
   record carries the root and the count but never the leaves (body_len
   = 0, Section 5.3), so a header-only verifier does not have the leaves
   to count and does not treat the field as verifiable here -- it is a
   commitment, checked only when the leaves are disclosed.  Section 5.3
   says how.

9.5.  Body verification (needs the key)

   SHA-256(body) == header.body_digest, then -- if key_id != 0 -- AES-
   256-GCM decrypt with the nonce and AAD of Section 5.4.  Failure to
   decrypt with a *matching* digest means the key is wrong or destroyed
   -- not that the log is corrupt.  These MUST be reported distinctly.

9.6.  Forward compatibility

   A verifier meeting an unknown format_version, record_type or TLV
   type:

   *  *MUST* still chain-verify it -- the hash is over raw bytes

   *  *MUST* report it as uninterpretable

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 25]
Internet-Draft            PALA-1 Audit Records              October 2026

   *  *MUST NOT* reject the chain

   *  *MUST NOT* apply Section 9.4 to it -- those checks belong to a
      version it claims

   *These fields are frozen for all future versions:* magic,
   format_version, header_len, record_type, seq, boot_id, prev_hash,
   body_len, body_digest, at their stated offsets.

   body_len is in the frozen set for a mechanical reason: without it a
   verifier cannot find the next record, and forward compatibility ends
   at the first unknown record with a body.

   That freeze is what allows a tool written today to report, on a trail
   written ten years later:

      _"Chain intact, 1.2M records, no gaps, 400 records I cannot
      interpret."_

10.  Test vectors

   The full set -- every record byte, the Merkle leaves and the
   inclusion proof -- is published as [PALA-VECTORS].  The vectors are
   deterministic: a fixed key, derived nonces and fixed identifiers --
   real cryptography over deterministic inputs.  Such inputs MUST NOT be
   used outside a test vector.

   The vector chain's record bodies and narrative follow the robotics
   profile (Section 3.4).  Every property demonstrated below is an
   *envelope* property and holds under any profile.

   The chain is a representative ten seconds: genesis, boot with no
   clock, a brain span, a c' write with an encrypted body, a second of
   frames, a second of Tier 0 statistics, a divergence event, a shed
   notice, span close, a local anchor, an external witness, and an
   erasure.

   key    = 000...02a (32 bytes)          key_id = 7
   nonce = 4 zero bytes || seq (u64 LE)
     seq 3 -> 000000000300000000000000
   body plaintext (seq 3) =
     "clear path ahead, one pedestrian at 12m, static"

   | seq | type | note | |---:|---|---| | 0 | GENESIS | tier A, time
   UNKNOWN | | 1 | BOOT | wall_clock_ns = 0, time_trust = UNSYNCED | |
   2 | SPAN_START | brain | | 3 | EVENT | AES-GCM body, key_id = 7,
   origin = eyes.tier1 + digests | | 4 | MERKLE | 30 frame digests | |
   5 | AGGREGATE | cleartext TLV body, key_id = 0 | | 6 | SAFETY |

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 26]
Internet-Draft            PALA-1 Audit Records              October 2026

   divergence, origin = perception_health | | 7 | SHED | class 1, 400
   records, 12 s window | | 8 | SPAN_END | | | 9 | ANCHOR | carries the
   head anchored at seq 8 | | 10 | WITNESS | transparency log, covers
   seq 0-9 | | 11 | KEY_SHRED | key 7 destroyed -> seq 3 body
   unreadable |

   *Expected results -- an implementation that disagrees with any of
   these is wrong, or this specification is:*

chain_head =
  3a1a3673f50498eb1d1c6f94b983d6c606cd85ed53627b4e4ffe55153c7af813
chain_ok           = true    record_count = 12
breaks = []   gaps = []   violations = []
complete_to_anchor = true
  (the anchor is the store's current head = the tip)
anchor_head =
  3a1a3673f50498eb1d1c6f94b983d6c606cd85ed53627b4e4ffe55153c7af813
  (== chain_head)

merkle_tree_hash =
  518f5be5173250f705e3bda029ec1c11ac5c4459115c07dde5bc1021d9f468db
merkle_leaf_count   = 30         proof(index 7) verifies   proof_len = 5

   The ANCHOR record at seq 9 carries, in its ANCHOR_HEAD TLV, the head
   as of seq 8
   (14434088e5f5866cf0276ba5a9055d8ee0d115a750b2cdf9cc4006d9481b29b4) --
   a historical store write that lags the tip by 3.  It is *not* the
   completeness anchor (which is the store's current head, anchor_head
   above); the stale_anchor demonstration below checks against it
   deliberately.

   Seven properties the vectors demonstrate rather than assert:

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 27]
Internet-Draft            PALA-1 Audit Records              October 2026

   +===============+===================================================+
   | Demo          | Result                                            |
   +===============+===================================================+
   | Flip one bit  | body_digest mismatch detected *and                |
   | in the seq-3  | the chain still verifies* -- body                 |
   | body          | damage and chain damage are distinct              |
   |               | failures                                          |
   +---------------+---------------------------------------------------+
   | Append a      | chain_ok = true, count = 13,                      |
   | record of     | uninterpretable = [12] -- Section 9.6             |
   | unknown type  | works                                             |
   | 0x7fff        |                                                   |
   +---------------+---------------------------------------------------+
   | Destroy key 7 | seq 3 body unreadable forever, chain              |
   |               | unchanged -- Section 5.4 works                    |
   +---------------+---------------------------------------------------+
   | *Drop the     | chain_ok = true *without* an anchor;              |
   | last record*  | complete_to_anchor = false *with* one             |
   |               | -- Section 9.1 cannot see truncation,             |
   |               | Section 9.2 can.  This is why the two             |
   |               | questions are separate.                           |
   +---------------+---------------------------------------------------+
   | *Stale        | anchor_lag = 3, reported as an                    |
   | anchor*       | unanchored tail, *not* a replacement              |
   | (anchor names |                                                   |
   | seq 8, chain  |                                                   |
   | has 12)       |                                                   |
   +---------------+---------------------------------------------------+
   | *seq gap* 11  | chain_ok = false, gaps = [99] --                  |
   | -> 99 with    | Section 5.1                                       |
   | valid hashes  |                                                   |
   +---------------+---------------------------------------------------+
   | *Chain with   | chain_ok = false, violation _"chain               |
   | no GENESIS*   | does not start with a GENESIS                     |
   |               | record"_ -- Section 5.2                           |
   +---------------+---------------------------------------------------+
   | *time_trust = | chain_ok = false, violation --                    |
   | UNKNOWN with  | Section 6                                         |
   | a non-zero    |                                                   |
   | clock*        |                                                   |
   +---------------+---------------------------------------------------+

                                  Table 10

   A companion vector [PALA-INTEROP] publishes a Signed Statement over
   this chain head in the construction of Section 8: 331 bytes, EdDSA
   under the published test key of [RFC8032] Section 7.1, with the
   expected bytes, digest, key identifier and a set of tamper

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 28]
Internet-Draft            PALA-1 Audit Records              October 2026

   expectations that includes the byte-stability cases stated there.
   The vector was reissued once, after a reproduction performed under a
   stated contamination boundary found the conformance defect described
   in Section 13; both versions and their digests are on the record.

11.  Related work

   Evidence for the conduct of AI systems is an active area, and most of
   the current work sits in a different place in the stack than this
   document.  The distinctions below are stated to locate this format,
   not to rank the documents.

   *Transparency substrate.* [RFC9943] defines an architecture in which
   an issuer registers a signed statement with a transparency service
   and receives a receipt, generalising the approach of certificate
   transparency to arbitrary content.  It is the substrate a number of
   the documents below profile, and, as described in Section 8, the
   natural witness for a PALA-1 chain head.  This document does not
   compete with it; the two operate at different points and compose.

   *Statement profiles for agent conduct.* A cluster of individual
   submissions profiles that substrate for AI agents.
   [I-D.mih-scitt-agent-action-capsule] records verdict-level
   disposition for a single agent action, with a binding that
   distinguishes a dispatched effect from an observed result and a flag
   that prevents a policy approval from being presented as human
   oversight.  [I-D.munoz-scitt-permit-profile] records pre-execution
   authorization -- whether an action was permitted, rather than what
   occurred.  [I-D.emirdag-scitt-ai-agent-execution] defines operator-
   signed interaction records with redaction receipts.
   [I-D.kamimura-vap-framework] frames hash chaining, signatures and
   anchoring as a conformance-tiered provenance architecture.
   [I-D.dawkins-scitt-ai-article50] profiles receipts for a specific
   regulatory transparency obligation.  [I-D.sato-soos-gar] records
   session-level governance audit records produced by an enforcing
   component.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 29]
Internet-Draft            PALA-1 Audit Records              October 2026

   These are per-action or per-session statement profiles, expressed in
   JSON or CBOR, made transparent by registration with a service.  This
   document specifies a wire format for a continuously appended local
   trail, verifiable without a service and without a key, under the
   constraints of Section 1.1.  The difference is not a disagreement
   about design: none of the documents above targets a deployment in
   which signing each record is unaffordable, an external service is
   forbidden by policy, and the verifier may not read what it verifies.
   A single agent action in one of those profiles may correspond to many
   PALA-1 records; conversely a PALA-1 chain head may be carried into
   that ecosystem as a signed statement.  The layers are complementary,
   and the practical relation is the anchoring path of Section 8.

   *Statement construction and binding.*
   [I-D.mih-sokolov-scitt-payload-binding] specifies how a Signed
   Statement declares the canonicalization applied to its payload, and
   leaves payload formats, serialization and structure out of scope.
   Its envelope conventions -- alg, kid or x5chain, and a content type
   in the protected header -- are the ones the statement of Section 8
   follows.  [I-D.nobuo-scitt-protected-object-binding] defines a common
   model for relating Signed Statements to the objects they describe,
   including device instances.  [RFC9995] defines a COSE structure
   carrying a digest of a payload that the verifier obtains elsewhere.
   The statement of Section 8 is a narrow instance of these concerns:
   its payload is a fixed-shape commitment to a chain head -- which is
   not a digest of a file but the result of the chain rules -- together
   with the range and format identifier a verifier needs to recompute
   it.  It could be expressed under either binding document, or as a
   hash envelope over the head, without loss, and this document does not
   preclude that.

   *Architectural requirements.*
   [I-D.daniel-ai-agent-internet-architecture] states requirements for
   supporting AI agents on the Internet, among them that audit evidence
   be tamper-evident and support selective disclosure, and that
   protocols not require the collection of private reasoning traces as a
   condition of accountability.  This format was designed before those
   requirements were written and satisfies the second by construction:
   chain verification inspects headers only and never requires a body to
   be disclosed.

   *Time and existence.* [RFC3161] timestamp tokens and [RFC6962]-style
   logs are alternative witnesses for the existence claim of Section 8.
   This document is deliberately indifferent to which is used; the
   witness record names a range and a witness, not a mechanism.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 30]
Internet-Draft            PALA-1 Audit Records              October 2026

   *Deployed tamper-evident logs.* Two deployed mechanisms address the
   same broad problem and are the nearest prior art.  Signed syslog
   [RFC5848] has an originator periodically emit Signature Blocks that
   carry hashes of the messages it has sent and a signature over them,
   with the signer's key conveyed in Certificate Blocks; the cost of a
   signature is amortised over a group of messages, an idea this
   document shares through its checkpoint and witness records.  It
   differs in what a verifier needs: checking a signed-syslog stream
   requires the signer's public key, whereas the integrity of a PALA-1
   chain is checked with no key at all; and signed syslog is a mechanism
   for text messages in transit rather than a stored record format whose
   bodies can be erased without falsifying the record.

   The systemd journal's Forward Secure Sealing [FSS] [SSKG] appends a
   message authentication tag at a fixed interval -- every fifteen
   minutes by default -- under a sealing key that evolves irreversibly,
   so that compromise of the current key does not permit undetected
   alteration of entries sealed earlier.  That forward-security property
   is one a tier A PALA-1 trail does not have on its own; PALA-1 obtains
   the corresponding guarantee only from an anchor or witness held
   outside the device (Section 7).  In the other direction, verifying a
   sealed journal requires a verification key from which every sealing
   key can be derived, so a party able to verify is also able to forge,
   which C3 excludes; entries written since the last seal are
   unprotected until the next one; and the journal provides neither
   selective disclosure nor erasure that leaves the record verifiable.
   Both mechanisms are reasonable choices where their assumptions hold.
   Neither is a substitute where C1 to C3 hold together.

   *What is not addressed here.* Selective disclosure at field
   granularity, agent identity, authorization, and cross-party
   attestation are all outside this document.  Where a deployment needs
   them, the profiles above address them directly and this format is not
   a substitute.

12.  Relationship to the agent auditing architecture

   This section is informative.

   [I-D.kuehlewind-audit-architecture] describes an architecture for
   auditing agent-driven interactions in which each acting role records
   its own behaviour, records are linked by a propagated audit context,
   and attestation and transparency logging are composed as optional
   trust mechanisms.  It proposes four record types -- Interaction,
   Action, Delegation and Authorization Transition Records -- and roles
   including an Auditing Service, an Audit Store, a Transparency Log and
   an Auditor.  This section states where PALA-1 sits in that
   architecture and, as importantly, where it does not.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 31]
Internet-Draft            PALA-1 Audit Records              October 2026

   *What PALA-1 corresponds to.* A PALA-1 trail written by an inference
   runtime records, at the runtime's dispatch boundary, the events that
   architecture assigns to Action Records: a tool call when it is handed
   to its executor, its result bound by digest to the call, and the
   explicit cancellation of a call that never returned (Section 4).
   Arguments and results enter the chain only as digests, which is the
   treatment that architecture's privacy considerations recommend for
   tool-call outputs.  The container is an Audit Store substrate in that
   architecture's sense -- append-only, and readable by an Auditor
   without the runtime that produced it -- and the verification of
   Section 9 is the Auditor's integrity check over it.  The chain-head
   publication of Section 8 is the composition with the Transparency
   Log, in the form that architecture already allows when it lets
   registration happen as soon as network conditions permit: a head
   published after the fact covers every record before it.

   *Where it sits differently.* That architecture's Action Records are
   produced where an action takes effect and, preferably, by the Tool or
   Service, reflecting a request as observed there rather than as
   reported by the agent.  A PALA-1 trail of the kind described here is
   agent-side: it records what the runtime dispatched and what it
   received back.  In that architecture's terms this is the co-located
   recorder of its role-aggregation discussion, with the recorder-
   collusion threat that discussion names.  The mitigation it offers --
   non-repudiable registration with a Transparency Service -- is the one
   Section 8 provides, and under C2 that mitigation is deferred rather
   than absent.  PALA-1 also does not sign records with an identity
   bound to the recorder: its integrity is the chain's, and signed
   statements exist only at a published head.

   *What PALA-1 does not provide.* Interaction Records -- user prompts,
   approvals and human-in-the-loop dialogue -- for which that
   architecture names [I-D.birkholz-verifiable-agent-conversations] as
   the principal candidate.  Delegation Records and Authorization
   Transition Records.  Propagation of an audit context across protocol
   interactions, and the actor and on-behalf-of identities that context
   carries.  A per-record serialisation in CBOR/COSE or JSON/JWS: PALA-1
   records are binary TLV (Section 1.3) and enter a COSE-based ecosystem
   only at the chain head.  Each of these is a non-goal of this
   document, not a gap it intends to close.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 32]
Internet-Draft            PALA-1 Audit Records              October 2026

   *How the two compose.* A record in that architecture can reference a
   PALA-1 record by its record hash, or a window of them by a Merkle
   root, without carrying any PALA-1 body; and a PALA-1 chain head
   registered as a Signed Statement is an artifact a SCITT Transparency
   Log already accepts.  The intended relation is a profile, not a
   competitor: PALA-1 as the local recorder of action events in
   deployments where an independent Auditing Service is not reachable at
   the moment of recording.

13.  Implementation status

   This section records implementation experience per [RFC7942] and is
   to be removed before publication as an RFC, should that occur.

   The wire format described here is frozen at version 1.0.  Five
   implementations of it exist: the reference implementation; one
   written by a co-maintainer under a stated contamination boundary; and
   three by implementers who were external to the project at the time of
   their runs -- one has since become a maintainer -- and who worked
   from the specification text and the published test vectors alone
   [PALA-VECTORS].  Each of the latter four reproduces the published
   expected values of the specification's test-vector section without
   access to any prior implementation.

   +=+=================+========+=======+============+=================+
   |#| Implementer     |Language|Date   | Spec       | Result          |
   | |                 |        |       | tested     |                 |
   +=+=================+========+=======+============+=================+
   |1| reference       |Python  |--     | --         | the format's    |
   | | (authors)       |        |       |            | origin, not a   |
   | |                 |        |       |            | verification    |
   | |                 |        |       |            | run             |
   +-+-----------------+--------+-------+------------+-----------------+
   |2| O.              |Python, |2026-08| 776aa15a,  | chain +         |
   | | Verteletskyi    |stdlib  |       | ce877e4    | completeness    |
   | | (co-maintainer, |        |       |            | reproduced;     |
   | | stated          |        |       |            | Merkle first    |
   | | boundary)       |        |       |            | blocked         |
   | |                 |        |       |            | (leaves         |
   | |                 |        |       |            | unpublished);   |
   | |                 |        |       |            | 2 spec defects  |
   | |                 |        |       |            | filed, closed;  |
   | |                 |        |       |            | Merkle then     |
   | |                 |        |       |            | reproduced      |
   +-+-----------------+--------+-------+------------+-----------------+
   |3| R.  Bakaiev     |Python, |2026-08| c8e8247    | 8/9 blind; 1    |
   | | (external,      |stdlib  |       |            | divergence --   |
   | | unaffiliated)   |        |       |            | the verifier    |

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 33]
Internet-Draft            PALA-1 Audit Records              October 2026

   | |                 |        |       |            | was right, the  |
   | |                 |        |       |            | vectors were    |
   | |                 |        |       |            | inconsistent;   |
   | |                 |        |       |            | confirmed at    |
   | |                 |        |       |            | 1294bd0,        |
   | |                 |        |       |            | verifier        |
   | |                 |        |       |            | unchanged       |
   +-+-----------------+--------+-------+------------+-----------------+
   |4| V.  Kurdybailo  |Python, |2026-08| ff2720a    | 11/11 blind     |
   | | (external,      |stdlib  |       |            | first run +     |
   | | unaffiliated)   |        |       |            | 7/7 demos; own  |
   | |                 |        |       |            | adversarial     |
   | |                 |        |       |            | construction    |
   | |                 |        |       |            | exposed a       |
   | |                 |        |       |            | common-mode     |
   | |                 |        |       |            | pseudocode/     |
   | |                 |        |       |            | prose defect;   |
   | |                 |        |       |            | fixed, vectors  |
   | |                 |        |       |            | byte-identical  |
   +-+-----------------+--------+-------+------------+-----------------+
   |5| O.  Turak       |Perl 5, |2026-08| tag        | 11/11 + 7/7     |
   | | (external and   |core    |       | pala1-v1.0 | first run; 13   |
   | | unaffiliated at |only    |       |            | own             |
   | | the time of the |        |       |            | adversarial     |
   | | run; a          |        |       |            | cases, 140      |
   | | maintainer      |        |       |            | checks, 0       |
   | | since)          |        |       |            | failures; 8     |
   | |                 |        |       |            | ambiguities     |
   | |                 |        |       |            | logged; span-   |
   | |                 |        |       |            | pairing gap     |
   | |                 |        |       |            | reported; AES-  |
   | |                 |        |       |            | GCM built from  |
   | |                 |        |       |            | the primitive   |
   | |                 |        |       |            | standards,      |
   | |                 |        |       |            | NIST-tested     |
   | |                 |        |       |            | first           |
   +-+-----------------+--------+-------+------------+-----------------+

                                  Table 11

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 34]
Internet-Draft            PALA-1 Audit Records              October 2026

   Run kind, stated in the vocabulary in current use for
   interoperability reporting: rows 2 through 5 are each an _independent
   implementation from the text_, checked against author-supplied
   vectors.  None is an _independent implementation with independent
   vectors_, since the vectors are this project's; rows 4 and 5
   additionally constructed their own adversarial inputs beyond the
   published set, and in row 4 that construction is what exposed the
   defect.  The distinction is recorded here rather than left to be
   inferred.

   The fifth run is described in more detail because it is the one that
   changed the specification after the freeze.  The gap concerned span
   pairing: the specification states that a crash must leave a visibly
   unclosed span, because that is the evidence, yet defines no pairing
   check anywhere -- so two conformant verifiers would differ on whether
   a user ever sees an unpaired span.  The resolution deliberately did
   not make span pairing a verification verdict, since a trail truncated
   by a crash is incomplete without being falsified; it is surfaced as
   an advisory finding instead.  The finding, the reasoning and the
   resolution are on the public record, as are the verifiers, run
   records and ambiguity logs of every run above.

   The reference implementation ships the published vectors inside its
   distribution package, so an installed build can be checked against
   them without network access.

   The cost claim of C1 has been measured rather than argued.  An in-
   repository harness compares chain hashing with per-record COSE
   signing, and a second run of the same comparison, performed by a co-
   maintainer under a stated contamination boundary, agrees with it:
   with native primitives on a workstation, which is the case least
   favourable to the format, per-record signing costs between 45 and 61
   times the header hash on the write path and between 116 and 168 times
   on the verify path [PALA-COST].  On the embedded targets of
   Section 1.1 the ratio is larger.  These are measurements of two
   implementations, not properties of the format, and are reported as
   such.

   *The transparency path.* The Signed Statement construction of
   Section 8 has its own record, kept separately from the wire-format
   runs above because neither is evidence for the other [PALA-INTEROP].
   Two runs by a maintainer, each performed under a stated contamination
   boundary from the referenced standards and the published vector
   alone, and each with its own implementation of the CBOR and Ed25519
   primitives, reproduced the statement byte-for-byte.  The first run
   found that the protected header omitted the kid header parameter that
   Section 6 of [RFC9943] requires when neither x5t nor x5chain is
   present, and that the subject truncated the chain head; the

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 35]
Internet-Draft            PALA-1 Audit Records              October 2026

   construction was corrected, the vector reissued, and the second run
   reproduced the corrected statement and independently re-derived the
   key thumbprint.  The second run additionally established that the
   published tamper expectations had not exercised Ed25519 signature
   non-uniqueness (a scalar increased by the group order verifies unless
   the verifier enforces the range check of [RFC8032] Section 5.1.7);
   the reference implementation's verifier was measured to enforce it,
   and the case is now an executable expectation.

   Registration was then exercised end to end: a statement over the head
   of a chain written during a co-maintainer's session with the serving
   interface described below was registered with the SCITT API emulator
   published by the scitt-community project (scitt-api-emulator -- an
   emulator, not a production service), and the receipt was verified
   both by that emulator's own verifier and offline from the published
   artifacts alone.  The run is reported with its scope: the emulator
   was operated by the authors on a local host for the duration of the
   run, under a single-use key, and its receipt structure is the
   emulator's own, predating [RFC9942].  One finding resulted: the
   emulator expected the CWT-claims header under a draft-era label,
   whereas [RFC9597] registered a different one; the statement was not
   altered to match, the emulator received a one-line correction whose
   diff is published with the run, and the matter is reported upstream.
   A registration with a transparency service operated by an unrelated
   party is the next class of evidence and is not claimed here.

   The reference implementation also serves an interface compatible with
   a widely deployed inference API, recording the tool-dispatch boundary
   of Section 4 for any client of that interface.  A measured limit of
   that recording is stated in the same record: when a client negotiates
   tool use with the model in free text and executes locally, no
   structured dispatch crosses the interface and nothing is recorded;
   the reference implementation reports this as a visibility limit and
   does not reconstruct dispatches from prose.

14.  Security considerations

   Tamper-evidence applies to record bytes, not to the honesty of the
   recorder.  This format makes alteration of a written trail
   detectable.  It cannot establish that the runtime which wrote the
   trail reported truthfully at the moment of writing, and no format
   can: a dishonest producer with no external observer can construct an
   internally valid record of a fiction.  Publication of a chain head to
   an external witness (Section 8) bounds when such a trail can have
   been constructed and makes its later substitution or omission
   detectable; it does not make its content true.  Every claim elsewhere
   in this document is bounded by this paragraph.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 36]
Internet-Draft            PALA-1 Audit Records              October 2026

   The boundaries below are stated here rather than discovered later.

   1.  *It does not make the log true.* The chain proves _this is what
       the system recorded, unmodified_. Not _this is what happened_. A
       hallucinated model output is preserved faithfully.

   2.  *It does not defend against the owner at tier A.* Key and anchor
       are both theirs.  Tier A is self-diagnostics.  Section 7 is the
       only mitigation, and it is partial.

   3.  *It does not bind to hardware.* _"This is the same device"_ needs
       tier B+.

   4.  *A digest without its frame proves nothing about content.*
       Commitment defeats fabrication; it does not reconstruct.

   5.  *Cleartext headers are metadata, and metadata discloses.* The
       span graph, origins and timing are readable without a key.  That
       is the cost of Section 1.1, and it is not zero.

   6.  *It does not guarantee an action was logged before it happened.*
       Section 3.1.

   7.  *The chain alone does not detect truncation.* Section 9.2 is not
       optional; without an anchor the last N records can be removed
       silently.

15.  IANA considerations

   This document has no IANA actions.

16.  References

16.1.  Normative References

   [FIPS180-4]
              National Institute of Standards and Technology, "Secure
              Hash Standard (SHS)", FIPS PUB 180-4, August 2015.

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997,
              <https://www.rfc-editor.org/rfc/rfc2119>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
              May 2017, <https://www.rfc-editor.org/rfc/rfc8174>.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 37]
Internet-Draft            PALA-1 Audit Records              October 2026

   [SP800-38D]
              National Institute of Standards and Technology,
              "Recommendation for Block Cipher Modes of Operation:
              Galois/Counter Mode (GCM) and GMAC", NIST SP 800-38D,
              November 2007.

16.2.  Informative References

   [FSS]      The systemd project, "journald.conf: Seal= (Forward Secure
              Sealing)",
              <https://www.freedesktop.org/software/systemd/man/latest/
              journald.conf.html>.

   [I-D.birkholz-verifiable-agent-conversations]
              Birkholz, H., Heldt, T., and O. Steele, "Verifiable Agent
              Conversation Records", Work in Progress, Internet-Draft,
              draft-birkholz-verifiable-agent-conversations-01, 31
              August 2026, <https://datatracker.ietf.org/doc/html/draft-
              birkholz-verifiable-agent-conversations-01>.

   [I-D.daniel-ai-agent-internet-architecture]
              Park, S. D. and I. Siddique, "Architectural Requirements
              for Supporting AI Agents on the Internet", Work in
              Progress, Internet-Draft, draft-daniel-ai-agent-internet-
              architecture-03, 28 August 2026,
              <https://datatracker.ietf.org/doc/html/draft-daniel-ai-
              agent-internet-architecture-03>.

   [I-D.dawkins-scitt-ai-article50]
              Dawkins, V. S., "A SCITT Profile for EU AI Act Article 50
              Transparency Receipts", Work in Progress, Internet-Draft,
              draft-dawkins-scitt-ai-article50-00, 25 May 2026,
              <https://datatracker.ietf.org/doc/html/draft-dawkins-
              scitt-ai-article50-00>.

   [I-D.emirdag-scitt-ai-agent-execution]
              Emirdag, P., "AI Agent Execution Profile of SCITT", Work
              in Progress, Internet-Draft, draft-emirdag-scitt-ai-agent-
              execution-00, 11 April 2026,
              <https://datatracker.ietf.org/doc/html/draft-emirdag-
              scitt-ai-agent-execution-00>.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 38]
Internet-Draft            PALA-1 Audit Records              October 2026

   [I-D.kamimura-vap-framework]
              Tokachi, K., "Verifiable AI Provenance Framework (VAP): An
              Architectural Framework for Evidentiary-Grade AI Decision
              Trails", Work in Progress, Internet-Draft, draft-kamimura-
              vap-framework-01, 21 July 2026,
              <https://datatracker.ietf.org/doc/html/draft-kamimura-vap-
              framework-01>.

   [I-D.kuehlewind-audit-architecture]
              Kühlewind, M. and H. Birkholz, "An Architecture for
              Auditing Agent Delegation and Interactions", Work in
              Progress, Internet-Draft, draft-kuehlewind-audit-
              architecture-01, 7 September 2026,
              <https://datatracker.ietf.org/doc/html/draft-kuehlewind-
              audit-architecture-01>.

   [I-D.mih-scitt-agent-action-capsule]
              Mih, S., "An Agent Action Capsule Profile for SCITT", Work
              in Progress, Internet-Draft, draft-mih-scitt-agent-action-
              capsule-05, 26 September 2026,
              <https://datatracker.ietf.org/doc/html/draft-mih-scitt-
              agent-action-capsule-05>.

   [I-D.mih-sokolov-scitt-payload-binding]
              Mih, S. and A. Sokolov, "Canonicalization Declaration for
              SCITT Signed Statements", Work in Progress, Internet-
              Draft, draft-mih-sokolov-scitt-payload-binding-05, 12
              September 2026, <https://datatracker.ietf.org/doc/html/
              draft-mih-sokolov-scitt-payload-binding-05>.

   [I-D.munoz-scitt-permit-profile]
              Munoz, C., "A SCITT Profile for Pre-Execution AI Action
              Authorization Records", Work in Progress, Internet-Draft,
              draft-munoz-scitt-permit-profile-01, 19 July 2026,
              <https://datatracker.ietf.org/doc/html/draft-munoz-scitt-
              permit-profile-01>.

   [I-D.nobuo-scitt-protected-object-binding]
              Aoki, N., "SCITT Statement Relationship and Protected
              Object Binding", Work in Progress, Internet-Draft, draft-
              nobuo-scitt-protected-object-binding-00, 6 July 2026,
              <https://datatracker.ietf.org/doc/html/draft-nobuo-scitt-
              protected-object-binding-00>.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 39]
Internet-Draft            PALA-1 Audit Records              October 2026

   [I-D.sato-soos-gar]
              Sato, "The Governance Audit Record (GAR) for Agentic AI
              Systems", Work in Progress, Internet-Draft, draft-sato-
              soos-gar-08, 7 September 2026,
              <https://datatracker.ietf.org/doc/html/draft-sato-soos-
              gar-08>.

   [PALA-COST]
              "Serialization cost, independently measured: chain hashing
              versus per-record signing", August 2026,
              <https://github.com/Assault-
              Consulting/Palimpsests/blob/main/docs/specs/pala-1/
              independent-runs/oleksandr/serialization-cost/REPORT.md>.

   [PALA-INTEROP]
              "PALA-1 SCITT bridge: statement vector, bridge runs and
              registration run", August 2026, <https://github.com/
              Assault-Consulting/Palimpsests/tree/main/docs/interop>.

   [PALA-SPEC]
              "PALA-1 wire format specification, v1.0 (frozen)", August
              2026, <https://github.com/Assault-
              Consulting/Palimpsests/blob/main/docs/specs/pala-1/PALA-
              1.md>.

   [PALA-VECTORS]
              "PALA-1 test vectors and independent verification record",
              August 2026, <https://github.com/Assault-
              Consulting/Palimpsests/tree/main/docs/specs/pala-1>.

   [RFC3161]  Adams, C., Cain, P., Pinkas, D., and R. Zuccherato,
              "Internet X.509 Public Key Infrastructure Time-Stamp
              Protocol (TSP)", RFC 3161, DOI 10.17487/RFC3161, August
              2001, <https://www.rfc-editor.org/rfc/rfc3161>.

   [RFC5848]  Kelsey, J., Callas, J., and A. Clemm, "Signed Syslog
              Messages", RFC 5848, DOI 10.17487/RFC5848, May 2010,
              <https://www.rfc-editor.org/rfc/rfc5848>.

   [RFC6962]  Laurie, B., Langley, A., and E. Kasper, "Certificate
              Transparency", RFC 6962, DOI 10.17487/RFC6962, June 2013,
              <https://www.rfc-editor.org/rfc/rfc6962>.

   [RFC7942]  Sheffer, Y. and A. Farrel, "Improving Awareness of Running
              Code: The Implementation Status Section", BCP 205,
              RFC 7942, DOI 10.17487/RFC7942, July 2016,
              <https://www.rfc-editor.org/rfc/rfc7942>.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 40]
Internet-Draft            PALA-1 Audit Records              October 2026

   [RFC8032]  Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital
              Signature Algorithm (EdDSA)", RFC 8032,
              DOI 10.17487/RFC8032, January 2017,
              <https://www.rfc-editor.org/rfc/rfc8032>.

   [RFC8785]  Rundgren, A., Jordan, B., and S. Erdtman, "JSON
              Canonicalization Scheme (JCS)", RFC 8785,
              DOI 10.17487/RFC8785, June 2020,
              <https://www.rfc-editor.org/rfc/rfc8785>.

   [RFC8949]  Bormann, C. and P. Hoffman, "Concise Binary Object
              Representation (CBOR)", STD 94, RFC 8949,
              DOI 10.17487/RFC8949, December 2020,
              <https://www.rfc-editor.org/rfc/rfc8949>.

   [RFC9052]  Schaad, J., "CBOR Object Signing and Encryption (COSE):
              Structures and Process", STD 96, RFC 9052,
              DOI 10.17487/RFC9052, August 2022,
              <https://www.rfc-editor.org/rfc/rfc9052>.

   [RFC9597]  Looker, T. and M.B. Jones, "CBOR Web Token (CWT) Claims in
              COSE Headers", RFC 9597, DOI 10.17487/RFC9597, June 2024,
              <https://www.rfc-editor.org/rfc/rfc9597>.

   [RFC9679]  Isobe, K., Tschofenig, H., and O. Steele, "CBOR Object
              Signing and Encryption (COSE) Key Thumbprint", RFC 9679,
              DOI 10.17487/RFC9679, December 2024,
              <https://www.rfc-editor.org/rfc/rfc9679>.

   [RFC9942]  Steele, O., Birkholz, H., Delignat-Lavaud, A., and C.
              Fournet, "CBOR Object Signing and Encryption (COSE)
              Receipts", RFC 9942, DOI 10.17487/RFC9942, June 2026,
              <https://www.rfc-editor.org/rfc/rfc9942>.

   [RFC9943]  Birkholz, H., Delignat-Lavaud, A., Fournet, C., Deshpande,
              Y., and S. Lasker, "An Architecture for Trustworthy and
              Transparent Digital Supply Chains", RFC 9943,
              DOI 10.17487/RFC9943, June 2026,
              <https://www.rfc-editor.org/rfc/rfc9943>.

   [RFC9995]  Steele, O., Lasker, S., and H. Birkholz, "CBOR Object
              Signing and Encryption (COSE) Hash Envelope", RFC 9995,
              DOI 10.17487/RFC9995, July 2026,
              <https://www.rfc-editor.org/rfc/rfc9995>.

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 41]
Internet-Draft            PALA-1 Audit Records              October 2026

   [SSKG]     Marson, G. A. and B. Poettering, "Practical Secure
              Logging: Seekable Sequential Key Generators",
              DOI 10.1007/978-3-642-40203-6_7, 2013,
              <https://doi.org/10.1007/978-3-642-40203-6_7>.

Acknowledgments

   The specification was hardened by its independent verifiers, whose
   findings were resolved on the public record before this document
   existed, and the transparency path was hardened in the same way by
   the runs recorded in Section 13.  The authors thank every external
   contributor to that effort, the maintainers of the scitt-community
   reference implementation, and the SCITT and COSE working groups,
   whose published work this document refers to and builds no claim
   upon.

Changes from draft-sparysh-pala-audit-00

   This section is to be removed before publication as an RFC.

   *  Literal blocks now use kramdown's native fence.  In the -00
      rendering seven blocks, including the verification procedure of
      Section 9.1, had been flattened into running text.  No normative
      content changed.

   *  References: corrected an empty co-author entry and missing
      publication months introduced by the -00 build.

   *  Related work: added signed syslog [RFC5848] and the systemd
      journal's Forward Secure Sealing; the description of
      [I-D.mih-sokolov-scitt-payload-binding] follows its -05 reframing
      as a canonicalization declaration.

   *  Added Section 12, the relationship to the agent auditing
      architecture.

   *  The expansion of the name PALA is stated.

Contributors

   Oleksii Turak
   Email: olexii.turak@gmail.com

   Produced the fifth implementation of the frozen wire format, in Perl
   5, working from the specification text and published vectors alone
   under the project's stated contamination boundary, and surfaced a
   specification-completeness gap in span pairing that was resolved on

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 42]
Internet-Draft            PALA-1 Audit Records              October 2026

   the public record before this document existed.  Later, as a
   maintainer, reproduced the SCITT-bridge Signed Statement byte-for-
   byte from the referenced standards in two further runs, the first of
   which identified a conformance defect against RFC 9943 that was
   corrected on the record.

Authors' Addresses

   Andrii Sparysh
   Assault Consulting
   Kyiv
   Ukraine
   Email: as@assault.consulting

   Oleksandr Verteletskyi
   Assault Consulting
   Kyiv
   Ukraine
   Email: ov@assault.consulting

Sparysh & Verteletskyi    Expires 5 April 2027                 [Page 43]