Skip to content

RFC-0003: Provenance typing — claimClass, assertedBy, mergedFrom (format 1.2) #14

Open

Description

@Krivoblotsky

Summary

Provenance today answers what justifies this (episodeID, evidenceEpisodeIDs, confidence, supersededBy, the audit log) but not how a memory came to be — asserted by a person, observed by the system, inferred by a model, merged from earlier records, imported through an adapter — nor who asserted it. Those are the cuts an accuracy or erasure review asks for first ("show me every inferred claim about this person"), and sources carry them (the Engram spec's claim_class / attribution; conversation roles) while our adapters keep them only as opaque vendor metadata.

Proposal (short form — full text in Spec/rfcs/0003-provenance-typing.md)

Three optional fields on episode, fact, edge, entity:

  • claimClass: asserted | observed | inferred | merged | imported (open enumeration; unknown values preserved).
  • assertedBy: one principal in RFC-0001's <type>:<id> syntax — user:…, agent:…, model:gpt-5@2026-06.
  • mergedFrom: ids of records consolidated into this one (with claimClass: merged); merged-away records are superseded, not deleted.
    Evidence Pack rows carry claimClass + assertedBy. Aligns with W3C PROV (wasAttributedTo, wasDerivedFrom) without carrying a graph.

Input wanted

  1. Five classes — right granularity? (Engram keeps documented vs asserted; this collapses them.)
  2. assertedBy singular vs list.
  3. Should episode carry claimClass at all, or is sourceType already that? (Proposed: both — channel vs epistemic status.)
  4. Model identifier convention: model:<name>@<version>?

Relationship: depends on RFC-0002 for lossless carriage on non-episode kinds; bundled into format 1.2.0 with RFC-0001 (#11). Comment period to 2026-10-05.

Activity

  1. added
    enhancementNew feature or request
    rfcRequest for Comments — a proposed change to the format/spec, open for discussion
    on Sep 14, 2026
  2. Krivoblotsky commented on Sep 14, 2026

    @Krivoblotsky
    ContributorAuthor

    RFC text: #12 (Python repo) · MacPaw/portable-memory-swift#13 (Swift repo — same bytes).

  3. wmdubberley commented on Sep 18, 2026

    @wmdubberley

    On input question 1 (five classes — right granularity?): the granularity looks right, but there is an axis the enumeration cannot express at any granularity.

    The five values type how a claim was obtained. They do not type when it was obtained relative to now, and for records consumed by systems reasoning about live state that distinction changes what the claim means.

    A case. A monitoring agent records "service X is running" with claimClass: observed. It was observed — the check ran and returned true. Five hours later a consumer reads that record. The class is still accurate, and the service has been down for three of those hours. A record written this second, also claimClass: observed, is indistinguishable from it.

    Both claims are correctly typed. They are not the same knowledge, and they should not drive the same decision.

    This cannot be fixed by adding a sixth class. Age is orthogonal to how a claim was obtained: an inferred claim can be hours old, an asserted one years old, and a sixth value would force a producer to choose between saying how it knew and saying when. That is two axes in one enumeration.

    Proposal: an optional asOf timestamp on the claim, recording when the evidence underlying it was obtained — distinct from the record's own write time, which may be much later for merged or imported claims.

    Deliberately not proposing a stale flag. Staleness is a judgement against a tolerance, and tolerances differ by claim: a process list is stale in seconds, an installed-package inventory in weeks. Encoding the judgement fixes a threshold the producer cannot know. The timestamp is the fact; staleness is the consumer's inference from it — which is itself a derived claim, and arguably wants its own claimClass when recorded.

    If age is considered out of scope for a format describing memory at rest, that is a reasonable line. The case for including it is that these records are read by systems acting on live state, and at that point a claim's age is load-bearing in a way its provenance alone cannot express.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestrfcRequest for Comments — a proposed change to the format/spec, open for discussion

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions