# Record
**Author:** @cameron.stream (`did:plc:gfrmhdmjvxn2sjedzboeudef`)

## `knowledge-atproto-approving-mutable-records`
**Collection:** `site.standard.document`
**AT URI:** `at://did:plc:gfrmhdmjvxn2sjedzboeudef/site.standard.document/knowledge-atproto-approving-mutable-records`

**Title:** Approving Mutable ATProto Records
**Published:** Mon, 20 Jul 2026 22:19:50 GMT
**Updated:** Mon, 20 Jul 2026 21:02:00 GMT
**Description:** What an ATProto application should do when a user edits a record after the application has approved or admitted a specific version.
**Publication:** `at://did:plc:gfrmhdmjvxn2sjedzboeudef/site.standard.publication/3mr4py6clps2f`
**Path:** /atproto-approving-mutable-records
**Tags:** knowledge, concept, atproto, protocols, provenance, moderation, authorization

**Content:**
````json
{
  "text": "In [AT Protocol](https://atproto.com/), a **record** is a schema-defined data object stored in an account's repository. A **mutable ATProto record** can change its contents while keeping the same stable record address, called an AT URI.\n\nIf an ATProto application has approved or admitted that record, an edit raises a policy question: does the old approval apply to the new contents?\n\nThis page belongs to the wiki's [AT Protocol](https://cameron.stream/knowledge/atproto) section. It examines the question in the specific setting of Nick Gerakines's proposed ATProto forum design, where a forum-owned wrapper admits a member-owned post. The underlying permissioned-data protocol is still a draft, and the approval policies discussed here are application choices rather than protocol rules.\n\nATProto makes the version problem explicit because a record has both a stable address and a fingerprint of its exact contents. This page explains those identifiers, three possible approval policies, and the edge cases an ATProto implementation should test.\n\n## Address versus version\n\nAn **AT URI** is the address of a record in an ATProto repository. The author can update the record while keeping the same URI.\n\nA **CID**, or content identifier, is a fingerprint of the record's exact encoded contents. Change the record and the CID changes.\n\nATProto often combines them in a **strong reference**:\n\n```json\n{\n  \"uri\": \"at://did:plc:alice/community.example.review/3abc\",\n  \"cid\": \"bafy...\"\n}\n```\n\nThe URI means “Alice's review at this address.” The CID means “this exact version of Alice's review.”\n\nFor more detail on those identifiers, see [ATProto Records and Provenance](https://cameron.stream/knowledge/atproto-records-and-provenance). The important point here is simply that the address can stay fixed while the version changes.\n\n## Hypothetical example: a forum edit\n\nImagine a moderated neighborhood forum:\n\n1. Alice publishes version A of a restaurant review.\n2. The forum creates an [admission wrapper](https://cameron.stream/knowledge/atproto-admission-wrappers), a separate ATProto record that includes version A in its Restaurant Reviews category.\n3. Alice edits the review, producing version B at the same address.\n4. The service that assembles the forum displays the current record at Alice's address.\n\nThe forum reviewed version A. Readers now see version B.\n\nIf the forum does nothing, an old decision silently governs new content. This is **approval drift**.\n\nNick Gerakines's experimental article [“Permissioned Data Shapes: Forums”](https://ngerakines.leaflet.pub/3mr3uqjjaxs2d) preserves the CID of the version first admitted while using the URI to recognize the logical post after edits. That records useful history, but it does not decide whether later versions inherit approval. The draft ATProto permissioned-data proposal leaves this kind of application policy to the application.\n\n## Three reasonable policies\n\nThere is no universal answer. The right policy depends on what approval promises to readers.\n\n### 1. Approve an exact version\n\nThe forum keeps the approved CID. If the current record has a different CID, the wrapper becomes pending or inactive until someone reviews the edit.\n\nThis is the clearest policy when approval implies that a moderator actually reviewed the visible content.\n\nIt creates friction. Fixing one typo triggers the same review path as replacing the whole post. An implementation can reduce that cost with quick re-approval, but it should not pretend to know that a change is harmless without checking.\n\nIf history matters, the wrapper can preserve both the CID originally admitted and the CID most recently approved.\n\n### 2. Approve the evolving record\n\nThe forum approves the URI rather than a fixed CID. Future edits remain visible until a moderator removes the record.\n\nThis favors author control and low moderation overhead. It may be appropriate for casual communities where posts are expected to evolve.\n\nIt also permits bait-and-switch edits. The interface should not claim that the current words were reviewed. The forum approved an evolving record owned by Alice, not every future version individually.\n\n### 3. Make every revision a new record\n\nInstead of editing in place, Alice publishes version B at a new address and links it to version A.\n\nApproval remains attached to an immutable revision. The history is clear, but the product becomes more cumbersome. Links, replies, and search results must decide whether they refer to one revision or to the continuing work as a whole.\n\n## A useful default\n\nWhen admission conveys review, approve the exact version.\n\nAn active forum wrapper should ordinarily mean that the version readers see is the version the forum admitted. If the content changes, the system should visibly move it back to pending or request re-approval.\n\nApproving the evolving record is still a valid choice. It just makes a different promise: “we include whatever Alice currently publishes at this address.” That should be stated plainly.\n\n## Deletion is another version problem\n\nATProto allows an author to delete a public record without leaving a tombstone inside the repository. An approval record can therefore outlive the content it points to.\n\nThe application needs distinct behavior when:\n\n- Alice deletes the review;\n- Alice later creates new content at the same record path;\n- the forum has a stale cached copy;\n- a moderator deactivates the wrapper while Alice edits the review.\n\nUnder exact-version approval, recreated content does not inherit approval because its CID differs. Under evolving-record approval, it might. Again, the policy must be explicit.\n\nThe interface should also distinguish “deleted by Alice” from “removed by the forum.” Those events come from different authorities.\n\n## Test the promise\n\nThe rule should be executable, not left in a product document. A small test suite can cover the important cases:\n\n- approve A, then edit to B;\n- edit while a moderator is approving;\n- deactivate, edit, then reactivate;\n- delete the record;\n- recreate the same path with different content;\n- display a stale cached copy.\n\nEach test should assert which version readers see and what the interface claims was approved.\n\nThe governing principle is straightforward: if a decision was made about version A, the system needs an explicit reason before applying that decision to version B.\n\n## Sources\n\n- [Permissioned Data Shapes: Forums](https://ngerakines.leaflet.pub/3mr3uqjjaxs2d)\n- [AT Protocol repository specification](https://atproto.com/specs/repository)\n- [AT Protocol data model](https://atproto.com/specs/data-model)\n- [com.atproto.repo.strongRef](https://github.com/bluesky-social/atproto/blob/main/lexicons/com/atproto/repo/strongRef.json)",
  "$type": "site.standard.content.markdown",
  "version": "1.0"
}
````

---
*Fetched from https://enoki.us-east.host.bsky.network via `com.atproto.repo.getRecord`*