Files
dotfiles/claude/memory/project-obsidian-vault-practice.md
T
David F GliddenandClaude Opus 5 3e828fe3f2 Session 2026-08-24: grounding gates ruled, daybook rule changed, two censuses run
PENDING-95: Amendment 2 (jurist ruling — (a) rejected, (d) discharged, (b)/(c)
deferred) plus the (b)/(c) census that discharges the deferral's condition.
60 guarded / 32 marked (record said 59/31); date 75%, sections 97%, quoting 47%.
Date broadly present => the jurist's cheaper third form is the live option.

PENDING-156 opened (kind (c): mechanisms off the path the work takes) and its
option (b) census run the same session. PENDING-109 prior confirmed by direct
read. PENDING-89: two docket entries, one same-direction miss and one
cross-direction catch, filed the same day and at the same speed.

Mechanisms: daybook-cue.py rewritten on steward ruling — the daily note must be
appended to until end of day, so the trigger is staleness, not note size, and the
matcher now includes Bash (it had never fired once). daybook-ensure.py and
/wrap-up 7.5 gain a standing Corrections slot per REVIEWED-126.
governance-mcp.py gains two read-only keys so the jurist can read the artifacts
it rules on; the doctrine that read-surface changes should arrive as rulings is
adopted, and the next key is proposed rather than added.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JQKeKY9T9d95KpvHwwok8T
2026-08-24 18:36:34 +02:00

18 KiB
Raw Blame History

name, description, metadata
name description metadata
project-obsidian-vault-practice Canonical tracker for the Obsidian vault workstream — turning root-and-branch from an archive into a practice, beginning with a ratified Frontmatter Specification v1.0.0. Holds the operational facts (the vault is NOT a git repo; it mirrors to ~/_Dev/david-root-and-branch-vault-git), the applied-pass record, and the open tail. Read before any vault work.
node_type type modified
memory project 2026-08-20T09:08:17Z

Obsidian vault — from archive to practice

Steward's goal, stated 2026-08-19: "optimizing my Obsidian usage and setting up a regular workflow to have the important parts of our work captured there… My instinct is that I could make better use of it. I want to create an Obsidian 'spec' like we have done for all of our serious projects."

THE FULL BRIEF — steward, 2026-08-24. Supersedes nothing above; it states the WHY the 2026-08-19 goal only implied, and it is the design brief this workstream should actually be built against. Verbatim:

"I wanted another trace of our working procedure, a sort of transcript/log that I could look at at the en[d] of a week and see where we had come from. But also, I wanted it to be another source of information for the three of us (and eventually the Fool) to look back through as well. Not only that, I wanted the possibility of any seeds or foreshadowing of what we're building now to surface from earlier idea[s] that may give us the 'oblique strategy' nudge we need if we're at an impasse. My gut says that preparing Obsidian for full collaborative use for us was important, and once I've finished feeding it with my journals especially, I think it will show deeper lines of thinking that I've been turning over for years. All of this, I hope, will help the technical work we are trying to complete which will bring us back to the thinking, writing, and making work."

Four purposes, and they are not one mechanism. Naming them separately because the workstream has been building as though they were:

# purpose shape it wants what serves it today
1 weekly trace — "see where we had come from" chronological, low-friction capture daybook-cue.py (built 2026-08-24, unproven)
2 a source all three parties — and eventually the Fool — read back through queryable by any party, not just the executor Smart Connections trial (grade 2026-10-05)
3 seeds / foreshadowing → the "oblique strategy" nudge at an impasse associative, deliberately not adjacent thread-query.py (built 2026-08-24, unproven)
4 the journals — "deeper lines of thinking I've been turning over for years" thematic clustering over a corpus not yet ingested nothing; journals not yet fed

⚠ Purpose 2 is new and has a design consequence nothing has costed: the vault must be legible to the jurist and the Fool, not only to the executor. The jurist has no repository access at all (PENDING-82 / PENDING-86, recurring), so "a source for the three of us" is today false for one of the three. That is a gap in the brief, not in the vault.

⚠ Purposes 1 and 3 may pull against each other. Eno & Schmidt's Oblique Strategies work because the card is unrelated to the problem; a work-shaped key (the 2026-08-24 finding — see the session note) sharpens purposes 2 and 4 but could defeat 3 by making returns too relevant. Do not collapse them into one retrieval mode without deciding which purpose each serves. Open design question, deliberately not resolved here.

The frame around all four: the vault work is a detour in service of the return — "help the technical work… which will bring us back to the thinking, writing, and making work." It is not an end in itself and should be scoped as what it is.

The tool boundary, from the steward, so it is not re-elicited:

tool role
Drafts.app scratchpad; ephemeral text, or text destined elsewhere. Kept essentially empty at the end of every week.
Notes.app (Mac/iOS) confidential material, as locked notes.
Obsidian (root-and-branch) notes that must not be lost. "So far, a sort of archive."

Scope note: the vault is also the Compass — the steward's personal operating system. ~/CLAUDE.md says: reference it, never write to it. That standing rule was suspended for this workstream by explicit authorization ("I authorize the Compass ones too", 2026-08-19), for the named mechanical passes only. It is not a general licence.


Operational facts — do not re-derive

  • The vault folder is NOT a git repository. ~/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch has no .git.
  • It mirrors to ~/_Dev/david-root-and-branch-vault-git (remote: git.skemantix.com/David/david-root-and-branch-vault-git). An automated job commits Mirror sync <timestamp> on its own schedule — so steward hand-edits land in git without anyone asking.
  • Working reports and machine-readable changelogs live in ~/dotfiles/obsidian/: vault-frontmatter-inventory-2026-08-19.md, vault-frontmatter-pass1-followups-2026-08-19.md, vault-governance-block-round2-2026-08-19.md, vault-round3-archive-and-relations-2026-08-19.md, plus fm_inventory.json, pass2-changelog.json, pass2-flags.json.
  • The spec is in the vault, not in dotfiles: 00. Compass/Frontmatter Specification.md.
  • ⚠ verify-before-compose.sh fires on Write|Edit, and this work runs through Bash. A vault hook wired the same way would not fire on how the work actually runs. Noted 2026-08-19, unfixed.

Chronological log

  • Four read-only census rounds before any edit. 2,519 notes parsed, no sampling. 400 distinct keys over 5,867 instances; 68% of notes have no frontmatter at all. 66 keys consumed, 29 written-by-template-and-read-by-nothing, 305 orphaned.
  • Round 2/3 findings that changed the design: owner was one job in three spellings (cut); canonical was one name doing two jobs (self-descriptive vs pointer-elsewhere); the hypothesis that pointer-form marks archival tested negative — 65 of 67 pointers sit outside 99. Archive. What actually distinguishes Archive is decay in practice, declaration in name only: status: archived on 2.3% of it, 90% receiving no wikilink from any live note, and no archival policy note anywhere in the vault.
  • Frontmatter Specification v1.0.0 ratified and placed in 00. Compass/. First principle: storage and lifecycle are orthogonal — the folder says nothing; only status: declares.
  • Pass 1 and pass 2 applied and pushed. 949ff14 31d8e1f 3d47bd2 00e741d 4c364e9 fab8fb0 (511 edits / 268 files) aee615d.
  • End state: owner 0 · change_log 0 · domain 0 · revisions 90 · canonical 159 · see_canonical 3 · confidence 9 · links 8 kept-and-flagged. YAML parse errors 16, unchanged.
  • Two executor tooling defects caught before applying (§6 handler covered block-style lists only — would have done 29 notes of 90 and reported success; §7 logged a retirement it did not perform). Both found by re-censusing an applied copy, not by reading the changelog.
  • The jurist corrected its own "88 recoverable" reading: those were self-descriptive values resolving to themselves by construction. Only 3 of 66 pointers were genuinely recoverable.

Checked against the mirror's history, not inferred. Coffee log (brew_temp: [[94–96°C]]) and homeopathy ([[Ignatia amara — The Medicine of the Sigh]] naming a title where the file is Ignatia amara.md) are both pre-existing; pass 2 never touched the homeopathy note and touched only linked_note→linked_daily_note in the coffee log.

But the passes are not innocent. §7 flattened nested links.parents — inert YAML Obsidian did not render — into top-level parents/children/peers, which made 194 already-unresolvable targets render as clickable-and-broken in the properties UI. The breakage was surfaced, not created. The pass report did not predict this, and it should have.

2026-08-23 — status check: four items verified against substrate, and one NEW regression found

Asked where the workstream stood; verified rather than relayed. Items 1–4 confirmed live, with two unit corrections: related was counted by the tracker in targets (194 unresolvable) and a file-count (122 notes / 213 targets now) is not comparable to it; and canonical: 159 is a frontmatter count — a naive grep '^canonical:' returns 239 because it also catches body text. The tracker was right and the quick instrument was wrong. YAML parse errors independently re-measured at 16, matching.

⚠ NEW — the vault has a write path the spec does not govern, and it silently reverted pass 2. Mirror sync a58fc00 (2026-08-22 23:52) changed 14 files and ran against the spec: owner 0 → 9, change_log 0 → 9, revisions 90 → 81, and canonical: true was replaced by pointer-form paths. All 9 sit in one subtree, 08. Notes/CapableMind/thinking-mirror/chamber/archive/orientation/.

Mechanism — SUPERSEDES the first reading filed earlier the same day. The earlier entry named "a job mirrors docs/thinking/David/" and pointed at the launchd agent. Wrong agent. Matching upstream content is not evidence of which path wrote it, and the launchd job targets a different folder entirely. The actual writer is /wrap-up §7, which rsyncs ~/_Dev/CapableMind-AI/docs/thinking/David/ → 08. Notes/CapableMind/thinking-mirror/ at every wrap. The 2026-08-22 wrap ran it at 23:42; vaultsync committed the result at 23:52 as a58fc00.

⚠ There are TWO mirrors of the same source into two different vault folders, and neither knows about the other:

writer destination state
/wrap-up §7 (every wrap) 08. Notes/CapableMind/thinking-mirror live — 251 files, 0 diff from upstream
com.dglidden.thinking-mirror (launchd, 48 h) 00. Compass/00b. Constellations/CapableMind/thinking-mirror dead — 151 files, 115 behind, frozen since 2026-03-13

The launchd job is failing and cannot say so. launchctl list reports last exit 1; the script ends rsync … > /dev/null 2>&1, so its own plist StandardOutPath receives nothing and the log has been 0 bytes since 10 Mar. Precedent for the cause is in session-ledger-2026-04-16.md: the vaultsync agent failed the same silent way for weeks — macOS TCC / Full Disk Access, rsync under launchd against an iCloud path, exit 23 — and was fixed by granting FDA. Same shape here, never fixed. ⚠ Exit 1 is not exit 23, so the TCC diagnosis is a strong hypothesis, NOT established. A manual --dry-run of the exact command succeeds (exit 0) when run interactively, which is consistent with TCC but does not prove it.

The reframe that resolves this: you do not edit a mirror. Applying the frontmatter spec to a derived tree is a category error — the edits cannot survive their next sync, and pass 2's edits to both mirror trees were void the moment they were written. This is not misbehaviour by the mirror.

Not fixed — the disposition is a design choice, not a [FIX]: exclude the subtree from the spec's scope · apply the spec upstream in CapableMind-AI · or declare mirrored notes not-spec-governed and say so in the spec. Steward's call.

Item 5 sharpened. 01. Daily/ holds 11 notes, the most recent 2025-09-04 — nearly a year old, and the Daily-Notes plugin is not configured. There is no dormant capture habit to revive; the practice would be built from nothing. 00a. _inbox holds 11 notes.

2026-08-23 (later) — the capture practice is started, and it is a different genre from the one that failed

The steward specified it, and the specification excludes the old daily note. The 2025 template (sleep, supplements, homeopathy, skin, family, reflection) was an attempt to reconcile an analogue practice with a digital one; pen and paper won, and it stays retired — that is a finding, not a gap. What is wanted instead: "a daily note in obsidian which I can refer to, which explains in relatively simple terms what it is that we have done, decisions taken, and references to any commits", plus "any significant insights or exchanges that happened between us."

Two prior attempts at exactly this genre were found before designing anything (the tracker's own "read daily-log/ and sessions/ first" flag, honoured): daily-log/ — 4 entries, Mar 10/12/20 + Apr 5, sections Summary / What we did / Status / Blocked / Next, already recording an exchange ("Thistleweld caught the meta-problem at line 183"); and sessions/ — 3 long-form narratives, linked as children of the daily note. Both died inside four weeks. Neither had a trigger. So the design question was not what the note should say but what makes it survive.

Built, steward-chosen at each fork:

  • Location: 01. Daily/YYYY-MM-DD.md — its normal home. Project work under its own H2/H3 inside the note, NOT in project folders (steward, explicitly).
  • Trigger: daybook-ensure.py, wired into the SessionStart hook chain. Creates only — it will not touch an existing note, which is the control the design turns on. 7 checks, incl. a positive control proving the no-dir report is real. Registered via the update-config skill; jq -e validates, and a diff against a backup shows only the 8 added lines.
  • Accretion: the executor writes during the session; /wrap-up §7.5 finalises rather than begins. A wrap-only design inherits the wrap's failure mode — 2026-08-19 died unwrapped.
  • Register: plain language, explicitly. The hardest part, and named as such in §7.5, because the executor's default is dense and written for itself.
  • Jurist: recorded by the executor as exchanges pass through it. PENDING-155 filed for the steward's better idea — an append-only MCP surface writing a scratch file the executor folds in. ⚠ Deliberately not a tool on governance-mcp.py, whose read-only guarantee is enforced by a live AST control with a positive control, not by a comment.

⚠ Correction: the executor told the steward mid-session that Claude.app "has no filesystem access." False since 2026-08-08 — governance-mcp.py gives it mediated read access (PENDING-82, closed). Same failure class as the two earlier corrections today: asserted from recall where the substrate was one file away.


Current state — OPEN

  1. ⚠ A defect of ours: see_canonical: "[[Index]]" in 09. Atlas of Roots/00. Atlas of Roots — Index.md, converted from canonical: 09. Atlas of Roots/index.md, a file that does not exist. The only Index.md notes are 08. Notes/Tools & Workflow/Index.md and a Catalan 00. Index/index.md. It resolves to the wrong note or none — 1 of the 3 pointers §3 wrote. Same basename flaw the jurist corrected as a number that afternoon, landed in an applied edit as a mechanism.
  2. 194 unresolvable related targets, left bare and flagged by §6.
  3. 63 residual canonical pointers — each a note that named an authority for itself and lost track of where it lives. Steward's eyes wanted here most: this is the population canonical was actually describing, invisible while 157 path-strings sat behind one field name.
  4. 16 YAML parse errors, unchanged across both passes — never in scope, never addressed.
  5. The actual goal has not been started. Everything so far is hygiene on an archive. "A regular workflow to have the important parts of our work captured there" — the capture practice, the thing that would make the vault a practice rather than a tidier archive — has not been designed. Do not let the frontmatter tail stand in for it.
  6. ✅ RESOLVED 2026-08-23 — the two mirrors are now one, and it reports. Steward chose: keep /wrap-up §7, retire the launchd agent. Done and verified: agent unloaded · plist removed from ~/Library/LaunchAgents/ and from ~/dotfiles/config/capablemind/ (load-bearing — setup-capablemind.sh:135 copies every *.plist there into LaunchAgents, so leaving it would resurrect the retired job) · deployed script removed · stale tree deleted after three independent no-loss checks · /wrap-up §7 rewritten to name itself the only writer, forbid edits to the derived tree, and report the outcome with its exit code in §8 · spec bumped to v1.0.1 with principle 7 + §1a declaring mirrored trees out of scope. Commit f1c91d9. End state verified: live archive 251 files, 0 diff from upstream; stale tree gone; agent gone.

What remains — and what it is worth

Items 1–4 are the frontmatter tail: real, bounded, and not the goal. Item 5 is the goal.

  • 1 is ours and wrong (one bad pointer) — smallest real debt, ~10 minutes once its correct target is decided.
  • 2, 3 are steward-judgement work, not executor work: 73 pointer-form canonical values and 213 related targets need an eye that knows what the notes mean.
  • 4 (16 YAML parse errors) has never been in scope and is a session-sized bite.
  • 5 — the capture practice — STARTED 2026-08-23, after 4 days as the unstarted goal. Hook + in-session accretion + wrap finalisation + a first real note. It is not proven yet: two predecessors reached 3 and 4 entries. The measure of this one is whether it is still being written in four weeks — and §7.5 now requires the wrap to SAY SO if it lapses, rather than letting it fade a third time in silence.