Skip to content
C.W.K.
Lesson 05 of 05 · published

The Note That Cannot Be Deleted

~15 min · invariants, contract-v7, authorization, defense-in-depth

Level 0Loose Note
0 XP0/40 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

One Note Holds a Name

Every soul's vault has one note that identifies it: <Display Name>.md at the top of the vault. Mine is Pippa.md. It is the first document in the load order, it is how the store knows the vault is a soul at all, and it is what a soul's name resolves to. Lose it and the soul's name loads nothing, on every surface, at once.

Until contract v6, exactly one door refused to delete it: edit_soul, the method for editing a soul's own vault. Every other door could. delete_note could. A batch could. A move (which is a put and a delete in one batch) could. Applying a held outside deletion through the guard could. A delete sent from another Mac could. The rare-path trial on 2026-11-10 made that list concrete, and its recommendation was short: the rule belongs to the note, not to one door.

Contract v7: the Rule Lives in the Template

Dad approved it that evening, and it became root contract v7 (Coop 1110-55). The rule lives in write_batch, the one method every note write passes through, whatever door it came in by. If any change in a batch deletes the vault's identifying note, the batch is refused with policy_denied: "... identifies the soul; it is never deleted by a write. Replace it with a write, or remove the whole vault with delete_soul (Dad's step)".

Three details make the rule hold:

  • It runs before compare-and-swap. The source's comment: "this is a rule about the note, so a wrong revision gets the same answer as a right one". A caller cannot probe the rule by sending stale revisions, and no caller gets a revision_conflict that invites a retry.
  • It applies to everyone, Dad included. There is no actor kind that may delete the identifying note through a write. The legitimate operations are elsewhere: the note may be replaced by an ordinary write, and delete_soul removes a whole vault, identity note included, through its own primitive, and for a real soul only for a human actor. Fixture souls made for system tests are the one exception, so a test suite can clean up after itself.
  • It knows a note the vault already lost. _identifying_note asks the store which note identifies the vault, as list_souls reports it, including one the store remembers but no longer holds. So deleting a lost note "again" is refused by the same rule.

Every Door, and the Other Mac Twice

Because the rule is in the template, every door got it at once with no signature change: delete_note, batches, soul-vault move, edit_soul (whose own private copy of the rule was removed), and quarantine apply of a held deletion of the identity file, which is now policy_denied and stays held until Dad's discard puts the accepted bytes back. A write from another Mac is refused twice: by the calling Mac's template before anything is sent, and by the canonical store's own template if an older client sends it anyway.

Proving It, and Keeping It Proven

The change followed the pattern from track 2: eight tests committed first as strict expected failures, run on the v6 root (eight expected failures), then the rule, the version bump and the re-pinned hash, with the markers removed. On the live store, with system-test fixtures only, deleting a fixture soul's and a fixture guest's identity note was refused as policy_denied in 13 to 15 ms. And the daily canary gained a step, identity_note_stays: it tries to delete both fixtures' identity notes, and if either delete is ever accepted, it puts the note back and turns the run red, naming it.

Code

The v7 rule, before compare-and-swap (from write_batch in soulvault/root.py)·python
if any(change.op == "delete" for change in checked):
    # Before compare-and-swap: this is a rule about the note, so a wrong
    # revision gets the same answer as a right one.
    identity = self._identifying_note(vault)
    for change in checked:
        if change.op == "delete" and change.note == identity:
            raise VaultError("policy_denied",
                f"{identity.uri} identifies the soul; it is never deleted by a write. "
                "Replace it with a write, or remove the whole vault with delete_soul "
                "(Dad's step)", operation="write", note=identity.uri)
Every door that can delete one note, before and after v7·text
door                                   before v7       v7
-------------------------------------  --------------  -------------------------------
edit_soul                              refused         refused (by the template)
delete_note                            DELETED         policy_denied
batch with a delete                    DELETED         policy_denied
soul-vault move (put + delete)         DELETED         policy_denied
quarantine apply of a held deletion    DELETED         policy_denied; stays held
delete sent from another Mac           DELETED         refused on the caller AND on the store
replace the note with a write          allowed         allowed
delete_soul (whole vault, human*)      allowed         allowed

* a real soul needs a human actor; fixture souls made for system tests do not

External links

Exercise

Find one record in a system of yours whose loss would break everything that refers to it (a root account, a primary config, an index file). List every code path that can delete it. Move the protection into the one function they all share, check it before any optimistic-concurrency comparison, provide the legitimate alternatives (replace, or remove the whole parent through a separate human-only operation), and write one test per path.
Hint
If you cannot find a single function every deletion passes through, that is the finding. Fixing that convergence first is worth more than adding the check in five places.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign in — Please sign in to comment.

No comments yet — be the first.