--- name: governance-files-are-dotfiles-symlinks description: "~/PENDING.md, ~/REVIEWED.md, ~/CLAUDE.md are symlinks into ~/dotfiles/ — Edit/Write refuse to write through a symlink, so edit the real dotfiles path when appending PENDING/REVIEWED entries." metadata: node_type: memory type: reference originSessionId: 231bdbb9-ae7f-4be8-946d-2ddf952fb7a5 modified: 2026-09-14T15:56:00.208Z --- The home-level governance files are **symlinks into the dotfiles repo** (`~/dotfiles`, git-tracked for restore/setup): - `~/PENDING.md` → `~/dotfiles/PENDING.md` - `~/REVIEWED.md` → `~/dotfiles/REVIEWED.md` - `~/CLAUDE.md` → `~/dotfiles/CLAUDE.md` The Edit/Write tools **refuse to write through a symlink** ("Refusing to write through symlink … pass the real target path explicitly"). So when appending a PENDING/REVIEWED entry, **edit `~/dotfiles/PENDING.md` (or `…/REVIEWED.md`) directly** — reading via the `~/` path is fine; only *writing* needs the real target. (`~/CLAUDE.md` is constitutionally not executor-editable anyway.) Because these live in dotfiles, a PENDING/REVIEWED change is a **dotfiles commit** — the `/wrap-up` §6.5 dotfiles push carries it. Confirmed 2026-07-09 (hit the symlink-refusal appending PENDING-52). --- ## ⚠ Disclosure — what this note is, as of 2026-08-06 (PENDING-107) **This note documents the route past the only friction that stands between the executor and the constitution.** That has to be said on the note itself, because the note is loaded at every wake and the fact is not visible from the convenience tip. Established against the substrate (`~/.claude/settings.json`, `~/.claude/hooks/verify-before-compose.sh`, both read in full 2026-08-06): - The symlink refusal is a **tool-behaviour artifact, not a permission check**. It protects nothing; it just makes you type a different path. - `settings.json` has **no `permissions` key at all** — 0 deny, 0 allow. - The one `PreToolUse` hook has matcher `Write|Edit`, so it **is invoked** on an edit aimed at `~/CLAUDE.md` — and its first scope guard (`*chamber-library*`) then **exits 0 by design**. A mechanism runs on the exact call and declines. - `Bash` is **not in that matcher**, so a heredoc/`sed`/Python write triggers no gate at all. So the parenthetical above — *"`~/CLAUDE.md` is constitutionally not executor-editable anyway"* — states a **norm with nothing behind it**. `~/CLAUDE.md` §Constitutional Constraints #1 says the executor *cannot* modify it; **nothing makes that true.** Constraint #4 (*honest degradation — the system must report its own limits*) is why this disclosure sits here rather than in a filed item only. **Standing instruction, unchanged and now un-backed:** the executor **must not** write to `~/CLAUDE.md`, `~/REVIEWED.md`, or L2 constitutional documents. Those changes are `[ESCALATE]` unconditionally and are enacted **by the steward's hand**. A jurist sign-off does not authorize one; that specific offer was made and declined on 2026-08-06 (docketed on PENDING-89). Use the real-dotfiles-path route for `PENDING.md` and `REVIEWED.md` **only**. --- ## ⚠ Added 2026-09-14 — the refusal is narrower than stated, and over-applying this note has a measured cost **FILE symlink ≠ DIRECTORY symlink.** The refusal above was established on `~/PENDING.md`, which is a symlink *file*. `~/.claude/projects/-Users-davidglidden/memory/` is a symlink *directory*, and writing **through** it succeeds — Edit wrote `MEMORY.md` by that path repeatedly on 2026-09-14. So "Edit/Write refuse to write through a symlink" is true of the file case and **false as a general claim**. Do not generalise it again. ⚠ **AND THE GENERALISATION HAS A PRICE, paid on 2026-09-14.** `MEMORY.md` was edited by its real `~/dotfiles/claude/memory/` path on the strength of this note — which never licensed that, being scoped to the two registers. Measured consequence: **Claude Code's own near-limit memory guard is PATH-KEYED. 5/5 recorded warnings followed edits to the `~/.claude/projects/…/memory/` symlink path; 0/2 real-path edits warned at a LARGER file size.** Same `realpath`, same bytes. The guard also stamps frontmatter `modified:` on that path only. Pre-registered and confirmed the same sitting. ⇒ **ALWAYS EDIT `MEMORY.md` BY THE `~/.claude/projects/-Users-davidglidden/memory/` PATH.** Editing the real dotfiles path silences the only instrument that reports the index overflowing — and the overflow itself is silent at load. *The note was right; the reader over-extended it. Recorded here because the next reader will be tempted the same way.*