Skip to main content

learnlog: A Verifiable Event Log Format for Learning Software
draft-srivastava-learnlog-01

Document Type Active Internet-Draft (individual)
Author Kumar Srivastava
Last updated 2026-10-12
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-srivastava-learnlog-01
Network Working Group                                      K. Srivastava
Internet-Draft                                 Quantum Learning Machines
Intended status: Standards Track                         11 October 2026
Expires: 14 April 2027

     learnlog: A Verifiable Event Log Format for Learning Software
                      draft-srivastava-learnlog-01

Abstract

   This document defines learnlog, a log format for learning software.
   A record holds typed events that describe what a learner did and what
   other parties, human or software, did in response.  As AI
   participates in learning and assessment, these records can preserve
   the assistance and producing instruments needed to interpret a
   performance.  The format does not establish independent learning or
   the effectiveness of an intervention.  Entries are chained by hash,
   and a producer can sign the chain.  A reader who trusts the signing
   key can then detect changes to the entries under a signed head that
   were made without that key.  Some changes remain undetectable, and
   the security considerations list them.  An event can be redacted, and
   the rest of the record still verifies.  The format defines files,
   records, entries, events, and registries for event schemas.  Subject-
   area event schemas and judgments about the applicability of research
   are out of scope.

Note to Readers

   This note is to be removed before publishing as an RFC.

   This individual Internet-Draft is a proposal for discussion.  This
   revision adds motivation and non-normative guidance for recording
   assistance in education with AI.  It makes no changes to the wire
   format, integrity rules, or test vectors of revision -00.  Appendix C
   lists the changes.  Appendix D lists open questions, and Appendix B
   describes implementation limits.

Status of This Memo

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

   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/.

Srivastava                Expires 14 April 2027                 [Page 1]
Internet-Draft                  learnlog                    October 2026

   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 14 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.  Code Components
   extracted from this document must include Revised BSD License text as
   described in Section 4.e of the Trust Legal Provisions and are
   provided without warranty as described in the Revised BSD License.

Table of Contents

   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   4
     1.1.  Scope . . . . . . . . . . . . . . . . . . . . . . . . . .   5
     1.2.  Conventions and Terminology . . . . . . . . . . . . . . .   6
   2.  Design Overview . . . . . . . . . . . . . . . . . . . . . . .   6
   3.  Log Files . . . . . . . . . . . . . . . . . . . . . . . . . .   7
     3.1.  Contained Files . . . . . . . . . . . . . . . . . . . . .   8
     3.2.  Sequential Files  . . . . . . . . . . . . . . . . . . . .   8
     3.3.  File Schema URIs  . . . . . . . . . . . . . . . . . . . .   9
   4.  Records . . . . . . . . . . . . . . . . . . . . . . . . . . .   9
     4.1.  Record Header . . . . . . . . . . . . . . . . . . . . . .  10
     4.2.  Entries . . . . . . . . . . . . . . . . . . . . . . . . .  12
     4.3.  Truncation  . . . . . . . . . . . . . . . . . . . . . . .  13
   5.  Events  . . . . . . . . . . . . . . . . . . . . . . . . . . .  13
     5.1.  Parties . . . . . . . . . . . . . . . . . . . . . . . . .  15
     5.2.  Activities  . . . . . . . . . . . . . . . . . . . . . . .  16
     5.3.  Instruments . . . . . . . . . . . . . . . . . . . . . . .  16
     5.4.  Event Names and Event Schemas . . . . . . . . . . . . . .  18
     5.5.  Defining and Extending Event Types  . . . . . . . . . . .  18
     5.6.  Guidance for Schema Designers . . . . . . . . . . . . . .  18
     5.7.  Companion Profiles for AI Use . . . . . . . . . . . . . .  19
   6.  Generic Event Schemas . . . . . . . . . . . . . . . . . . . .  20
     6.1.  The consent Namespace . . . . . . . . . . . . . . . . . .  20
     6.2.  The assist Namespace  . . . . . . . . . . . . . . . . . .  21
       6.2.1.  Hypothetical AI Assistance Example  . . . . . . . . .  23
     6.3.  The dialog Namespace  . . . . . . . . . . . . . . . . . .  24

Srivastava                Expires 14 April 2027                 [Page 2]
Internet-Draft                  learnlog                    October 2026

   7.  Integrity . . . . . . . . . . . . . . . . . . . . . . . . . .  25
     7.1.  Canonical Form  . . . . . . . . . . . . . . . . . . . . .  25
     7.2.  Hashes  . . . . . . . . . . . . . . . . . . . . . . . . .  25
     7.3.  Redaction . . . . . . . . . . . . . . . . . . . . . . . .  26
     7.4.  Signed Heads  . . . . . . . . . . . . . . . . . . . . . .  27
     7.5.  Verification  . . . . . . . . . . . . . . . . . . . . . .  28
   8.  Serialization . . . . . . . . . . . . . . . . . . . . . . . .  31
     8.1.  JSON  . . . . . . . . . . . . . . . . . . . . . . . . . .  31
     8.2.  JSON Text Sequences . . . . . . . . . . . . . . . . . . .  32
     8.3.  Other Serializations  . . . . . . . . . . . . . . . . . .  32
   9.  Relationship to Existing Work . . . . . . . . . . . . . . . .  32
   10. Security Considerations . . . . . . . . . . . . . . . . . . .  33
     10.1.  What Verification Shows  . . . . . . . . . . . . . . . .  33
     10.2.  Removal of Recent Entries  . . . . . . . . . . . . . . .  34
     10.3.  Redaction and Truncation by a Holder . . . . . . . . . .  34
     10.4.  Rewriting by the Producer  . . . . . . . . . . . . . . .  34
     10.5.  Trusted Keys . . . . . . . . . . . . . . . . . . . . . .  34
     10.6.  Where the Producer Runs  . . . . . . . . . . . . . . . .  34
     10.7.  Guessing Redacted Events . . . . . . . . . . . . . . . .  35
     10.8.  Meaning of Event Names . . . . . . . . . . . . . . . . .  35
     10.9.  Hash Algorithms  . . . . . . . . . . . . . . . . . . . .  35
     10.10. Canonical Form . . . . . . . . . . . . . . . . . . . . .  35
     10.11. Untrusted Input  . . . . . . . . . . . . . . . . . . . .  36
   11. Privacy Considerations  . . . . . . . . . . . . . . . . . . .  36
     11.1.  Identifiers  . . . . . . . . . . . . . . . . . . . . . .  36
     11.2.  People Other Than the Subject  . . . . . . . . . . . . .  36
     11.3.  Data Minimization  . . . . . . . . . . . . . . . . . . .  36
     11.4.  Limits of Redaction  . . . . . . . . . . . . . . . . . .  36
     11.5.  Correlation and Identification . . . . . . . . . . . . .  37
     11.6.  Signing Keys . . . . . . . . . . . . . . . . . . . . . .  37
     11.7.  Storage and Transfer . . . . . . . . . . . . . . . . . .  37
     11.8.  Children . . . . . . . . . . . . . . . . . . . . . . . .  37
   12. IANA Considerations . . . . . . . . . . . . . . . . . . . . .  37
     12.1.  URN Sub-namespace  . . . . . . . . . . . . . . . . . . .  37
     12.2.  File Schema URIs . . . . . . . . . . . . . . . . . . . .  38
     12.3.  Event Schema URIs  . . . . . . . . . . . . . . . . . . .  38
     12.4.  Media Types  . . . . . . . . . . . . . . . . . . . . . .  39
       12.4.1.  application/learnlog+json  . . . . . . . . . . . . .  39
       12.4.2.  application/learnlog+json-seq  . . . . . . . . . . .  39
   13. References  . . . . . . . . . . . . . . . . . . . . . . . . .  40
     13.1.  Normative References . . . . . . . . . . . . . . . . . .  40
     13.2.  Informative References . . . . . . . . . . . . . . . . .  42
   Appendix A.  Example  . . . . . . . . . . . . . . . . . . . . . .  43
     A.1.  An Example Event Schema . . . . . . . . . . . . . . . . .  43
     A.2.  A Complete File . . . . . . . . . . . . . . . . . . . . .  44
     A.3.  Intermediate Values . . . . . . . . . . . . . . . . . . .  50
     A.4.  The Signed Head . . . . . . . . . . . . . . . . . . . . .  51
     A.5.  Redaction and Truncation  . . . . . . . . . . . . . . . .  52

Srivastava                Expires 14 April 2027                 [Page 3]
Internet-Draft                  learnlog                    October 2026

     A.6.  Canonical Form Check  . . . . . . . . . . . . . . . . . .  53
   Appendix B.  Implementation Status  . . . . . . . . . . . . . . .  54
   Appendix C.  Changes in Revision -01  . . . . . . . . . . . . . .  55
   Appendix D.  Open Issues  . . . . . . . . . . . . . . . . . . . .  55
   Author's Address  . . . . . . . . . . . . . . . . . . . . . . . .  57

1.  Introduction

   This document defines learnlog, a log format for learning software.
   The format has two aims.  The first is to record actions that have
   meaning in the subject being learned, as distinct from interface
   activity such as clicks and page views.  The second is to let a
   reader check a record for changes, within the limits that Section 10
   states.  Both aims cover the help that a learner receives, whether
   from a teacher, a tutoring system, or an AI assistant.

   Education software that includes AI needs records that distinguish
   the learner's observable actions from assistance supplied by another
   party.  A submitted explanation alone does not state whether the
   learner composed it, responded to a prompt about an approach, or
   received an explanation from software.  These different histories
   matter when researchers, educators, or assessment designers interpret
   a performance.  Recording them at the time of use makes later
   inspection possible; a log cannot reconstruct assistance that its
   producer did not observe.

   The prospective purpose is to support interpretable evidence from
   future learning activities and studies.  The existing event members
   can identify the actor, task, session, and producing instrument,
   while the assistance events preserve the help the producer observed.
   A deployment may also need a companion profile that describes the
   activity stage, applicable permission, and observation boundaries
   (Section 5.7).  Neither an intact chain nor such a profile
   establishes a learning effect, independent performance, or the
   validity of applying a study to a different context.

   The format has the following properties:

   *  Events are typed.  An event schema defines the event types of one
      area, such as a prediction committed in a simulation
      (Section 5.4).

   *  Every event can state who acted and toward whom.  A request for
      help and a scaffold given in reply are events of their own,
      whether the helper is a person or a program (Section 5.1,
      Section 6.2).

Srivastava                Expires 14 April 2027                 [Page 4]
Internet-Draft                  learnlog                    October 2026

   *  Entries are chained by hash, and a producer can sign the latest
      hash.  A reader who trusts the signing key can then detect a
      change to the signed entries that was made without that key
      (Section 7).  Section 10 states the limits.

   *  An event can be redacted without breaking the chain (Section 7.3).

   *  Records are kept in files.  A record can be written, and its
      hashes checked, without a server.

   The structure of files, records, and event schemas follows qlog
   [QLOG], which defines structured logging for network protocols.  This
   document adds integrity rules and the members that a record of
   learning needs.

1.1.  Scope

   This document defines:

   *  the structure of files, records, entries, and events (Section 3
      through Section 5);

   *  event schemas for consent, assistance, and dialog, which are not
      tied to one subject area (Section 6);

   *  the canonical form, the hashes, redaction, signed heads, and
      verification (Section 7);

   *  two JSON serializations (Section 8);

   *  registries for file schemas and event schemas (Section 12).

   The following are out of scope:

   *  Event schemas for subject areas.  Other documents can define them.

   *  Transport and storage interfaces.

   *  Estimates of what a learner knows, such as scores or mastery
      values.  A record states what the producer recorded.  This
      document leaves conclusions drawn from a record to other formats.

   *  Distribution of the keys that verify signed heads.

   *  The legal basis for collecting data about learners.

Srivastava                Expires 14 April 2027                 [Page 5]
Internet-Draft                  learnlog                    October 2026

   *  Decisions about whether an intervention or research finding
      applies in a new setting.  Such decisions can cite records but are
      not event facts or core verification results.

1.2.  Conventions and Terminology

   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.

   Data structures are defined in the Concise Data Definition Language
   (CDDL) [RFC8610].  Examples are in JSON [RFC8259].  Some figures wrap
   long lines as described in [RFC8792].

   This document uses the following terms:

   Learner:  A person whose learning activity is recorded.

   Subject:  The learner that a record is about.

   Producer:  The software that writes a record.

   Holder:  A party that stores a record or passes it on.  The producer
      is the first holder.

   Verifier:  Software that checks a record against this document.

   Record:  A header and the entries about one subject, written by one
      producer.  A record forms one hash chain.

   Entry:  One element of a record.  An entry carries one event and the
      hashes that bind it into the chain.

   Event:  A typed description of one action.

   Event schema:  A definition of a namespace of event types.

   Head:  A statement that names the latest entry of a record at some
      moment (Section 7.4).

2.  Design Overview

   A log file holds one or more records.  A record holds a header and a
   sequence of entries.  Each entry holds one event.

Srivastava                Expires 14 April 2027                 [Page 6]
Internet-Draft                  learnlog                    October 2026

   log file
    +-- record
         +-- header          what the record is about
         +-- entry 1         one event and its hashes
         +-- entry 2
         +-- ...
         +-- signed heads    signed statements of the latest entry

                     Figure 1: Structure of a log file

   Each entry holds the hash of its event and the hash of the entry
   before it.  The first entry holds the hash of the header, and every
   entry hash covers that hash as well.  A change to the header or to an
   earlier entry therefore changes every later entry hash.  A producer
   can sign a statement of the latest entry hash, which gives a verifier
   a fixed point to check against.

    +--------+       +---------+       +---------+       +---------+
    | header |<------| entry 1 |<------| entry 2 |<------| entry 3 |
    +--------+ prev  +---------+ prev  +---------+ prev  +---------+
               hash       |      hash       |      hash       |
                     event hash        event hash        event hash
                          |                 |                 |
                       event 1           event 2          (redacted)

                    Figure 2: The hash chain of a record

   An entry commits to the hash of its event.  The event itself can be
   removed later, and the chain still verifies (Section 7.3).

   Event types live in namespaces that event schemas define.  This
   document defines schemas for three namespaces that are not tied to
   one subject area.  Other schemas are identified by URI.

3.  Log Files

   A log file takes one of two forms.  A contained file holds one or
   more records (Section 3.1).  A sequential file holds one record and
   grows by appending (Section 3.2).  Both forms hold the members of the
   log-file group, as in Section 3 of [QLOG].

Srivastava                Expires 14 April 2027                 [Page 7]
Internet-Draft                  learnlog                    October 2026

   LearnlogFile = {
       log-file,
       records: [+ Record]
   }

   log-file = (
       file_schema: text,
       serialization_format: text,
       ? title: text,
       ? description: text
   )

       Figure 3: LearnlogFile and the members common to all log files

   file_schema:  A URI [RFC3986] that identifies the file schema
      (Section 3.3).

   serialization_format:  The media type of the serialization
      (Section 8).

   title, description:  Free text about the file.  These members SHOULD
      NOT hold information about a learner.

   No hash covers these members.  A producer SHOULD write file_schema
   and serialization_format within the first 256 octets of a file, as
   Section 3 of [QLOG] also asks, so that a tool can identify the file
   from its start.

   The CDDL in this document has two root rules, LearnlogFile and
   LearnlogFileSeq.  A third rule, SeqItem, describes each later element
   of a sequential file.

3.1.  Contained Files

   A LearnlogFile is one JSON text that holds one or more records.  It
   suits export and exchange.  Its file schema URI is
   urn:ietf:params:learnlog:file:contained.

   The records in a file are verified one at a time.  They can come from
   different producers and describe different subjects.

3.2.  Sequential Files

   A LearnlogFileSeq holds one record and grows by appending.  It suits
   a log that is written while the learner works.  Its file schema URI
   is urn:ietf:params:learnlog:file:sequential.

Srivastava                Expires 14 April 2027                 [Page 8]
Internet-Draft                  learnlog                    October 2026

   LearnlogFileSeq = {
       log-file,
       record: RecordStart
   }

   ; every element after the first
   SeqItem = Entry / SignedHead

                    Figure 4: LearnlogFileSeq definition

   The first element of a sequential file is the LearnlogFileSeq object.
   Every later element is a SeqItem.  An element with a seq member is an
   Entry.  Any other element with a head member is a SignedHead.
   Entries appear in order of seq.  A producer writes a SignedHead after
   the entry that it names, and a reader accepts one at any position.

   The Entry elements, in file order, are the entries of the record, and
   the SignedHead elements are its signed heads.  In a sequential file,
   event_schemas lists the schemas known when the file is started.

3.3.  File Schema URIs

   A registered file schema uses a URN of the form
   urn:ietf:params:learnlog:file:<identifier> (Section 12.2).  Any other
   file schema uses a URI that its definer controls and MUST NOT use
   that URN form.  Such a URI is not registered.

4.  Records

   A record holds a header and the entries about one subject, written by
   one producer.

   record-start = (
       header: RecordHeader,
       event_schemas: [+ text],
       ? truncated: Truncation
   )

   RecordStart = { record-start }

   Record = {
       record-start,
       entries: [* Entry],
       ? signed_heads: [+ SignedHead]
   }

                        Figure 5: Record definition

Srivastava                Expires 14 April 2027                 [Page 9]
Internet-Draft                  learnlog                    October 2026

   header:  The record header (Section 4.1).

   event_schemas:  The URIs of the event schemas used in the record
      (Section 5.4).  As in Section 8 of [QLOG], the list is a hint to
      tools about the event namespaces in the record.  No hash covers it
      (Section 10.8), and it can grow with the record.  A record MAY
      hold events from schemas that are not listed.

   truncated:  Present when the oldest entries were removed
      (Section 4.3).

   entries:  The entries, in order of seq (Section 4.2).

   signed_heads:  Signatures by the producer over heads of this record
      (Section 7.4).

   The CDDL in this document defines what a producer writes.  A reader
   MUST ignore a member that it does not recognize, wherever the member
   appears.  A hash or a signature covers such a member only in a
   header, an event, or a head.  A producer SHOULD NOT add members
   anywhere else.

4.1.  Record Header

   The header states what a record is about and is fixed when the record
   is created.

Srivastava                Expires 14 April 2027                [Page 10]
Internet-Draft                  learnlog                    October 2026

   RecordHeader = {
       record_id: text,
       subject: text,
       hash_alg: HashAlg,
       created: Timestamp,
       ? producer: Producer,
       * text => any
   }

   Producer = {
       name: text,
       ? version: text,
       * text => any
   }

   HashAlg = "sha-256" / text

   ; lowercase hexadecimal
   HashValue = text .regexp "([0-9a-f][0-9a-f])+"

   ; RFC 3339, UTC only
   Timestamp = text .regexp
       "[0-9]{4}(-[0-9]{2}){2}T[0-9]{2}(:[0-9]{2}){2}([.][0-9]{1,9})?Z"

                     Figure 6: RecordHeader definition

   record_id:  An identifier for the record, unique among the records of
      the producer.  A version 4 UUID [RFC9562] is RECOMMENDED.

   subject:  A pseudonymous identifier for the learner.  Section 11.1
      gives the requirements.

   hash_alg:  The hash algorithm used throughout the record.  The value
      is a name from the IANA "Named Information Hash Algorithm
      Registry" [RFC6920].  That registry gives the output length of
      each algorithm, and the length MUST be at least 256 bits.
      Implementations MUST support sha-256 [FIPS180].

   created:  The time the record was created.

   producer:  The name and version of the software that writes the
      record.

   A header MAY hold other members.  The record hash (Section 7.2)
   covers every member, so a change to the header changes the record
   hash and every entry hash.

Srivastava                Expires 14 April 2027                [Page 11]
Internet-Draft                  learnlog                    October 2026

   A Timestamp is a date and time in the format of [RFC3339], in UTC,
   with an uppercase T and the suffix Z.  The pattern in Figure 6 admits
   some impossible values, such as month 13.  A Timestamp MUST also be a
   valid date and time.  The second 60 is valid only in the time
   23:59:60.  A HashValue is the whole output of the hash named by
   hash_alg, written as two lowercase hexadecimal digits for each octet.

4.2.  Entries

   Entry = {
       seq: Seq,
       time: Timestamp,
       event_hash: HashValue,
       prev_hash: HashValue,
       entry_hash: HashValue,
       ( event: Event // redacted: true )
   }

   ; a position in a record, from 1 to (2^53)-1
   Seq = 1..9007199254740991

                         Figure 7: Entry definition

   seq:  The position of the entry in the record.  The first entry of a
      record has seq 1.  Each later entry has the seq of its predecessor
      plus 1.  A Seq is an integer of at least 1 and below 2^53.

   time:  The time the event occurred, as observed by the producer.
      Order within a record is given by seq.  Values of time SHOULD NOT
      decrease from one entry to the next.

   event_hash:  The hash of the event (Section 7.2).

   prev_hash:  The hash that links the entry to what precedes it
      (Section 7.2).

   entry_hash:  The hash of the entry (Section 7.2).

   event:  The event (Section 5).

   redacted:  Present with the value true, in place of event, when the
      event was removed (Section 7.3).

   An entry holds exactly one of event and redacted.

Srivastava                Expires 14 April 2027                [Page 12]
Internet-Draft                  learnlog                    October 2026

   A producer appends an entry when the event occurs, or as soon after
   as it can.  A written entry keeps its position and its hashes.  This
   document permits two changes to the entries of a record.  Redaction
   removes an event, and a party that kept the event can put it back
   (Section 7.3).  Truncation removes the oldest entries (Section 4.3).

4.3.  Truncation

   A holder can remove the oldest entries of a record, for example to
   meet a retention limit.  The truncated member then holds the seq and
   entry_hash of the last entry that was removed.

   Truncation = {
       seq: Seq,
       entry_hash: HashValue
   }

                      Figure 8: Truncation definition

   The first remaining entry has a seq of truncated.seq plus 1 and a
   prev_hash equal to truncated.entry_hash.

   A record can be truncated more than once.  The truncated member then
   names the last entry removed overall.  A holder can remove every
   entry, which leaves entries empty.

   A signed head that names an entry before truncated.seq can no longer
   be compared with an entry, and a holder MAY remove it.  A holder
   SHOULD keep every other signed head.

   A verifier cannot check the entries that were removed.  A change to
   the header still shows in the remaining entries, because every entry
   hash covers the record hash (Section 7.2).  Section 10.1 states what
   such a check establishes.

5.  Events

   An event describes one action: something the learner did, or
   something another party did that bears on the learner's work.

Srivastava                Expires 14 April 2027                [Page 13]
Internet-Draft                  learnlog                    October 2026

   Event = $Event

   event-type<Name, Data> = {
       name: Name,
       salt: Salt,
       data: Data,
       ? actor: Party,
       ? to: Party,
       ? session: text,
       ? activity: Activity,
       ? instrument: Instrument,
       * text => any
   }

   ; 22 or more characters of the base64url alphabet
   Salt = text .regexp "[A-Za-z0-9_-]{22,}"

                         Figure 9: Event definition

   The event-type rule is a CDDL generic.  An event type is an instance
   of the rule that fixes the name and the type of data.  The $Event
   socket collects the instances (Section 5.5).

   name:  The event type, written as a namespace, a colon, and a type
      identifier (Section 5.4).

   salt:  A random value that keeps a removed event from being guessed
      from its hash (Section 7.3).  For each event, a producer MUST
      generate at least 16 octets from a cryptographically secure source
      and encode them in base64url without padding [RFC4648].

   data:  An object with the members that the event type defines.

   actor:  The party that performed the action (Section 5.1).  When
      absent, the actor is the subject.

   to:  The party the action was directed at (Section 5.1).  When
      absent, an action by another party was directed at the subject.
      An action by the subject then has no stated addressee.

   session:  An identifier that groups the events of one continuous
      period of use.

   activity:  The task in which the action took place (Section 5.2).

   instrument:  How the data of the event was produced (Section 5.3).

Srivastava                Expires 14 April 2027                [Page 14]
Internet-Draft                  learnlog                    October 2026

   An event MAY hold other members.  The event hash covers every member
   of the event.

5.1.  Parties

   A Party describes who acted or who was addressed.

   Party = {
       role: Role,
       ? kind: "human" / "software",
       ? id: text,
       * text => any
   }

   Role = "learner" / "instructor" / "assistant" / "peer" /
          "guardian" / "system" / text

                        Figure 10: Party definition

   The role member has one of these values:

   learner:  A person who is learning.  A learner without an id is the
      subject of the record.

   instructor:  A party responsible for teaching the subject in this
      activity.

   assistant:  A party that responds to requests and has no teaching
      responsibility.

   peer:  Another learner.

   guardian:  A person who acts for the subject, such as a parent.

   system:  The producer acting in none of the roles above, for example
      a simulation that reveals an outcome.

   Other values MAY be used.

   The kind member states whether the party is a person (human) or a
   program (software).  When the member is absent, a learner, peer, or
   guardian is a person, and a system is a program.  The member is
   REQUIRED with any other role.  The CDDL in Figure 10 does not express
   this rule.

   The id member identifies a party other than the subject.  For a
   person, the value is pseudonymous and follows Section 11.1.  For a
   program, the value names the program.

Srivastava                Expires 14 April 2027                [Page 15]
Internet-Draft                  learnlog                    October 2026

   Table 1 shows how some common parties are described.

      +====================================+============+==========+
      | Party                              | role       | kind     |
      +====================================+============+==========+
      | A teacher working with the learner | instructor | human    |
      +------------------------------------+------------+----------+
      | An intelligent tutoring system     | instructor | software |
      +------------------------------------+------------+----------+
      | A general AI chat assistant        | assistant  | software |
      +------------------------------------+------------+----------+
      | A classmate                        | peer       | human    |
      +------------------------------------+------------+----------+

                       Table 1: Examples of parties

   When the actor is a program, the instrument member (Section 5.3)
   describes the model or the version that produced the data.

5.2.  Activities

   The meaning of an event can depend on the task it belongs to.  A
   producer SHOULD include activity in every event that belongs to a
   task.

   Activity = {
       id: text,
       ? version: text,
       ? variant: text,
       * text => any
   }

                       Figure 11: Activity definition

   id:  An identifier for the task, such as a URI.

   version:  The version of the task content.

   variant:  The form of the task that this learner received, when forms
      differ.  A random seed is one example.

5.3.  Instruments

   The instrument member states how the data of an event came to be.  A
   reader needs it to weigh an event that a model wrote or judged.

Srivastava                Expires 14 April 2027                [Page 16]
Internet-Draft                  learnlog                    October 2026

   Instrument = {
       source: "deterministic" / "model" / "human" / text,
       ? model: text,
       ? config_hash: HashValue,
       ? parameters: { * text => any },
       ? validated: bool,
       * text => any
   }

                      Figure 12: Instrument definition

   The source member has one of these values:

   deterministic:  Fixed program logic produced the data.

   model:  A statistical or generative model produced the data.  A hint
      written by a language model and a transcript of speech are
      examples.

   human:  A person entered or judged the data.

   Other values MAY be used.  The remaining members are:

   model:  The identifier and version of the model or program.

   config_hash:  The hash of the configuration that governed the output,
      such as a prompt (Section 7.2).  The producer chooses the octets
      that are hashed and needs to keep them for the hash to be of use.

   parameters:  Settings that affect the output, such as a sampling
      temperature.

   validated:  True when a deterministic check accepted the output of a
      model before it was used.

   An event without an instrument member makes no statement about how
   its data was produced.

   The producer.version member identifies recording software;
   instrument.model identifies the model or program that produced the
   event data.  Keeping these identifiers distinct lets a reader inspect
   changes in either.  A configuration hash identifies retained octets;
   it does not make those octets available, show that the named
   configuration was executed, or make a probabilistic output
   reproducible.  The validated member reports a deterministic
   acceptance check, not empirical validation of educational
   effectiveness or a learner's knowledge.

Srivastava                Expires 14 April 2027                [Page 17]
Internet-Draft                  learnlog                    October 2026

5.4.  Event Names and Event Schemas

   Event types are grouped in namespaces, as in Section 8 of [QLOG].  An
   event schema is a document that defines a namespace or extends one.
   The name of an event is the namespace identifier, a colon, and the
   type identifier.  Each identifier starts with a letter from a to z
   and continues with such letters, digits, or underscores.

   Each event schema has a URI.  A registered schema uses the form
   urn:ietf:params:learnlog:events:<namespace> (Section 12.3).  A schema
   that extends a namespace adds a fragment identifier to the URI of
   that namespace.  Any other schema uses a URI that its definer
   controls and MUST NOT use that URN form.  A URI that contains a
   domain name SHOULD include a month and year in the form mmyyyy.
   Section 8.1 of [QLOG] gives the same rule, to avoid problems when a
   domain name changes ownership.

   A record can hold an event whose schema a tool does not know.  Such
   an event does not match the CDDL that the tool has.  Verification
   (Section 7.5) checks its hashes like any others and does not depend
   on its schema.

5.5.  Defining and Extending Event Types

   An event schema adds each of its event types to the $Event socket.
   The lines below, taken from the example schema in Appendix A.1,
   define the event type sim:prediction_committed.

   $Event /= event-type<"sim:prediction_committed",
                        SimPredictionCommitted>

   Each data type in this document ends with a group socket named after
   the type, such as $$dialog-message-extension.  A later schema can add
   members to the data type through that socket.

5.6.  Guidance for Schema Designers

   The points below apply to any event schema.

   *  Define events for actions that have meaning in the subject area,
      such as a prediction committed before an experiment or a claim
      filed with its evidence.  Interface activity, such as clicks and
      page views, does not belong in a record unless a schema gives it
      that kind of meaning.

   *  Record what happened and leave conclusions out.  A detected
      misconception is a judgment about the learner.  An event that
      holds one SHOULD carry an instrument member.

Srivastava                Expires 14 April 2027                [Page 18]
Internet-Draft                  learnlog                    October 2026

   *  Refer to an earlier entry of the same record by its seq.

   *  Allow text written by a learner to be left out.  Free text can
      hold personal data.  A hash can stand in for the text, within the
      limits that Section 10.7 describes.

   *  State which members can identify a person.

   *  Prefer integers and strings to fractional numbers where exact
      values matter (Section 7.1).

5.7.  Companion Profiles for AI Use

   This subsection gives non-normative guidance.  It adds no core fields
   or event types.  A companion profile can use the extension points of
   the header and events to state context needed by a particular
   deployment.  The profile needs its own identifier, version, and
   public specification.  Event-schema URIs follow Section 5.4.  A
   profile identifier is not a registration in the registries requested
   by this document.

   A profile can distinguish practice, assessment, and other activity
   stages; identify the policy that permitted or prohibited specified
   assistance; and bind that policy to the relevant actor, task, stage,
   and period.  Permission to use assistance in an activity is separate
   from consent to collect, use, or disclose data (Section 6.1).
   Neither can be inferred from the other.  A policy assertion also does
   not establish compliance.

   A profile can state which channels, sessions, activities, and periods
   the producer planned to observe, which it asserts it captured, and
   which it excluded.  Planned capture and achieved capture are
   different assertions.  A missing assistance event does not
   demonstrate that no assistance occurred.  Outside applications, other
   devices, between-session use, a capture interruption, and unavailable
   content can leave relevant exposure unknown.  Describing a gap does
   not establish that AI was used in that gap.

   The header is fixed when a record is created (Section 4.1).  A plan
   stated there is not a later completion report.  A change in stage,
   applicable policy, model, configuration, or observation coverage can
   be represented by starting another record with the new context, or by
   an explicitly defined extension carried in a hashed event.  A profile
   using such an extension needs to define its effective scope and how
   events refer to the context.  This document defines no runtime
   context-update or capture-completion event, and modifying an existing
   header changes the hash commitments.

Srivastava                Expires 14 April 2027                [Page 19]
Internet-Draft                  learnlog                    October 2026

   A profile can require the existing actor, activity, session, and
   instrument members in particular events.  It can also identify where
   retained content or configuration is available to an authorized
   reviewer.  A hash or content reference alone does not give that
   reviewer the semantic content needed to classify a scaffold, and
   access can be limited by Section 11.  Profiles need to distinguish
   missing information from information that has not been reviewed.

   Conditions such as whether AI changed practice, comparison-group
   exposure, or grading usually require evidence beyond one record.
   Condition assessments and judgments about the applicability of
   educational research belong in separately specified analytical
   records.  Those records can refer to the relevant learnlog record and
   entries, state the reviewed scope and comparators, and preserve
   unresolved questions.  The core verifier does not endorse those
   judgments or decide whether a study needs to be repeated.

6.  Generic Event Schemas

   This section defines event schemas for three namespaces that are not
   tied to one subject area: consent, assist, and dialog.

6.1.  The consent Namespace

   The schema URI is urn:ietf:params:learnlog:events:consent.  The
   namespace has two event types, consent:granted and consent:withdrawn.
   Both carry the same data.

   ConsentChange = {
       scopes: [+ ConsentScope],
       ? ref: text,
       * $$consent-change-extension
   }

   ConsentScope = "instruction" / "research" / "export" / text

   $Event /= event-type<"consent:granted", ConsentChange>
   $Event /= event-type<"consent:withdrawn", ConsentChange>

                 Figure 13: Events of the consent namespace

   scopes:  The uses that the consent covers.

   ref:  A reference to the consent that the producer holds, such as the
      identifier of a signed form.

   This document defines three scopes.  Other values MAY be used.

Srivastava                Expires 14 April 2027                [Page 20]
Internet-Draft                  learnlog                    October 2026

   instruction:  Use of the record to support the instruction of the
      subject.

   research:  Use of the record in research.

   export:  Disclosure of the record outside the organization that
      operates the producer.

   The actor of a consent event is the party that gave or withdrew
   consent, for example a guardian.

   A consent event records that consent was given or withdrawn, as the
   producer observed it.  This document does not define how consent is
   obtained or how a producer acts on it.

   A scope is in effect from a consent:granted event that names it until
   a later consent:withdrawn event that names it.  A reader cannot tell
   which scopes are in effect when a consent event may be among the
   entries that were redacted or removed.  For that reason, a holder
   SHOULD NOT redact a consent event.

6.2.  The assist Namespace

   The schema URI is urn:ietf:params:learnlog:events:assist.  The
   namespace records the help that the producer observed.  A reader can
   treat an action by the learner that follows a scaffold in the same
   activity as possibly assisted.

   assist:help_requested:  The actor asked for help.  The to member of
      the event names the party that was asked.

   assist:scaffold_provided:  The actor gave the learner a scaffold,
      which is support meant to help the learner make progress.  The
      actor can be an instructor, an assistant, a peer, or the system.
      The event MUST hold the actor member, because an absent actor
      would mean the subject.

Srivastava                Expires 14 April 2027                [Page 21]
Internet-Draft                  learnlog                    October 2026

   AssistHelpRequested = {
       ? type: ScaffoldType,
       * $$assist-help-requested-extension
   }

   AssistScaffoldProvided = {
       type: ScaffoldType,
       ? request: Seq,
       ? level: uint .ge 1,
       ? reveals_answer: bool,
       ? modality: "text" / "speech" / text,
       ? content: text,
       ? content_ref: text,
       ? content_hash: HashValue,
       * $$assist-scaffold-provided-extension
   }

   ScaffoldType = "socratic" / "probing" / "metacognitive" /
                  "scaffolding" / "explain" / "hint" /
                  "demonstrate" / text

   $Event /= event-type<"assist:help_requested", AssistHelpRequested>
   $Event /= event-type<"assist:scaffold_provided",
                        AssistScaffoldProvided>

                 Figure 14: Events of the assist namespace

   In AssistHelpRequested, type is the kind of help that was asked for,
   when the interface distinguishes kinds.  The members of
   AssistScaffoldProvided are:

   type:  The kind of scaffold (Table 2).

   request:  The seq of the entry that this scaffold answers, such as an
      assist:help_requested entry or a dialog:message entry.  Absent
      when the scaffold was not requested.

   level:  The position of the scaffold among those given for the
      current activity, starting at 1.

   reveals_answer:  True when the scaffold discloses the answer that the
      activity asks for.

   modality:  How the scaffold was expressed.  The default is text.

   content:  The words of the scaffold.

   content_ref:  An identifier for authored scaffold content.

Srivastava                Expires 14 April 2027                [Page 22]
Internet-Draft                  learnlog                    October 2026

   content_hash:  The hash of the scaffold as shown to the learner
      (Section 7.2), for use when content is left out.  An event MUST
      NOT hold both content and content_hash.

              +===============+=============================+
              | Value         | Meaning                     |
              +===============+=============================+
              | socratic      | An open question that leads |
              |               | the learner toward an idea  |
              +---------------+-----------------------------+
              | probing       | A question about an         |
              |               | assumption the learner made |
              +---------------+-----------------------------+
              | metacognitive | A prompt about the          |
              |               | learner's own approach      |
              +---------------+-----------------------------+
              | scaffolding   | The problem broken into     |
              |               | parts                       |
              +---------------+-----------------------------+
              | explain       | A direct explanation        |
              +---------------+-----------------------------+
              | hint          | A hint                      |
              +---------------+-----------------------------+
              | demonstrate   | A worked example            |
              +---------------+-----------------------------+

                      Table 2: Values of ScaffoldType

   Other values MAY be used.

   A producer SHOULD record every scaffold given to the learner,
   requested or not.  The actor member identifies the provider.

   Help can arrive as a turn in a conversation.  A producer that knows a
   turn to be help records it as assist:scaffold_provided, with the
   words in content or their hash in content_hash, and writes no
   dialog:message for that turn.  When a producer cannot tell whether a
   turn is help, it records the turn as dialog:message (Section 6.3).
   The replies of a general chat assistant are an example.

6.2.1.  Hypothetical AI Assistance Example

   Consider a task that asks a learner to solve 2x + 3 = 11 and explain
   the approach.  An AI assistant might say, "Before calculating,
   describe your plan and how you will check whether it worked."  An
   assist:scaffold_provided event could describe this as type equal to
   metacognitive, with reveals_answer equal to false and the words in
   content.  The actor identifies a software assistant, and the

Srivastava                Expires 14 April 2027                [Page 23]
Internet-Draft                  learnlog                    October 2026

   activity, session, and instrument identify the task and producing
   model.

   In a different hypothetical history, the assistant says, "Subtract 3
   from both sides to get 2x = 8, then divide both sides by 2, so x =
   4."  The event could instead use type equal to explain and
   reveals_answer equal to true.  These examples illustrate existing
   members; they are not measurements of learning and introduce no new
   event type.

   If a subject-area schema records a learner response after either
   scaffold, the sequence can distinguish the two recorded assistance
   histories.  It cannot establish the learner's internal reasoning,
   when internal retrieval took place, whether another source was used,
   or which assistance caused a later outcome.  A declaration of type or
   reveals_answer remains a producer assertion.  A reviewer needs the
   relevant content and task to inspect it.  An applicability assessment
   comparing this activity with a classroom intervention needs
   additional evidence and separately stated assumptions.

6.3.  The dialog Namespace

   The schema URI is urn:ietf:params:learnlog:events:dialog.  The
   namespace has one event type, dialog:message, which is one turn in an
   exchange between the subject and another party.  The actor is the
   party that produced the turn, and to names the party addressed.

   DialogMessage = {
       ? modality: "text" / "speech" / text,
       ? content: text,
       ? content_hash: HashValue,
       ? reply_to: Seq,
       * $$dialog-message-extension
   }

   $Event /= event-type<"dialog:message", DialogMessage>

                 Figure 15: Events of the dialog namespace

   modality:  How the turn was expressed.  The default is text.

   content:  The words of the turn.

   content_hash:  The hash of the words (Section 7.2), for use when
      content is left out.  An event MUST NOT hold both content and
      content_hash.

   reply_to:  The seq of the entry that this turn answers.

Srivastava                Expires 14 April 2027                [Page 24]
Internet-Draft                  learnlog                    October 2026

   A producer SHOULD include activity when the exchange takes place
   during a task.  A reader can then treat a turn by another party as
   possible help.

   The words of a turn can hold personal data, and Section 11 applies.
   When software transcribes speech, the event SHOULD carry an
   instrument member that identifies the transcriber.

7.  Integrity

7.1.  Canonical Form

   Hashes are computed over a canonical form, so that two
   implementations produce the same octets for the same value.  The
   canonical form of a JSON value is its serialization under the JSON
   Canonicalization Scheme (JCS) [RFC8785], encoded in UTF-8.

   The following rules apply to a whole log file, including the parts
   that no hash covers:

   *  A log file MUST conform to I-JSON [RFC7493].  In particular, no
      object holds two members with the same name, and no string holds a
      noncharacter or a surrogate without its pair.

   *  A number is hashed as the IEEE 754 double nearest to its value, in
      the form that [RFC8785] gives that double.  A file MUST NOT hold a
      number too large for a double.  A number written without a
      fraction or an exponent MUST have an absolute value below 2^53.  A
      larger integer is carried as a string.

   *  A string is hashed as the characters it denotes.  An escape
      sequence and the character it stands for give the same hash.  A
      holder MUST NOT apply Unicode normalization.

   *  A holder MUST preserve every member of a header, an event, and a
      head, including members it does not recognize.

   A serialization other than JSON (Section 8.3) is mapped to the JSON
   data model first.  Hashes are always computed over the canonical JSON
   form.

7.2.  Hashes

   In this section, H(x) is the hash named by hash_alg, applied to the
   octets x and written in lowercase hexadecimal.  C(v) is the canonical
   form of the JSON value v.

Srivastava                Expires 14 April 2027                [Page 25]
Internet-Draft                  learnlog                    October 2026

   record hash  = H(C(header))

   event_hash   = H(C(event))

   prev_hash    = record hash       in the entry with seq 1
                = entry_hash of the preceding entry, otherwise

   entry_hash   = H(C({ "record_hash": record hash,
                        "seq": seq, "time": time,
                        "event_hash": event_hash,
                        "prev_hash": prev_hash }))

                        Figure 16: Hash computation

   *  The record hash is the hash of the header object.

   *  event_hash is the hash of the event object with all its members.

   *  prev_hash of the entry with seq 1 is the record hash.  In every
      other entry, it is the entry_hash of the entry before it.

   *  entry_hash is the hash of an object with exactly five members.
      The member record_hash holds the record hash.  The other four are
      the seq, time, event_hash, and prev_hash of the entry.

   *  A member named content_hash or config_hash holds the hash of a
      string of octets.  For text, the octets are its UTF-8 encoding.
      For other content, the producer chooses the octets.

   Every entry hash covers the record hash.  An entry that is moved to a
   record with another header therefore fails step 4e of Section 7.5,
   even after the entries before it are removed (Section 4.3).

   A header and an event each require members that the object hashed for
   an entry lacks.  The canonical form of that object therefore differs
   from the canonical form of any header or event.

7.3.  Redaction

   A holder redacts an entry by removing its event member and adding the
   member redacted with the value true.  No other member changes.

   The entry hash is computed from event_hash, without the event itself.
   Every hash in the record therefore still verifies, and so does every
   signed head.

Srivastava                Expires 14 April 2027                [Page 26]
Internet-Draft                  learnlog                    October 2026

   The salt is removed with the event.  A party that does not have the
   salt cannot confirm a guess at the event from event_hash
   (Section 10.7).

   Redaction leaves seq, time, and the hashes of the entry in place.  A
   holder that needs to remove those as well truncates the record
   (Section 4.3) or deletes it.

   A verifier reports which entries are redacted.  Redaction does not
   cause a check to fail.

   Only a party that kept the event can restore it.  A restored event is
   checked against event_hash like any other.

7.4.  Signed Heads

   A head names the latest entry of a record at some moment.  A producer
   signs a head so that a verifier can authenticate the record up to
   that entry.

   SignedHead = {
       head: Head,
       signature: text
   }

   Head = {
       record_hash: HashValue,
       seq: Seq,
       entry_hash: HashValue,
       time: Timestamp,
       * text => any
   }

                      Figure 17: SignedHead definition

   record_hash:  The record hash (Section 7.2).

   seq, entry_hash:  The seq and entry_hash of the entry that the head
      names.

   time:  The time of signing, as observed by the producer.

   The signature member is a JSON Web Signature (JWS) [RFC7515] in the
   compact serialization with detached content (Appendix F of
   [RFC7515]).  The JWS payload is the canonical form of the head
   object.  The value of signature is therefore the encoded protected
   header, two periods, and the encoded signature.

Srivastava                Expires 14 April 2027                [Page 27]
Internet-Draft                  learnlog                    October 2026

   *  The protected header MUST contain alg and kid and MUST NOT contain
      crit.

   *  The value of alg MUST name a digital signature algorithm that uses
      a public key.  The value none and MAC algorithms such as HS256
      MUST NOT be used.  Implementations MUST support ES256 [RFC7518].

   *  The value of kid MUST be the JWK Thumbprint [RFC7638] of the
      public key, computed with SHA-256 and encoded in base64url without
      padding.

   To check a signature, a verifier computes the canonical form of head,
   encodes it in base64url, places it between the two periods, and
   verifies the result as a JWS.  A verifier uses each key it trusts
   with exactly one algorithm (Section 3.1 of [RFC8725]).

   A producer SHOULD sign a head at the end of each session and whenever
   a record leaves its control.

   This document does not define how a verifier obtains the public key
   or decides to trust it.  A key that travels in the file itself shows
   nothing about who signed.

7.5.  Verification

   A verifier is configured with the public keys it trusts and, for each
   key, the one signature algorithm it accepts.  A verifier MUST report
   the result that the steps below define.  Any procedure that gives the
   same result is acceptable.

   1.  Read the file.

       a.  Read a file that begins with the octet 0x1E as a JSON text
           sequence (Section 8.2).  Read any other file as one JSON text
           (Section 8.1).

       b.  Check that each JSON text conforms to I-JSON and to the rules
           for numbers in Section 7.1.

       c.  Check that file_schema names a file schema that the verifier
           knows and that fits the serialization.  Check that a
           contained file holds a records array with at least one
           element, and that the first element of a sequential file
           holds a record object.

Srivastava                Expires 14 April 2027                [Page 28]
Internet-Draft                  learnlog                    October 2026

       A verifier MUST reject a file when its JSON text fails this step,
       or when the first element of a sequential file does.  None of its
       records is verified.  A later element of a sequential file that
       fails step 1b is discarded (Section 8.2).  Steps 2 to 5 apply to
       each record of a file that passes.

   2.  Check the header.

       a.  Check that header is an object, that record_id, subject, and
           hash_alg are strings, and that created is a Timestamp.

       b.  If step 2a passed and the verifier does not support hash_alg,
           the outcome for the record is "unsupported" and no further
           step applies.  A verifier MUST NOT support an algorithm whose
           output is shorter than 256 bits.

       c.  Compute the record hash.

   3.  Set the expected seq to 1 and the expected link to the record
       hash.  If truncated is present, check that truncated.seq is a Seq
       and that truncated.entry_hash is a HashValue.  The expected seq
       is then truncated.seq plus 1, and the expected link is
       truncated.entry_hash.

   4.  Check that entries is an array.  For each entry, in order:

       a.  Check that seq is a Seq, that time is a Timestamp, and that
           event_hash, prev_hash, and entry_hash are HashValues.  Check
           that the entry holds exactly one of event and redacted.

       b.  Check that seq equals the expected seq.

       c.  Check that prev_hash equals the expected link.

       d.  If event is present, check that it is an object, that its
           name has the form given in Section 5.4, that its salt matches
           the Salt pattern of Figure 9, and that its data is an object.
           Then check that the hash of the event equals event_hash.  If
           redacted is present, check that its value is true.

       e.  Compute the entry hash and check that it equals entry_hash.

       f.  Set the expected link to entry_hash and add 1 to the expected
           seq.

   5.  If signed_heads is present, check that it is an array.  For each
       signed head:

Srivastava                Expires 14 April 2027                [Page 29]
Internet-Draft                  learnlog                    October 2026

       a.  Check that head is an object in which record_hash and
           entry_hash are HashValues, seq is a Seq, and time is a
           Timestamp.  Check that signature consists of two base64url
           strings, neither of them empty, joined by two periods.  Check
           that the first string decodes to a JSON object that conforms
           to I-JSON.  Check that this object holds the strings alg and
           kid, that alg is not none, and that crit is absent.

       b.  Check that head.record_hash equals the record hash.

       c.  Check that head.seq is no greater than the seq of the last
           entry.  A greater value shows that entries are missing from
           the end of the record.  For a record without entries, the
           comparison uses truncated.seq, or 0 when the record is not
           truncated.

       d.  If an entry has the seq that the head names, check that
           head.entry_hash equals its entry_hash.  If head.seq equals
           truncated.seq, check that head.entry_hash equals
           truncated.entry_hash.  A head with a lower seq names an entry
           that was removed, and this check does not apply to it.

       e.  If the verifier trusts a key whose JWK Thumbprint equals kid,
           check that alg is the algorithm it accepts for that key, and
           verify the signature with that key as Section 7.4 describes.
           If the verifier trusts no such key, the signature is not
           checked.

   Section 4.1 and Section 4.2 define the terms Timestamp, HashValue,
   and Seq. A member that this document does not define is ignored in
   every step, apart from its part in a hash or a signature.

   Once a check in steps 2 to 5 fails, the outcome is settled, and a
   verifier MAY stop.

   The result for a record has these parts:

   Outcome:  "consistent" when every check in steps 2 to 5 passed,
      "inconsistent" when a check failed, or "unsupported" as step 2
      describes.

   Authenticated through:  For a consistent record, the highest seq
      among the heads that had an entry hash to compare in step 5d and a
      signature that verified in step 5e, together with the kid of a
      head that names it.  This part is absent when no head qualifies.
      Entries up to that seq were in the record when the holder of that
      key signed.  Later entries are consistent and unauthenticated.

Srivastava                Expires 14 April 2027                [Page 30]
Internet-Draft                  learnlog                    October 2026

   Redacted:  The seq of each redacted entry.

   Truncated:  The value of truncated.seq, when the record is truncated.
      The entries up to that seq were not checked.

   A verifier reports the following conditions, and they leave the
   outcome unchanged:

   *  a time that is earlier than the one before it, with the two
      compared as instants;

   *  a signed head whose signature was not checked;

   *  an element of a sequential file that was discarded (Section 8.2).

   Verification does not use title, description, serialization_format,
   or event_schemas.  The data of an event is not checked against an
   event schema, and an event of an unknown type is handled like any
   other.  A tool MAY validate events against the schemas it knows and
   report the result separately.

   A consistent record agrees with itself.  A verified head ties the
   entries up to its seq to a key.  Section 10.1 states what these
   results establish and what they leave open.

8.  Serialization

   The structures in this document are defined in CDDL.  Section 11 of
   [QLOG] takes the same approach and maps its structures to JSON and to
   JSON text sequences.  This document defines the same two
   serializations.  Hashes always use the canonical JSON form
   (Section 7.1).

   Where this document defines a member as an integer, a producer writes
   the number without a fraction or an exponent.  A reader compares
   numbers by value.

8.1.  JSON

   A LearnlogFile is serialized as a JSON text [RFC8259] in UTF-8.  The
   media type is application/learnlog+json, which is also the value of
   serialization_format.  The file extension is .learnlog.

Srivastava                Expires 14 April 2027                [Page 31]
Internet-Draft                  learnlog                    October 2026

8.2.  JSON Text Sequences

   A LearnlogFileSeq is serialized as a JSON text sequence [RFC7464].
   Each element is preceded by a record separator (0x1E) and followed by
   a line feed (0x0A).  The media type is application/learnlog+json-seq,
   which is also the value of serialization_format.  The file extension
   is .slearnlog.

   A producer can add an entry or a signed head to a sequential file
   without rewriting what came before.  Redaction and truncation rewrite
   the file.  In Figure 18, <RS> stands for the record separator and
   most values are left out.

   <RS>{"file_schema":"urn:ietf:params:learnlog:file:sequential",
        "serialization_format":"application/learnlog+json-seq",
        "record":{"header":{...},"event_schemas":[...]}}
   <RS>{"seq":1,"time":"2026-10-07T14:00:05Z","event":{...},
        "event_hash":"...","prev_hash":"...","entry_hash":"..."}
   <RS>{"seq":2,"time":"2026-10-07T14:01:10Z","event":{...},
        "event_hash":"...","prev_hash":"...","entry_hash":"..."}
   <RS>{"head":{...},"signature":"..."}

                  Figure 18: Outline of a sequential file

   A crash can leave the last element of a file cut off.  A reader MUST
   discard an element that is cut off (Section 2.3 of [RFC7464]) or that
   fails step 1b of Section 7.5.  The same applies to an element that is
   neither an Entry nor a SignedHead.  When the first element is
   unusable, the file is rejected.  When an entry is discarded, the
   entries after it fail verification.

8.3.  Other Serializations

   Other serializations MAY be defined, for example one in CBOR.  A
   serialization MUST map every structure to the JSON data model without
   loss, because hashes are computed over the canonical JSON form
   (Section 7.1).

9.  Relationship to Existing Work

   The file structure and the event schema model come from qlog [QLOG].
   A learnlog record corresponds to a qlog trace (Section 4.2 of
   [QLOG]).  This document adds hashes, redaction, and signed heads.

   The Experience API (xAPI) [XAPI] defines a JSON data model and a web
   service for communication between activities and a Learning Record
   Store.  This document defines a file format and no web service.  A
   mapping between the two is not defined here.

Srivastava                Expires 14 April 2027                [Page 32]
Internet-Draft                  learnlog                    October 2026

   Caliper Analytics [CALIPER] defines events and entities, and an
   envelope that carries them to an endpoint.  This document defines no
   transport.

   Deployments that use xAPI or Caliper need explicit mappings for
   assistance, actors, task context, and instrument provenance before
   exchanging such information with learnlog.  A mapping needs to state
   which distinctions it preserves, what information it loses, and
   whether learnlog integrity commitments can be retained.  This
   document provides no such mapping or interoperability result.

   Redaction relies on salted hashes, an approach that Selective
   Disclosure for JSON Web Tokens also uses (Section 1 of [RFC9901]).  A
   signed head is similar to the Signed Tree Head of Certificate
   Transparency (Section 4.10 of [RFC9162]), applied to a chain in place
   of a tree.

10.  Security Considerations

10.1.  What Verification Shows

   A record that verifies as consistent has entries that agree with one
   another and with the header.  Consistency alone does not show who
   wrote the record or that nothing was replaced.  Anyone who holds a
   record without a signed head can change an event and recompute every
   later hash.

   A signed head limits this.  Take a party without the signing key that
   changes the seq, time, or event of an entry at or before the head.
   The head stays valid only when the change is a redaction, the
   restoring of a redacted event, or a truncation (Section 10.3).  After
   any other such change, a verifier that trusts the key reports the
   record as inconsistent, or as unauthenticated when the head was
   removed as well.

   Neither property shows that events took place as recorded.  A
   producer can write an event that is false.  Verification establishes
   at most that the signed entries were not changed by a party without
   the key.

   No hash covers title, description, or event_schemas.  The same holds
   for a member that this document does not define, unless it sits in a
   header, an event, or a head.  A reader cannot rely on those values.

Srivastava                Expires 14 April 2027                [Page 33]
Internet-Draft                  learnlog                    October 2026

10.2.  Removal of Recent Entries

   A holder can remove the latest entries of a record together with any
   signed head that covers them.  What remains verifies.  A verifier
   detects the removal only if it knows a later head from another
   source.  This document defines no way to exchange heads.

10.3.  Redaction and Truncation by a Holder

   Any holder can redact an event or truncate a record, and the result
   still verifies.  A verifier reports which entries are redacted and
   whether the record is truncated.  What the missing events said, and
   who removed them, stays unknown to the verifier.

   A reader that draws a conclusion from the absence of an event SHOULD
   treat each redacted or removed entry as a possible instance of that
   event.  A redacted entry inside an activity may have been a scaffold.
   A redacted or removed entry may have been a withdrawal of consent.

10.4.  Rewriting by the Producer

   The producer holds the signing key, so it can rewrite a record and
   sign a new head.  Detection requires that another party received a
   head before the rewrite.  A time stamping authority [RFC3161] can
   provide evidence that a head existed before a given time.  This
   document does not define how to use one.  The time of a head is a
   statement by the signer and proves nothing about when the head was
   signed.

10.5.  Trusted Keys

   A signature that verifies shows that the holder of a trusted key
   signed a head.  Any trusted key authenticates any record.  A verifier
   that trusts the keys of several producers needs to know which
   producer each key belongs to.  The result of verification names the
   key for that purpose.

10.6.  Where the Producer Runs

   A signature shows that the holder of a key signed a head.  When the
   producer runs on a device that the learner controls, the learner may
   control the key.  A verifier needs to know where signing took place
   before it treats a record as evidence about that learner.

Srivastava                Expires 14 April 2027                [Page 34]
Internet-Draft                  learnlog                    October 2026

10.7.  Guessing Redacted Events

   An event can have few possible values.  Without a salt, a party could
   hash each candidate and compare the result with event_hash.  The salt
   prevents this only if it is unpredictable and is deleted with the
   event.  A producer MUST NOT reuse a salt and MUST NOT derive one from
   the content of the event.

   The position and time of a redacted entry stay visible, as do the
   entries around it.  Together they can suggest what was removed.

   Members named content_hash and config_hash carry no salt.  A party
   can test a guess at a short or predictable text against such a hash.
   Redaction of the event removes these members with it.

10.8.  Meaning of Event Names

   A hash covers the name of an event.  No hash covers event_schemas,
   the list that ties a namespace to a schema URI.  For a registered
   namespace (Section 12.3), the name alone identifies the schema.  For
   any other namespace, a holder can replace the URI in the list, and
   with it the apparent meaning of the events.  A reader that depends on
   such events needs to know the schemas of the producer from another
   source.

10.9.  Hash Algorithms

   The integrity of a record rests on the collision resistance of the
   hash algorithm.  A checksum or any other function that is not a
   cryptographic hash MUST NOT be used.

   All hashes in a record use one algorithm, so a record cannot move to
   another.  A producer that needs a new algorithm starts a new record.

10.10.  Canonical Form

   Two parsers that read the same text differently can disagree about a
   hash, or agree about a hash while they hold different values.
   Sections 4, 6, and 8.2 of [RFC8259] describe three such cases: member
   names that are not unique, numbers beyond the range or precision of a
   double, and strings with unpaired surrogates.  The rules in
   Section 7.1 address these cases, and step 1 of Section 7.5 applies
   them before any hash is computed.

Srivastava                Expires 14 April 2027                [Page 35]
Internet-Draft                  learnlog                    October 2026

10.11.  Untrusted Input

   A log file can come from a source that is not trusted.
   Implementations need limits on file size, nesting depth, and string
   length.

11.  Privacy Considerations

   A record describes the behavior of a person in detail, and that
   person can be a child.  The considerations of [RFC6973] apply.  This
   section covers points that are specific to this format.

11.1.  Identifiers

   The subject member, and the id member of a party that is a person,
   MUST NOT hold a name, an email address, or an identifier taken from
   another system, such as a student number.

   A RECOMMENDED construction is HMAC [RFC2104] with SHA-256 over the
   internal identifier, under a secret key that the producer keeps, with
   at least 128 bits of the output retained.  A hash without a key is
   not sufficient, because identifiers can be guessed and hashed.

   The subject identifier is part of the header and stays fixed for the
   life of a record.  Every party that receives the record sees the same
   identifier and can link the record to other copies.

11.2.  People Other Than the Subject

   A record can describe instructors, peers, and guardians, and a dialog
   event can hold their words.  The data is then about them as well.
   Their identifiers follow Section 11.1.

11.3.  Data Minimization

   *  A producer SHOULD record an event only if the event has a use.

   *  A producer SHOULD use no more precision in time than its purpose
      needs.  Precision cannot be reduced later, because time is hashed.

   *  Text written by a learner SHOULD be left out unless it is needed.

11.4.  Limits of Redaction

   Redaction removes the content of an event.  The entry remains and
   shows that something happened at that time.  Copies of the content in
   other events, or outside the record, are not affected.

Srivastava                Expires 14 April 2027                [Page 36]
Internet-Draft                  learnlog                    October 2026

   The event_hash of a redacted entry remains as well.  A party that
   kept a copy of the event can still show that the event belonged to
   the record.  Truncation or deletion of the record removes that hash.

   Redaction may not be enough after consent is withdrawn.  Truncation
   or deletion of the record removes more.  Unless it is redacted or
   removed, the consent:withdrawn event remains in the record as the
   trace of the withdrawal.

11.5.  Correlation and Identification

   The actions and times in a record can be combined with other data
   about a person.  Sections 5.2.1 and 5.2.2 of [RFC6973] describe how
   such correlation can lead to identification.  A record SHOULD be
   treated as personal data whatever identifiers it carries.

11.6.  Signing Keys

   The kid of a signed head is the same in every record signed with one
   key.  A key that serves one learner or one device links the records
   of that learner, whatever their subject identifiers.  A key that
   serves a whole deployment does not.

11.7.  Storage and Transfer

   Records SHOULD be encrypted in transit and at rest.  Access to them
   SHOULD be controlled and logged.  A holder SHOULD set a retention
   period.

11.8.  Children

   A learner can be a child.  This document does not address compliance
   with any law.

12.  IANA Considerations

12.1.  URN Sub-namespace

   IANA is requested to register the following in the "IETF URN Sub-
   namespace for Registered Protocol Parameter Identifiers" registry
   [RFC3553]:

   Registry name:  learnlog
   Specification:  This document
   Repository:  https://www.iana.org/assignments/learnlog
   Index value:  The part of a URN that follows
      urn:ietf:params:learnlog:, which has the form file:<identifier> or
      events:<namespace>.  No transformation is needed.

Srivastava                Expires 14 April 2027                [Page 37]
Internet-Draft                  learnlog                    October 2026

12.2.  File Schema URIs

   IANA is requested to create the "learnlog File Schema URIs" registry
   at https://www.iana.org/assignments/learnlog.  The registration
   policy is Expert Review [RFC8126].  The expert checks that the URI
   has the form given in Section 3.3 and that a public specification
   defines the file schema.  An entry holds a file schema URI, a
   description, and a reference.  The initial entries are:

   File Schema URI:  urn:ietf:params:learnlog:file:contained
   Description:  A file that holds one or more records
   Reference:  Section 3.1

   File Schema URI:  urn:ietf:params:learnlog:file:sequential
   Description:  A file that holds one record and grows by appending
   Reference:  Section 3.2

12.3.  Event Schema URIs

   IANA is requested to create the "learnlog Event Schema URIs" registry
   at the same location.  The registration policy is Expert Review
   [RFC8126].  The expert checks the following:

   *  The URI has the form given in Section 5.4.

   *  A public specification defines the event types, with CDDL for the
      data of each.

   *  A schema for a new namespace uses a namespace identifier that is
      not yet registered.

   *  A schema that extends a registered namespace uses the URI of that
      namespace with a fragment identifier, and leaves the registered
      event types unchanged.

   An entry holds an event schema URI, a namespace, the event types, a
   description, and a reference.  The initial entries are:

   Event Schema URI:  urn:ietf:params:learnlog:events:consent
   Namespace:  consent
   Event Types:  granted, withdrawn
   Description:  Consent given or withdrawn
   Reference:  Section 6.1

   Event Schema URI:  urn:ietf:params:learnlog:events:assist
   Namespace:  assist
   Event Types:  help_requested, scaffold_provided
   Description:  Help requested and scaffolds provided

Srivastava                Expires 14 April 2027                [Page 38]
Internet-Draft                  learnlog                    October 2026

   Reference:  Section 6.2

   Event Schema URI:  urn:ietf:params:learnlog:events:dialog
   Namespace:  dialog
   Event Types:  message
   Description:  Turns in an exchange with another party
   Reference:  Section 6.3

12.4.  Media Types

   IANA is requested to register the following media types [RFC6838].

12.4.1.  application/learnlog+json

   Type name:  application
   Subtype name:  learnlog+json
   Required parameters:  N/A
   Optional parameters:  N/A
   Encoding considerations:  binary; see Section 8.1
   Security considerations:  See Section 10 and Section 11
   Interoperability considerations:  See Section 7.1
   Published specification:  This document
   Applications that use this media type:  Software that writes,
      verifies, or analyzes learnlog records
   Fragment identifier considerations:  As for application/json
      [RFC6839]
   Additional information:  Deprecated alias names for this type:  N/A
                            Magic number(s):  N/A
                            File extension(s):  .learnlog
                            Macintosh file type code(s):  N/A
   Person & email address to contact for further information:  See the
      Author's Address section
   Intended usage:  COMMON
   Restrictions on usage:  N/A
   Author:  See the Author's Address section
   Change controller:  IETF
   Provisional registration? (standards tree only):  No

12.4.2.  application/learnlog+json-seq

   Type name:  application
   Subtype name:  learnlog+json-seq
   Required parameters:  N/A
   Optional parameters:  N/A
   Encoding considerations:  binary; see Section 8.2
   Security considerations:  See Section 10 and Section 11
   Interoperability considerations:  See Section 7.1
   Published specification:  This document

Srivastava                Expires 14 April 2027                [Page 39]
Internet-Draft                  learnlog                    October 2026

   Applications that use this media type:  Software that writes,
      verifies, or analyzes learnlog records
   Fragment identifier considerations:  As for application/json-seq
      [RFC8091]
   Additional information:  Deprecated alias names for this type:  N/A
                            Magic number(s):  N/A
                            File extension(s):  .slearnlog
                            Macintosh file type code(s):  N/A
   Person & email address to contact for further information:  See the
      Author's Address section
   Intended usage:  COMMON
   Restrictions on usage:  N/A
   Author:  See the Author's Address section
   Change controller:  IETF
   Provisional registration? (standards tree only):  No

13.  References

13.1.  Normative References

   [FIPS180]  National Institute of Standards and Technology, "Secure
              Hash Standard (SHS)", FIPS PUB 180-4,
              DOI 10.6028/NIST.FIPS.180-4, August 2015,
              <https://doi.org/10.6028/NIST.FIPS.180-4>.

   [RFC2104]  Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-
              Hashing for Message Authentication", RFC 2104,
              DOI 10.17487/RFC2104, February 1997,
              <https://www.rfc-editor.org/info/rfc2104>.

   [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/info/rfc2119>.

   [RFC3339]  Klyne, G. and C. Newman, "Date and Time on the Internet:
              Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002,
              <https://www.rfc-editor.org/info/rfc3339>.

   [RFC3986]  Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
              Resource Identifier (URI): Generic Syntax", STD 66,
              RFC 3986, DOI 10.17487/RFC3986, January 2005,
              <https://www.rfc-editor.org/info/rfc3986>.

   [RFC4648]  Josefsson, S., "The Base16, Base32, and Base64 Data
              Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006,
              <https://www.rfc-editor.org/info/rfc4648>.

Srivastava                Expires 14 April 2027                [Page 40]
Internet-Draft                  learnlog                    October 2026

   [RFC6920]  Farrell, S., Kutscher, D., Dannewitz, C., Ohlman, B.,
              Keranen, A., and P. Hallam-Baker, "Naming Things with
              Hashes", RFC 6920, DOI 10.17487/RFC6920, April 2013,
              <https://www.rfc-editor.org/info/rfc6920>.

   [RFC7464]  Williams, N., "JavaScript Object Notation (JSON) Text
              Sequences", RFC 7464, DOI 10.17487/RFC7464, February 2015,
              <https://www.rfc-editor.org/info/rfc7464>.

   [RFC7493]  Bray, T., Ed., "The I-JSON Message Format", RFC 7493,
              DOI 10.17487/RFC7493, March 2015,
              <https://www.rfc-editor.org/info/rfc7493>.

   [RFC7515]  Jones, M., Bradley, J., and N. Sakimura, "JSON Web
              Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May
              2015, <https://www.rfc-editor.org/info/rfc7515>.

   [RFC7518]  Jones, M., "JSON Web Algorithms (JWA)", RFC 7518,
              DOI 10.17487/RFC7518, May 2015,
              <https://www.rfc-editor.org/info/rfc7518>.

   [RFC7638]  Jones, M. and N. Sakimura, "JSON Web Key (JWK)
              Thumbprint", RFC 7638, DOI 10.17487/RFC7638, September
              2015, <https://www.rfc-editor.org/info/rfc7638>.

   [RFC8126]  Cotton, M., Leiba, B., and T. Narten, "Guidelines for
              Writing an IANA Considerations Section in RFCs", BCP 26,
              RFC 8126, DOI 10.17487/RFC8126, June 2017,
              <https://www.rfc-editor.org/info/rfc8126>.

   [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/info/rfc8174>.

   [RFC8259]  Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
              Interchange Format", STD 90, RFC 8259,
              DOI 10.17487/RFC8259, December 2017,
              <https://www.rfc-editor.org/info/rfc8259>.

   [RFC8610]  Birkholz, H., Vigano, C., and C. Bormann, "Concise Data
              Definition Language (CDDL): A Notational Convention to
              Express Concise Binary Object Representation (CBOR) and
              JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610,
              June 2019, <https://www.rfc-editor.org/info/rfc8610>.

Srivastava                Expires 14 April 2027                [Page 41]
Internet-Draft                  learnlog                    October 2026

   [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/info/rfc8785>.

   [RFC9562]  Davis, K., Peabody, B., and P. Leach, "Universally Unique
              IDentifiers (UUIDs)", RFC 9562, DOI 10.17487/RFC9562, May
              2024, <https://www.rfc-editor.org/info/rfc9562>.

13.2.  Informative References

   [CALIPER]  1EdTech Consortium, "Caliper Analytics Specification,
              Version 1.2", 27 March 2020,
              <https://www.imsglobal.org/spec/caliper/v1p2>.

   [QLOG]     Marx, R., Ed., Niccolini, L., Ed., Seemann, M., Ed., and
              L. Pardue, Ed., "qlog: Structured Logging for Network
              Protocols", Work in Progress, Internet-Draft, draft-ietf-
              quic-qlog-main-schema-14, 6 July 2026,
              <https://datatracker.ietf.org/doc/html/draft-ietf-quic-
              qlog-main-schema-14>.

   [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/info/rfc3161>.

   [RFC3553]  Mealling, M., Masinter, L., Hardie, T., and G. Klyne, "An
              IETF URN Sub-namespace for Registered Protocol
              Parameters", BCP 73, RFC 3553, DOI 10.17487/RFC3553, June
              2003, <https://www.rfc-editor.org/info/rfc3553>.

   [RFC6838]  Freed, N., Klensin, J., and T. Hansen, "Media Type
              Specifications and Registration Procedures", BCP 13,
              RFC 6838, DOI 10.17487/RFC6838, January 2013,
              <https://www.rfc-editor.org/info/rfc6838>.

   [RFC6839]  Hansen, T. and A. Melnikov, "Additional Media Type
              Structured Syntax Suffixes", RFC 6839,
              DOI 10.17487/RFC6839, January 2013,
              <https://www.rfc-editor.org/info/rfc6839>.

   [RFC6973]  Cooper, A., Tschofenig, H., Aboba, B., Peterson, J.,
              Morris, J., Hansen, M., and R. Smith, "Privacy
              Considerations for Internet Protocols", RFC 6973,
              DOI 10.17487/RFC6973, July 2013,
              <https://www.rfc-editor.org/info/rfc6973>.

Srivastava                Expires 14 April 2027                [Page 42]
Internet-Draft                  learnlog                    October 2026

   [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/info/rfc7942>.

   [RFC8091]  Wilde, E., "A Media Type Structured Syntax Suffix for JSON
              Text Sequences", RFC 8091, DOI 10.17487/RFC8091, February
              2017, <https://www.rfc-editor.org/info/rfc8091>.

   [RFC8725]  Sheffer, Y., Hardt, D., and M. Jones, "JSON Web Token Best
              Current Practices", BCP 225, RFC 8725,
              DOI 10.17487/RFC8725, February 2020,
              <https://www.rfc-editor.org/info/rfc8725>.

   [RFC8792]  Watsen, K., Auerswald, E., Farrel, A., and Q. Wu,
              "Handling Long Lines in Content of Internet-Drafts and
              RFCs", RFC 8792, DOI 10.17487/RFC8792, June 2020,
              <https://www.rfc-editor.org/info/rfc8792>.

   [RFC9162]  Laurie, B., Messeri, E., and R. Stradling, "Certificate
              Transparency Version 2.0", RFC 9162, DOI 10.17487/RFC9162,
              December 2021, <https://www.rfc-editor.org/info/rfc9162>.

   [RFC9901]  Fett, D., Yasuda, K., and B. Campbell, "Selective
              Disclosure for JSON Web Tokens", RFC 9901,
              DOI 10.17487/RFC9901, November 2025,
              <https://www.rfc-editor.org/info/rfc9901>.

   [XAPI]     IEEE, "IEEE Standard for Learning Technology--JavaScript
              Object Notation (JSON) Data Model Format and
              Representational State Transfer (RESTful) Web Service for
              Learner Experience Data Tracking and Access", IEEE
              Std 9274.1.1-2023, October 2023.

Appendix A.  Example

   This appendix shows one record in full.  Every hash in it can be
   recomputed from the text of this document.

A.1.  An Example Event Schema

   The example uses a private event schema with the namespace sim and
   the URI https://example.org/102026/sim.  It defines two event types
   for a simulation.

Srivastava                Expires 14 April 2027                [Page 43]
Internet-Draft                  learnlog                    October 2026

   SimPredictionCommitted = {
       prediction: text,
       ? confidence: "guess" / "fairly_sure" / "certain",
       * $$sim-prediction-committed-extension
   }

   SimExplanationFiled = {
       explanation: text,
       * $$sim-explanation-filed-extension
   }

   $Event /= event-type<"sim:prediction_committed",
                        SimPredictionCommitted>
   $Event /= event-type<"sim:explanation_filed", SimExplanationFiled>

                   Figure 19: Event schema of the example

A.2.  A Complete File

   The file in Figure 20 holds one record with eight entries and one
   signed head.  Entry 4 is a hint from a tutoring system.  Entries 5
   and 6 are an exchange with an AI chat assistant.  Entry 7 is a spoken
   hint from a teacher, transcribed by software.

   The content_hash and config_hash values are hashes of the texts in
   Table 3.  Each text is one line, with single spaces between words and
   no line ending.

       +=======+==============+====================================+
       | Entry | Member       | Text                               |
       +=======+==============+====================================+
       | 4     | content_hash | Look for a number that divides     |
       |       |              | both 12 and 16.                    |
       +-------+--------------+------------------------------------+
       | 4     | config_hash  | example tutor configuration 7      |
       +-------+--------------+------------------------------------+
       | 6     | content_hash | Simplifying a ratio means dividing |
       |       |              | both parts by the same number.     |
       +-------+--------------+------------------------------------+
       | 6     | config_hash  | example chat configuration 3       |
       +-------+--------------+------------------------------------+

         Table 3: Texts behind the content and configuration hashes

   The explanation in entry 8 holds the character U+00BE, written in the
   figure as an escape.  In the canonical form, that character is the
   two octets C2 BE.

Srivastava                Expires 14 April 2027                [Page 44]
Internet-Draft                  learnlog                    October 2026

   =============== NOTE: '\' line wrapping per RFC 8792 ================

   {
     "file_schema": "urn:ietf:params:learnlog:file:contained",
     "serialization_format": "application/learnlog+json",
     "title": "Example record",
     "records": [
       {
         "header": {
           "record_id": "66a921d7-55be-4589-afcc-84ea4d2c26ef",
           "subject": "L-fdda6e0e3413590a303a3737d4176389",
           "hash_alg": "sha-256",
           "created": "2026-10-07T14:00:00Z",
           "producer": {"name": "example-sim", "version": "1.4.0"}
         },
         "event_schemas": [
           "urn:ietf:params:learnlog:events:consent",
           "urn:ietf:params:learnlog:events:assist",
           "urn:ietf:params:learnlog:events:dialog",
           "https://example.org/102026/sim"
         ],
         "entries": [
           {
             "seq": 1,
             "time": "2026-10-07T14:00:05Z",
             "event": {
               "name": "consent:granted",
               "salt": "SUe3daeuE7ZsSfKRHA9RkQ",
               "actor": {"role": "guardian", "kind": "human"},
               "data": {"scopes": ["instruction", "research"]}
             },
             "event_hash": "0e144a6edfb39ded22fab2dba4f60a69dc9fc72cdfe\
   7006ab78001e5ac11deef",
             "prev_hash": "dcfc869849b6088bb8cba0761987f4fa90a181335e20\
   a95b120bb0e8dfcd5556",
             "entry_hash": "ff3f6b48ed7a77379e68a08f6a0c2bfa71bdc757671\
   ceb88d905e5d307638433"
           },
           {
             "seq": 2,
             "time": "2026-10-07T14:01:10Z",
             "event": {
               "name": "sim:prediction_committed",
               "salt": "yqUo0sZAN2gYAhADsPJjKw",
               "session": "s-01",
               "activity": {
                 "id": "https://example.org/activities/ratio-mixing",
                 "version": "2.0",

Srivastava                Expires 14 April 2027                [Page 45]
Internet-Draft                  learnlog                    October 2026

                 "variant": "seed-8675309"
               },
               "data": {
                 "prediction": "3:4",
                 "confidence": "fairly_sure"
               }
             },
             "event_hash": "1b878146c3e51d20d0411979dc7fbac81da5fd08846\
   9a725b9afcf8395c2a518",
             "prev_hash": "ff3f6b48ed7a77379e68a08f6a0c2bfa71bdc757671c\
   eb88d905e5d307638433",
             "entry_hash": "ac64c6867336279286d1837e60312b56b106978d648\
   db62360f211306d65b6e5"
           },
           {
             "seq": 3,
             "time": "2026-10-07T14:01:42Z",
             "event": {
               "name": "assist:help_requested",
               "salt": "eKmBaP2uRROEiC4HVbWZfA",
               "to": {
                 "role": "instructor",
                 "kind": "software",
                 "id": "example-tutor"
               },
               "session": "s-01",
               "activity": {
                 "id": "https://example.org/activities/ratio-mixing",
                 "version": "2.0",
                 "variant": "seed-8675309"
               },
               "data": {"type": "hint"}
             },
             "event_hash": "5485100233e98c7bca12183cf9f9da23ee91f8bb029\
   d82e46ddab320661cc51b",
             "prev_hash": "ac64c6867336279286d1837e60312b56b106978d648d\
   b62360f211306d65b6e5",
             "entry_hash": "afa914e1952ca0d6878b901e32279a09f1462f252df\
   b3f289ea846c63b048e06"
           },
           {
             "seq": 4,
             "time": "2026-10-07T14:01:43.200Z",
             "event": {
               "name": "assist:scaffold_provided",
               "salt": "DgQiQwSuZLoHwnBLIox60g",
               "actor": {
                 "role": "instructor",

Srivastava                Expires 14 April 2027                [Page 46]
Internet-Draft                  learnlog                    October 2026

                 "kind": "software",
                 "id": "example-tutor"
               },
               "session": "s-01",
               "activity": {
                 "id": "https://example.org/activities/ratio-mixing",
                 "version": "2.0",
                 "variant": "seed-8675309"
               },
               "instrument": {
                 "source": "model",
                 "model": "example-tutor-2026-09",
                 "config_hash": "c9f3b7ca43165de9e1df7bc7ec6cff14e7498d\
   a4250a6df8e8f1885a9b4aeea8",
                 "parameters": {"temperature": 0.2}
               },
               "data": {
                 "type": "hint",
                 "request": 3,
                 "level": 1,
                 "reveals_answer": false,
                 "content_hash": "86c2216ed616d2d0097475056db432d1f9f76\
   e1ac5e712742157a3fe64ded70d"
               }
             },
             "event_hash": "b4bd1e82ee9019fb8ece8ab96192a64fdc953fc9ab2\
   7b2d046664ac8525cc789",
             "prev_hash": "afa914e1952ca0d6878b901e32279a09f1462f252dfb\
   3f289ea846c63b048e06",
             "entry_hash": "3b8fb5a69bc9701329888b081538f1cc243a2fadb14\
   8f6fc2f619de4f7671f61"
           },
           {
             "seq": 5,
             "time": "2026-10-07T14:02:30Z",
             "event": {
               "name": "dialog:message",
               "salt": "HySIGmOXiD_e0G3jppGMVg",
               "to": {
                 "role": "assistant",
                 "kind": "software",
                 "id": "example-chat"
               },
               "session": "s-01",
               "activity": {
                 "id": "https://example.org/activities/ratio-mixing",
                 "version": "2.0",
                 "variant": "seed-8675309"

Srivastava                Expires 14 April 2027                [Page 47]
Internet-Draft                  learnlog                    October 2026

               },
               "data": {
                 "modality": "text",
                 "content": "What does simplifying a ratio mean?"
               }
             },
             "event_hash": "a83a6d085d8ae61dfe3b3783ecaea3c51d52588d7a4\
   c2182245236b2b0b7d2dd",
             "prev_hash": "3b8fb5a69bc9701329888b081538f1cc243a2fadb148\
   f6fc2f619de4f7671f61",
             "entry_hash": "4cf6025ac1e0aa85ed8a9f1e3c678f544a73319d1e0\
   8eecb3fbe6ae695b65a2d"
           },
           {
             "seq": 6,
             "time": "2026-10-07T14:02:33.500Z",
             "event": {
               "name": "dialog:message",
               "salt": "wf_VFXE_2WNouptIJguFuQ",
               "actor": {
                 "role": "assistant",
                 "kind": "software",
                 "id": "example-chat"
               },
               "session": "s-01",
               "activity": {
                 "id": "https://example.org/activities/ratio-mixing",
                 "version": "2.0",
                 "variant": "seed-8675309"
               },
               "instrument": {
                 "source": "model",
                 "model": "example-chat-2026-08",
                 "config_hash": "fcfd5153bc5c0d1f52417f66ab078c749eb21f\
   4cebb5504cf274821a79a17aa5"
               },
               "data": {
                 "modality": "text",
                 "reply_to": 5,
                 "content_hash": "fb4ede48d160a985aeca77af68fcc7abdc3af\
   cdbff6781574146ecd02c2b45ed"
               }
             },
             "event_hash": "0d8d14d15cb3a606a857e86fc4fbe838a9ec11dfa3e\
   bdb73a5eef53bbb96d4c9",
             "prev_hash": "4cf6025ac1e0aa85ed8a9f1e3c678f544a73319d1e08\
   eecb3fbe6ae695b65a2d",
             "entry_hash": "43f068599a10f02217bc7287ca082d99818aa1fd92f\

Srivastava                Expires 14 April 2027                [Page 48]
Internet-Draft                  learnlog                    October 2026

   a3e12115cf1a7d5bfc23b"
           },
           {
             "seq": 7,
             "time": "2026-10-07T14:03:05Z",
             "event": {
               "name": "assist:scaffold_provided",
               "salt": "lMgpY68f-AMZ-mEMbfR3cg",
               "actor": {
                 "role": "instructor",
                 "kind": "human",
                 "id": "T-c1a8a3a416c9098d21b2baf451464304"
               },
               "session": "s-01",
               "activity": {
                 "id": "https://example.org/activities/ratio-mixing",
                 "version": "2.0",
                 "variant": "seed-8675309"
               },
               "instrument": {
                 "source": "model",
                 "model": "example-transcriber-1"
               },
               "data": {
                 "type": "hint",
                 "level": 2,
                 "reveals_answer": false,
                 "modality": "speech",
                 "content": "Try it with the smaller numbers first."
               }
             },
             "event_hash": "3e305baf5a3fad47f1e9c3d412d799fdd18926ff159\
   169a26034af74e6214f91",
             "prev_hash": "43f068599a10f02217bc7287ca082d99818aa1fd92fa\
   3e12115cf1a7d5bfc23b",
             "entry_hash": "4a0646f97bb877a347b7ba98eb6d1a7d9e0e3e0978e\
   d5706b0e07b7ef6ec4668"
           },
           {
             "seq": 8,
             "time": "2026-10-07T14:04:20Z",
             "event": {
               "name": "sim:explanation_filed",
               "salt": "y0_vEXCW8JNMCBA0MnLr2w",
               "session": "s-01",
               "activity": {
                 "id": "https://example.org/activities/ratio-mixing",
                 "version": "2.0",

Srivastava                Expires 14 April 2027                [Page 49]
Internet-Draft                  learnlog                    October 2026

                 "variant": "seed-8675309"
               },
               "data": {
                 "explanation": "12 out of 16 is \u00be. Both divide b\
   y 4."
               }
             },
             "event_hash": "3689aa3e1f8fdea9494f10a9607ffd84db805ad0475\
   f57077129a34cd8ebb5d0",
             "prev_hash": "4a0646f97bb877a347b7ba98eb6d1a7d9e0e3e0978ed\
   5706b0e07b7ef6ec4668",
             "entry_hash": "d2b47063f53bcce905ef687c5f7f1c3f008078d0a3e\
   ece78d2bc54bf8c1ca5b5"
           }
         ],
         "signed_heads": [
           {
             "head": {
               "record_hash": "dcfc869849b6088bb8cba0761987f4fa90a18133\
   5e20a95b120bb0e8dfcd5556",
               "seq": 8,
               "entry_hash": "d2b47063f53bcce905ef687c5f7f1c3f008078d0a\
   3eece78d2bc54bf8c1ca5b5",
               "time": "2026-10-07T14:04:21Z"
             },
             "signature": "eyJhbGciOiJFUzI1NiIsImtpZCI6IkNPSWFUYTctOFoz\
   VElOYmhBOFJjczZmcjAyWlRERzExMzM3MVQzR01aUlUifQ..9SbLqNvt-_gfXkz4sYqC\
   znBecvxy1YojXXOujGN2pdy5jJ7IZOOw37pxBsrdjr7K4p52Rqlo4va5MGFbP5vVWg"
           }
         ]
       }
     ]
   }

                    Figure 20: A complete contained file

A.3.  Intermediate Values

   The canonical form of the header is:

   =============== NOTE: '\' line wrapping per RFC 8792 ================

   {"created":"2026-10-07T14:00:00Z","hash_alg":"sha-256","producer":{"\
   name":"example-sim","version":"1.4.0"},"record_id":"66a921d7-55be-45\
   89-afcc-84ea4d2c26ef","subject":"L-fdda6e0e3413590a303a3737d4176389"}

   Its SHA-256 hash is the record hash, which is also the prev_hash of
   entry 1:

Srivastava                Expires 14 April 2027                [Page 50]
Internet-Draft                  learnlog                    October 2026

   dcfc869849b6088bb8cba0761987f4fa90a181335e20a95b120bb0e8dfcd5556

   The canonical form of the event in entry 2 is:

   =============== NOTE: '\' line wrapping per RFC 8792 ================

   {"activity":{"id":"https://example.org/activities/ratio-mixing","var\
   iant":"seed-8675309","version":"2.0"},"data":{"confidence":"fairly_s\
   ure","prediction":"3:4"},"name":"sim:prediction_committed","salt":"y\
   qUo0sZAN2gYAhADsPJjKw","session":"s-01"}

   Its hash is the event_hash of entry 2:

   1b878146c3e51d20d0411979dc7fbac81da5fd088469a725b9afcf8395c2a518

   The canonical form of the object that is hashed for entry 2 is:

   =============== NOTE: '\' line wrapping per RFC 8792 ================

   {"event_hash":"1b878146c3e51d20d0411979dc7fbac81da5fd088469a725b9afc\
   f8395c2a518","prev_hash":"ff3f6b48ed7a77379e68a08f6a0c2bfa71bdc75767\
   1ceb88d905e5d307638433","record_hash":"dcfc869849b6088bb8cba0761987f\
   4fa90a181335e20a95b120bb0e8dfcd5556","seq":2,"time":"2026-10-07T14:0\
   1:10Z"}

   Its hash is the entry_hash of entry 2:

   ac64c6867336279286d1837e60312b56b106978d648db62360f211306d65b6e5

A.4.  The Signed Head

   The head was signed with the private key that matches this public
   key:

   {
     "kty": "EC",
     "crv": "P-256",
     "x": "hLOF5epJKOENr_YLdw3iuvlSeuuUdVewL1BqcNtOKYw",
     "y": "PwQdWqmdT3_EOKIQvttI8kFeZLUePMifTFD5CpM-1WY"
   }

   The JWK Thumbprint of the key, used as kid, is:

   COIaTa7-8Z3TINbhA8Rcs6fr02ZTDG113371T3GMZRU

   The protected header is:

   {"alg":"ES256","kid":"COIaTa7-8Z3TINbhA8Rcs6fr02ZTDG113371T3GMZRU"}

Srivastava                Expires 14 April 2027                [Page 51]
Internet-Draft                  learnlog                    October 2026

   The JWS payload is the canonical form of the head:

   =============== NOTE: '\' line wrapping per RFC 8792 ================

   {"entry_hash":"d2b47063f53bcce905ef687c5f7f1c3f008078d0a3eece78d2bc5\
   4bf8c1ca5b5","record_hash":"dcfc869849b6088bb8cba0761987f4fa90a18133\
   5e20a95b120bb0e8dfcd5556","seq":8,"time":"2026-10-07T14:04:21Z"}

   The value of signature in the file is:

   =============== NOTE: '\' line wrapping per RFC 8792 ================

   eyJhbGciOiJFUzI1NiIsImtpZCI6IkNPSWFUYTctOFozVElOYmhBOFJjczZmcjAyWlRE\
   RzExMzM3MVQzR01aUlUifQ..9SbLqNvt-_gfXkz4sYqCznBecvxy1YojXXOujGN2pdy5\
   jJ7IZOOw37pxBsrdjr7K4p52Rqlo4va5MGFbP5vVWg

   The private key is not given here, so an implementation cannot
   reproduce this value.  The value can be verified with the public key
   above.

A.5.  Redaction and Truncation

   After entry 8 is redacted, it reads as shown below.  Every hash in
   the record and the signed head verify as before.

   =============== NOTE: '\' line wrapping per RFC 8792 ================

   {
     "seq": 8,
     "time": "2026-10-07T14:04:20Z",
     "redacted": true,
     "event_hash": "3689aa3e1f8fdea9494f10a9607ffd84db805ad0475f5707712\
   9a34cd8ebb5d0",
     "prev_hash": "4a0646f97bb877a347b7ba98eb6d1a7d9e0e3e0978ed5706b0e0\
   7b7ef6ec4668",
     "entry_hash": "d2b47063f53bcce905ef687c5f7f1c3f008078d0a3eece78d2b\
   c54bf8c1ca5b5"
   }

   If entries 1 to 5 are removed from the original record instead, the
   record gains the member shown below and its first remaining entry is
   entry 6.  The signed head still verifies.

Srivastava                Expires 14 April 2027                [Page 52]
Internet-Draft                  learnlog                    October 2026

   =============== NOTE: '\' line wrapping per RFC 8792 ================

   {
     "truncated": {
       "seq": 5,
       "entry_hash": "4cf6025ac1e0aa85ed8a9f1e3c678f544a73319d1e08eecb3\
   fbe6ae695b65a2d"
     }
   }

A.6.  Canonical Form Check

   The record above has few values that separate the canonical form of
   [RFC8785] from other compact JSON output with sorted member names.
   The JSON text in Figure 21 has more of them.  It holds numbers in
   several spellings, a control character, and two member names whose
   order by UTF-16 code unit differs from their order by code point.

   {
     "numbers": [1e21, 1.0, 0.000001, 1e-7, -0, 0.2, 4.50, 2E-3,
                 333333333.33333329],
     "string": "\u000f\u00be/\"\\\n",
     "\ud83d\ude00": 1,
     "\ufb33": 2,
     "a": null,
     "A": true
   }

           Figure 21: A JSON text for checking the canonical form

   In the canonical form, the member names appear in the order A, a,
   numbers, string, U+1F600, U+FB33.  The numbers appear as 1e+21, 1,
   0.000001, 1e-7, 0, 0.2, 4.5, 0.002, and 333333333.3333333.  The
   canonical form has 131 octets, shown here in hexadecimal:

   7b 22 41 22 3a 74 72 75 65 2c 22 61 22 3a 6e 75
   6c 6c 2c 22 6e 75 6d 62 65 72 73 22 3a 5b 31 65
   2b 32 31 2c 31 2c 30 2e 30 30 30 30 30 31 2c 31
   65 2d 37 2c 30 2c 30 2e 32 2c 34 2e 35 2c 30 2e
   30 30 32 2c 33 33 33 33 33 33 33 33 33 2e 33 33
   33 33 33 33 33 5d 2c 22 73 74 72 69 6e 67 22 3a
   22 5c 75 30 30 30 66 c2 be 2f 5c 22 5c 5c 5c 6e
   22 2c 22 f0 9f 98 80 22 3a 31 2c 22 ef ac b3 22
   3a 32 7d

   The SHA-256 hash of those octets is:

   afbc268398163c4f856a4d881d1eb85ba85b85e609c8473a11ebaf56cf28a0d1

Srivastava                Expires 14 April 2027                [Page 53]
Internet-Draft                  learnlog                    October 2026

Appendix B.  Implementation Status

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

   This section records the status of known implementations at the time
   of writing, as described in [RFC7942].

   The following description of qlm-measure version 0.7.0 is retained
   from revision -00.  It is an earlier implementation and does not
   establish conformance to this revision. qlm-measure version 0.7.0
   (Quantum Learning Machines; TypeScript and Python; Apache 2.0
   license; https://github.com/QuantumLearningMachines/qlm-measure)
   writes and verifies records that it labels schema 0.3.  This document
   was derived from that format.  Both chain entries by hash and allow
   an event to be redacted.  Both place consent events in the chain.
   The differences are:

   *  The recorder of qlm-measure serializes hashed values with sorted
      member names.  Its documentation lists [RFC8785] for schema 0.3 as
      planned.

   *  A record has no header.  The first entry links to an empty string.
      No hash covers the studentScopeId member, which names the learner
      of the record.

   *  Events carry no salt.

   *  A record can hold attestations that refer to an entry by version
      or by hash.  The verifier checks that reference and a payload
      hash.  No signature is verified.

   *  Member names differ.  For example, qlm-measure uses version and
      prevHash where this document uses seq and prev_hash.

   *  The kind of scaffold is a member of an observation event.  No
      event type exists for a request for help or for a scaffold.

   Quantum Learning Machines plans to extend qlm-measure so that it
   writes records in the format of this document.

   A local Learnlog AI Use Profile v0.1.0 prototype adds proposed
   context fields, condition-assessment sidecars, two entirely synthetic
   examples, and a Python reference checker.  It checks a subset
   consisting of contained, unsigned SHA-256 records without redaction
   or truncation and the example-profile constraints.  It does not
   verify signatures, establish full CDDL conformance, or implement
   runtime context-update and capture-completion events.  The examples
   contain no participant observations or learning-effect measurements.

Srivastava                Expires 14 April 2027                [Page 54]
Internet-Draft                  learnlog                    October 2026

   The prototype is not an independent implementation or an
   interoperability result.  No public publication location is specified
   in this revision.

Appendix C.  Changes in Revision -01

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

   *  Add prospective motivation for interpretable learning and
      assessment records when AI supplies assistance.

   *  Clarify that judgments about research applicability are outside
      the core format.

   *  Add non-normative companion-profile guidance for activity stage,
      scoped pedagogical permission, planned and asserted observation
      coverage, capture gaps, context changes, and review status.

   *  Add a hypothetical metacognitive prompt versus supplied-
      explanation example using the existing assist members.

   *  Clarify the distinction between recorder and producing-model
      provenance and the limits of configuration hashes and
      deterministic validation.

   *  Identify the need for explicit xAPI and Caliper mappings and
      describe the limited local synthetic profile prototype.

   *  Leave all existing CDDL, sourcecode examples, integrity rules,
      registries, and test vectors unchanged.

Appendix D.  Open Issues

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

   *  The name of the format is open.

   *  [RFC8785] is an Informational RFC from the Independent Submission
      stream.  A normative reference to it from a Standards Track
      document is a downward reference.  The alternative is to define
      the canonical form in this document.  [RFC2104] is Informational
      as well.

   *  JSON text sequences follow Section 11.2 of [QLOG].  JSON objects
      separated by line feeds are an alternative.

Srivastava                Expires 14 April 2027                [Page 55]
Internet-Draft                  learnlog                    October 2026

   *  Signed heads use JWS with ES256.  Open points are explicit typing
      of the JWS, a second algorithm, key discovery, and whether COSE
      would serve better.

   *  A defined way to lodge heads with a third party would address
      Section 10.2 and Section 10.4.

   *  A sequential file holds one record.  A server that writes for many
      learners may want to mix records in one file.

   *  Every event repeats its session and activity.  Section 7.5 of
      [QLOG] lets a trace state such values once, as common fields.  An
      equivalent here would have to fit the rule that each event is
      hashed by itself.

   *  The assist and dialog namespaces are small.  Feedback on a
      response and questions put to the learner are candidates for
      generic event types.  The values of ScaffoldType may belong in a
      registry.

   *  The roles instructor and assistant separate parties by teaching
      responsibility.  Deployments may need finer roles.

   *  The consent scopes are a starting point.

   *  A reader ignores members that this document does not define, and
      outside a header, an event, or a head no hash covers them.  A
      stricter rule may be safer.

   *  The content_hash and config_hash members carry no salt
      (Section 10.7).

   *  A producer cannot yet state in the chain which entries it
      redacted.  Such a statement would let a reader tell a redaction by
      the producer from one by a later holder (Section 10.3).

   *  No hash covers the list of event schemas (Section 10.8).  The
      header or an event could carry the list.

   *  A subject identifier cannot differ by recipient (Section 11.1).

   *  A record cannot change its hash algorithm.  A way to continue a
      record in a new one may be needed.

   *  Mappings between learnlog events and xAPI statements or Caliper
      events, including assistance semantics, provenance, and
      information loss.

Srivastava                Expires 14 April 2027                [Page 56]
Internet-Draft                  learnlog                    October 2026

   *  Independent review and implementation of companion-profile
      requirements for scoped assistance permission and observation
      coverage, including explicit context changes and completion
      claims.

   *  A companion format for estimates that refer to entries.

Author's Address

   Kumar Srivastava
   Quantum Learning Machines
   Email: kumar@quantumlearningmachines.com

Srivastava                Expires 14 April 2027                [Page 57]