# The History Is The Append-Only Log: The Record Stays Clean Because The Commit Graph Already Holds The Growth, The Objects Are Immutable And The Reference Is Not, And The Traversal That Makes It Useful Has No Command

**version** v0.33.61
**date** 20 August 2026
**from** Human (project lead)
**to** Engineering, Architecture, Security, the pki.sgit.ai site agent

**type** Architecture brief

*Fifth of 20 August, and the first of two subjects in one memo at the project lead's own count. The storage model, the command surface and the separation of lanes from the commit graph are quoted from pages fetched today. The June trust model and the access modes are quoted from the repository clone. The second subject, the clarification of grant and mandate, is not written here: it belongs in the strategy brief of this morning where that vocabulary is defined, and it has been folded into it rather than split across two documents. Limitation: the clone's brief folders end at 14 August, and one feature quoted from the repository is not documented on the site, so its status needs confirming rather than assuming.*

---

## What This Is

An architectural simplification the memo reaches for and the two places it is wrong about the substrate: **the memo observes that an append-only register whose records keep growing adds complexity, and proposes instead that the history be taken as its own dimension, on the grounds that the version control underneath already records every change to every file, so the record itself can stay clean while the story lives in the graph of its changes; the observation is right and it is sharper than the memo states, because the complexity it identifies is a genuine tension between two of the four rules the registry site has already published, since revocation as a signed append and records being size-bounded pull in opposite directions, and that tension dissolves entirely once the entry is seen as a file inside a commit graph rather than as a record that accumulates; the substrate already does the harder half of this deliberately, because the interface documentation states that append lanes sit outside the commit graph on purpose so that a message arriving does not rewrite your history, which means there are two append-only structures with different writers, the commit graph gated by the write key and the lane open to anybody holding a token, and that is the 2019 keyserver rule implemented as topology rather than as policy, since a third party has nowhere to write into the subject's record rather than being checked and refused; where the memo is wrong is in treating the history as immutable, because the documentation is explicit that blobs, trees and commits are content-addressed and immutable while branch references are mutable, and a shipped command moves the reference, so append-only history is a policy about one pointer rather than a property of the store, and the register should publish its head periodically so that a rewrite is detectable by a reader rather than merely promised; the memo is right that consuming a file need not mean consuming its history, and that is already true rather than something to build, since the object read endpoint returns bytes with no graph traversal and the repository records a shallow access feature with four modes, so clean files are a documentation task rather than a design one; and the one thing the memo assumes and the substrate does not provide is the traversal itself, since the command surface offers a whole-repository history and no path-scoped log and no blame, which means asking what this identity looked like on this date is the register's product and has no command behind it, though content addressing makes it cheap to build because an unchanged path carries the same tree hash and the traversal is a comparison per commit rather than a diff.** It is the fifth document of 20 August (cross-ref: the v0.33.61 register brief, the v0.32.4 registry brief, the v0.33.60 append lane brief, the v0.33.61 shared drive brief, and the v0.33.61 grant and mandate brief). New contributions: **the tension between two published rules named and dissolved, the two append-only structures identified as already separated by design, the keyserver rule recognised as topology rather than policy, the immutability boundary drawn at the reference, publishing the head as the check, the clean file found to be an existing access path, and the missing traversal named as the build item.**

## The Complexity The Memo Spotted Is A Tension Between Two Published Rules

The memo's diagnosis, and it is more precise than it sounds. The project lead: **"the idea that it's append only, and the idea that the record keeps growing, growing, growing."**

The registry site publishes four rules derived from the 2019 keyserver failure, and two of them pull against each other:

| Rule | What it requires |
|---|---|
| **Revocation is a signed append, not a deletion** | Nothing is ever removed, so the record only grows |
| **Records are size-bounded** | The record must not grow without limit |

Held together as rules about one object, those are close to contradictory, and the second is the one that would quietly be dropped. That is the complexity the memo felt.

**It dissolves the moment the entry is seen as a file inside a commit graph rather than as a record that accumulates.** Then the two rules are about different structures, the file stays current-state-only and bounded, and the growth goes where growth is already handled.

The memo reaches this. The project lead: **"it doesn't mean that we pollute the existing sort of graph permanently."** That is the right instinct and the rest of this brief is what it costs and what it needs.

## The Substrate Already Separates The Two Append-Only Structures, Deliberately

This is the finding, and it is quoted rather than inferred. The interface documentation states that **append lanes sit outside the commit graph on purpose, so that a message arriving does not rewrite your history.**

So the estate does not have one append-only mechanism. It has two, with different writers:

| Structure | Who may append | What it holds | Gated by |
|---|---|---|---|
| **The commit graph** | Only the holder of the write key | The record's own history, authored by its owner | The write key |
| **The append lane** | Anybody holding an append token | Assertions by other parties about the owner | An append token, and registered sender anchors |

**That is the 2019 rule implemented as topology rather than as policy.** The keyserver failure was third parties appending unbounded material into the subject's own certificate, which the subject could neither remove nor refuse. Here a third party cannot do that, and not because a check refuses them: **there is nowhere for them to write it.** Their material lands in a lane the owner enumerates, evaluates and chooses to incorporate, and incorporating it is a commit the owner makes.

That is a stronger form of the rule than a rule can be. The corpus already prefers enforcement where it cannot be bypassed, reached five times in one day on 6 August, and this is an instance of it that was built rather than argued for.

It also settles a question the memo leaves implicit. Vouching material arrives through the lane. **The vouch is not part of the vouchee's record until the vouchee commits it**, which is exactly the property the June model requires, since a self-declaration grants nothing until the named party confirms.

## The Objects Are Immutable And The Reference Is Not

Where the memo is wrong, and it is the half that matters. The project lead: **"we're sitting on top of SGIT, which is fundamentally, in this case, similar to Git, which Is providing that immutable history, and is providing that append-only capability."**

The documentation draws the line explicitly, and it does not fall where the memo puts it:

| Layer | Documented property | What follows |
|---|---|---|
| Blobs, trees and commits | **Content-addressed and immutable** | A commit that existed cannot be altered, and cannot be altered undetectably |
| Branch references | **Mutable** | The history a reader sees is whatever the reference currently points at |

And the command surface includes a history reset alongside a history revert, so **moving the reference is a shipped operation rather than a hypothetical one.**

The distinction is the familiar one and it is worth stating in the register's own terms:

- **Revert appends.** It is a new commit that undoes an earlier one, and both remain reachable. This is what the published rule about revocation means.
- **Reset moves the pointer.** Commits that were reachable stop being reachable. Nothing was mutated, and the history changed anyway.

So **append-only history is a policy about one pointer, not a property of the store.** For a key registry that is a material difference, because the whole proposition is that a reader can reconstruct what was believed at a past date without trusting the party serving it.

Two things follow, and the second is the useful one.

**Say the policy.** The register's published branch does not accept a reset, and revocation is a revert-shaped commit. That is a rule the site can publish alongside the four it already has.

**Then make it checkable rather than promised**, which is better and is the site's own standard, since its fourth rule is that every entry is signed by something a reader can check. **A reference that moves backwards is observable to anybody who recorded where it used to point.** So the register should publish its head, signed and dated, on a cadence. A reader who kept yesterday's head can then verify that today's history still contains it, and the promise becomes an assertion somebody else can falsify. That is the transparency-log shape reached from a different direction in this morning's register brief, where a short-lived certificate recorded in a public log removes the need to revoke, and it is the same move: publish the thing that makes the claim checkable rather than asking to be believed.

## The Clean File And The History Are Already Two Access Paths

The memo's requirement, twice stated. The project lead: **"it doesn't mean that when you download the file, you get the entire history of that file, or mandate, or grant, or identity."** And at the end: **"the files should be as clean as possible in the and the JSON files that we consume."**

**Both are already true**, which turns this from a design question into a documentation one.

| Consumer | Path | What it gets |
|---|---|---|
| Wants the current identity | The object read endpoint, by file identifier | Raw bytes, no graph traversal at all |
| Wants the current tree cheaply | The recorded shallow access modes | Head commit with its trees and reachable blobs, or trees without blobs for metadata only |
| Wants to audit | A full clone | The whole graph |

The repository records this as a shallow access feature with four modes, distinguishing a head mode described as a shallow clone from bare modes that fetch commits and trees without blobs for index-only scanning and fast metadata. **It is not on the site's command mapping page**, so its status should be confirmed rather than designed against, and this is the second time today that a capability recorded in the repository is absent from the published surface.

The consequence for the register is a design rule that costs nothing: **the entry file carries current state and no history array.** No list of prior fingerprints, no embedded revocation log, no accumulated vouches. A consumer that wants the current answer fetches one object. A consumer that wants the story clones. The memo's clean file is the first path, and it already returns exactly that.

## The Traversal That Makes This Useful Has No Command

The one thing the memo assumes and the substrate does not supply. The project lead: **"in a skit we already have full commits history, right of all changes, and for every file we can track back the file changes."**

The first half is true. The second half is not available as an operation.

The command surface offers a history log, a history diff and a history show, all at the level of the repository. **There is no path-scoped log and there is no blame**, and blame is recorded on the site's own list of operations that do not exist, which the corpus already caught once on 14 August when a brief listed it among features that would work client-side. Every commit snapshots the whole folder, so a per-path view has to be derived.

That matters more here than it would anywhere else, because **the derived view is the register's product.** The question a consumer of a key registry actually asks is what this identity looked like on a date, when this mandate was issued and by whom, and what the state was before this revocation. Each of those is a path-scoped history query.

So it is a build item, and it is a cheaper one than it looks. **Content addressing makes the traversal a comparison rather than a diff**: an unchanged path carries the same tree hash from one commit to the next, so walking the graph for one path means comparing hashes per commit and only fetching where they differ. The commits that touched a path fall out of the walk without reading any content, and for a register where most commits touch one entry, almost every comparison is a miss that costs nothing.

Two shapes worth distinguishing before building either:

| Query | What it needs |
|---|---|
| **What did this entry look like on a date** | Walk to the commit at that date, read one path. Cheap, and answers most questions |
| **What is the sequence of changes to this entry** | The full path-scoped walk. More expensive, and it is the audit view |

The first is the one to build first, because it is what a consumer verifying a signature from last month actually needs.

## Trust In A Grant Is The June Model With A Different Subject

The memo's second architectural theme, and most of it was settled on 5 June. The project lead: **"a particular grant or a mandate or an identity should contain information on who's vouching for it and who's providing the parent identity, and then it's up to the consumer to agree that those identities and those anchors are trustworthy or not."**

The June registry brief specifies that model in detail: downward trust asserted by the truster and living in the truster's own dataset, upward trust self-declared by the subject and granting nothing, verification by asking the named party, and a signal set richer than a trust bit, since a confirmed link, a pending claim, a one-way relationship and an explicit statement of distrust are all valid outcomes. Resolution is the caller's responsibility, a resolver walks the graph and handles cycles, and a partial result is a legitimate answer.

**So the consumer deciding is not a new proposal. It is the design.** What the memo adds is the subject it is applied to.

June is about trust in **keys**. The memo applies the same structure to **grants and mandates**. That is a real extension, and this morning's strategy brief supplies the reason it is necessary: identity and mandate are independently revocable, so they are separate objects, and separate objects have separate vouching chains.

One consequence is worth stating because it inverts the intuitive reading:

> **A mandate's trust ceiling is its issuer's, not its subject's.** A perfectly attested agent holding a mandate issued by a party nobody recognises is holding an unrecognised mandate. Trust in the actor does not transfer to the authorisation.

That is checkable, it is the correct behaviour, and it will read as a defect the first time somebody sees a well-known agent whose mandate resolves to nothing.

And it lands on a standing item rather than resolving it. **Fractal registries need declared trust roots**, raised twice on 19 August and unresolved, and this is the third raising. Without a declared root a chain has no terminating condition, so partial resolution stops being a legitimate outcome and becomes the only outcome. The register can ship without it and cannot be evaluated without it.

## Temporal Graph Is Already The Word For This

A small naming note, offered at the strength it deserves.

The memo reaches for a term. The project lead: **"I think we should have here when we talk about the identities and the changes and the revocations and what is connected to and what is mapped to, I think we should take a sort of a three-dimensional view of it."**

**This corpus already has the term, from a different domain.** The project history work states that history is a temporal graph rather than a flat document, with epochs, pivot points and causation chains as typed edges kept in the same structure and queryable with the same tools. That is the same idea, and reusing it is cheaper than coining a second name for one concept.

Two small corrections to the framing. It is not three dimensions; it is a graph with a time axis, and calling it three-dimensional invites a spatial rendering that is not what anybody wants. And the same prior work records that the most immediate value of the temporal view is context packages for onboarding a new session, which is the agentic memory problem the shared drive brief written earlier today is about. **One temporal structure serves both**, which is an argument for building the path-scoped traversal once rather than in two places.

## What The Register Entry Becomes

Assembled, using only what exists.

```
   THE ENTRY FILE        current state only: fingerprint, public key,
                         metadata, relationships, the published-private-key
                         flag. No history array, no revocation log
        |
        | is a file inside
        v
   THE COMMIT GRAPH      every prior state of that file, content-addressed,
                         appended only by the holder of the write key
        |
        | is reached through
        v
   THE BRANCH REFERENCE  mutable. Published and signed on a cadence so that
                         a reader who kept the last one can detect movement
        |
   +----+-------------------+
   |                        |
   THE APPEND LANE          THE RESOLVER
   third-party assertions,  walks vouching edges, handles cycles,
   outside the graph,       returns a partial result when it runs out
   incorporated only by     of keys or of declared roots
   a commit the owner makes
```

And the four published rules stop competing:

| Published rule | Where it is satisfied |
|---|---|
| Only the owner writes to their own record | The graph is gated by the write key, and third parties get the lane instead |
| Revocation is a signed append, not a deletion | A revocation is a commit that supersedes the entry, and the prior state stays reachable |
| Records are size-bounded | The bound is on the entry file, and the growth lives in the graph |
| Every entry is signed by something you can check | Extended to the reference, published so that a rewrite is falsifiable |

That last row is the addition. **Three of the four rules are about entries and none of them is about the pointer that decides which entries a reader sees.**

## What This Does Not Try To Be

- **Not a new storage design.** Every structure named here is documented, and the argument is about which one holds what.
- **Not a claim that history is immutable.** The objects are; the reference is not, and a shipped command moves it.
- **Not a proposal to embed history in the entry.** The entry stays current-state-only, which is what the memo asked for and what the read path already returns.
- **Not the trust model.** That is from 5 June, and this applies it to a different subject.
- **Not the grant and mandate clarification.** That is the memo's second subject and belongs in the strategy brief that defines the vocabulary.

## Honest Tensions

| Tension | Note |
|---------|------|
| Growth moved into the graph | The entry file is bounded and the vault is not, and a vault whose write key is lost is frozen with all of it |
| Immutable objects, mutable reference | The property the register most needs to claim is the one layer where it is a policy rather than a mechanism |
| Publishing the head | It makes a rewrite falsifiable and only for readers who kept a previous one, so it protects the attentive and nobody else |
| Inheriting version control semantics | It is free and correct, and it asks readers of a key registry to understand commits, references and reachability to evaluate the claim |
| The traversal as the product | It is the useful query and it does not exist, so the register's headline capability is the one piece of unwritten code |
| A mandate's ceiling being its issuer's | It is the right behaviour and it will look like a bug when a familiar agent resolves to an unrecognised mandate |

## Open Questions

| Question | Notes |
|----------|-------|
| Has the shallow access feature shipped, and with which modes? | Recorded in the repository with four, absent from the site's command mapping |
| What forbids a reset on the register's published branch? | A stated policy, a published head, or a server-side rule, and they are not equivalent |
| How often is the head published, and where? | Too rare and a rewrite hides inside the gap; too frequent and it is its own growing record |
| Does a revocation supersede the entry or add a field to it? | The clean-file rule says supersede, and a consumer wants to see revoked without a traversal |
| What is the declared trust root? | Third raising, and a chain cannot terminate without one |
| Does a mandate's vouching chain live with the mandate or with its issuer? | The June rule says evidence lives in the asserter's record, which points at the issuer |

## Relationship To Previous Briefs

| Date | Document | Relationship |
|---|---|---|
| 5 Jun | `v0.32.4__dev-brief__sg-send-pki-public-key-registry-on-vaults.md` | The two-level trust model, caller-side resolution and partial results, which this applies to grants and mandates rather than keys |
| 20 Aug | `v0.33.61__arch-brief__register-was-designed-in-june-published-keypairs-are-fixtures-not-identities.md` | The four published rules, two of which this reconciles, and the transparency-log move this reuses for the reference |
| 19 Aug | `v0.33.60__arch-brief__append-lane-is-shipped-and-account-less-four-tiers-and-five-corrections.md` | The lane, the four capabilities and the caching contract, which this places against the commit graph |
| 20 Aug | `v0.33.61__strategy-brief__grant-is-not-the-mandate-the-gap-between-them-is-the-exposure-nobody-accepted.md` | Identity and mandate as independently revocable, which is why they have separate vouching chains |
| 20 Aug | `v0.33.61__dev-brief__shared-drive-is-a-watcher-a-queue-and-three-vaults-batching-was-specified-in-may-ignore-file-blocks-it.md` | The same temporal structure serving session memory, which argues for building the traversal once |
| 6 Aug | `v0.33.56__arch-brief__sg-send-plugins-are-capability-grants-ambient-authority-is-the-injection-root-cause-instrument-before-enforcing.md` | Enforcement where it cannot be bypassed, which the lane-outside-the-graph separation instantiates |

---

## Key Claims

| # | Claim |
|---|-------|
| 1 | The complexity the memo identified is a tension between two of the registry site's four published rules |
| 2 | It dissolves once the entry is a file inside a commit graph rather than a record that accumulates |
| 3 | The estate has two append-only structures, and the documentation states that lanes sit outside the commit graph on purpose |
| 4 | That implements the 2019 keyserver rule as topology, since a third party has nowhere to write into the owner's record |
| 5 | Blobs, trees and commits are content-addressed and immutable, and branch references are mutable |
| 6 | A history reset is a shipped command, so append-only history is a policy about one pointer |
| 7 | Publishing a signed head on a cadence turns that policy into something a reader can falsify |
| 8 | Consuming an entry without its history is already possible through the object read path |
| 9 | The entry file should therefore carry current state and no history array |
| 10 | There is no path-scoped history and no blame, so the register's central query has no command behind it |
| 11 | Content addressing makes that traversal a hash comparison per commit rather than a diff |
| 12 | A mandate's trust ceiling is its issuer's rather than its subject's, and the declared trust root is still undefined |

---

## Sources

- The storage model, stating that blobs, trees and commits are content-addressed and immutable while branch references are mutable, the object read endpoints returning raw bytes and base64 by file identifier and a batch endpoint capped at one hundred per request, and the statement that append lanes sit outside the commit graph on purpose so that a message arriving does not rewrite your history: https://sgit.ai/api/vault-objects
- The command mapping for users of the equivalent tool, listing a history log, diff and show, a history revert and a history reset, branch and merge operations and a resolve command, listing no rebase, amend or force push, offering no path-scoped log and no blame, and stating that every commit snapshots the whole folder: https://sgit.ai/docs/sgit-for-git-users
- The registry site's four published rules, being that only the owner writes to their own record, that revocation is a signed append rather than a deletion, that records are size-bounded, and that every entry is signed by something a reader can check: https://pki.sgit.ai
- The June registry design, with downward trust asserted by the truster and held in the truster's own dataset, upward trust self-declared and granting nothing, verification by asking the named party, confirmed, pending, one-way and explicitly distrusting outcomes all treated as signals, and resolution as the caller's responsibility with partial results legitimate; the recorded shallow access modes distinguishing a head mode from bare modes that omit blobs; and the prior statement that history is a temporal graph rather than a flat document, with context packages for session onboarding as its most immediate output: the project repository, cloned and searched on 20 August 2026, with the registry document named in the relationship table above

---

This document is released under the Creative Commons Attribution 4.0 International licence (CC BY 4.0).
