agentm vault - alexherrero/agentm GitHub Wiki
Note
LAUNCHED โ 2026-09-23 with agentm v10.0.0, when the last of its plans shipped; approved as final 2026-09-07. It succeeds Filing v2, and each session's decisions are its Detailed Design subsection.
The filing system is built: every part Filing v2 named has shipped, the corpus has migrated, and the daemon and the dreaming binary run it nightly. What has not happened is you sitting down with the result and shaping it until it is yours. That means a layout that reads the way you think, a card that holds what you would want it to hold, and machinery you can explain in a sentence. This design is that shaping, one decision at a time, written down with the reason and the alternative beside each. It refines what shipped; it does not rebuild it.
Filing v2 landed between v9.9.0 and v9.20.0 and a survey on 2026-09-06 read the result the way you would, folder by folder in Obsidian. The bones held: six classes, the contract in standards/, the lifecycle axis, the write path, the calendar register, the Go dreaming binary. Around them sat what the build had not reached โ five empty desk/ folders kept alive by Drive's icon files, engine state still inside Agent/, a nested memory/memory/ written by the daemon's own probe, maps named workflow-2.md through workflow-7.md, a hand-kept Home.md eight weeks stale, and ten calendar reviews each saying nothing was recorded. The corpus told the larger story. Of 744 notes in the six classes, 251 are enriched tool tallies, 99 are truncated "User stated" fragments, 115 are one-line skill-discovery blurbs, 31 are mined opinion supplements, and 32 are ~dup twins. The memory a person would keep is on the order of 200 to 250 notes, and only two preference notes exist that are not a fragment. The queue was not behind: 283 of the 356 unfiled notes had already been enriched and scored below the floor, and nothing owned that verdict.
The reference layout is your work vault, a sibling deployment of the same lineage, photographed the same evening and transcribed into the research bundle. It is lowercase throughout, and its agent half holds desk, diagnostics and memory with nothing loose. Its memory classes are a few dozen notes each, named by subject; every project carries the same skeleton; a task flows from agent/desk/tasks/ into its project's drafts/ when it closes; its scorecards are daily; its card is ten readable fields. Home already matches on the bones. Where the two differ, this design says which way home goes and why. Some differences are drift to correct. Some are deliberate, because home is a few long projects with many tasks each, and a personal space work does not have.
The series runs seven sessions, each taking one question and ending with a written decision here. You decide anything about how the vault looks and reads, anything touching personal/ or projects/ content, every threshold that demotes or forgets, every deletion, and every change to what a surface shows you. The agent decides mechanism, ordering and naming inside the code, and says so in the log so you can reverse it. Design sessions run on the strong model; the builds that follow hand off to /work sessions on the cheaper one, one plan per landing group, deployed the same day, migrations under quiesce.
The vault becomes one lowercase tree that reads the same on both machines. agent/ holds archive/, diagnostics/ and memory/ and nothing loose. memory/ holds only the classes, each a few hundred notes at most once the residue is purged, each note named by its subject. A project opens on the same five root files everywhere โ project.yaml, a charter, a blueprint, a generated tracker and a map โ with its living documents in docs/, then decisions, designs and research, and its tasks live inside it, one directory per task with a plan, a progress log and a tracker. Two shared spaces sit beside the projects: resources/, the reference library, and systems/, the systems you run. standards/ is the four-file always-load surface, plus the templates a new project starts from. The calendar is facet files under a year map. One root note maps the vault; Ideas.md is generated over your idea cards.
A memory card is what you would write: a title, a type, a one-line summary, the reason it was kept, an importance you read, the filing state, the lifecycle, one confidence tier, the transport it arrived by and the trust that implies, two dates, tags and relations โ then a machine block the passes own. A card gets one deep pass, with analysis and research, and light passes afterwards, updated only when new input arrives. Your own spaces โ projects/ and personal/ โ are permanent: never demoted or archived by policy, ranked by importance rather than age, and enriched only in ways that leave the original content untouched. A card is written where the knowledge is: by the model in the room, the moment something durable settles, with the reason it was kept. What a writer cannot know it leaves empty, and an empty why is what marks a candidate for the nightly pass to judge.
No new component. The series changes the contract, the writers, the generators and the migrations that already run.
| component | role | what the series changes |
|---|---|---|
agentmd |
index, retrieval, MCP surface, capture, enrichment, the probe | field stamps, the card shape, ranking by importance in permanent spaces, the probe's root; the tool's four capture fields, one meaning for status, enrichment owed by stamp, the eager trigger removed, the tally gate; the batch reads the tier table, the two-shape prompt, usage printed (session 3); a hit is the card's readable head, the clock written for MCP and CLI hits, the ledger's surface: field, Claude Desktop as a client (session 6) |
agentmdream |
the nightly mutation pass, maps, rollups | map naming and pagination, empty-rollup skip, deep-once enrichment state; -every 24h, promote reads Captured and Candidates and writes semantic candidates, a report pass leaves the clock alone (session 3); the mocs job over the projects space and the weekly crystallize phase (session 4); the archive move and deletion inside the lifecycle job with a manifest first, the retain and reconcile jobs, the completed/ moves, the activity signal on project trackers and the dreaming facet (session 5) |
| session hooks | recall at start and prompt; the trace and the miner at stop | the trace's shape; the miner files HIGH only and hands the rest to the trace (session 2, decided); project: and task: stamped from the binding and the twenty-line opening brief (session 4); the loader strips the contract's block under a 40,000-token gate, standards/ leaves recall, traces are served on time questions only (session 6) |
| the pasted payload | claude.ai, the Gem, Antigravity | layout-free, pointing at index.md, standards/ and moc-projects.md; local copies derived from the template; the inbox as the one write path for a chat surface that can reach it โ claude.ai can, Gemini cannot (session 6, amended 2026-09-19 โ was the email door; narrowed 2026-09-20 by test) |
| the runner | scheduled jobs | the parked health scorecard, a daily corpus scorecard, the nightly enrichment batch; the night window, the morning note, the Python cycle shrunk (session 3) |
| the gate battery | deterministic verification | naming, card-shape and class-directory gates |
Everything still runs on your Mac under launchd, triggered at session boundaries and nightly, with no server and no cloud component.
The tree, with the reason and the alternative beside each move.
<vault>/
โโโ agent/ archive/ diagnostics/ memory/ nothing loose ยท archive/ mirrors memory/ (session 5)
โโโ calendar/ YYYY/ facet notes ยท moc-calendar-YYYY.md ยท rollups only for periods with entries
โโโ personal/ yours; your Title Case filing inside, untouched by this series ยท ideas/ holds the idea cards (session 7)
โโโ projects/ completed/<slug>/ ยท <slug>/ project.yaml charter.md blueprint.md tracker.md moc-<slug>.md, locked ยท docs/ decisions/ designs/ research/ drafts/ ยท tasks/NNN-<verb-slug>/ completed/ desk/ (2026-09-24) ยท completed/tasks/ (2026-09-27)
โโโ resources/ topics/<topic>/ ยท briefs/ ยท university/ ยท moc-resources.md โ the reference library; its topic cards rank as any note does, and its weekly briefs are dampened in recall (the whole space until 2026-09-25, the watchlist alone until 2026-10-03, the briefs from then)
โโโ systems/ homelab/ system.md components/ ยท agentm/ and crickets/ system.md, each a front door to its repo's wiki ยท moc-systems.md (2026-09-24)
โโโ standards/ storage-rules ยท user-preferences ยท security-and-secret-governance ยท moc-standards ยท voice/ ยท templates/ (2026-09-24)
โโโ index.md the one root map
โโโ Ideas.md generated over personal/ideas/, your preamble kept (session 7)
The root spaces are lowercase. agent, calendar, personal, projects, standards, and since 2026-09-24 resources and systems. Today four are Title Case and one is not, and the other tree you read every day is lowercase. Filing v2 ruled no top-level renames because renames churn; the churn is one landing group with the structural-move tooling that already exists, and a case-only rename on a case-insensitive disk goes through a temporary name. Why not Title Case everywhere: it would rename one folder instead of four, but every path in the loader, the contract and the daemon names standards, and it would keep the two vaults different for no reason you hold. Re-audit if Drive ever fails to follow a case-only rename; the two-step exists for that.
agent/ holds diagnostics/, memory/ and, since session 5, archive/, nothing loose, nothing hidden. desk/ goes: its five folders are empty, scratch left the vault and projects moved out, and a task now lives inside its project. _dream/, _meta/repos.json, .heat.json and .lifecycle.json leave for the engine directory, which already holds the same layer's insights, staging and journals; the how-to twin in _meta/ moves to standards/, where an operator-facing rule document belongs. Home.md retires (below). Why not keep desk/tasks/ for tasks without a project: none exists today, and this vault's own rule is that a directory is discovered, never conjured; the day one appears, desk/ returns with it. Re-audit when the first project-less task is filed.
memory/ holds only the classes. The pen, voice-kernel.md, moves to standards/, where the loader already reads; the two watchlists and the three loose settings files move to projects/agentm/, because they are that repo's feature state and not memory (the watchlist items moved on again to the reference library on the operator's ruling of 2026-09-24, below, and out of it on 2026-10-03 into the project's completed/ folder, when the first forward pass retired); the nested memory/memory/ is deleted once the probe writes at the memory root. Why not the engine directory for the watchlists: you edit those files in Obsidian, and the engine directory is not in the vault. Re-audit if a second feature grows working state that wants to live beside the classes โ the answer is the same, its project.
crystallized/ is flat and holds only lessons with consolidated_from. The six opinion lanes retire; they hold 31 mined fragments at status: proposed, and the class holds no lesson at all. Work's crystallized/ is ten syntheses, one per system or task cluster, and that is the shape sessions 3 and 4 decided: a lesson is written only by the weekly crystallize phase, with consolidated_from naming every source. Why not keep the lanes elsewhere: the accumulate loop that read them retired with the inbox triage engine, and a feature with no reader is a directory with no purpose. Re-audit if the opinion feature returns with a reader; its data then lives under the feature's project.
entities/ returns with its first writer, in one folder per type (amended 2026-09-29). The directory held only its index from 2026-08-19 until the nightly entity builder shipped (task 179). The builder writes one page per repo, repo-qualified issue, release and person, under entities/repos/, entities/issues/, entities/releases/ and entities/people/, and nothing else writes there (Dreaming, below). The folders go by type rather than flat, as Filing v2's D7 had it: a person and a repo can share a name, and a folder per type keeps their slugs apart. person is no longer held back for email ingest. People are found across the vault, and mail becomes one more source of evidence, behind a switch that ships off. Why not flat: two kinds of thing with one slug would need a suffix to tell them apart, which is a counter standing in for a name. Why not keep the empty directory as a promise: an empty shell is how the six-class layout failed once already. Re-audit when a fifth kind of entity wants a page.
episodic/ stays. Session traces are its writer now; ingested threads and mail join when ingest arrives. What a trace holds is decided in session 2 (Asked ยท Outcome ยท Captured ยท Recalled ยท Candidates); when the survey ran it was a first prompt and a list of what recall injected.
Maps are named for what they map, and Home.md retires. mocs/ holds moc-root.md, moc-memory.md and needs-review.md; a per-type page exists only past a member threshold, and a page that must paginate paginates inside itself, never into workflow-2.md. moc-root.md is the entry point, generated nightly; each area keeps its own moc-<area>.md beside its files, as diagnostics already does. As built, the threshold is the contract's moc_min_members of five. moc-memory.md links each type's page at or past it and lists a smaller type's members in full, moc_split_at sizes the sections a long page is divided into, and the class directory's own _index.md record stays beside the three maps. When a type falls below the threshold, the nightly pass removes the page it wrote for that type. The removal goes through its journal, which keeps the page's bytes. Why not a generated Home.md: the map already exists under its own name, and a second entry point is a second thing to keep true. Why not a hand-kept one: it has been wrong for eight weeks and was the first link on every map. Re-audit if the root map grows past a screen; split by area then.
calendar/ is facet files under a year map. YYYY/YYYY-MM-DD-<facet>.md, created only on a day with content for that facet, and moc-calendar-YYYY.md beside the year, generated. The bare-date day index Filing v2 drafted is dropped: work runs without one, and home has no entry to prove it by. As built, a year map lists the year's facet notes newest day first under a heading per month. A week or month review links each day's facet notes. Weekly and monthly rollups are written only for a period with something recorded in it. A facet note counts when it holds a timed entry or prose beyond the daily template, and a day of prose alone is listed without an entry count. The ten empty reviews go. The stray day note and template at the calendar root fold into the year or go, and session 4 made your Obsidian daily note the register's diary facet, so the two are one note. Re-audit if a facet ever needs a per-day summary that the year map cannot carry.
standards/ is four files and a voice library. storage-rules.md (the contract), user-preferences.md (the pen folded in, and the durable "how I want things done" โ few lines, written by you, loaded every session), security-and-secret-governance.md (the standing constraints, today scattered across a brief, a follow-ups file and a CLAUDE.md), moc-standards.md (generated), and voice/ holding the nine on-demand voice rules that sit in projects/_global/wiki-style/ today. A convention you confirm through the wiki plugin's capture joins the set as a further file: that plugin's always-load tier resolves to standards/, and the confirmation is yours. The set is decided here; session 6 capped the always-load tier at 40,000 tokens with the contract's block stripped from the injection. Why user-preferences.md matters beyond tidiness: 99 of the 101 preference notes in the corpus are truncated fragments the miner cut from your sentences. The durable preferences are few, and a file you write beats a corpus mined from transcripts. Re-audit if the four files pass a quarter of that ceiling. Since 2026-09-24, standards/templates/ holds the blank front page every project starts from โ project.yaml, charter.md, blueprint.md and tracker.md โ with the task and daily templates beside them as they are written. A template is placeholder text, so no ranked arm indexes the folder: a search that matched a template's filler would serve words nobody wrote. The daily template itself stays at calendar/_daily-template.md, where Obsidian's daily-notes setting reads it. Why a folder in standards/ rather than one per project: the front page is the same for every project, and one copy is one thing to keep true.
Two shared spaces hold what is neither memory nor a project (2026-09-24). resources/ is the reference library: topics/<topic>/ holds the reference cards that sat under projects/agentm/research/<topic>/reference/, briefs/ holds the weekly field brief (one kind: brief note a week, at most ten links), and university/ holds study guides, opening with an index note that says what goes there. Only briefs/ is dampened: an unreviewed digest of external links ranks low unless the question names it, and the topic cards rank as any note does, because a dampened space is dampened whatever the question, and a card is exactly what a question about its topic wants (your ruling of 2026-09-25). systems/ describes the systems you run. homelab/ holds them in full: a system.md overview beside components/, built from the six homelab notes that sat in memory/semantic/. agentm/ and crickets/ each hold a one-page system.md that says what the system is and links to its repo wiki's Home and designs index rather than copying either. Both spaces are shared: the agent maintains them without a grant. Both are in the embed scope, and each keeps a generated moc-<space>.md. resources/university/ is the one directory this design creates before anything is filed into it. You asked for it by name: you plan to study at home the way you do at work. Why not keep the reference cards in their project: 233 cards about SQLite and llama.cpp competed with memories in everyday recall, and a project folder cannot be dampened without dampening the project. Why not put the homelab notes in a project: a system you run is not work with a start and an end, and systems/ is where a session asking how the NAS is backed up should land. Re-audit if a third kind of reference material wants its own space, or if a topic card ever outranks a memory on a question that was not about its topic โ then topic-aware dampening, not a blanket one, is the fix.
One root map. Filing.md folds into index.md; they carry the same write-authority table today. Ideas.md becomes a generated list over the idea cards, your preamble kept between markers (session 7). Why not no root notes, as at work: the map is for you, and the daemon enforces the table whether or not a note restates it.
A project's tree converges on work's skeleton. charter.md is the charter (session 4 renamed it from _index.md); decisions/, research/ and drafts/ are the same folders under the same names; moc-<slug>.md is generated; docs/ holds the project's living documents โ the followups, the roadmap, conventions, how-tos and runbooks โ since the root locked to five files on 2026-09-24 (The project skeleton, below). Work's plans/ is not created at home: a plan belongs to a task and lives in it (session 4, reversing this session's listing). A task lives at projects/<slug>/tasks/NNN-<verb-slug>/ with plan, progress, tracker and its artifacts flat beside them, and a generated projects/moc-tasks.md gives the cross-project view of everything in flight. Why nest tasks under the project rather than work's flat agent/desk/tasks/: home is a few long projects with many tasks each, and work's flat list has already grown project buckets inside itself within three weeks. _harness/ dissolves into the skeleton by a mapping table (session 4), paired with the crickets development-lifecycle repoint in three landings. Tasks are never archived: the sequence prefix orders them and the map collapses the done ones (session 5, reversing the archive step this session and session 4 named).
Naming. Directories and files are kebab-case with a subtype word where the directory does not carry it: protocol- and recipe- in procedural/; doc-, plan-, brief-, research- and decision- in a project; task directories verb-first with any external identifier last (fix-grad-issue-519271308, not b519271308-โฆ). A gate holds it, because work's rule without a gate drifted within weeks into two spellings of one task. Dates appear in a name only where the date is the identity: calendar, scorecards, session traces. An order prefix is not a date: a task directory carries a per-project three-digit sequence number (session 5). A project's documents do not โ session 5 gave them the same prefix and the operator reversed it on 2026-09-18, before the first run; the order they carried is going to live in sub-folders instead.
Housekeeping the survey found, the agent's to do. The probe writes at the memory root and the nested directory goes; the vault-root diagnostics/ was a wrong-root write and goes with its writer repointed; walkers and the empty-directory cleanup treat Drive's Icon files as absent; the runner's health-pass job, parked at the watchdog's stop rung since 2026-07-25, is revived and the corpus scorecard gets a daily job of its own; the empty reviews stop. Each is recorded in the follow-ups file so a build session can take it.
What a memory note holds, in the order Obsidian's properties panel shows it: what you read first, what the machinery reads last.
---
title: Keep git out of Google Drive's mirrored folders # the name; the filename is only the address
type: workflow # or kind: for a record; never both
summary: One line โ what this is and when it applies.
why: Why this was kept โ the reasoning at capture. # what was happening, and what this decides; only a writer that knows may write it
importance: 7 # 1โ10; you read it; enrichment proposes, your edit wins
status: active # active | unfiled
lifecycle: active # pinned | active | dormant | archived | superseded
filing_confidence: high # the one confidence tier you read
source: conversation # the transport; source_url / source_id beside it when present
trust: trusted # derived from source, stamped on every note
created: 2026-09-06
updated: 2026-09-06
tags: [git, google-drive] # never an empty list
related: [[drive-upload-staging-churns-transient-files]] # supersedes / superseded_by live here too
slug: keep-git-out-of-google-drive # machine-owned from here down
confidence: 0.91
enriched_by: enrich/1+prompt/a73ff0f4f5dc
enriched_at: 2026-09-06T14:00:00Z
rules_hash: 3c57fd89087c1a25
fingerprint: bd36f748โฆ
importance_proposed: 6 # what enrichment proposed; when importance differs, the value is yours
---The body is the memory in prose โ your words where they were yours, enrichment's where it wrote them โ followed by an optional ## Evidence block quoting the excerpt it came from. There is no metadata block in the body; the frontmatter already says it.
Field by field, against the corpus of 744 and against the work card (id ยท type ยท title ยท status ยท created ยท updated ยท importance ยท tags ยท related_notes ยท aliases):
| field | today | decision |
|---|---|---|
title |
on 48% | required on every memory; the miner and save.py write one at capture. A card no pass has judged yet may wait for the deep pass to write it; the card backfill took a title only from a body that opens with an H1 |
type / kind
|
93% / 7% | unchanged, one or the other, never both |
summary |
on 30%, enrichment only | required when the body exceeds a paragraph; written at capture, refined by enrichment |
why |
nowhere | new; what was happening when this was kept and what it decides later, one or two sentences. Written at capture by the model in the room or by you, never by enrichment; absent on a candidate (session 2) |
importance |
nowhere | new, 1 to 10, the same field you read at work; capture or enrichment proposes it into importance_proposed, and a value that differs from the proposal is yours and is never overwritten |
status |
100% |
unfiled means no judgment has been made, active means one has โ one meaning for every writer (session 2); proposed retires with the opinion lanes |
lifecycle |
97% | unchanged; stamped where it is missing, with lifecycle_since beside it |
filing_confidence |
14% | the one confidence tier you read, on every note โ backfilled high where an enrichment scored at or above the contract's floor, low below, and medium (the filing engine's own tier for a filing that stated none) where nothing was ever scored |
confidence |
43% | enrichment's numeric reading, machine block |
mining_confidence, mining_rationale, mining_occurrences
|
15% | retire with the miner's shape (session 2) |
source, source_url, source_id
|
95%, 17%, 2% | unchanged; a capture whose source_id or source_url and title an active card already carries updates that card in place (amended 2026-09-28) |
trust |
20% | stamped everywhere; it is a table lookup from source, so the backfill is deterministic |
created, captured
|
30%, 26% | one field, created; captured folds in at the earlier of the two days. A note with neither takes the earliest of captured, its first vault commit and enriched_at, because the ingest sweep had moved captured to a later write on some unfiled cards |
updated |
85% | unchanged |
tags |
84%, 91 empty | an empty list is omitted, not written |
slug |
57% | machine block; always equals the filename |
altitude |
52% | retire; lifecycle: pinned is what canonical meant |
group |
16% | retire from the memory card; the path says it. A project-space entry keeps it, because the recall fallback's project filter reads it there |
always_load |
13%, all false | retire; the tier is a directory |
evaluator_classification, rubric_score
|
15% | move to the watchlist's own record; not a memory field |
fingerprint, occurrences, aliases, enriched_by, enriched_at, rules_hash
|
9% to 43% | machine block |
superseded_by, supersedes, lifecycle_since
|
โค 7% | unchanged; supersedes and superseded_by beside related, lifecycle_since beside lifecycle, where every writer already put it |
project, task
|
nowhere | new (session 4); the project slug and the task's verb-slug the card was captured under, stamped by every writer that knows its binding, taken as optional fields by memory_capture; readable fields, placed after related. A convention or preference carries no project unless its writer sets one (amended 2026-09-28) |
excerpt_edges_unverified, review_flags, derived_from
|
โค 6% | machine; derived_from gains promote as a writer (session 3); the card backfill found readers for review_flags (the needs-review map and the refile job), which stays, and none for excerpt_edges_unverified, which retired |
Slugs. The slug is the address and reads as one. ~dup, ~dup2, -1, -2 and workflow-bash-259 are counters standing in for a name; the collision rule produces a meaningful word, and a ~dup the copies job will collapse is never a file. As built, a writer grows a taken name by the next meaningful words of the note's own title and text, skipping numbers, words shorter than three characters and stopwords, and ends it in six characters of the note's hash only when no word frees it. The card backfill renamed each counter to its title, or grew a title-less one from its text, and rewrote the links to it in the navigation spaces, Agent/ and Calendar/, repointing a path only where it names the renamed note under memory/<class>/ in the note's own class. A record under Projects/ or Personal/ keeps the names it was written with, since the paths in it record what was measured under them at the time, and so does any other path that ends in the same file name, such as a card's derived_from naming the inbox capture it was mined from. Why the card is heavier than work's ten fields: home carries a lifecycle axis, a transport vocabulary and a trust tier that work does not, and each has a reader in the daemon. Everything a reader does not have is in the machine block or retired. Re-audit if a field in the operator-read block goes a month without you or a surface reading it.
Records (kind: notes โ traces, scorecards, maps, reviews) keep the same order for the fields they share and add their own; a record never carries importance, why, filing_confidence or trust.
Who holds the shape. Each side keeps one definition of the order: card_shape.py in the toolkit and internal/cardshape in the daemon, with a test that fails when the two part. Every writer of a class card applies it, and check-card-shape, check-class-directories and check-no-empty-tags hold the corpus to it. A class directory is flat, so the card backfill removed the six opinion-lane directories the purge had emptied. What the backfill stamped, rather than a writer that knew, is named in the machine block's backfilled: list. It never writes enriched_by or enriched_at, because those two stamps say which pass a note is owed, and they rebuild the enrichment ledger when its file is lost. A re-judgment that reaches the same answer leaves the note as it is, so enriched_at and rules_hash name the judgment that last changed the note, and the ledger holds the latest one.
What holds for a memory the moment it lands, and who may write which field. Measured on 2026-09-06 against the live writers: enrichment had run once by hand on 2026-08-27; the daemon's eager trigger was never attached and never fired; the Stop hook's candidates landed status: active at low confidence, a state enrichment never reads; and 572 of the 769 notes in the classes were residue from the old miner. The queue the daemon was red about was not a pass falling behind. It was a pass nobody runs.
The in-session card is the primary capture. When something durable settles in a session โ you say how you want a thing done, a decision is made, a fix is found, or a fact is learned that a later session will need โ the agent writes the card immediately through memory_capture. It fills the fields you read: title, type, summary, why, importance, tags, and related. It lands status: active, filing_confidence: high, because a writer that could say why already judged it. The cost is a few hundred output tokens per card on the model already holding the context. This replaces a cold model reconstructing the same card from a 200-character excerpt. Why not a model call in the Stop hook: it reconstructs too, only sooner, inside a 30-second hook budget against a transcript that can reach a megabyte, and it pays on every session boundary whether or not anything durable happened. It stays named as the fallback. Re-audit: a month in which sessions write fewer than one card a day while the traces show decisions being made.
why is the reasoning, and only a writer that knows may write it. One or two sentences: what was happening when this was kept, and what it decides later. You or the model in the room write it at capture; enrichment never writes, rewrites, or removes it. A card without why is a candidate โ nothing has judged it worth keeping yet โ and it lands status: unfiled. The firing miner rule is not a why; it goes to the trace. Why not let enrichment write one: a reason guessed from the note reads exactly like a real one, and the field is only worth having if it is always yours or the room's.
status means one thing. unfiled means no judgment has been made; active means someone or something judged this worth keeping. The Go writer already meant the first. The Python lane meant the second and wrote active at low confidence, which enrichment's gate never reads. Every writer now agrees: a knowing writer's card lands active; anything else lands unfiled; enrichment's floor moves a note up or leaves it. filing_confidence stays the tier you read. No ranker reads it, and no document may imply one does.
The Stop hook keeps the trace and stops writing fragments. The session trace is the handoff record, written with no model call. Its title is the first prompt; project and surface are stamped; touched: (renamed from entities:, which held basenames) lists what was captured and recalled. The body contains ## Asked, ## Outcome โ the closing recap every session already ends with, which is free and the best summary the session produced โ followed by ## Captured, ## Recalled, and ## Candidates. ## Candidates holds every line the miner once filed as a note, kept as a line with the firing rule, excerpt, and count. The miner files a card only for a HIGH candidate: a durability cue typed by you, under the utterance ceiling, whatever the host says about who sent it. It files that card unfiled with why empty, so the nightly pass judges it. MEDIUM and LOW never become notes. The four rulings from the write path's labeled sample are built as written. The tally template becomes a gate at the write door, so a stale miner in a worktree cannot refill the purged population. Why not retire the miner: the candidates list costs nothing and is the record of what a session said in passing; the next session's model, or dreaming, can promote from it with context a nightly pass over a lone note never has. Why not keep MEDIUM as unfiled notes: enrichment scored 85 of the 283 fragments it read at 0.2 or below; a fragment does not become a memory by being rewritten.
The deep pass is owed once, and the stamp says whether it has happened. Eligibility moves from status to stamp. A card with no enriched_at is owed the deep pass whether active or unfiled. A card whose body changed since its stamp is owed a light pass. A card with neither is skipped at no cost; the fingerprint key (pass version, judgment hash, body) already carries this. What the deep pass does is session 3's. What it may not touch is decided here: why, the Evidence block, and an importance you set. The machine block records importance_proposed; when importance differs from it, the value is yours and no pass writes it again.
The "no" is a demotion. A note enrichment scores below the floor stays unfiled and is listed in needs-review. On a second verdict below the floor โ which happens only when the body, the prompt, or the contract changed โ the note moves to lifecycle: dormant, journaled and in the day's dreaming facet, as the contract already allows for demotion. It leaves the queue, stays on disk, and returns on a genuine recall; from there it runs the ordinary line session 5 set. Why not archive it at once: the verdict is about filing, not silence; the silence line archives it in time. Why not leave it unfiled: 283 notes unfiled forever is what the daemon was red about.
Enrichment runs as a nightly batch; the eager trigger retires. This is the agent's call and reversible. The eager trigger never fired and would spend a model call per capture as it lands. The batch does the same work in one place, under a budget, with a report. Session 3 sets the budget, the order, and the prompt, which drops altitude and gains importance_proposed. The first real batch runs after that, not before, so the corpus is judged once under the new prompt rather than twice. The daemon's queue-age alert stays red until then, and that is the honest reading.
The Go capture and the MCP tool. memory_capture gains summary, why, importance, and related, all optional, and its description says what why is. The surface stays two tools. A capture that names its type and gives a why lands active; one that does not lands unfiled. instructions moves into the Go door so the one front door carries the one security rule. The daily write cap stays. captured is written as created.
A memory is saved once (amended 2026-09-28). Each writer looks for the note it would repeat before it reserves a new file. A session keeps one trace: the trace writer finds it by its session: id, so a session whose title changes updates the same file, and only a session with no trace gets a new name. The same outside source updates its note: a capture carrying a source_id (a registry identity, <namespace>:<ref>, never a session id) or a source_url that an active card already carries under the same title merges its frontmatter into that card and replaces the body. The path, links and id stay, your importance and the card's created are kept, and git keeps the old wording. The title is part of "the same" because one source yields several memories: an article's atomic facts share its address, and each is its own card. An article is one note: ingest writes the document and its atomic facts, and the index cuts a long note into several chunk vectors that all point back to it, so dense search scores the document by its best chunk. A captured idea that matches a card in personal/ideas/ by slug, title or body is added to that card under a dated ## Added by capture heading with its source, and no semantic note is written. A reply you typed to the agent ("yes and then please file aโฆ", "let's do follow-up b", "ack on theโฆ", a numbered answer list "1. agree, 2. โฆ") directs the session, so the miner and the route pass drop it and log what they dropped; the bare word "follow-up" no longer marks an idea at all. A memory the miner filed and someone removed stays removed: the route pass keeps a ledger in the engine's state directory of what it has filed, keyed by slug and the body's first line, and does not file the same candidate again when a later pass reads the same conversation (amended 2026-10-03). Why update in place rather than keep both: the survey of 2026-09-24 found one article filed as about twenty-seven notes, six ideas carried twice, and eleven sessions split across two traces; the second copy is found by recall as often as the first and adds nothing. Why chunk inside the index: a chunk file existed so the vector arm could reach deep text past the embedder's safe window of about two thousand tokens, and the index can hold several vectors for one note without putting twenty files in the vault. Re-audit if an update in place ever replaces a body you edited by hand, because the merge would then need to keep your text beside the new one.
The purge, ruled 2026-09-06 by count. Six non-overlapping manifests live in the series' working directory under S2-manifests/: A tool tallies 292 ยท B "User stated" fragments 107, including the seven TempleCoordination rules because the 2026-09-05 session's own records carry that ground ยท C "Fix observed" fragments 21 ยท D skill-discovery blurbs 116 ยท E opinion supplements 32 ยท F ~dup twins 4. That totals 572 notes, leaving 172: 76 ideas, 47 conventions, 36 references, 5 workflows, 3 fixes, 2 preferences, 3 traces. Each manifest runs only when the day's fresh count matches the ruled count, and the tally gate lands in the same group.
What runs at night, in what order, what it may spend, and what you read in the morning. Measured on 2026-09-06 against the runner, the binary, the Python cycle and the engine state. No step spent a token, because enrichment is the only code that calls a model and enrichment has no scheduler. Every daily job fires at 13:07, because the runner's daily is twenty-four hours since the last run with no hour anywhere. A report-only diagnostic pass resets the binary's clock. The dreaming scorecard named a test fixture as last night's run. The promote job, had it fired, would have filled crystallized/ with eight targets counted off the traces' recall lists, one of them a test token. The details and the arithmetic are in the series' working file, S3-dreaming-proposal.md.
The night runs in one order, inside a window. Enrichment first, then the binary, then the Python cycle, then the scorecards and the morning note. Enrichment goes first because everything after it reads what it writes: type decides the refile, the body fingerprint decides the copy collapse, type and tags decide the maps. The runner gains a window: field on a manifest โ 02:00โ06:00 local for every step of the night, the morning note and the email that carries it included โ and a job that falls due outside its window waits for it. The hourly ingest sweep and the shepherds carry no window. Why not leave the cadence to drift: a batch registered as daily today would spend model calls at one in the afternoon, against the same allowance as your own sessions. Re-audit if a night's work ever runs past the window's end; the morning note's footer gives the time it was written.
What the night measures, it embeds first (amended 2026-10-01). The night runs agentmd embed before the retrieval gate, so the gate grades a corpus with current vectors. Nothing scheduled the embed step before, and the gate skipped on stale vectors on four of the thirteen nights between 2026-09-19 and 2026-10-01. The eval's canary note is an instrument, not a memory: enrichment and dreaming leave it byte for byte, the way they treat the daemon's self-probe. Re-audit if the gate skips on stale vectors on a night the embed step ran.
The budget is a token line, per night, per tier. Two million tokens, on whichever tier the night runs on, with a call cap of 250 as a runaway guard. It began as a million on the strong tier or two million on the cheap one โ one night's money written at two prices โ and became a single number on 2026-09-11, so the allowance is a count of tokens and the tier decides only what they cost. Both are printed in the morning note from the batch's own usage, which it now reads from claude -p --output-format json; the runner's spend line reads the same field. The line counts what a call adds: its input, its cache writes and its output. The batch reads its spend before it starts a card and never mid-card, so the last card to start under the line finishes over it, by 0.8% on the two-million line and 1.5% on the one-million one as measured on 2026-09-11, and no reserve is held back for it (ruled 2026-09-11, as built). Each call also re-reads about 37,000 tokens of Claude Code's own baseline from the cache, the same prefix every time, and the line leaves that out. The run still reports every token it processed, and each reading prints both figures. Measured on the first supervised batch (2026-09-11), a card adds about 33,000 tokens and processes about 107,000, for about $0.39. The first batch under the new prompt was the whole remaining corpus. It ran by hand on 2026-09-11, in three invocations each taking one full line and resuming from the last one's cursor: 184 cards considered, 115 written, 46 refused by a post-gate, 5,569,418 tokens added, $62.80 in 44 minutes. Eighteen before-and-after pairs went to you first, and nothing was scheduled until you had read them. That is how the corpus is judged once under the new prompt rather than twice. A prompt change re-owes the deep pass to every note, as the pass version already encodes; at the corpus's size that is one supervised batch. Why a token line and not a call cap: a call cap bounds the wrong thing, since a card's cost varies with the card, and the allowance you actually pay in is tokens. Why the line counts what a call adds: counting the cached prefix bounded a constant, and a night stopped after nine cards of 181. Raising the line to fit it would have kept a meter that said nothing about the night's work. Re-audit when the corpus passes a thousand notes, when a prompt change needs a rollout plan of its own, when the CLI's baseline or the prompt's size changes materially, or when a card's cost moves by more than half.
The night pays for a judgment only when something the judgment reads has changed (amended 2026-10-01). A note is owed a judgment when it has never had one, when its body has changed since its last one, when its stamp names an older pass, or when the part of the filing contract that enrichment reads has changed. That part has its own hash, the judgment hash, taken over the type vocabulary (memory_types, default_type and deprecations), the only part of the contract the prompt and the answer's checks read. A ledger row keys each judgment to the pass version, the judgment hash and the note's body, so an edit to the dampened spaces, the walled areas or the thresholds re-judges nothing. The importance rubric stays outside both hashes, as session 3 ruled, and a changed confidence floor applies at each note's next judgment. The hash of the whole contract still decides whether the contract parses, and filing halts when it does not. The night takes the notes it owes by cause: never judged first, then changed, then owed the deep pass, then judged under an older judgment hash, least recently judged first. A contract change therefore reaches the corpus over a run of nights, instead of re-judging the same notes at the head of the queue every night. The ledger lives in a file of its own in the engine state directory, so it survives an index schema change. A row follows its note through a move, matched by body the way the index follows one, and the stamps in the notes rebuild the ledger only when its file is lost. A gate that skips a note never replaces the note's finished judgment. A re-judgment that reaches the same answer writes nothing to the note, and the ledger records the judgment against the file as it stays on disk. A project record with no frontmatter block is declined before the call, since nothing could be merged into it. Why: over the nine nights to 2026-09-30, about $75 of the $197 enrichment spent bought re-judgments that changed nothing but the stamps. 84% of them followed a contract edit, and the 413 rewrites touched only 146 notes. Re-audit if a contract edit that changes what enrichment reads leaves a judgment standing, or if stamp-only rewrites climb back above a few a night.
The deep pass runs strong; the light pass is the first cheap-tier audit, and a model judges it. Enrichment consults the tier table instead of naming a model. The deep pass โ a note with no stamp โ runs on the strong tier because it sets importance_proposed and related, the two fields you read and the daemon ranks by, and because the tier doctrine routes every unaudited job strong. The light pass โ a stamped note whose body changed โ may move summary, tags, related and confidence, and title or type only above the floor; it is the job that qualifies a cheap tier. The audit is agentmd tiers --audit --job summarize --cheap MODEL, run by you. It draws a seeded sample from the cards the current pass has already judged on the strong tier and makes three calls per card: the cheap tier and the strong tier answer the light-pass prompt under identical conditions, then a judge is shown the card and both answers and says whether they would file and rank the card the same way, with one sentence of reason. Agreement is that judgment, not byte equality โ the same meaning in the summary, tags that name the same things, a related set that overlaps on what matters, confidence on the same side of the floor. The judge is Fable (claude-fable-5-1) unless --judge names another. The cheap model is named at invocation or in daemon.cheap_model, never defaulted. The command projects the calls and their cost and stops unless --yes is passed; a verdict at the bar is saved to the tier table and the light pass runs cheap from the next night; every run is recorded beside the enrichment record whether it qualified or not. Why the strong tier is asked again rather than read from disk: the stamped answer is the deep pass's, post-gated and carried, not the raw light answer the comparison needs. Why not audit the deep pass for the cheap tier too: a wrong importance on a permanent card is a wrong rank on every recall until you notice it; the light pass touches nothing you rank by. Re-audit if the cheap tier's agreement on the light pass falls under the bar on any later sample, and the judge itself if its reasons on a disagreement stop naming what would file differently.
The prompt is one string, one hash, two shapes. The deep pass is handed the note, its five nearest neighbours by the daemon's own search as title and summary, and the contract's prose, which gains a one-paragraph rubric for importance you can edit. It returns title, type, summary, body, tags, derivable aliases, related chosen from the neighbours offered and never invented, importance_proposed on the rubric, and confidence. It drops altitude. It never returns why, and the gate strips one if it comes back; the Evidence block is preserved verbatim; an importance that differs from importance_proposed is yours and is never sent back. The verdict is session 2's: at or above the floor a note lands active at filing_confidence: high; below it stays unfiled and is listed for you; on a second sub-floor verdict it sinks to dormant, journaled and in the morning note. Why the neighbours in the prompt: that is the research the card ruling named, it is free, and related chosen from a list cannot invent a link. Re-audit if related on enriched notes is more than a fifth links you would not have made.
The binary runs at twenty-four hours, activity-gated. -every 24h replaces 168h; an idle night โ no capture, no genuine recall โ exits at once, as the gate already does. The maps and the copy collapse then follow the night's judgments instead of lagging a week. Only an applying pass moves the binary's last done; a report pass records its own stamp. Why not weekly, as shipped: the weekly interval was set when the binary was report-only and the Python cycle still carried the lanes; now the maps are the entry point.
Crystallized holds syntheses, and a counter never writes one. A crystallized note is a synthesis written by a model on the strong tier โ the tier table already pins crystallize โ with consolidated_from naming every source, and never nightly: it is written by dreaming's weekly crystallize phase, which reads across closed-task outcomes and cards for what has recurred over time (session 4 owns the phase, below), and on request by /memory crystallize <topic>, which runs the same phase over what it is pointed at. The _crystallize-staging/ directory and its fifty-two markers are deleted; nothing was ever composed from one, and the session brief stops counting them. The binary's promote job stops reading ## Recalled, which is whatever the hook injected, and reads ## Captured and ## Candidates, session 2's trace shape; a candidate the miner saw in three distinct sessions is a real recurrence, and what promote writes for it is a semantic candidate โ status: unfiled, why empty, derived_from naming the traces โ for the next batch to judge like any other. Why not let promote write crystallized entries as built: recurrence over recall lists is a popularity count of the injector, and today's five traces would have promoted zorbulax, talk, progress and roadmap. Re-audit when the candidates lists have run a month: if promote has written nothing, the recurrence bar of three is too high for a session-a-day cadence.
The Python cycle shrinks to what has no Go owner and a reader. Kept: the lint report; dedup at the shipped 0.92 over memories only โ the three observational classes and personal/ideas/, never a diagnostics report, an _index.md or summary.md page, a latest_* copy or a record (amended 2026-09-28) โ landing as a Possible twins section in the needs-review map with the similarity and both titles, and contradiction triage beside it as a Shared keys, different bodies section; facet promotion as a Proposed facets section; and the needs-review map itself. The link sweep this session meant to keep had already left the cycle with the vector stack, so there is no sweep to keep. Retired, each with its reason. The lifecycle stage and the calendar rollups: the binary owns both, and two writers on one axis is the shape that produced the superseded-vocabulary plan. Tidying: its shelf lane moves kind-less files after a year untouched, kind-less files are your documents in permanent spaces, and the one move the axis makes โ archive, since session 5 โ belongs to the binary's lifecycle job. Compression: it walks supersedes: chains that no longer exist in that direction and has proposed nothing on any run. The opinion-supplement stage: its lanes retired in session 1. Insight generation and qualification: they write a kind: insight candidate into _dream/insights/ that no surface reads, seven so far, and _dream/ leaves the vault in landing group 4. The sampled audit: it audits a stage that makes no model call, and it returns with the cheap tier. Entity rollups, stub synthesis and the unfiled drain: the class folded, and the drain is the batch. The confirm-and-revert path for dedup: it took 167 proposals to 11 confirmations in two months. Each retires with a count of what it would have proposed on its last night. Why not keep the confirm path as the safe option: a proposal you act on in Obsidian by merging or by writing superseded_by is the same act with the revert log replaced by git, which the vault already has.
Fuzzy pairs are a section, not machinery. The parking removed in v9.20.0 does not come back: what was removed was a staging directory and a triage engine, and the list it kept is the twins section above. The fuzzy-merge model job is not built. Re-audit if the section holds more than twenty pairs for a month.
Restated rules merge on their own (amended 2026-09-28, as built 2026-09-29). A nightly pass compares convention, preference and workflow notes by embedding similarity, and the similarity only shortlists: a pair whose best chunk vectors reach the review line (0.74) is put to the strong tier, which answers whether the two state one rule. A pair it calls the same merges by supersede. The older note survives with its path, links and slug, takes the newer note's summary and body, keeps your importance, and names the newer in supersedes. The newer note is marked superseded_by the older one, which ranks it at ร0.30. The merge goes through the journal, and the morning note names it. A pair it calls different is listed for you in the needs-review map with its reason. A verdict is kept against both bodies, so a pair is judged once until one of them changes. The pass merges only while its switch is on, and it was switched on after its first judged list had been read. Git keeps the older wording. Why a judge and not a line: on the live corpus the known restated pair scored 0.794 and ranked ninth, below eight pairs of distinct rules, and word overlap separated nothing, so any line low enough to merge it would have merged eight rules that are not one. Why automatic for rules and not for other types: a rule stated twice is one instruction, and the newer wording is the one you chose last; two notes on one topic in another type usually carry different facts. Why supersede and never delete: deletion is never a policy outcome, and a wrong merge is undone by removing one field. Re-audit if you undo an automatic merge, or if the judged list grows past what one night's line pays for.
Entity pages are built each night, with no model call (amended 2026-09-29). A free phase in the binary gives "what do I know about X?" a first answer. It writes one page for each thing the vault keeps mentioning, and the page lists every note that mentions it, grouped by project and then by space, newest first. The phase reads the index's entity references and writes a page for every repo, repo-qualified issue and release that two or more sources mention. A note is its own source, except that a task's folder, open or completed, is one source, because a task's progress log restates its plan's status line (amended 2026-10-03). An issue gets a page only when its repo is known. Where the repository's clone is on this machine, found through the project's code_paths, the clone also decides: an issue page needs its number to be no higher than the highest #N any of the clone's commit subjects cites, on any ref, and a release page needs its version to be one of the clone's tags. A repository whose clone cites no number has no issue pages, so a listing number in the home research or a colour in the blog's brand notes is never an issue. A repository with no clone here keeps the reading from the text alone. A repository renamed on GitHub keeps one page: former_names: in its project's project.yaml lists the old owner/repo, the builder folds the old name's repository, issue and release references into the current repository's, and the repository page carries the old name among its aliases. The extractor qualifies a bare #NN from the note's project, when that project's project.yaml lists exactly one repository. It looks at the note's place under projects/<slug>/ first, then at its project: label, because task files carry no label. A bare number it cannot qualify gets no page, and neither does a bare number six or more digits long, or one right after a word that numbers something else: a roadmap's item, a plan's step, a task, a track, or a version line read as a bucket ("ROADMAP item #15", "V4 #30"). A number in parentheses or brackets, the (#851) a squash merge leaves, is always a reference (amended 2026-10-03). Nor does a number below its repository's floor. A project's project.yaml may set bare_issue_floor, and a bare #NN under it stays unqualified, as does one after the repository's short name (crickets #41). Below the floor the project's notes used the same numbers for roadmap items. owner/repo#NN, PR #NN, issue #NN and a GitHub address qualify whatever the number. agentm and crickets set 48, one above their roadmaps' last item (amended 2026-10-04). A release is owner/[email protected], taken from a version tag beside a repo reference, or from a note in a single-repo project. Commits are still extracted for search, but never get a page.
A person gets a page once named in two distinct pieces of shared work: a task's plan, progress or tracker (open or completed), a decisions/ note, a project tracker, a calendar/ note or a meeting note. Mentions anywhere else are listed on the page once it exists, but never qualify a person on their own. Enrichment says who the people are: the deep pass returns people:, the people a note names, leaving out you, the authors of cited work and public figures mentioned in passing, and the grounding judge checks each name against the note's text. An alias and deny table you edit, standards/people/aliases.md, merges spellings and drops wrong names; it sits outside the always-load glob, so no session carries it. The builder then finds where each person appears by matching their names and aliases across the vault, because enrichment never reads a tracker, a plan or a progress log. Walled areas are never read, and superseded notes, the derived classes and generated maps never count as mentions, so a page never counts itself.
A page is a record, kind: entity-profile, carrying entity_type, entity_id, aliases, first_seen, last_seen, mentions, projects and, for a person, shared_work. Each mention is dated by the note's own updated field, or by its created field when updated is absent, and a release by its tag's date. A note with neither is listed as undated and is never dated by its file, so a move or a machine rewrite never makes an old mention look recent (amended 2026-10-01). A page that falls below its bar is removed through the journal, which keeps its bytes, and the mocs job lists the four folders. A future mail ingest will count a thread with you as shared work for each person on it, once daemon.people_email_evidence_enabled is on; it ships off, and nothing reads mail. Why a shared-work bar for people: the vault names every author you have read, and a page for each would bury the few people you work with. Why no page per commit or bare number: neither is something you ask about by name, and a bare #12 is a different issue in every repo. A query that names an entity puts its page first (your ruling of 2026-09-30): the query itself, or what follows "what do I know about", "who is", "what shipped in" and the like, matched against a page's title, aliases and id, the way a file-name match would. Every other query ranks as before, and a name two pages share names neither. Why a name rule and not ranking on content alone: a page lists every note that mentions its entity, so it is long, and the 576 issue and release pages each carry their repository's name; on the live index "alexherrero/crickets" put the repository's page 107th, and no shorter title, compacter page or higher bar brought it inside the top ten. Why not a general boost for entity pages: it would lift an issue page into every question that mentions its repository. Re-audit if a person gains and loses a page night after night (then keep the page until no shared work remains), if a people page names someone who is not a person, or, after a month of use, if a question you ask by name still misses its page.
One morning note. agent/diagnostics/morning/YYYY-MM-DD.md with a latest_morning_note.md copy beside it, written as the night's last step at order 5, after the corpus scorecard. It is the body of the daily email, which sends at order 6. It replaces the dreaming scorecard and the daily observability digest. Four sections, each omitted when empty: what ran โ enrichment as judged ยท filed active ยท below the floor ยท sank ยท calls ยท tokens ยท model, the binary's seven jobs as a table, the Python cycle's findings in one line, and which steps did not run and why; what needs you โ counts and the first five items of the unfiled notes below the floor, the possible twins, the shared keys, the proposed facets, the binary's archive candidates and what sank this week, with a link to the needs-review map for the full lists; the corpus in one line, with a link to the day's corpus scorecard, whose parked daily job is revived; and spend, last night's tokens against each tier's line and the call guard, the seven-day total, and session spend from the observability rollup when it is not zero. What needs you also carries, as of plan 11: the link to the day's dreaming facet with the night's counts on one line, the two forward lists โ sinking within 30 days and archiving within 30 days โ and lessons this week, naming every note the weekly crystallize phase wrote with the count of what taught each one. The archive-candidate list left with them: the night moves those itself now, so what is worth the operator's eye is not the backlog but what is coming. Spend gained a line per tier-table job โ enrichment deep, enrichment light, crystallize โ beside the nightly and seven-day totals, and a line for the weekly phase's own run. The observability ladder no longer writes a digest that would say "$0 ยท 0 events", the same rule the calendar's empty reviews got. The session brief line reads the morning note's first section, and a note that stops arriving is its deadman. The daemon's queue-age alert keeps its three-day threshold; after the first batch it is measuring something real. Why one note and not the seven surfaces: on 2026-09-06 the scorecard named a fixture, the digest said nothing, and the brief counted markers nobody would ever compose; a page you read has to be one page.
How a project, a task, a decision and a handoff are represented; what is written when a task changes state; what dreaming adds over time and what it consolidates; how a session opens on a project and knows where it stands. Measured on 2026-09-06 against the live Projects/ tree. 760 files sit under _harness/ across twelve projects, 502 of them in archives and 493 with no frontmatter. No tracker file exists anywhere; the plan's Status line does that job, in nine spellings. Zero memory notes carry a project: field. Eight handoff files exist, the largest opening with two banners saying it is finished. The orientation read the tails of fourteen progress logs and said nothing about where the project stands. The working file is vault-perfection/S4-projects-and-tasks-proposal.md in the agentm project's harness directory; the rulings are its twenty-four questions.
The words. A project is a directory under projects/ with a charter and a tracker. A task is a directory under projects/<slug>/tasks/: one unit of work with a plan, a progress log and a tracker โ what the crickets loop calls a plan today. A step is one checkbox inside a task's plan โ what the loop calls a task today, and the paired release changes "task N" to "step N" in the six commands' prose. The plan is the task's intent, written at /plan and changed only by re-planning; progress is the append-only log, never rewritten; the tracker is the living head โ objective, state now, next steps, outcome at close โ rewritten in place by the session that changes it. A decision is a decisions/ note; a handoff is not a file; an arc is a set of tasks that closes together. Why rename the checkbox and not the directory: "a task's tasks" is the sentence you would otherwise have to explain away, and the directory name is the one you type.
The project skeleton. The root holds five files and no others: project.yaml, charter.md, blueprint.md, tracker.md and the generated moc-<slug>.md. docs/ holds the living documents: followups.md, roadmap.md where a project has one, conventions, how-tos and runbooks. Then come decisions/, designs/, research/, drafts/ (only where a project drafts), tasks/, completed/ (session 5's name for the finished-work folder, mirroring the others; never tasks) and desk/. The door holds the lock. Creating any other file directly under projects/<slug>/ answers Alignment, so a sixth root file is yours to allow; the folders below keep their rules. project.yaml is the grounding config. It is a small YAML file naming the project's slug, title, status, repositories (owner/repo), code_paths (home-relative), and an optional board and sensitivity. A session tells which project it is in by matching its working folder against it, and a gate holds every copy to the schema. The charter is yours, and it is the business document: what the project is, why it exists, what it returns, its major components and what to read first. The machinery never rewrites it. _index.md was renamed to charter.md because that is work's name and the two vaults converge. The blueprint holds the details the charter leaves out: the components, how they fit, where the code lives and what to read first. It links to a repo's own wiki rather than copying it. desk/ holds only what you do not open: the board mirror, features.json, corrections.md, session markers, briefs that have no task yet, and the config and source lists machinery reads โ the trusted sources, the skill-discovery sources, the auto-orchestration config, the field brief's topics and sources. standards/templates/ holds the blank of each root file. Why five files, locked: on your ruling of 2026-09-24, the root is the project's front page and should read the same in every project. agentm's root had grown to ten files and blog's to eight, each added because nothing said no. It reverses the door's earlier rule that a project may have as many root documents as it needs, with no cap, and session 4's skeleton, which kept followups.md and roadmap.md at the root. Why YAML for the grounding config and not the JSON the 2026-09-17 ruling named: you edit it by hand in Obsidian, and YAML is the vault's own frontmatter language. Why not keep the followups at the root, where you open them: one click into docs/ costs less than a root that means something different in every project. Why no plans/: a plan at home always belongs to a task; a directory is discovered, never conjured. Re-audit if a project accumulates plan documents that are not tasks โ then plans/ returns for that project โ or if you find yourself allowing the same sixth root file in several projects, which would mean the five are the wrong five. As built (plan 10, 2026-09-17): the migration wrote the eleven charters and left every project without a tracker.md, because a project's tracker is not a task tracker one level up; the four front-page files land with the AgentKV convergence (task 176, planned 2026-09-24).
_harness/ dissolves; nothing renames to desk/. Every file moves once, by a table rather than a judgment. A PLAN-<slug>.md and its progress-<slug>.md become tasks/<verb-slug>/plan.md and progress.md, with a tracker.md written from the Status line and the Goal, or moved from the tracker-<slug>.md beside the pair when one was written before the migration. A queued plan becomes a task whose tracker says queued, and queued-plans/ goes. An archived plan becomes tasks/NNN-<slug>/ with a tracker at done and closed: from its archive date, numbered by its creation order (session 5: tasks are never archived). Briefs, prompts and probes go into their task as brief.md, or into desk/briefs/ when no task exists. designs/ and the research bundles merge into the project's designs/ and research/. FOLLOWUPS.md becomes followups.md. ROADMAP-MASTER.md becomes roadmap.md, with ROADMAP.md's open table folded in by hand while you read the diff. The board and feature ledgers go to desk/, the eight handoff files to completed/. This series becomes tasks/NNN-refine-the-vault/, numbered like the rest (session 5), the first task in the new shape. The repo-local copies (init.sh, verify.sh, known-migrations.md, .project-mode) stay where the repo reads them. Task slugs are verb-first, derived from today's plan slugs and listed for your correction before the migration runs; the naming gate holds them after. Nothing is deleted, the structural-move tooling rewrites the links, and agentmd embed closes the move.
The tracker is its own file, and it has one schema. Frontmatter: kind: tracker, title, project, task (absent on the project's own tracker), status, importance (yours), opened, updated, closed, issue when a board row exists, design when a living design governs, sensitivity when you have marked the project's notes (the home project's personal-financial), carried through every rewrite and never set by a writer. Body, for a task's tracker (the project's is a generated checklist, below): ## Objective, one paragraph copied from the plan's Goal at open; ## State, what is true right now in three to eight lines, rewritten and never appended; ## Next, the immediate steps in order, the first line being what the next session does; ## Outcome, written once at close. Above ## Objective, a task's tracker carries one derived line that links its plan and its progress log by path: [[projects/<p>/tasks/<t>/plan|Plan]] ยท [[โฆ/progress|Progress log]]. Every write computes it from where the tracker sits and links only the files that exist, so it never dangles, and tracker.py relink writes that line alone, the one write a final tracker takes. The map links the tracker, so the line is what reaches the task's other two files. The plan loses its **Status:** line. Why split it out: a session opening on a task reads twenty lines instead of five hundred. The board sync, the map, the opening brief and the crystallize phase all read one small file with fields. And the plan stops being rewritten by every session, which is what let the Status line drift into nine spellings on seventy-eight files. Why not parse the Status line: a paragraph in a header has no fields, and the temple plan shows it grows into a tracker on its own. Re-audit if trackers are found stale as often as the charters are today โ then the writer, not the shape, is the defect.
Five statuses, and what each transition writes. queued (shaped, no session has worked it), active, parked (stopped on purpose, the reason in State), done, dropped (withdrawn, the reason in Outcome); today's nine spellings map onto them in the migration. Open, at /plan: the directory, the plan, the tracker at queued with Objective from the Goal and Next as step one, a progress line. First step, at /work: active, State and Next rewritten, a progress line per step as today. Each later step rewrites State and Next under active, through a transition to the tracker's own status: a rewrite in place that names State, Next or both, stamps updated and never writes the Outcome. A final status is never rewritten. Park and resume, on your word: the status, the reason, a line. Close, at the last step or at /release: done and closed:; the Outcome, which is the close-out recap the session already writes; the close-out progress line; the board row to Done; and the task's research, briefs and drafts moved to the project's completed/ by the night. Drop: the same with dropped. The task directory itself stays where it is (session 5, reversing this session's move to archive/tasks/). The project's tracker is not written by any session. Since 2026-09-24 the nightly mocs job generates it from the project's task trackers: the frontmatter in the schema above (kind: tracker, project, no task, status, updated), and a body that is a checklist of where the project stands across its tasks. It lists the open ones first with their status, grouped by design: where one is set, and collapses the done ones under a count. It is shaped so board sync can read it, and written through the journal. The session-start brief and /orient render the project line from it. Why generated and not rewritten at each open and close, as session 4 had it: on your definition of 2026-09-17, the project tracker is a checklist over the project's plans, and a checklist derived from the task trackers cannot disagree with them; a session-written summary drifts the first time a session forgets. Re-audit if the checklist grows past what the twenty-line brief can carry for the largest project. Why the directory stays: your ruling in session 5 โ a task is short, an archive split across every project is what you did not want, and the sequence prefix plus the map's collapsed done list is the eyeline. Re-audit if agentm's forty-seven task directories make the folder unreadable in Obsidian โ a recent view in the map is the answer, not an archive.
A decision is a note with a kind; a handoff is a tracker. A decisions/ note carries kind: decision and one ruling, with its alternative not taken and its re-audit trigger. For agentm and crickets, whose decisions live in living designs' amendment rows, the note points at the row and does not restate it. A handoff is the tracker's State and Next plus the session trace's Outcome. The standalone handoff files go to the project's completed/ (session 5's name), and no new one is written. Why: a handoff file is stale the moment the next session runs and nothing retires it; a tracker is rewritten by construction.
Every card and trace carries project: and task:. The in-session writer, the Stop hook's miner and the trace stamp them. The project comes from the session's working folder, matched against the code_paths of every projects/*/project.yaml. The longest prefix wins, and the repo's .harness/project.json is the fallback. A trace takes the first folder in its transcript's head that binds; when none does, it takes the folder the host filed the transcript under, because a desktop session can open in a scratch workspace and move into its repo later (amended 2026-09-30). .harness/active-plan names the task. An explicit project given to memory_capture wins. A convention or preference stays unlabeled unless its writer sets one, because a rule applies in every project and a label would age it with one project's activity (amended 2026-09-28). Only a type the writer named counts: an untyped capture defaulted to the contract's preference is labeled like any card. Existing notes are labeled where their source makes it clear: a trace through its session's transcript folder, and a card through a derived_from or related link to a labeled trace or record in one project. A bare link to a file name several projects hold, such as [[tracker]], names none of them, and a card carrying one is left unlabeled. memory_capture takes both as optional fields. Recall at session start gives a card whose project: matches the session's binding a modest boost; the multiplier is the agent's, on the dampen mechanism the ranker already has. The project tracker is itself a note, kind: tracker, ranked by importance like everything in the permanent space, so "where does agentm stand" finds it on any surface; it reaches the pasted payload through moc-projects.md, which the payload names (session 6). Why not infer the project from tags or path words: zero notes carry the field and twenty-four carry a project tag; inference has already failed. Re-audit when a session works two projects at once โ the field holds one value, and the second project goes in related:.
Dreaming enriches a card beyond what the session had. A session hook lays a card down from what was in front of it: title, summary, why, excerpt. The next deep pass makes it much richer from what the session did not have: the neighbours recall finds, the decisions, designs and research that bear on it, the analysis session 3 named. That content is written into the body under its own dated heading (## Added by dreaming), below what the session wrote, and never rewrites the captured text or the why. As built (2026-09-11), that prose is held to what the card and a neighbour already state between them, since the grounding judge refuses anything inferred. Most cards gain frontmatter and no prose. The pass walks only the class directories the contract routes a memory type into, semantic/ and procedural/ today, and keeps the other four out on purpose: episodic/ holds session traces, which are records with a writer of their own, and entities/, crystallized/ and mocs/ are written by their own nightly builders from notes the pass has already judged, so enriching them would feed one pass's output back into its own input (ruled 2026-10-02). The frontmatter moves as session 3 already rules, your importance never overwritten. A card with project: is enriched with its project's records as neighbours first, which is the difference the field makes. Inside projects/, the pass reads everything โ tracker, plan, progress, decisions, research โ as input, and writes the same additive section into the charter, decisions/, designs/ and research/ notes. Their frontmatter is merged rather than rendered: the pass sets summary, related, importance_proposed, updated and its stamps, adds its tags and aliases to the record's own, and keeps every other field the record's writer gave it. It writes no filing verdict, because a record is not filed, and it never renames one. The records queue after the cards, inside the night's token line. It never writes tracker.md, plan.md or progress.md: a task's are the session's, and a nightly writer would race the session that owns them; the project's tracker.md is the mocs job's alone. personal/ keeps session 1's frontmatter-only rule, personal/ideas/ excepted (session 7). moc-<slug>.md, projects/moc-tasks.md and projects/moc-projects.md are generated nightly by the binary's mocs job, extended from memory/mocs/ to the projects space; Projects/index.md retires into the last. The index keeps a project's completed/ and ranks it at ร0.30 by its path segment, penalized rather than excluded, and the Go arm reads a bounded head of a progress log as the Python arm already does. Why additive and never a rewrite: the captured text is the evidence, and a rewrite that reads well is how residue survived the last purge. Re-audit if an added section on a project record is longer than the record โ then the pass is writing a synthesis where a link would do.
Crystallize is a weekly phase of dreaming, and a session never writes one. A crystallized note is a hard-learned lesson: something that proved itself over time, across more than one task or more than one card, that you would keep after every card it came from has aged out. A session closing a task cannot see that, and a nightly pass over one card cannot either. So the phase runs weekly for now, inside session 3's night window and against its budget line, until its cost is known and a cheaper shape is found. It reads across the Outcomes of closed tasks, in tasks/ and completed/tasks/ alike, the candidate lines the traces and the nightly pass accumulate, and the cards sharing a project: or a subject. It looks for recurrence: the same mechanism, failure or method in at least three Outcomes or cards, across at least two sessions, at least seven days apart โ your bar. For each lesson it writes one memory/crystallized/<subject>.md, a kind: crystallized record with consolidated_from naming every source and project: where the lesson is one project's, on the strong tier the tier table pins. The phase's reason, why this is a lesson and not a coincidence, is written in the body under the lesson, because a record never carries the card's why. When an arc closes โ the roadmap item moves to Completed, the version line ships, the series ends โ the closing session marks it in the project tracker, and the phase's next run writes the arc's synthesis at memory/crystallized/<project>-<arc>.md from the arc's Outcomes. /memory crystallize <topic> runs the same phase on request. Task close writes only the Outcome, which is the phase's raw material; there is no per-task harvest note, because a lesson is what recurs and only the weekly phase sees recurrence. The phase is switched on after one run funded to finish. Its weekly job's budget: line starts at one and a half times that run's tokens. It stays provisional until you set the lasting one from the average of the first weekly runs. Why not the closing session: it has the task in context but not the time axis; a lesson is what survives the next three tasks. Why not nightly: the night is mechanical and cheap by session 3's ruling, and a cross-corpus synthesis is neither. Re-audit after three runs: if the phase wrote nothing, the bar is too high for a task-a-week cadence; and when its cost is measured, whether weekly is the cadence to keep.
A session opens on twenty lines. The session-start hook prints, for the bound project and task: the project line from the generated project tracker (its open tasks and their status), the task tracker's State and Next, the last three progress lines, the count of open followups, and the count of unfiled captures carrying this project:. That is under twenty lines, because the surface collapses anything larger unread. The plan is one click away, and the hook says where. /orient renders the same brief, then the task table from moc-<slug> with in-flight tasks first by importance and the archive collapsed, then decisions and designs by recency; its gloss reads the charter's What line, and it stops reading the progress tails of closed tasks. As built (plan 10, 2026-09-17): no project keeps a tracker yet, so the brief renders no project line and the session-start hook falls back to its plan block. That block lists the tasks that are not done or dropped โ seven in agentm, not the 172 the first migrated listing printed (PR #653) โ so it stays inside the twenty lines.
The paired repoint, in three landings. First, agentm's resolver and writers, backward compatible: resolve_active_plan finds a task at tasks/<slug>/plan.md and falls back to PLAN-<slug>.md, returning the tracker path beside the pair; captures and traces gain the two fields; memory_capture takes them; the mocs job learns the projects space; the seven readers of _harness accept both layouts; nothing moves. Second, the crickets commands, as the paired release: /plan writes the tracker and drops the Status line; /work rewrites the tracker at each step and writes the Outcome at close (the directory stays, and the night moves the task's finished records to completed/, session 5); /orient and the session-start nudge render the brief; bugfix, review and release read the tracker for status; "step" replaces "task" in the prose; the three crickets scripts that compose _harness compose the new path; the crickets development-lifecycle design is amended in the same change. Third, the migration, same day, under quiesce: the structural-move tooling applies the table, trackers are written for all seventy-eight units, and the embed backfill runs after. The four open tasks' State and Next are written by hand from their progress tails, and you read them before the move. The resolver's _harness fallbacks retired with part 15 on 2026-09-22, once the doctor found no _harness/ anywhere. Why this order: each landing leaves both plugins and the live vault consistent, and the first two can sit for a day without the third.
Every plan lives in its task, and a task is named by its directory (part 15). There is no plans/ folder. An arc is a design with scope: arc: its parts sit under designs/<design>/parts/, its index is generated at arcs/<arc>.md, and its tasks sit flat under tasks/NNN-<verb-slug>/, each naming the design in design:. A task's name is its directory name, number included. --name <verb-slug> finds the one task with that slug, and refuses by name when two tasks carry it. A bare /plan proposes a verb-first name and points to /design when the brief is arc-sized; a bare /work or /release asks which task. The resolver answers a task, a placement, or exit 4 for a bare call, and nothing else. A project with no checkout is read by slug through list-plans --project and resolve-active-plan --plan NAME --project SLUG, and neither ever places a task. The plan's **Status:** line is gone: once no writer or reader was left, it came off 284 plans on 2026-09-23, and plan_graph.py reads the tracker. A repo with no vault home keeps its flat plan pair in its own repo-local .harness/, a local fallback that was never the vault's _harness/. check-no-harness-paths fails on the old spelling in tracked files outside dated history, and the doctor's harness-dirs row fails on a _harness/ directory under any project. Why ask rather than pick the newest task: when two sessions work one project, the newest task is the wrong guess for one of them, and asking costs one line. Re-audit if harness-dirs ever finds a _harness/ again, because it would mean a writer outside both repos still builds the path.
The daily note is the diary facet. Obsidian's daily-notes format becomes YYYY/YYYY-MM-DD-diary under the calendar folder, so the note the daily-note command opens is the register's diary file. The template becomes the diary facet's frontmatter, ## Today, and a link to the morning note where the retired digest embed sat. The one existing day note moves to 2026/2026-08-10-diary.md. Why one note: two notes for one day, one yours and one the register's, is the split session 1 deferred here, and nothing in the second the first cannot carry. Re-audit if you want a day note the register must never touch.
For every space: what is consolidated, demoted in search, archived, deleted, and untouched by machinery. It sets the thresholds, how you track what moved, and how you undo it. Measured on 2026-09-07 against the live vault and the code. The axis had never moved a note: zero pinned, zero dormant, zero archived, and every journal line was the 09-05 migration. The daemon applied no decay because the switch is absent from live config. The Python arm halved notes every thirty days on a curve the stepped bands were built to replace. Nothing read the contract's five decay_* lines. The prompt-submit hook was the only writer to the recall clock, leaving memories claude.ai uses daily over MCP silent to it. Its keys were basenames, and twenty-six named multiple files. Half the corpus carried no date the clock could anchor to. Personal/Home/Important Docs/ holds recovery codes and certificates, yet it sat in the index and could enter a prompt at reduced rank. The working file is vault-perfection/S5-lifecycle-per-space-proposal.md. The rulings come from its ยง12 across three reads.
The machinery changes a note's state only where you said it may: the three observational classes, the calendar and the diagnostics. Everything else is permanent: projects/, personal/, standards/, crystallized lessons, and root notes. They rank and receive enrichment. You supersede or replace them; no pass demotes, archives, or deletes them. Five acts apply automatically where permitted, each journaled and listed the next morning. Decay is a rank on the curve without writes; recall undoes it at once. Demotion sets lifecycle: dormant in place, keeping the note in every search at ร0.30 on top of the curve. Archive moves a note to agent/archive/, mirroring the memory tree (agent/archive/memory/semantic/<slug>.md), stamped archived. It leaves everyday search, returning on an explicit archive query or when you move it back. Deletion follows archive after an additional wait; the binary writes a manifest first, and the vault's git history preserves the file. Consolidation writes a new note from several. This reverses two rulings the arc that built the system held: archive is no longer confirm-gated, and it is no longer never-by-moving. Why automatic: your ruling โ a stage nobody confirms is a stage that never happens, and the folders it may touch are named. Why by moving: Obsidian resolves links by basename, so a moved note is still found by every link that named it, and what the move buys is the eyeline the field never gave you โ the class folders hold what is alive, one folder holds what is not. Re-audit if a link ever breaks on an archive move; the structural-move tooling rewrites links and would take the job.
One memory, in sequence. A card in semantic/ or procedural/ that nobody recalls again, by days of silence, every number from the contract plus the last:
| day | what happens | still findable in |
|---|---|---|
| 0 | captured, active, full rank |
every search, every surface |
| 180 | rank halves on the curve | everywhere, lower |
| 365 | sinks to dormant, in place, lifecycle_since stamped; ร0.30 on top |
everywhere, well down |
| 1,095 | rank an eighth, still ร0.30 | everywhere, near the bottom |
| 1,825 | archived: moved to agent/archive/memory/<class>/
|
an explicit archive query, or Obsidian |
| 2,555 | deleted: manifest under agent/diagnostics/migrations/purge/<date>/, journaled |
git history, through the deep search |
A genuine recall before archive returns the card to day 0. After archive, serving it on an explicit archive query or moving it back returns it active with its clock reset. A session trace follows a shorter line: dormant at 90, archived at 365, and deleted at 1,095 days from creation, clocked from created. A trace is the handoff record and the raw material for promote and crystallize, and both have read it inside a quarter. Several categories are exempt from the lifecycle: lifecycle: pinned (never decays, never sinks); type: preference and type: convention (decay, never sink โ a rule unread for a year remains the rule, moving only by supersession or your edit); crystallized lessons; and anything outside the three observational classes. Why exempt the two rule types and not idea: sinking a rule is how the agent forgets how you want things done; an idea nobody has needed in a year is exactly what the curve is for. Re-audit when the first dormant transition fires, no earlier than 2027-08, and again when the retrieval gate first shows a decayed note beating an active one on a query you wanted the active one for.
The mechanics under the table are the agent's calls. Both arms run one curve from the contract's decay_* lines. Go bands stop being constants, and the Python exponential retires. daemon.decay_enabled goes on, and the retrieval gate runs before and after the flip. The contract caps demotions at demotion_cap: 25 per night, draining backlogs across multiple nights. The clock resets on any hit served to any surface: prompt-submit, session-start, memory_search over MCP, or agentmd search. It never resets on enrichment's neighbour search, the nightly, lint, or the index. The daemon writes the sidecar for its own surfaces. The sidecar keys by path, using fingerprint re-keying on a move. Both sidecars leave Agent/ for the engine directory. The backfill assigns every note a created date: from captured, else the vault repository's first commit of the file, else enriched_at. Notes the axis cannot see never age. importance only ranks; a silent 9 sinks like a 3, and pinned is the one word that exempts. Your edit of lifecycle in Obsidian counts as a touch. The binary journals it as yours, with you as the actor, and stamps lifecycle_since with the day it found the edit if you did not stamp one. Quiet time then counts from the later of that day and the note's last activity. No night sinks the note again until it has been quiet for the full threshold since your edit, and a note you set dormant comes back only when something recalls it after the edit. The same holds for every dormant note: it returns to active only on a genuine recall after its lifecycle_since. An edit is yours when no writer journaled it, and enrichment journals its own sink, so its verdict never reads as yours (amended 2026-10-04). A second sub-floor verdict from enrichment sinks a note (session 2, unchanged). The archive move and deletion run inside the binary's lifecycle job, capped like demotion. purge.py apply remains the manual lane for manifests you write yourself. The test rule shifts from "nothing under the night deletes a memory" to "every deletion has a manifest and a journal line first". A deep search reaches the deleted, by request only: /memory search --deep <query> searches the archive, then the purge manifests and the vault repository's git history for what they name, and prints the commit a note lives in, so one git checkout restores it; ordinary recall never reaches it. Why manifests plus git and not a shadow index of the deleted: the manifest already records every deleted note's path, title and hash, and git already holds the bytes.
Consolidation leaves the sources where they are, and a lesson outranks what taught it. Copies collapse nightly to the earliest created, the rest marked superseded, capped at 25. Twins and contradictions enter a needs-review section for you to merge (session 3), and restated rules merge on their own (Dreaming, amended 2026-09-28). The weekly crystallize phase writes a lesson synthesizing what several cards taught, listing every source in consolidated_from. The lesson is permanent learning: it never decays or sinks, and changes only when a later lesson supersedes it or by your edit. Sources must not crowd the lesson out of recall. Once a lesson lands, each source it rests on gains the lesson in its consolidated_into: one link, or a list when several lessons rest on the same card, because a week's clusters overlap and one card can teach more than one lesson (amended 2026-10-01). The stamp is a fact about the note, and no later pass drops it: enrichment carries consolidated_into through a rewrite, like every field another writer stamps. When a result list holds a stamped source and any lesson it names, the source ranks at ร0.30, the same demotion dormant gives, so it sits below what it taught. When the lesson is absent from the results, the source keeps its rank (amended 2026-10-01). The model names those sources as it writes the lesson, and only those are stamped and listed: a source that shares the subject and not the lesson keeps its rank. agentmd crystallize -recheck asks the same question of every lesson already written and releases the stamps it was not true of, one lesson at a time so a card keeps the lessons that are true of it, as a manifest the night's journal applies (#749). A released card stays in the lesson's consolidated_from and "What taught it" as provenance, because it still taught the lesson, and the lesson names it in a released: list so nothing stamps it again (amended 2026-10-01). agentmd crystallize -restamp writes the reverse: a manifest that gives each card back the lessons that still list it and that it no longer names. Sources continue down the ordinary line to archive and deletion, staying in place until then so the lesson's reference links open. Promote writes semantic candidates from traces (session 3). Why demote rather than archive the sources at once: a query that names the specific case still finds the card, below the lesson, and the links resolve while the card is where it was. Why not leave them at full rank: your ruling โ the things that taught a lesson should not affect recall of the lesson. Why only beside the lesson: at ร0.30 everywhere, a card sank out of reach when its lesson did not answer the question. The gold set's rc11 card fell to rank 55 while its lesson was not returned at all, so a query that named the specific case no longer found the card (#778).
Maps and entity views are generated; diagnostics age and are deleted. mocs/ pages and entities/ pages have no lifecycle. Their generator rebuilds them, removing any page whose members fall below threshold. The entity builder rewrites and removes only its own entity-profile pages; a hand-written note in entities/ is left where it is. agent/diagnostics/ has no archive, using retention rules instead: daily digests and morning notes 90 days, three-day digests 180, weekly 365, lint reports 90, scorecards 365, divergence notes 90, monthly digests and latest_* mirrors five years, with migration and purge manifests kept. A retention: block in the contract holds the numbers. A free retain job in the binary applies them, counted in the morning note. Diagnostics rank at ร0.30 as a dampened space in both arms. Why delete rather than stop indexing: sixty-five digests in a folder you open for one is the eyeline problem again, and the doctrine that no policy deletes a memory or your document does not cover a digest of Tuesday.
projects/ is permanent, and active work is told from finished work by name, by field, and by one folder at each level. Nothing under projects/ is demoted or deleted by a pass, and nothing under it runs on the decay curve. A finished project moves to projects/completed/<slug>/ the night after its tracker reads done with its Outcome written. The closing session updates the tracker; the move is bookkeeping. The night rewrites links, journals the move, and lists the project under a collapsed completed heading in moc-projects. Moving it back and setting the tracker active reopens it. The five directories in Projects/_archive/ land there in group 8. A closed task moves to completed/tasks/ two weeks after it closes (2026-09-27). A task directory lives at projects/<slug>/tasks/ while it is open. Fourteen days after its tracker reads done or dropped, the night moves the whole folder, under its own name, to projects/<slug>/completed/tasks/, where the completed segment ranks it at ร0.30 like every other finished record. The fourteen days are the contract's task_completed_after_days. The night journals the move and rewrites every link into the folder, as well as the moved notes' own relative links, which now sit one level deeper. A folder moves whole or not at all: the night's cap counts folders, never files. A folder whose link rewrites would reach personal/ or standards/ stays where it is and is listed in the morning note for you. Every reader that finds a task by its name looks in both folders. /work's duplicate guard still finds a moved task done, and /plan never gives a new task a number or a slug that a completed one holds. Reopening a task is a hand move back to tasks/ with its tracker set active, the same way a finished project reopens. The tracker's status and closed: fields say whether a task is active and when it finished. Its name establishes work order: every task directory carries a per-project sequence number zero-padded to three digits (tasks/001-refine-the-vault/, tasks/002-land-the-purge/), assigned at /plan as one more than the highest in the folder. Obsidian, ls, and maps display tasks in creation order. moc-<slug> shows in-flight tasks first, collapsing completed tasks under their closed: dates. Session 5 reversed session 4's ruling that completion moves directories to archive/tasks/. The operator's ruling of 2026-09-24 reversed session 5's rule that a task directory never moves. Project documents are not ordered by a prefix. Session 5 gave the files under decisions/, designs/, research/ and drafts/ the same per-folder number, written by whichever writer created them and by a free sequence job for anything dropped in without one. The operator reversed that on 2026-09-18, reading the job's first โ and only โ report: a set of sub-folders will carry that ordering instead, designed once the series' fifteen plans are done, and a number in a filename would be a second scheme to hold in agreement with the first. No document was renamed. The job is gone; task directories keep their numbers. A project has a completed/ folder that mirrors it: <slug>/completed/ holds decisions/, designs/, research/, drafts/, and desk/ as needed, using original file names. A record moves there when its parent work finishes: research bundles, briefs, or drafts when their task: closes; decisions or designs when superseded_by is written; the eight handoffs now; and desk/ briefs when their task exists. The night moves them based on frontmatter and journals the changes. The five root files, the living documents in docs/, launched designs, and standing decisions never move. You move anything by hand in either direction. In both arms, the completed segment ranks at ร0.30, matching archive and _archive. The Python arm's exclusion of _archive retires for it. Why "completed" and not "archive": the memory archive holds what is retired from use; a project's completed folder holds finished work that is still true โ two words for two meanings, one ranker rule for both. Why a number and not a date for the order: a date is nine characters and still needs a tie-break for two files from one day; the tracker carries the dates, and the name only has to carry the order. Why three digits: two overflow at a hundred, and agentm's research folder holds 233 files. Rank in the space is importance times activity. The night computes each project's activity from the past ninety days: sessions bound to it, captures carrying its project:, task transitions, and genuine recalls of its records. It writes this into the tracker's machine block as activity: with last_worked:. Every record under the project inherits that activity multiplier: 1.0 when worked in the last thirty days, 0.7 inside ninety, 0.5 inside a year, and 0.3 beyond, never dropping lower and never changing state. The multiplier is read from the night's reading at the moment a query runs, so a project that changes bands ranks by its new band from the next query onward, without waiting for each note to be indexed again. Only work moves last_worked. A file that a generator or a migration writes, such as a project's blueprint.md or a map, never counts (amended 2026-10-01). The tracker's importance is yours where you set it and computed from activity where omitted; records carry enrichment's importance_proposed. decisions/ keeps the decay exemption both arms already give it, and the rest of the space joins it. A superseded decision moves to completed/decisions/ and is walled like any superseded note, one click from its successor. Enrichment continues adding sections to project records, including in completed/. Why a project-level signal and not per file: what you meant by "how much I'm working with a project" is the project, and a per-file clock in a permanent space is decay by another name. Re-audit after ninety days of the signal: if a project you consider live ranks below one you consider done, the bands are wrong.
personal/ is permanent, yours, and readable. It has no demotion, policy archiving, deletion, or lifecycle field. You archive by moving notes manually. Home/_Archive stays as you keep it, ranking at ร0.30 by its segment. The space ranks at ร0.30 in both arms without a curve, and by importance on each file where enrichment proposed one. Background models may read it: the contract's model_exempt_spaces loses its Personal line. Enrichment reads the space and writes frontmatter only โ summary, tags, importance_proposed โ never the body, except in personal/ideas/, where session 7 lets it add a body section. This reverses session 1's per-area opt-in on your ruling. Temple Coordination records stay under personal/Church/, enriched in frontmatter and linked from the project charter. If you want them ranked and enriched as project records, the move to projects/temple-coordination/ is yours. One folder is walled from recall entirely: the contract adds recall_exempt_areas: with personal/Home/Important Docs as its first line. It is never indexed, embedded, or served to any surface, remaining on disk and in Obsidian only. Why a wall beside the dampen and the model gate: a background pass reading a recipe to tag it is one thing; a foreground recall putting recovery codes into a cloud model's prompt because a query matched them is another, and the second could happen at ร0.30. Never indexed means no row anywhere, not no answer. Every walker refuses the area before reading a file, and naming the area removes what is already there โ which means the delete underneath has to clear every table a document owns, or the wall drops the row that names the note and keeps its text. That is what it did until 2026-09-19, and the tests that were supposed to catch it asked search what it would serve rather than asking the tables what they held. They read the rows now.
calendar/ ages on a five-year horizon; standards/ and the root notes never change state. A facet file ranks on the curve from its date, with no demotion or archiving. At 1,825 days, a year's facet files are deleted, manifest and journal line first. The year's map and monthly rollups stay as its record. The register gains a dreaming facet at calendar/YYYY/YYYY-MM-DD-dreaming.md. The night writes this with one line per act: what sank, archived, deleted (with manifest path), consolidated, removed by retention, or skipped due to hand moves. This records the machinery daily in the register beside your facets. standards/, index.md, and Ideas.md are permanent with no lifecycle. The loader reads standards/ whole every session, so recall stops serving it, replacing the hook's current deduplication. Why delete calendar years rather than archive them: your ruling โ one archive folder for the internal space, none elsewhere.
How you find out what moved, and how you undo it. The morning note's what needs you section links to the day's dreaming facet with counts on one line. It keeps two forward-looking lines of its own, omitted when empty: sinking within 30 days and archiving within 30 days, listing counts and the first five titles. The needs-review map carries both lists in full. A card you open displays its lifecycle and lifecycle_since properties. To undo an action, move the file back, edit the field, or run a command: an archived note moved from agent/archive/ back into its class returns active with its clock reset and the move journaled as yours; editing dormant to active does the same; editing active to pinned exempts it; /memory revive <slug> and /memory pin <slug> execute these actions from a session; a deleted note is reached through deep search and restored from its commit. Nothing you move or edit is moved or edited back by the night. The facet names a note you edited under Left alone once, on the night that journals the edit (amended 2026-10-04).
The night follows your hand moves. You work in the vault during the day, and the night may run concurrently. Whatever you move โ a note into agent/archive/, a project into completed/, or a file between folders in Obsidian or Finder โ the night detects and follows. It rewrites links to the old path, re-keys clock and index rows, updates maps, and journals the move as yours. Three mechanisms hold it. A reconcile step opens every night before enrichment. It reads the vault repository's rename detection since the last run (the daemon commits the vault, so every hand move is a commit) and the index's fingerprints, pairs each vanished path with the file carrying its body hash, and applies the repairs with the structural-move tooling the migrations use. No job trusts a listing it took earlier. Before each write, the job confirms the file is still at the path with the hash the plan saw. A file that moved in the meantime is skipped and named in the dreaming facet as moved by hand during the run, for the reconcile step to repair at the end of the same night. And Obsidian's automatically update internal links setting is on in this vault, so a move made inside Obsidian already carries its links; the reconcile step covers moves made outside it and the paths Obsidian does not rewrite. Why not a lock that keeps you out while the night runs: the night is four hours in a window you may be awake for, and a vault you cannot touch is not yours. Re-audit if the dreaming facet lists a hand move the reconcile step did not repair โ that is a missing pairing rule, not a reason for a lock.
Two loose ends from session 4. The trust stamp: 620 of 784 cards lack one. Because it is a table lookup from source, the group 5 backfill writes it on every note with a source. It stamps thirteen memory notes without one as conversation where the miner or hook wrote them, and lists any notes it cannot attribute. Records never carry it. The crystallize phase's cost is read from the morning note's spend section. It gains per-job lines for enrichment deep, enrichment light, and crystallize, alongside nightly and seven-day totals. The cadence re-audit reads that line after three runs.
What each surface reads, what it may write, and how the same memory reaches all of them. Measured on 2026-09-07 against the live machine, the live Drive and the code. No client but Claude Code was registered against the daemon, and the Claude desktop app's configuration held no server at all; session 5's line about memories claude.ai uses over MCP was wrong on the transport. claude.ai reaches the vault through the Google Drive connector alone. That connector searches the whole Drive, where two retired vault trees still sat beside the live one, and a full-text search for the commit-trailer rule returned ten files and not the live note. The Gemini rules file on disk was from 2026-07-06 and taught the inbox; the reconciled template from 2026-09-04 already named eight things sessions 1 to 5 change. The daemon's search returned a path and a 24-word snippet with no title, type or summary. The always-load tier was 17 KB a session, a third of it the contract's machine block, and the prompt hook could inject the contract a second time because its dedupe set did not include standards/. This session's own first recall returned five session traces of the same pasted brief. The working file is vault-perfection/S6-surfaces-proposal.md; the rulings are its fifteen questions, taken one at a time.
One memory means three reads, in one order, on every surface. The always-load tier, the project state, and search over the corpus. A surface that can run the daemon gets the daemon's answer; a surface that can only search Drive gets Drive's answer over the same files; a surface that can do neither says so. A surface that can write writes the clock, and a surface that cannot is named as one that cannot. Nothing else is a surface: the morning note and the email are yours to read, and Obsidian is the files.
The payload is layout-free and pasted once. The instructions you paste into claude.ai, the Gem and (through the installer) Antigravity stop carrying a folder map. The map is what changes on every landing, and it is why three surfaces have served a July layout since July. The payload names three things that never move: index.md at the vault root, which is the map and is current; everything in standards/; and moc-projects.md, generated nightly with every project's State and Next, with the project's own tracker.md and charter.md behind it. It carries the reading order, a guide to the card's readable fields (what unfiled, dormant, superseded, completed/ and agent/archive/ mean), and the posture. The text is yours, ruled in session 6 and held in the series' working file until landing group 11a writes it into the template; the design's Documentation Plan names both. Why layout-free: a surface that looks for a folder that no longer exists finds nothing, says nothing, and answers from its own knowledge, which is the failure the payload was written to prevent. Why those three names: Drive search is by title, and each is unique in the vault and stable across every landing group. Re-audit if a surface, asked where a capture goes, answers with a path index.md does not name.
index.md describes the vault; the twin retires. The hand-copied Agent/_meta/how-to-use-agentmemory.md goes with _meta/ in group 4, and index.md gains a short "how to read this vault" section carrying the same reading order and card guide as the payload without the per-surface part, and naming standards/storage-rules.md as the file that decides where a capture goes. An agent that reaches the vault opens the map, and the map explains itself. Why name the contract rather than copy its routing in: the payload's reading order is index.md and then everything in standards/, so a surface following it has both, and the contract is the one gated source of truth for routing โ check-storage-rules parses it, the daemon reads it at runtime, and the taxonomy growth rule guards it, none of which would cover a second copy in the map. What the map owes is a pointer that still resolves after group 7 folds Filing.md into it, since [[Filing]] is where the map sends a reader for the address space today. Why not keep the twin: nothing regenerated it, and Drive held three copies, two stale. Re-audit if a surface given index.md and standards/ cannot say which class a capture lands in.
One paste, and a re-paste only when the payload's own sections change. The template lands in the repo first, ahead of every migration, and you paste it the same day. A surface asked about project state before group 8 answers from the charter and says the projects page is not there yet, which the payload tells it to do. After that, a paste is owed only when the posture, the card guide or the surface list changes, and the design owns each of those. The local copies stop being hand-made. The Antigravity rule and the managed section in ~/.gemini/GEMINI.md are derived from the template by the build under a parity gate; /memory payload prints the body and rewrites them; the doctor reports a copy whose hash differs from the template's. Why not wait for the casing rename and paste once after it: the layout-free text survives the rename, and a month more of July's map on three surfaces costs more than a paste.
Four checks prove a paste took, replacing the four in the follow-ups file. First, on each chat surface in a fresh chat: what's our commit-message convention?, answered from the vault with the note's path. Second: where does agentm stand?, answered from moc-projects.md or the tracker's State; this one can pass only after group 8. Third: where does a new capture go?, naming a class and status: unfiled and never _inbox/, _always-load/, _index.md or _harness/. Fourth, from a session: a Drive title search for storage-rules.md, voice-kernel.md and index.md returns exactly one file each, and the doctor reports the Gemini section equal to the template. You run the first three and the result goes in the series log or the project's followups; the fourth runs from any session.
The Drive copy is one copy. You keep the live Vault folder in Drive as the read-only copy chat surfaces search, and you remove the two retired trees (Obsidian/Agent/ and AgentMemory.pre-rename-backup/). That is your act on your Drive; the design does not delete your files. The vault's git remote is the NAS and stays off external clouds, so no chat surface reads a git copy.
The always-load tier is capped at 40,000 tokens, and the contract's block is not injected. The loader strips the fenced storage-rules block the way it strips frontmatter; the daemon reads the block from the file, and no session reads it. A gate in the battery fails when the packaged standards/ set exceeds 40,000 tokens (your number), the session-start hook prints one visible line when the live tier does, and the loader's own truncation stays as the last resort. The four-file set projected after group 4 is under 4,000 tokens. Why a ceiling that high: user-preferences.md is the file you write, and a budget that makes you count words there is the wrong pressure; the gate is against creep, not against you. Re-audit if the tier passes a quarter of the ceiling.
standards/ leaves recall by exclusion. The contract gains always_load_areas: naming standards/, and both arms drop hits under it before ranking, the mechanism recall_exempt_areas: already uses. The files stay indexed so Drive-side surfaces find them by name; the memory surfaces never serve them, because the loader already read them whole. Why not dedupe in the hook: a dedupe has to be repeated in every reader, and one of them forgets.
The session opens on two blocks, from two hooks. The always-load tier collapses into a persisted blob and is meant to; the twenty-line brief (session 4) stays visible because it is small. They are not merged: a large hook output is collapsed unread, so the visible line has to come from a hook of its own. The orchestration briefing's inbox and incubator counts retire with the features they counted.
Prompt-submit serves a trace only on a time question. A kind: session-trace hit is admitted when the prompt carries a temporal bound the hook already extracts, and dropped before the five are chosen otherwise. Traces stay indexed, memory_search returns them when asked, and promote reads them. Why not a score floor: the fused score is a rank, not a confidence, and a floor silences real hits on a thin corpus. Why not stop writing traces on an aborted start: the trace is the handoff record, and the 90-day line retires the useless ones.
A search hit is the card's readable head. memory_search returns, per hit, title, type or kind, summary, importance, status, lifecycle, project, then path, the score, the dates and the snippet as evidence; agentmd search and /memory search print the same. It never returns the body, which the surface reads from the file, and never why, which is the room's reasoning written for you. The surface stays two tools; memory_capture carries session 2's four fields and session 4's two. Why the head and not the body: five bodies is the budget the prompt hook already spends; five heads are a screen.
The daemon writes the clock for its own surfaces; chat surfaces are clock-blind, and the design says so. Every hit served over MCP or by agentmd search resets that note's clock. The recall ledger gains a surface: field (session-start, prompt-submit, mcp:<client>, cli), written by both arms. A claude.ai read through Drive leaves no mark the axis can see, so a memory you only ever use there ages as if unread. Why not poll Drive's view times: the connector's reads do not reliably move them, and a clock with two sources of truth is the basename-key problem again. Re-audit the first time a note you used on claude.ai appears in the morning note's sinking within 30 days list.
Claude Desktop becomes a daemon surface. Superseded 2026-09-19 โ dropped unbuilt; see the amendment row and part 16-the-inbox. The paragraph below is what session 6 ruled and what part 12 documented; part 16 removes the stdio bridge, the claude-desktop-entry doctor row and the how-to. A Code session on the machine already gets recall injected by hook, which beats a tool a model must choose to call, and the surfaces the operator actually uses are mobile and web, which no loopback client can reach. The daemon is registered in the desktop app as a local server: the same two tools, the same walls, the clock written. It is your account's configuration, so the build documents the entry and the doctor checks for it, and you add it; if the app cannot take the daemon's URL directly, the build ships a stdio bridge, which is the agent's call. Until then Claude Desktop is claude.ai in another window.
A chat surface gets one write path. It is the inbox (amended 2026-09-19); it was an email door, and the paragraph below describes what part 12 built and part 16 retires. agent/inbox/ is a fourth standard child of agent/. A chat surface drops a card into it over the Drive mirror; the card sits untouched by the sweep, enriched by the night, until the operator asks to look at the inbox and the two of them decide card by card where it goes. Nothing files an inbox card except the operator, at that pass. Which surfaces can reach the folder was settled by test on 2026-09-20, and it is one of the three the part named: claude.ai can, and its card is what proved a connector can create a file inside a Computers-mirrored folder at all; Gemini cannot, in a Gem or out of one, because it has no Drive-write capability for any instruction to reach; Claude Code's cloud agent is reasoned, not tested. A surface that cannot reach the folder prints the card instead, and a card dropped in by hand is governed by exactly the same rule as one that synced โ everything in the folder is unfiled and untrusted whatever carried it there, so the transport was never what made a card safe. The Claude Desktop surface retires in the same part, unbuilt rather than merely unused: the machine's own Code sessions already get recall injected by hook, which is better than a tool a model must choose to call, and the surfaces that matter are mobile and web, which no loopback client can serve. What the door was for, and why it goes: it answered "a chat surface has no route to the machine", which was never true โ the vault is a Drive mirror root. See part 16-the-inbox. Superseded, kept for the record: A mailbox on a Gmail account made for it receives captures. The hourly ingest sweep gains a reader that polls it and accepts only mail from your own addresses that passes authentication. Each accepted message becomes one card: type from a subject tag, source: email, trust: untrusted, status: unfiled, the sender's why kept, project where named. Everything else in the mailbox is dropped and counted. The sweep's review window and its fixed instructions grammar apply unchanged, so the most a spoofed mail can do is sit as an unfiled, untrusted note that never becomes instructions. The nightly pass judges it like any candidate, and the morning note lists what arrived by mail. The Gem's instructions are the payload plus a capture section: it writes the card in the session-1 shape, mails it one card per message, and says what it filed. Its knowledge is the always-load tier and index.md as live Drive files. claude.ai does the same through its Gmail connector, so the payload's posture line reads "to keep something durable, write it as a card and mail it to the door" instead of "offer a ready-to-paste note". A mailed idea folds into Ideas.md as the sweep already does. The mailbox credential is yours to provide and lives in the engine config beside the SMTP one, never printed. Why email: it is the transport the contract already names, the identity seam for mail units already exists in the daemon, and the sweep's staging is built for exactly an untrusted unit. Why not let a chat surface write the vault: the read-only posture is the boundary that holds every other ruling. Re-audit if a week's mailed captures sit unfiled past the morning note's second listing.
The deep search is by request. /memory search --deep and agentmd search -deep reach the archive, the purge manifests and the vault repository's history (session 5). No hook injects them and no MCP tool exposes them; memory_search keeps include_archived as its one explicit reach into the archive. A session runs the deep search when you ask for one in words, which is the by-request path session 5 named. Why: the deep search reaches what the axis retired on purpose, and a surface that injects it undoes the axis one query at a time.
The /memory skill gains the commands the series names. search (calling the daemon and printing the heads, replacing the stub), search --deep, revive, pin, crystallize <topic> and payload; diary leaves the table and the stale status block is rewritten.
Ideas.md is a list over cards (session 7, decided). An idea is a card at personal/ideas/<slug>.md, flat, in session 1's shape with type: idea and an area: field holding one of your own group names โ home-tech, coding, agentm, blog and other to start. No closed list goes into the filing contract: the generator makes a heading for whatever values the cards carry, and you rename or merge a group by editing one word on a card. The space's rules apply: permanent, never demoted or archived, ranked by importance under the ร0.30 dampen, and in the vector arm's scope by name, as the rest of personal/ is not. One rule is different there, on your ruling. Enrichment may write the body of an idea card under its dated ## Added by dreaming heading, because thinking an idea through is what you want the machinery to do with one โ and it never re-grades one you filed: the card keeps its status, filing_confidence, title and type whatever the score, gains no lifecycle, and is never renamed. Capture may add to an idea card too (amended 2026-09-28): a captured idea that matches a card is appended under a dated ## Added by capture heading with its source, below everything already there. Everywhere else in personal/ the rule is ยง Lifecycle per space's frontmatter-only one โ and as built, no other folder there is queued at all. Ideas.md is generated nightly by the dreaming binary with the maps. Everything from the top of the file through the end marker is yours and is copied into every rebuild byte for byte; below it, one heading per group, one line per idea carrying the card's title and summary and linking to the card, and the dismissed ideas (a dismissed: date on the card) in one collapsed callout at the end. A file without the markers is never written: the first rebuild replaces your hand-kept file once, deliberately, after you have read its dry run (agentmdream ideas). An idea arrives as a card in the inbox and is filed there with its group at your review (/memory inbox --file <name> --type idea --area <group>), which is where it gets its group; the machinery that kept the old ledger โ the surface writer, the promote-and-GC step, the ledger's lint, the sweep's fold and the briefing's two ledger nudges โ retired with it. The migration merges two sets into one, from one mapping you correct: every card typed idea and every entry in Ideas.md, each with the session's proposed verdict and group. An idea moves to personal/ideas/, active at its group; a duplicate stays where it is, superseded and naming its survivor; a note that is not an idea is relabelled when it holds something real, and otherwise deleted on the count you confirm, through the purge lane's manifest. Each entry without a card becomes one, keeping its date as created and its cluster as related:. The incubator graduates keep their research bodies. Measured 2026-09-07: Ideas.md was 52 KB with 27 entries and a preamble teaching the retired incubator paths; 91 type: idea cards sat in semantic/, 34 of them unfiled one-line fragments. Why personal/ and not a sixth root space: an idea is yours the way a recipe is, the areas already exist, and a space at full rank beside the classes would reopen session 1's layout and the payload's map. Why not leave the file hand-kept: it has been wrong about where ideas go since the incubator retired, and a card can be enriched where a line cannot. Re-audit if the generated file passes a screen per area, or if a dismissed idea reappears from a card you meant to drop.
Amend Filing v2 instead of a successor. Rejected. Its body is the record of a build, organized by the six parts that shipped, and the series touches three designs; amending one leaves two stale by construction. It stays inherited and pointed forward.
Work's flat agent/desk/tasks/. Rejected for home. The flat list is already growing project and activity buckets inside itself at work, and home is few projects with many tasks each. The cross-project view work gets from the flat directory, home gets from a generated map.
Title Case root spaces. Rejected. Today's mix is the one state nobody chose; lowercase matches the other vault you read and the kebab rule everything below the root follows.
A generated Home.md. Rejected in favour of the root map that already exists under its own name.
Keep the empty entities/ as a promise. Rejected; discovered, never conjured.
People pages from people: alone (2026-09-29). Rejected. Enrichment never reads a tracker, a plan, a progress log or a calendar note, so shared work would count only in decisions/; the builder matches the names enrichment found across every note instead. Widening enrichment to those notes was rejected too: it would pay for every night's edit to a progress log, and a tracker has one writer.
A page for every person the vault names. Rejected; the shared-work bar keeps authors you have read off the list.
Keep the bare-date day index. Rejected; work runs on facet files and a year map, and home has no entry to justify a per-day file.
Ten fields, exactly the work card. Rejected; home's lifecycle, transport and trust each have a reader in the daemon. The fields without a reader are retired instead.
A model call in the Stop hook as the primary capture. Rejected for now; it reconstructs from the transcript inside a 30-second hook budget and pays on every session boundary. Named as the fallback with its re-audit trigger.
Enrichment writes why. Rejected; a guessed reason reads like a real one.
Retire the miner outright. Rejected; its candidates cost nothing as lines in the trace and are the record of what a session said in passing.
Auto-archive a twice-rejected note. Rejected; archived is conspicuous by contract. It sinks to dormant instead.
A call cap as the nightly budget. Rejected; it bounds the wrong thing. The budget is a token line per tier, with a call cap only as a runaway guard.
The deep pass on the cheap tier once audited. Rejected; a wrong importance on a permanent card is a wrong rank on every recall. The light pass is the cheap-tier candidate.
Promote writes crystallized entries from recall recurrence, as built. Rejected; it counts the injector, and would have promoted a test token. It reads the trace's captured and candidate lines and writes semantic candidates.
Rebuild the fuzzy-pair parking. Rejected; the list is a needs-review section, and the engine's ambiguous band was never measured against a filed corpus.
Keep the dreaming scorecard and the digest email beside a morning note. Rejected; a page you read has to be one page.
Keep the tracker as the plan's Status line. Rejected; a header paragraph has no fields, and it drifted into nine spellings on seventy-eight files.
Flatten a closed task into drafts/, as work does. Rejected; blog's drafts/ holds drafts, and a task's artifacts stay together in its numbered directory under tasks/ (session 5; session 4 had them under archive/tasks/).
Crystallize at task close, by the closing session. Rejected after being proposed; the session has the task in context but not the time axis. A lesson is what recurs, and only the weekly phase can see recurrence.
Enrichment writes frontmatter only in projects/. Rejected; enrichment exists to make a session's card much richer from what the session did not have, and a project record is enriched the same way. personal/ keeps the frontmatter-only rule.
Rename _harness/ to desk/. Rejected; the folder is three of work's folders in one, and it dissolves into them by a table instead.
Archive by field only, never by moving, as Filing v2 ruled. Rejected in session 5; links resolve by basename, and one archive folder is the eyeline the field never gave.
Propose-and-confirm for archive and deletion. Rejected; a stage nobody confirms never happens. Both run automatically in the folders named, with a manifest and a journal line first, and the vault's git history behind them.
Leave decay off, as the live install has it. Rejected; a note that changes nothing for a year and then drops to 0.30 in one step is a cliff, and the curve is what makes the step legible.
Archive a lesson's sources the moment the lesson lands. Rejected; the lesson's reference links would break until a reader asked for the archive. They are demoted at once instead and follow the ordinary line.
A per-file decay in projects/. Rejected; a decision from June is not less true in December. Rank there is importance times a project-level activity signal.
Per-project archive/tasks/, as session 4 ruled. Rejected in session 5; archives split across every project is what you did not want. Tasks never archive; a sequence prefix orders them and the map collapses the done ones. Finished work moves to the project's completed/, and a finished project to projects/completed/. completed/tasks/ (2026-09-27) is not this folder brought back: it lives inside the one completed/ each project already has, beside the finished records its tasks produced, rather than in a second folder per project.
A date prefix for the order of tasks and project documents. Rejected; nine characters on every name and still a tie-break for two files from one day. A per-folder three-digit number carries the order; the tracker carries the dates.
Keep personal/ model-exempt, per area. Rejected on your ruling; background models may read it, and enrichment writes frontmatter only. Important Docs is walled from recall instead, which is the boundary that matters.
A lock on the vault while the night runs. Rejected; the night is four hours you may be awake for. The reconcile step and the per-write re-check follow your hand moves instead.
Re-paste the September payload as written. Rejected in session 6; its folder map is already eight items behind this series and would need a third paste after the migrations. The payload is layout-free and points at index.md.
Keep the vault twin of the payload. Rejected; nothing regenerated it and Drive held three copies. index.md describes the vault.
Dedupe standards/ in the prompt hook. Rejected; a dedupe has to be repeated in every reader. The contract's always_load_areas: excludes it from recall in both arms.
A score floor on prompt-submit recall. Rejected; the fused score is a rank, not a confidence. Traces are served on a time question only.
Return the body, or why, from memory_search. Rejected; five bodies is the budget the hook already spends, and why is written for you. A hit is the card's readable head.
Poll Drive's view times so chat reads reset the clock. Rejected; the connector's reads do not reliably move them, and a second clock source is the basename-key problem again. Chat surfaces are named clock-blind.
Chat surfaces write the vault through a Drive or filesystem connector. Rejected; the read-only posture is the boundary every other ruling stands on. The write path is an email door into the ingest sweep, untrusted and unfiled. Accepted, 2026-09-19 โ this is now the design. The rejection rested on the premise that a chat surface has no route to the machine, and that premise was wrong: the vault root is a Google Drive mirror root and always has been, so a Drive connector is a route that needs no credential on any device and no inbound connection. The read-only posture was never what the door protected either โ the door let a chat surface write, through a transport that authenticated the sender and landed the result untrusted, and a Drive drop keeps both of those properties while dropping the IMAP client, the DMARC reader, the allow-list and the mailbox credential. See part 16-the-inbox.
A Gem that hands you text to paste. Rejected; that is the Gem you built and stopped using. It mails cards to the door. Now the Gem's only path, 2026-09-20 โ not chosen, but what is left. The door it was rejected in favour of is retired, and the Drive drop that replaced the door needs a capability Gemini does not have. What makes it tolerable now where it was not then is that the card it hands you has somewhere to go that treats it exactly like every other card.
Expose the deep search over MCP or inject it. Rejected; it reaches what the axis retired on purpose. It runs on your request, from a session or the shell.
A sixth root space, ideas/. Rejected in session 7; it would rank at full weight beside the classes and reopen session 1's layout and the payload's map. Idea cards live in personal/ideas/, where the areas already exist.
Leave Ideas.md hand-kept. Rejected; the file has taught retired paths since the incubator went, and a line cannot be enriched where a card can. It is generated over the cards, with your preamble kept.
Filing v2 for every decision inherited unchanged; Capture and Experience & Dreaming, which sessions 2 and 3 reconcile; the storage seam for the root-versus-memory-root distinction the probe and the retrieval gate both got wrong; the live contract in standards/storage-rules.md; the crickets development-lifecycle plugin for the _harness/ repoint and the design template and prose pass; Obsidian's basename link resolution and the Drive sync path, which make a case-only rename a two-step; and the work vault reference in the research bundle, REFERENCE-work-vault-layout.md, as the transcription this design compares against.
Landing groups, in the order that keeps the live vault consistent at every step. Session 7 sequenced them on 2026-09-07 into fourteen plans (ยง Launch Plans): one per group, with group 8 split at its crickets landing and the night moved up behind the capture writers.
-
Hygiene. The probe's root, the vault-root
diagnostics/, theIcon-kept empties,health-pass, the empty reviews. No design needed; each is in the follow-ups file. -
The purge, and the tally gate. The six manifests ruled in session 2 (572 notes), run through the migration engine under
--confirm-count, with the write-door gate that refuses the tally template landing in the same group so nothing refills manifest A. Before any backfill, so nothing dresses residue up again. -
The capture writers. The tool's four fields and
instructionsin the Go door; one meaning forstatusin the Python lane; the trace's shape and the miner's HIGH-only filing; the eager trigger and its never-called attachment removed; enrichment eligible by stamp; the nightly batch registered as a runner job with its budget left to session 3. Writers land before the backfill they define. -
The memory root trims.
_always-loadintostandards/, watchlists and settings intoprojects/agentm/, engine files out ofagent/,_dream/and_meta/out. Path repoints ship with the moves. -
The card backfill. Titles and summaries where derivable,
filing_confidencefrom the enrichment score,trustfromsource,createdfromcaptured, the retired fields dropped, empty tag lists removed; the 74 notes the Python lane filedactiveat low confidence re-stampedunfiled. Dry-run counts first; every backfilled note keeps itsenriched_byso a model-written title is never mistaken for yours. -
Maps and root notes.
moc-root,moc-memory, the retirement ofHome.mdand the paginated pages,Filing.mdintoindex.md,moc-calendar-YYYY. -
The root casing. Last of the structural moves: quiesce, temp-name two-step per folder, the repoint inventory, link check before and after,
agentmd embedto close. -
Projects and tasks. Three landings in order: agentm's resolver and writers accepting both layouts, with
project:andtask:on captures and traces and the mocs job over the projects space; the crickets commands writing and reading the tracker, the paired release; then the migration under quiesce โ the_harness/table applied, seventy-eight trackers written, task directories given their sequence prefixes by creation order,charter.mdrenamed, the handoffs and closed tasks' research intocompleted/, the five retired projects fromProjects/_archive/intoprojects/completed/, the daily-note wiring, embed backfill โ and the_harnessfallbacks retired one release later. The weekly crystallize phase registers with the night's jobs in group 9, after this group's trackers exist for it to read. -
The night. The runner's
window:field; the batch job registered with its token line, reading the tier table and printing usage; the two-shape prompt and theimportancerubric mirrored into the live contract; the binary at-every 24hwith the report-pass clock fix and promote's new sources; the Python cycle's retirements, each with its last-night count;_crystallize-staging/deleted; the morning note and the empty-digest rule; then the first supervised batch, and only after your sample the nightly cadence. After group 3, which lands the writers the batch judges; independent of groups 4 to 8. -
The axis per space. The contract's lines: the
decay_*bands read by both arms withdaemon.decay_enabledon behind the retrieval gate,demotion_cap: 25,forget_after_days,lifecycle_overridesforepisodic,retention:,recall_exempt_areas:withImportant Docs, thedreamingfacet, thePersonalline dropped frommodel_exempt_spaces;agent/archive/created; the archive path class (archive,_archive,completed) in both arms and the Python arm's exclusion retired, its dampen forpersonal/anddiagnostics/added; the sidecars keyed by path and moved to the engine directory, the daemon writing them for its own surfaces; the lifecycle job's archive move and deletion with the manifest, theretainandreconcilejobs, the per-write re-check, the activity signal on project trackers;consolidated_intofrom the crystallize phase;/memory revive,/memory pin,/memory search --deep; the two how-tos rewritten. After group 9 (the night) and group 8 (the trackers the activity signal andcompleted/rules read). -
Surfaces, in two plans. 11a, the paste, independent of every other group and first: the payload template rewritten to session 6's text, the Antigravity rule and the Gemini managed section derived from it under a parity gate,
/memory payload, the doctor's copy check, the follow-ups' four checks replaced, the retired Python MCP server and its how-to removed; then your paste and checks 1, 3 and 4, and your removal of the two retired Drive trees. 11b, the rest, after group 5 (the card fields the hit shape returns) and group 8 (the trackers andmoc-projects.mdcheck 2 reads):index.md's self-description; the loader's block strip and the 40,000-token gate;always_load_areas:in the contract and both arms; the trace rule in the prompt hook; the hit shape, the ledger'ssurface:field and the daemon writing the clock for MCP and CLI hits; the mail door (the credential in the engine config, the reader in the hourly sweep, the sender allow-list, the morning note's line, the Gem's instructions and knowledge); the/memorysubcommands; the Claude Desktop entry documented and checked, added by you. -
Ideas.
personal/ideas/created; the 81 idea cards moved fromsemantic/witharea:proposed; the 27 entries ofIdeas.mdwritten as cards where none exists; the mocs job generatingIdeas.mdbetween your markers; the embed backfill. After group 5 (the card shape) and group 7 (lowercasepersonal/).
Every group is dry-run first, link-check green before and after, and inherits Filing v2's vault-wins collision doctrine and embed backfill. Rollback for every group but the purge is git revert plus the repoints replayed.
- A case-only rename on a case-insensitive disk under Drive. Mitigation: the two-step through a temporary name, under quiesce. Re-audit trigger: Drive shows a duplicate folder after the rename.
-
The purge is irreversible. Mitigation: a manifest per population, an exact count you confirm, the migration engine's
--confirm-count. Re-audit trigger: any population whose count moves between the manifest and the run. -
Backfilled titles and summaries are model-written. A stub enriched into confident prose is how 251 tallies survived the last purge. Mitigation: the purge runs first, and every backfilled field carries
enriched_by. Re-audit trigger: a backfilled title on a note you would not have kept. - Automatic deletion in the memory classes and the calendar. A policy now deletes what the doctrine said only an operator could. Mitigation: a manifest and a journal line before every deletion, the 730-day wait after archive, the vault's git history behind every file, and the deep search that reaches it. Re-audit trigger: any deleted note you go looking for that the deep search cannot name.
- A hand move during the night's run. A job could write to a path you just emptied. Mitigation: the per-write re-check skips a moved file and names it in the dreaming facet; the reconcile step repairs it the same night. Re-audit trigger: a hand move the facet lists as skipped that the next morning has not repaired.
-
The activity bands rank a live project below a done one. Mitigation: the tracker's
importanceis yours and multiplies the signal. Re-audit trigger: ninety days after the signal ships, if a project you consider live ranks below one you consider done. - The switch from no decay to the curve changes every ranking at once. Mitigation: the retrieval gate before and after the flip, and the curve's first band leaves anything under 180 days untouched. Re-audit trigger: the gate's first regression after the flip.
-
The
_harness/repoint is a paired release. Mitigation: three landings โ agentm's resolver accepts both layouts first, crickets' commands second, the move third โ so both plugins and the vault are consistent at every step. Re-audit trigger: any plan-resolution path that still probes_harness/after the fallbacks retire. -
Seventy-eight trackers written by a migration. A generated State on a closed task is a summary of a summary. Mitigation: closed trackers carry only Objective,
doneand the archived Outcome; the four open ones are written by hand and read by you before the move. Re-audit trigger: a tracker whose State you would not have written. -
The weekly crystallize phase writes a wrong lesson into the decay-exempt layer. Mitigation: the strong tier,
consolidated_fromon every note, the recurrence bar of three across two sessions seven days apart, and the morning note listing every lesson written. Re-audit trigger: any crystallized note you would not keep. - Additive enrichment on project records grows them past reading. Mitigation: the section is dated and headed, and the re-audit fires when an added section outgrows its record. Re-audit trigger: that.
- The always-load budget grows with the standards set. Mitigation: a 40,000-token ceiling held by a gate in the battery and a visible line at session start, with the contract's block stripped from the injection (session 6). Re-audit trigger: the tier past a quarter of the ceiling.
-
The email door receives mail from anyone. Mitigation: the reader accepts only mail from your own addresses that passes authentication, a card lands
trust: untrustedandstatus: unfiled, the sweep's fixedinstructionsgrammar never executes free text, and everything else is dropped and counted. Re-audit trigger: any mailed card that landsactive, or a dropped-mail count that is not zero on a day you sent nothing. - A chat surface's reads never reset the clock. A memory used only from claude.ai sinks at a year of Claude Code silence. Mitigation: named in the design; sinking is a rank change one recall undoes; Claude Desktop gets the daemon. Re-audit trigger: a note you used on claude.ai in the sinking within 30 days list.
-
The payload goes stale again. Mitigation: it names no folder but
standards/and three stable files, the local copies derive from the template under a gate, and the doctor reports drift. Re-audit trigger: a surface answering with a pathindex.mddoes not name. -
The empty-shell failure can repeat. Mitigation:
entities/is not recreated until written, and class populations sit on the daily scorecard. Re-audit trigger: any class at zero thirty days after its writer ships. -
A people page can name someone who is not a person. Enrichment can take a place or a product for a name. Mitigation: the grounding judge checks every name against its note, the shared-work bar keeps a stray name from earning a page, and a deny line in
standards/people/aliases.mdremoves it the next night. Re-audit trigger: more than one wrong page in the first list you read. -
A people page gathers everything about one person. Mitigation: your ruling of 2026-09-24 accepts it; walled areas stay walled, and Drive already mirrors
personal/. Re-audit trigger: a page you would not want a chat surface to read. - The in-session card may be sparse. A capture that depends on the agent noticing a durable moment can miss them. Mitigation: the always-load payload names when to capture, the session brief asks at the end what went uncaptured, and the trace's candidates list keeps what the miner saw. Re-audit trigger: fewer than one card a day over a month while the traces show decisions being made; the Stop-hook model call is the next step.
- The daemon stays red until session 3's first batch. Nothing judges the queue between the capture writers landing and the budgeted batch. Mitigation: the alert is reading a true state, and the purge removes 316 of the 356 it counts. Re-audit trigger: the first batch not scheduled within a week of session 3.
-
The first batch judges the whole corpus under one prompt. 181 cards judged by one model under one prompt, over several nights, with
relatedandimportance_proposedon every card. Mitigation: the run is by hand, with--dump, and the second night waits on your twenty-pair sample; every write is journaled and the enrichment journal already carries the undo. Re-audit trigger: any pair in the sample where the new title or summary lost a term you would search for. -
Test fixtures write into the live engine state. The dreaming scorecard read one as last night's run. Mitigation: the scorecard retired for the morning note, which reads only what the night's steps wrote since the window opened and never reads
dream-runs/. Both test runners set a scratch engine state, andtest_engine_state_not_leaked.pyasserts that it holds. Re-audit trigger: any/var/folderspath in a vault surface. - A stale miner in a worktree. The hook resolves the miner relative to the session's working directory, so a worktree from an older base runs an older miner. Mitigation: the tally gate at the write door. Re-audit trigger: any note matching a retired template after the gate lands.
The write-authority table is inherited unchanged: agent/ written freely, calendar/ shared, projects/ under a session grant, personal/ per task, standards/ and the root notes on instruction. The one new boundary is enrichment of your own spaces, which writes frontmatter and never the body in personal/, except the body of an idea card under personal/ideas/ (session 7); background models may read that space (session 5), and one folder, personal/Home/Important Docs, is walled from every recall surface by recall_exempt_areas:. A capture is visible to recall from the moment it lands, at reduced weight while unfiled; there is no review window. The guard is that captured content never gains instruction authority, that a fetched or mailed transport carries trust: untrusted through every pass, and that recalled memory is data to the surface that reads it. Session 6 adds one door and one client. The email door is the only write path a chat surface has: the reader takes mail only from your own addresses that passes authentication, a mailed card lands untrusted and unfiled, the sweep's instructions grammar stays fixed, and the mailbox credential lives in the engine config beside the SMTP one and is never printed. The daemon's MCP server stays loopback-only with its Host and Origin guards, and registering it in the Claude desktop app adds a client on the same machine, not a network exposure.
ID-stability holds through every move: basenames survive the casing rename, the trims and the fold of Filing.md, so name-resolved links keep resolving. Backfills are additive and stamped; nothing in your spaces has its body rewritten by a pass; the purge is manifested and count-confirmed. A move keeps the note's file identity too. The journal renames the note, so a sync client such as Google Drive sees a move rather than a new file and a deleted one; a move that repairs links renames first and rewrites in place.
personal/ stays exempt from the memory contract. Background models may read it for enrichment, which writes frontmatter only and never the body (session 5, your ruling), with personal/ideas/ the one exception (session 7). What a foreground recall may put into a prompt is the boundary the contract now draws: recall_exempt_areas: names folders no surface is ever served from, and personal/Home/Important Docs is its first line. The Temple Coordination records stay under personal/ and are enriched in frontmatter like the rest of it. What a chat surface can see is the Drive copy of the vault, whole, at your account's permission; the payload's read-only posture is an instruction to the model, not an access control, and the one folder walled from the daemon's recall is still a file in Drive. standards/ is excluded from recall by always_load_areas: because the loader already served it, not for privacy.
Each rule lands as a gate: kebab names with a subtype word, the card's field order and required fields, a class directory holding only classes, no empty tag lists, no empty rollups. Every backfill and every move prints its dry-run count before it runs.
| landing group | size |
|---|---|
| hygiene | S |
| the purge and the tally gate | S, ruled |
| the capture writers | M |
| the memory root trims | S |
| the card backfill | M |
| maps and root notes | M |
| the root casing | M |
| projects and tasks | L, paired with crickets |
| the night | M |
| the axis per space | L |
| surfaces, the paste (11a) | S |
| surfaces, the rest (11b) | M, with one credential from you |
| ideas | M |
This design; the crickets development-lifecycle design amended when its paired landing ships; the pointer row and note in agentm-filing-v2.md; Designs.md and _Sidebar.md entries; the vault's index.md rewritten when Filing.md folds in; reference/Memory-Daemon.md for the probe's root; reference/CI-Gates.md for the new gates; the how-to for the vault layout once the casing lands; Capture reconciled by session 2; Experience & Dreaming pointed here by session 3 for the Python cycle's retirements and the crystallization trigger, its body reconciled in the landing group that retires the stages; reference/Memory-Daemon.md for the batch's flags and the tier wiring; the runner's how-to for window:; how-to/Tune-The-Archive.md and how-to/Archive-A-Finished-Project.md rewritten to the per-space policy when group 10 lands, and the contract's lifecycle prose mirrored into the live file under that plan's authority (session 5); templates/agentmemory-context.md rewritten to session 6's text with the Antigravity rule derived from it, how-to/Use-AgentMemory-In-Any-Agent.md and reference/AgentMemory-Context-Payload.md rewritten to the layout-free payload, the email door and the four checks, how-to/Stand-Up-Memory-MCP-Server.md retired with the Python server, the follow-ups entry on the re-paste closed, and the /memory skill's search section and status block rewritten (session 6).
Approved as final on 2026-09-07 and sequenced the same day into fourteen plans, one per landing group, in the order ยง Migrations names, with the night moved up to follow the capture writers. That move is the agent's call and reversible: group 9 is independent of groups 4 to 8, and the risk register wants the first batch within a week of session 3. Plan 00, the paste, is the active named plan PLAN-agentm-vault-00-paste.md in the project's harness directory; the rest wait in queued-plans/, and a coordinator activates each when its dependencies have shipped. Every plan runs in a /work session on opusplan, deploys the same day it merges, and runs its migration under quiesce after its writers. Nothing goes live all at once.
Your steps, in the order the plans reach them:
| when | your step |
|---|---|
| already done | the Drive cleanup: one copy, check 4's Drive half passing on the gmail account (2026-09-07) |
| 00, the paste lands | paste the template into the claude.ai project and the Gem the same day; run checks 1 and 3 in a fresh chat on each and note the result in the project's followups; check 2 waits for plan 10; the doctor half of check 4 runs from any session |
| 02, the purge | confirm each manifest's fresh count the day it runs, six confirmations, manifest E re-selected first (40 notes in the lanes against its 32 rows) |
| 04, the night | after the first supervised batch, read the twenty before-and-after pairs before the second night is allowed to run; edit the importance rubric in the contract if the proposals read wrong |
| 05, the memory-root trims | write standards/user-preferences.md in your words; read the drafted security-and-secret-governance.md
|
| 10, the projects migration | correct the task-slug derivation list; write State and Next for the four open trackers; fold ROADMAP.md's open table into roadmap.md while reading the diff; the crickets release that writes trackers ships first |
| 11, the axis | nothing owed; optionally move the Temple Coordination records to projects/temple-coordination/
|
| 12, surfaces | make the Gmail account for the email door and place its credential in the engine config, never in a session; add the daemon to Claude Desktop per the build's how-to |
| 13, ideas | correct the proposed area: on the migrated cards; keep the preamble between the markers |
15, the _harness/ retirement |
run the arc-closing /release, which works the coalescence checklist, flips this design to launched and closes #609 and #610; change the group: line on the 16 notes that still name projects/agentm/_harness/โฆ; drop _harness/archive/** from the frozen-evidence line in standards/security-and-secret-governance.md, as the template already has |
A re-paste is owed only when the posture, the card guide or the surface list changes, and the design owns each.
The daily corpus scorecard gains: residue count (zero after the purge, and a line that stays), class populations, the card-shape gate's count of non-conforming notes, empty directories under agent/, and the health-pass cadence itself. The corpus scorecard also lists tasks by status per project and the age of each project tracker's updated stamp, and the morning note lists every crystallized note the weekly phase wrote. The morning note carries the night's spend against each tier's token line and the call guard, the steps that did not run and why, what sank this week, and the archive candidates. A night that ran past its window has no line of its own yet; the note's footer gives the time it was written. Plan 11 landed the rest of what plan 04 had marked pending: the link to the day's dreaming facet with the counts of what sank, archived and was deleted, the two forward lists, the list of crystallized notes, and the per-job spend lines. The dreaming facet names every hand move the run skipped and the reconcile step repaired. [PENDING-IMPL] The mail line waits for plan 12. The morning note lists what arrived by mail and how many mails were dropped; the session-start hook prints one line when the live always-load tier passes its ceiling; the doctor reports a payload copy whose hash differs from the template and whether the Claude Desktop entry is present; the recall ledger's surface: field lets a scorecard count recalls per surface (session 6).
Every migration writes its manifest and its dry-run count to agent/diagnostics/migrations/; backfills journal what they stamped; the purge writes its manifest before deleting.
Each landing group reverts with git revert in the vault repository plus its repoints replayed; the casing rename reverts by the same two-step in reverse; the purge does not revert and is bounded by its manifest.
| Date | Change | Status |
|---|---|---|
| 2026-10-07 |
As built and measured (task 181 close-out). Three corrections to the 2026-10-01 row, reconciled in the body above. First, the judgment hash covers the type vocabulary alone, because the prompt and the answer's checks read nothing else from the contract. Second, the order by cause applies where the batch serves its queue, not only in the pending report, since the nightly run starts at the top of the queue every night. Third, a project record with no frontmatter block is declined before the call: the cause order sent the night to the project records first, and on 2026-10-07 all 43 judgments failed on such records after they were paid for. Measured over the nights of 2026-10-02 to 10-06: 0 stamp-only rewrites of 124, against 159 of 413 in the nine nights before; no note judged twice in the window, against 64.6% of rewrites before; the never-judged backlog fell from 385 to 238. Why not mask enriched_by too: PassDepth reads it, and a prompt change rewrites nearly every note anyway. Re-audit trigger: stamp-only rewrites above a few a night, or a night whose failures leave notes owed as never judged. Prose pass: cross-model, fact-checked. |
final |
| 2026-10-04 |
Amended on the operator's ruling of 2026-10-04: a task's tracker links its plan and progress log. The orphan census in agent/diagnostics/2026-10-04-card-volume-and-orphans.md found that the maps link every task's tracker (none of 266 archived trackers is unlinked), but that the tracker linked nothing. 51 of 266 archived plans and 29 of 115 archived progress logs had no link in or out, and the rest were reached only when an entity page or a lesson happened to cite them. The tracker now opens with a derived links line, and a one-time relink pass writes it into the existing trackers. Why a path wikilink and not a relative Markdown link to plan.md: Obsidian resolves a link that doesn't start with ./ by name across the vault, where hundreds of plans share a name. The task mover also rewrites a relative link without its ./, but it carries a path wikilink into completed/ with its label intact. Why not hide completed/ in Obsidian: that would also take the archived plans out of search, when what they lacked was the link. Re-audit if a task folder gains another file that sits unlinked at scale, or if the mover stops rewriting path wikilinks. |
Amended |
| 2026-10-04 |
Amended on the operator's rulings of 2026-10-04: the night journals your lifecycle edit as yours, as Lifecycle per space says, and a bare issue number below its repository's floor is no issue. These are the two follow-ups task 186 left open, built in task 187. Hand edits. The lifecycle pass never journaled your edit of lifecycle. A standing "touch" (the journal's last state disagreeing with the note's) kept the night off the note every night after, and the facet named the note as yours. The five notes carrying that touch were enrichment's sinks, not your edits. A second verdict below the floor writes lifecycle: dormant with no journal line. The revive rule then bounced each one between dormant and active from 09-15 to 09-23, until the touch froze it. Now enrichment journals its own sink, and a state no writer journaled is journaled as yours with lifecycle_since stamped. Quiet time counts from the later of the edit and the last activity, and a dormant note comes back only on a recall after its lifecycle_since. The five are seeded into the journal as enrichment's before the touch retires. This supersedes the 2026-10-03 facet row's note that the claim was not true of the code. Bare numbers. A survey of the 73 issue pages numbered below 100 (projects/agentm/tasks/187-finish-the-186-follow-ups/low-number-survey.md) found that both repositories' roadmaps numbered their items 1 to 47, the same range as their first issues. crickets #41 meant the roadmap item as often as the issue. project.yaml takes an optional bare_issue_floor. Below it a bare or repo-named #NN stays unqualified, and owner/repo#NN, PR #NN, issue #NN and a GitHub address still qualify. Both projects set 48. Why journal the edit and not keep the touch: the touch could not tell your edit from a writer that forgot to journal, so it named enrichment's verdicts as yours and froze them. Why revive on a recall after lifecycle_since and not on the clock alone: a note sunk before its threshold, by you or by enrichment, reads as recently active, and the clock alone brought it straight back. Why a floor per project and not one number: each project's roadmap range is its own, and a project that never numbered a roadmap needs none. Re-audit trigger: the facet names a lifecycle edit as yours that you did not make (another writer changing lifecycle without journaling), or a real issue above a floor loses its page. |
final |
| 2026-10-03 |
Amended on the operator's ruling of 2026-10-03 on the vault growth audit: an entity page needs two sources, a number and a version the repository had, and one name per repository. The audit (projects/agentm/research/vault-growth-audit-2026-10.md) found 278 of 702 pages at exactly two mentions, 101 of them from inside one task's folder; 24 issue pages for numbers that were never issues (listing and pest-report numbers under home-tools, a CSS colour under the blog, dev-setup#17 in a repository with two issues); 22 release pages for versions never tagged (ROM dump versions under movies-tv-games, agentm versions that were never releases); and two repositories paged under their old names as well as their new ones. The bar now counts sources, with a task folder as one; the repository's clone bounds its issue numbers and lists its releases; and former_names folds a renamed repository into one page. Planned against the live index on 2026-10-03: 702 pages become 566. The body above is reconciled (task 186). Why not a flat bar of three: it removes 278 pages, among them 25 repositories the vault names in two separate places, and still pages a bare number two tasks repeat. Why the clone and not a list of which projects take issues: the clone is evidence the vault already points at, it needs no upkeep, and it catches the version that was never tagged as well as the number that was never an issue. Re-audit trigger: a real issue or release that a note names and whose page does not appear, or a project whose code_paths does not hold its clone. |
final |
| 2026-10-03 |
Amended on the operator's ruling of 2026-10-03 on the vault growth audit: a roadmap's numbers and a colour are not issues. The audit (projects/agentm/research/vault-growth-audit-2026-10.md, rows 2 and 3) found about 49 issue pages for roadmap item numbers โ agentm#15 listed 31 notes about "ROADMAP item #15", a number that is also a real pull request โ and pages for a CSS colour and for listing numbers. The extractor now leaves a bare #NN unqualified after a roadmap word or at six digits and more; it is still indexed for search and never paged. The body above is reconciled (task 186). Why a word list and not the number's size alone: agentm's roadmap items and its pull requests share the same range of numbers, and only the word before tells them apart. Re-audit trigger: a page for a roadmap number after the next reindex, or a real issue written after one of the words and missing its page. |
final |
| 2026-10-03 |
Amended on the operator's ruling of 2026-10-03 on the vault growth audit: the facet names a hand-edited note once. A note whose lifecycle you edit stays a touch on every night after, because nothing journals the edit, and the facet named it every night: the 2026-09-30 and 10-01 facets carried the same five lines. The facet now names it on the first night only, by reading what the earlier facets named (task 186). Why not journal the edit as yours, as the paragraph above says the night does: the lifecycle pass never has, and the standing touch is what keeps the night from re-sinking the note; journaling it changes when notes sink, which is its own decision. Re-audit trigger: the lifecycle pass starts journaling hand edits, which makes this filter redundant. Superseded on 2026-10-04 by the row above: the pass journals the edit, and the facet reads the journal. |
final |
| 2026-10-03 |
Amended on the operator's ruling of 2026-10-03 on the vault growth audit: replies the filter missed, and a removed card that came back. The audit found the idea lane still filing chat replies after the 2026-09-28 filter ("1. agree, 2. private on github okโฆ", "ack on the minor follow-upโฆ"), and a mined reply the night deleted on 09-16 filed again on 09-28 by a second pass over its transcript, because "already captured" looked only at what was still on disk. The reply rules now take an ack/agree opener and a numbered answer list; the bare "follow-up" marker is retired (plan 13's census: it fired on 62 of the miner's 69 idea cards, 7 of which were kept); and the route pass keeps a filed-ledger in the engine's state directory. This is the narrow half of #676; the rebuild (mine every session, judge every night) stays open (task 186). Why key the ledger by slug and first line, not slug alone: two different captures that slug alike are two notes, and the miner's own test holds that. Re-audit trigger: #676's nightly judge lands, or a reply shape this misses is filed again. |
final |
| 2026-10-02 |
Amended on the operator's rulings of 2026-09-11 and 2026-10-02: the line stops just over, and four classes are never offered to enrichment. The two sentences the plan-04 close-out owed to Dreaming. The budget paragraph now says the batch reads its spend only between cards, so the last card to start under the line finishes over it, with no reserve. The enrichment paragraph now says the pass walks only the class directories the contract routes a memory type into, and keeps episodic/, entities/, crystallized/ and mocs/ out on purpose: traces are records, and the other three are written by their own builders from notes the pass already judged. The code had said both since 2026-09-11 (enrichQueueDirs, ForbiddenDirs); the design now does too. Why not open the four up: a model rewriting generated text spends the night's line on the system's own output. Re-audit if a memory type is ever routed into one of the four, or if a reserve is ever wanted below the line. |
final |
| 2026-10-02 |
As built, task 182 closed. All six reversals ship as amended above. That is PRs #796, #798โ#803, #805 and #823, deployed at f26955f6. Live repairs ran through the journal: 38 cards were re-stamped; the recheck of 31 lessons released 76 links ($8.13); 31 lessons got their released sources back as provenance; and 31 aliases were restored on 11 notes. The canary was marked an instrument and pinned. The retrieval gate on the live vault reads R@5 0.651, clean against the 2026-09-19 baseline. The four questions it still misses are named in scripts/health/fixtures/week1-gold/REPIN-QUEUE.md for the next re-pin, and none of them is a defect this task left open. Two things are left to time. An entity page skips enrichment's updated only once the note's new enriched column fills, at its next index. Nine aliases from the 2026-08-08 cold backfill remain on 2 notes under never-remove, for you to rule on. Re-audit trigger: the gate's next miss that REPIN-QUEUE.md does not explain. |
final |
| 2026-10-01 |
Amended for task 182: a lesson keeps the sources a recheck released. On the operator's ruling of 2026-10-01, a card the recheck finds a lesson is not true of loses its stamp but stays in the lesson's consolidated_from and "What taught it", named in the lesson's new released: list. The recheck had taken it off the lesson too. On 2026-10-01 that emptied ci-green-closes-work, released by all five of its cards, leaving a pinned lesson with no provenance that the vault gate refused. -restamp skips a released card, so the two tools cannot cycle. A one-time pass gave 31 lessons back what the two rechecks had removed. Why not retire a lesson that rests on none of its sources: the lesson is permanent learning and changes only by a later lesson or your edit. The recheck judged that the cards are not subsumed by it, not that it is false. Why not undo the release: the cards would rank ร0.30 beside a lesson that does not answer for them, and the next recheck would release them again. Re-audit trigger: a lesson whose every source is released, read by you. |
final |
| 2026-10-01 |
Amended for task 182, step 2: a card names every lesson it rests on. On the operator's ruling of 2026-10-01, consolidated_into is one link, or a list when several lessons rest on the card. The first two crystallize runs put 28 of the 47 cards their lessons list into two to seven lessons each. A run reads its candidates once, its clusters overlap, and the single stamp kept only the lesson written last. The recheck had asked each card only about that last lesson, and enrichment had then dropped most stamps. Reconciled in Consolidation leaves the sources where they are above: a card is demoted beside any lesson it names, the recheck releases one lesson at a time, and -restamp gives back what a rewrite dropped. Why not one lesson per card: choosing would take a card off the provenance of lessons it really taught, and it costs a model call per card for no ranking gain. Why not leave the multi-lesson cards unstamped: they would rank at full weight beside lessons that rest on them, the defect the stamp exists to prevent. Re-audit trigger: a card naming a lesson whose consolidated_from no longer lists it, or a lesson listing a card that names none. Prose pass: Claude-only; the cross-model pass leaked a fact-guard line twice and was not applied. |
final |
| 2026-10-01 |
Amended for task 182: what a nightly pass must not undo, and when a demotion applies. Four changes, each reconciled in the body above. First, on your ruling of 2026-10-01 (#778), a source a lesson rests on ranks at ร0.30 only in a result list that also holds the lesson, and enrichment carries consolidated_into, which it had been dropping: on 2026-10-01, 111 lesson-to-card links across 37 cards had lost their stamp. Second, the project-activity multiplier is read at query time, and only work moves last_worked; eight of thirteen projects read 2026-09-25, the date of a generated blueprint.md. Third, an entity page dates a mention by the note and never by the file, so the task-177 move no longer reads as dev-setup work on 2026-09-28. Fourth, the night embeds before the retrieval gate, and enrichment and dreaming leave the eval's canary alone. The evidence is the retrieval investigation of 2026-09-29 to 2026-10-01 and its adversarial review. Why not a milder weight for every stamped card: it would still sink a card whose lesson never surfaces, and still let a card crowd a lesson that does. Why not count every file write as activity: a migration then reads as a month of work on every project at once. Re-audit trigger: a stamped card ranking above its own lesson in one result list, or a gold-set miss whose expected card carries a stamp from a lesson that does not answer its question. Prose pass: cross-model, fact-checked. |
final |
| 2026-10-01 | Amended for task 181: the night pays only for judgments whose inputs changed. Four changes to Dreaming, reconciled in the body above, with the stamp sentences in The card and the fingerprint key in Capture to match. First, a judgment is keyed to a judgment hash over the contract fields enrichment reads, in place of the hash of the whole contract. Second, the night takes the notes it owes by cause, least recently judged first among the stale. Third, the ledger moves out of the index into a file of its own and survives a schema change; a row follows its note through a move, and the notes' stamps rebuild the ledger only when its file is lost. Fourth, a re-judgment with the same answer writes nothing to the note. A defect fixed alongside, #785: a gate's skip had replaced a note's finished judgment in the ledger, so the fingerprint gate's own "already enriched" made the note owed again the next night; on 2026-10-01, 44 notes stood that way. The evidence is task 180's measurement: about $75 of $197 over nine nights bought stamp-only re-judgments, 84% of them after a contract edit. Why not order the batch alone: a contract edit enrichment never reads would still re-judge every note, only more slowly. Why not hash each class's own rules: the prompt shows every note the whole list of memory types, so a per-class hash would miss what the model was shown. Re-audit trigger: a contract edit to a field enrichment reads that leaves a judgment standing, or stamp-only rewrites above a few a night. Prose pass: cross-model, fact-checked. | final |
| 2026-10-01 | Amended as task 180 shipped: a move keeps the note's identity. The journal moved a note by writing it at the new path and deleting the old one, so Drive for Desktop, which mirrors the vault, uploaded every move as a new file and trashed the original; Plan B's 675 moved task files reached every synced device as new downloads. A move is now a rename, reconciled in Data Integrity above, and the first live night's three moves kept their Drive IDs. Why not a hard link then unlink: a sync client can read that pair as a create plus a delete, the defect itself. Re-audit if a sync client is seen treating renames as a delete plus a create. | final |
| 2026-09-30 |
Amended from the review of task 178 (Plan C). Three corrections to how a note learns its project, each reconciled in Projects and tasks above. First, a trace whose session opened in a desktop scratch workspace and moved into its repo was left unlabeled: the binding read only the first folder in the transcript's head. Four of nine traces since the writers shipped were pixelcity sessions of that shape. The binding now takes the first folder that binds, then the folder the host filed the transcript under. Second, an untyped capture defaulted to preference and so skipped labeling; only a type the writer named exempts a note now. Third, the step-10 backfill labeled three cards home through [[tracker]], [[conventions]] and [[plan]], which sit in many projects; a link to such a file name now leaves a card unlabeled. One manifest (plan-c/2026-09-30-relabel.json) labeled eight traces and took the three wrong labels off. Why not match a plain dash after a code path in the folder name: the name spells / and - alike, so pixelcity-poc would read as under pixelcity; only the path itself or a dot-directory under it (a worktree) binds. Re-audit trigger: a new trace from a registered repo with no project, or a link-labeled card a reader corrects. |
final |
| 2026-09-30 |
Amended for #749: a lesson stamps only the sources it rests on. The first crystallize run stamped every source in a cluster, so a card that shared the subject and not the lesson was ranked x0.30 below a lesson that does not answer it; nine frozen gold-set questions lost their note and R@5 fell 0.667 โ 0.540. The model now names the sources each lesson rests on and only those are stamped and listed, and agentmd crystallize -recheck put the same question to the 18 lessons already written: 25 stamps across 13 lessons were released through an agentmdream apply manifest, nothing deleted. Where a lesson is true of a gold card, the retrieval eval accepts the lesson as the card's successor from a hand-verified table, taken only while the card still names it; R@5 0.635 and the gate clean. Why not infer the successor from the stamp: the system under test would be writing the answer key. Why not spare a consolidated card whose lesson is not in the results: it changes this design's x0.30 rule in both arms and needs a reindex, and two correctly folded cards (pp10, rc11) are the whole of the evidence so far; left to the operator. Re-audit trigger: a gold question lost to a stamp the recheck keeps, or a second weekly run whose recheck releases more than one stamp in ten. |
final |
| 2026-10-03 |
The reference library gains briefs/ (task 185, step 3; the operator's rulings of 2026-10-02). The weekly field brief writes resources/briefs/<YYYY-MM-DD>-field-brief.md, a kind: brief record (a registered record kind: it carries kind: and no type:), at most ten items a week. The layout block, the shared-spaces paragraph and the desk-files sentence now name the folder and the operator's desk/field-brief.md, and the contract's dampened_spaces gains resources/briefs, mirrored in the live contract. Why dampen it: a brief is a digest of external links nobody has reviewed, which is what the watchlist it replaces was; undampened, months of weekly notes about agent memory would answer questions about the operator's own memory work. A link worth keeping becomes a card through field_brief.py keep and ranks as one. Why only briefs: dampening all of resources/ cost seven of ten gold questions their reference card (the 2026-09-25 row). Re-audit trigger: a brief ranking above a memory on a question that was not about it, or the operator keeping so few items that the folder is noise; revisit whether it should expire. |
final |
| 2026-10-03 |
The reference library loses its watchlist (task 185, step 1; the operator's rulings of 2026-10-02). resources/ no longer holds watchlist/<source>/: the 113 entries and the sources file moved under the project's completed/ folder, nothing deleted, and the contract's dampened_spaces loses its one resources/ line, so the library ranks as any note does. The layout block, the shared-spaces paragraph and the desk-files sentence are reconciled; the dated rows below keep what each ruling said that day. Why not leave the entries in resources/ undampened: 113 unreviewed papers and posts would have ranked beside the cards a question about their topic wants, and completed/ already ranks finished work lower. Re-audit trigger: none of its own. |
final |
| 2026-09-30 | Amended on the operator's ruling of 2026-09-30: a query that names an entity puts its page first. The 2026-09-29 row had entity pages rank on their own content, and the first live build showed they cannot: 576 issue and release pages each carry their repository's name, and "alexherrero/crickets" put the repository's page 107th lexically and outside the top twenty in every mode. Measured on a copy of the index, shorter titles (103rd), a compact page (101st) and a higher bar (15th at ten mentions; agentm's page 76th) did not fix it, and dampening issue and release pages reached crickets but not agentm, which about 2,000 notes name. The rule matches the query, or what follows a question frame, against a page's title, aliases and id; every other query ranks as before. The body above is reconciled. Why not dampen issue and release pages: it still left the busiest repository's page out of reach. Re-audit trigger: a question asked by name that misses its page after a month of use. | final |
| 2026-09-29 |
Amended on the operator's rulings of 2026-09-24 on the work agent's AgentKV layout convergence spec, section 5, and the three choices of 2026-09-28 (task 179, Plan D). Three reversals, each reconciled in the body above. First, entities/ returns in four folders by type, repos/, issues/, releases/ and people/, where session 1 said it would return flat per Filing v2's D7. Second, people are found across the vault, personal/ included, where the person class was held for email ingest; mail becomes a source of shared-work evidence behind daemon.people_email_evidence_enabled, off. Third, entities/ has one writer, a free nightly builder, where a hand-written note there was a card. The rulings also set the bars: two mentions for a repo, a qualified issue or a release; two shared-work notes for a person; no page for a commit or a bare #NN. The nightly enrichment adds people:. Checked against what Plan C shipped, two premises moved and the build follows them: a bare #NN is qualified by the note's place before its project: label, because 2,145 of the 2,422 bare mentions sit in unlabelled task files; and the builder matches the names enrichment finds across every note, because enrichment never reads trackers, plans or progress logs. Why not the AgentKV spec's pages for every entity it extracts: a commit or a bare number is never asked about by name, and a page for every person the vault names would bury the few you work with. Re-audit trigger: a person's page that comes and goes night after night, or a people page naming someone who is not a person. |
final |
| 2026-09-29 |
As built, task 178 (Plan C). Three corrections to the 2026-09-28 row, each reconciled in the body above. First, restated rules are judged, not lined: calibration on the live corpus put the known restated pair ninth by embedding similarity (0.794), below eight pairs of distinct rules, and on your ruling of 2026-09-28 the similarity shortlists and the strong tier decides. Its first run called the known pair the same and the other 24 different. Second, "the same source" is the same source and title: one source yields several memories (an article's facts share its address, a message mined into cards shares its id), and keying on the source alone would overwrite one with the next. Third, the one-time cleanups ran through a new agentmdream apply, which journals a manifest planned in Python. Why not raise the line until only the known pair passes: at 0.80 the known pair (0.794) falls out and seven distinct pairs stay in. Re-audit trigger: an automatic merge you undo, or a re-captured page that arrives under a changed title and files a second note. |
final |
| 2026-09-28 |
Amended on the operator's rulings of 2026-09-24 on the work agent's AgentKV layout convergence spec, sections 6 and 7 (task 178, Plan C). Five reversals, each reconciled in the body above. First, one outside source is one note: ingest stops writing chunk notes, the index embeds a long note as several chunk vectors, and a second capture of the same source_id or source_url updates the note in place; this reverses the capture design's "both forms of the article". Second, restated convention, preference and workflow notes merge on their own by supersede, keeping the newer wording, where twin review had been yours alone ("merge by hand, or write superseded_by"). Third, capture may add to an existing idea card under ## Added by capture, where only the night wrote an idea card's body. Fourth, a note's project comes from the code_paths of projects/*/project.yaml, where it came from the repo's project.json alone, and conventions and preferences stay unlabeled. Fifth, the twin detector covers memories only, where it walked the whole vault and listed 61 report pairs. The same rulings settle two more duplications without reversing anything: a session keeps one trace, found by its session: id, and a reply typed to the agent is not filed. Why not AgentKV's 72-character title auto-merge: it would catch one pair in the live corpus, and the survey found six kinds of duplication with six causes. Why supersede and never delete: a wrong merge is undone by removing one field, and git keeps the older wording. Re-audit trigger: an automatic merge you undo, or dense recall on a long article falling after the chunk notes retire. |
final |
| 2026-09-28 |
Amended as task 177 released: a crystallized lesson is a record, not a card. The crystallize paragraph said a lesson was "a card in session 1's shape" with why in its frontmatter; the contract names crystallized a record kind, and a record never carries the card's judgment fields. The first funded run wrote 42 lessons in the card's fields and both vault gates refused them, so the writer now writes the record and puts the phase's reason in the body. Why not keep why in the frontmatter: it would make the one record kind that carries a card field, and every gate that reads the record shape would need an exception for it. Re-audit trigger: a reader that needs a lesson's reason as a field rather than from its body. |
final |
| 2026-09-27 |
Amended on the operator's rulings of 2026-09-24 on the work agent's AgentKV layout convergence spec, sections 2 and 4 (task 177, Plan B). Two changes, each reconciled in the body above. First, section 2: a closed task's folder moves from projects/<slug>/tasks/ to projects/<slug>/completed/tasks/ fourteen days after its tracker reads done or dropped, the contract's new task_completed_after_days: 14. The night journals the move, rewrites the links into the folder and the moved notes' own relative links, moves a folder whole or not at all, and holds back any folder whose rewrites would reach personal/ or standards/. Every reader that finds a task by its name looks in both folders, and reopening a task is a hand move back. This reverses session 5's rule that a task directory stays under tasks/ for the life of the project. Second, section 4: crystallize reads Outcomes from both folders and writes no per-task harvest note, and the phase is switched on after one run funded to finish, its weekly budget: provisional until you set the lasting one from the average. Why not leave closed tasks where they are: some 270 finished task folders sat beside a handful of live ones, and a finished plan ranked like live work. Why not session 4's archive/tasks/: it was a second folder in every project, and completed/ is already the one place a project keeps finished work. Why not a harvest note per task: a lesson is what recurs, and one task cannot show that. Re-audit trigger: a gold question whose answer is a closed task's plan leaving the top five after the move; a folder held back for more than a week; or the first three weekly runs writing no lesson. |
final |
| 2026-09-25 |
Amended on the operator's ruling of 2026-09-25: only the watchlist in resources/ is dampened. The 2026-09-24 ruling put all of resources/ in dampened_spaces, expecting a card to rank low unless the question was about its topic. The ranker's dampening is unconditional, so after the move (task 176 step 8) seven of the ten gold questions that ask about a reference card (rd02, rd03, rd05 to rd08, rd10) lost their card from the top five, and check-retrieval-regression failed (R@5 0.667 to 0.492). The contract now dampens resources/watchlist only; the topic cards rank as any note does. Why not re-pin the baseline and keep the blanket dampening: it would accept losing the very answers the ruling wanted kept. Why not topic-aware dampening now: it is a ranker change outside Plan A; it is filed as a backlog item. Re-audit trigger: a topic card crowding an everyday query, or the topic-aware dampening landing. |
final |
| 2026-09-24 |
Amended on the operator's rulings of 2026-09-24 on the work agent's AgentKV layout convergence spec, sections 1, 3 and 8 (task 176, Plan A). Five reversals, each reconciled in the body above. First, two new root spaces, both shared: resources/ (topics, watchlist, university; dampened) and systems/ (homelab in full, one-page front doors for agentm and crickets); the layout had five root spaces. Second, the watchlist leaves projects/agentm/_watchlist/ for resources/watchlist/, reversing session 1's "that repo's feature state". Third, the project root locks to five files โ project.yaml, charter.md, blueprint.md, tracker.md, moc-<slug>.md โ and any other new root file answers Alignment; this reverses the door's "as many root documents as it needs, with no cap" and session 4's skeleton, whose followups.md and roadmap.md move to docs/, and the config and source lists to desk/. Fourth, the grounding config is project.yaml, not the JSON the 2026-09-17 ruling named. Fifth, the project tracker is a checklist the nightly mocs job generates from the task trackers, not a summary the opening and closing session rewrite. standards/ gains templates/, kept out of every ranked arm. Kept as they are, by the same rulings: storage-rules.md in standards/, the index and the heat and lifecycle state outside the vault, the calendar shared, and no generated map at the vault root. Why not AgentKV's target tree wholesale: four of its items would have moved what already works โ the contract, the index, the calendar's authority and the root map โ and none of the four fixed a problem this vault has. Why lock the root rather than cap it by count: a count says how many, and the front page is about which. Re-audit trigger: you allowing the same sixth root file in more than one project; resources/ outranking a memory on a question that was not about its topic; or the generated project tracker outgrowing the twenty-line brief. |
final |
| 2026-09-23 |
Launched with agentm v10.0.0, the arc-closing release. Parts 00 to 16 have all shipped, and the version (GH #609) and feature (GH #610) are closed. The coalescence checklist ran before the tag. Its orphan census found one gate built and never wired, check-memory-skill-table, which now runs (PR #690). The release review found four resolver defects, fixed in PR #691. Still yours: the six notes in the home project's plans/ folder that carry kind: plan, which a plans/ folder cannot keep under this design. |
launched |
| 2026-09-23 |
Amended on the operator's rulings for the standing vault findings. A tracker may carry sensitivity: the home project marks 32 notes personal-financial, and its trackers carried the line the schema refused. scripts/tracker.py now reads it, writes it last and keeps it through every step, and never sets it. The contract registers two record kinds the projects space already carried, how-to (a project's runbook) and proposal. Task files lose kind:, because a task file is known by its place. Why not drop the marking: it is how you mark the notes that hold your finances, and a tracker without it would be the one note in the project unmarked. Re-audit trigger: a pass starts reading sensitivity to decide anything. Today it is a label only. |
final |
| 2026-09-23 |
Amended as part 15, the _harness/ retirement, landed (agentm-vault plan 15, PR #679 and PR #680; the project-homes verbs, PR #681 and PR #686; crickets v4.0.0 and v5.0.0). The paired repoint now dates the retirement of the resolver's fallbacks. A new paragraph, Every plan lives in its task, records the three rulings of 2026-09-14 that the part carried: no plans/ folder, with an arc as a design; a task named by its directory; and a bare command that asks. It also records the Status line coming off 284 plans, the slug readers that never place, and the gate and the doctor row that keep the old path gone. ยง Launch Plans gains the part's row. Why in the body rather than only in the plan: the plan is archived at close, and the rulings govern every later task. Re-audit trigger: harness-dirs finds a _harness/ again. |
final |
| 2026-09-21 |
Amended by the operator's seven rulings of 2026-09-20 for part 13, the ideas surface. area: takes the operator's own group names, starting from home-tech, coding, agentm, blog and other, and no closed list enters the filing contract โ the generator heads whatever values exist. The session proposes each card's group in one mapping the operator corrects, and the nightly reviewer proposes nothing, its instructions unedited (the pass version stays 5d3a4cca1b02). The night never re-grades a filed idea: status, filing confidence, title and type are the card's, no lifecycle is written or defaulted, and the card is never renamed; area and dismissed join the fields every rewrite carries. Ideas.md is written only through its markers, and the first rewrite is one deliberate adoption after a dry run. An idea is filed from the inbox with its group, which replaces "a mailed idea lands as a card" โ the door retired in part 16. A note typed idea that is not one is relabelled when it holds something real and otherwise deleted on a confirmed count; a duplicate stays in place, superseded. The ledger's own machinery retires โ ideas_surface.py, ideas_promote.py, incubator_lint.py, the sweep's fold, the briefing's ledger nudges and IDEAS_SURFACE_PATH โ while the incubator skeleton and its researcher, which never touch Ideas.md, wait on their own follow-up. Why not let the night propose the group: a group is the operator's word for where they look, and a proposal a model writes every night is a proposal the operator corrects every morning. Why a byte-for-byte head rather than re-rendering the preamble: re-rendering is how a preamble drifts, and copying cannot. Re-audit trigger: an idea card found re-graded or renamed by any writer, or a new idea card appearing in memory/semantic/ โ two writers (the reflection's idea lane and memory_capture of type: idea) still aim there, pending the operator's ruling. |
final |
| 2026-09-20 |
Amended after the inbox's write path was tested: one surface of the three can use it. Part 16 shipped with its central question open, by the operator's ruling to delete the door first and prove the write afterwards: DriveFS reporting MIRROR proved this laptop syncs up, and said nothing about whether a chat surface's connector could create a file inside a Computers-mirrored folder. claude.ai answered it โ a card it wrote arrived in agent/inbox/ and read correctly at review, unfiled and quoted behind the gutter. Gemini cannot use the path in a Gem or out of one: a Gem does not inherit the main agent's Drive access, and the bare agent, asked to create one named file in one named folder with no alternative offered, answered that it cannot create files in Drive. Claude Code's cloud agent stays reasoned but untested, by the operator's ruling. So the rejected alternative a Gem that hands you text to paste is reversed into the Gem's only path, the write rule is restated as a boundary rather than a list of surfaces โ one folder, however a card reached it โ and the Gem leaves the paste's targets. The part's verification criterion, a card from each of three surfaces, is left standing with its partial falsification recorded beneath it rather than narrowed to the surface that passed. Why not a shorter paste for Gemini's smaller personalization box: an instruction box changes behaviour, not permissions, and no wording reaches a tool that is not there. Why not keep the Gem as a target and let its paste fall back: a target that can never take the path it is given teaches every reader of the template that it can. Re-audit trigger: Gemini gaining a Drive file-create capability โ the paste would need one sentence, and the one-turn probe that settled this is in the task's handoff.md. |
final |
| 2026-09-17 |
Amended as the projects migration landed (agentm-vault plan 10, PR #650, PR #651, PR #652 and PR #653). _harness/ is gone from every project: 903 files moved once each by the table into 292 numbered tasks, each with a plan, a progress log and a tracker in one of the five statuses, beside eleven charters, completed/ at both levels, ledgers in desk/ and the diary facet. The project skeleton and A session opens on twenty lines are reconciled above: no project keeps a tracker.md, because the operator ruled on the day that a project's tracker, charter, blueprint and grounding config are a separate plan. Why the basename rewrite was not enough: it matched [[PLAN-foo]] alone, so 184 links written as a path, as a shared basename or as a relative link inside a moved note stayed broken, and the link check could not see them because it resolves a wikilink by basename and skips tasks/; they were repaired from the run's own journal, and a resolver that reads the files before and after the move is the instrument that proves it. Why finished tasks leave the listing by their tracker: a task never moves, so nothing else says the work is over. Re-audit when the project-documents plan lands, since it defines the tracker this design still names in the skeleton; and when plan 15 retires the _harness/ fallbacks, since /orient on a project with no repo checkout still composes one. |
final |
| 2026-09-14 |
Amended as a tracker gained a rewrite under its own status (agentm-vault, the tracker rewrite, PR #646). Five statuses, and what each transition writes now says each later step rewrites State and Next under active. tracker.py transition takes a queued, active or parked tracker's own status as that rewrite: it names State, Next or both, stamps updated, and never writes the Outcome or closed. A rewrite that names neither section, or names an Outcome, is refused, and done and dropped are never rewritten. The five statuses, the transition table and the two final statuses are unchanged. Why not a separate update verb: your ruling of 2026-09-14, so that crickets writes every step, the status changes and the rewrites alike, through one command, tracker.py transition. Re-audit if a caller needs a rewrite that does not stamp updated. |
final |
| 2026-09-14 |
Amended as the root casing landed (agentm-vault plan 08, PR #636 and PR #643; crickets PR #252, released as v3.38.1). The four root spaces are agent/, calendar/, personal/ and projects/ beside standards/, renamed on 2026-09-14 by scripts/migrate/root_casing.py under quiesce, each through a temporary name in one git mv two-step so the index moved with the tree (442, 5, 1,552 and 1,468 tracked files, none left under an old name), with a pause between roots for Drive. As built: check-no-title-case-roots keeps the retired spelling out of the code (the path form anywhere, the bare quoted name in code, comment lines skipped; the wiki, the changelog, _harness/, the frozen health fixtures, the finished migrations and any root-casing:-marked line allowed); the retrieval eval keeps the frozen gold set's Agent/... and folds the first segment at score time to the spelling the vault lists; the root map's Calendar and Projects headings stay Title Case, being headings; the exact-name probes keep their job with a new reason, that a directory still spelled the retired way is not the root space. Crickets shipped first with both spellings on its project-space rungs, lowercase first, a rung's path handed back as the disk lists it. The contract block's three - Personal lines are plan 11's; only the prose at line 37 moved. The data run's own lessons: the index and the ledger are keyed by the relative path, so agentmd reindex comes before the ledger rebuild and the forgets, or the night reads as owing nothing (the runbook now says so); the marker agent/memory/.root-casing-complete needed the shape gate's tolerance, found by the first battery after the run and given in #643; the link check read identical before and after (1,326 findings, none new); the retrieval gate stayed clean, with one question, pp18, moving from a hit to rank 13 because the dense arm re-embedded every note, its 149 KB progress.md re-chunked, not because of a spelling. Why not rewrite the 133 path-qualified links: 44 already pointed at retired layouts, and the 89 that resolve keep resolving, since Obsidian resolves case-insensitively and the lint falls back to the basename; a class card rewritten is a light pass owed. Why lowercase-only in agentm, both spellings in crickets: the vault and the code deploy in one quiesce here, while crickets serves other vaults from its installed copies. Re-audit trigger: Drive showing a duplicate folder after the rename (the operator's web-view check is still owed); a reader appearing that composes a Title Case root from a group value stamped before the rename; or the owed deep and light counts moving on the night after. |
final |
| 2026-09-13 |
Amended: a feature's state has no fallback to memory/ any more. The trims moved the two watchlists and the three settings files into projects/agentm/, but readers and writers still took the retired memory/<name> when it existed and the project copy did not, so a vault in that state had new watchlist entries written into the retired home. feature_state_candidates() now offers only the project spelling, to readers and writers alike: the rule that both resolve through one function still holds, and the retired home is neither read nor written. check-memory-root-shape.py reported the live vault clean before the change, and still names a retired location that comes back. The adapt-evaluator agent's write target moves from personal-private/_skill-watchlist/ to Projects/agentm/_skill-watchlist/. Why not switch only the writers: the first write would create the project copy and hide whatever a reader still found in memory/, the split the one-function rule exists to prevent. Re-audit if a vault that never ran the trims migration has to be read again. |
final |
| 2026-09-13 |
Amended on two rulings from the plan 07 review (follow-up (b)). A type's page no longer outlives its type. When a type falls below moc_min_members, the nightly pass removes the page it wrote for that type. The removal is a journaled delete that keeps the page's bytes, and moc-memory.md lists the type's notes in full. It removes only a page carrying type_of_members for that type, and nothing when no note is typed at all. A week or month review now needs a facet note that holds a timed entry or prose beyond the daily template. A day of prose alone is listed without an entry count, and a daily note opened from the template and never written in is not content. Why not keep a below-floor page current: small pages would gather as types shrink, which is what the threshold exists to prevent, and moc-memory.md already lists a small type in full. Why not require a timed entry: the Obsidian daily note is the diary facet, and a day written in prose is a day with something in it. Re-audit if a type crosses the threshold often enough that its page is removed and remade week after week, or when plan 10 wires the diary facet and its template changes. |
final |
| 2026-09-13 |
Amended as plan 09 built the projects writers. A project record's frontmatter is merged rather than rendered, as Dreaming enriches a card beyond what the session had now says: the pass sets its retrieval fields and adds its tags and aliases, keeps every field the record's writer gave it, writes no filing verdict and never renames the file. A tracker written before the migration sits beside its flat pair as tracker-<slug>.md (tracker.md beside the singleton), so the move table in _harness/ dissolves moves it rather than writing a second one. The session's project lifts its cards by damping every note it does not match to ร0.80, inside the multiplier the ranker already applies, which ranks a matching card ร1.25 against an equal one. The completed segment ranks in the index's arm only for now: the in-process arm walks the memory root, where no project's completed/ sits, so its mirror lands with the axis per space. The projects space's maps follow the body. A project's map counts its research per bundle rather than listing every note, so agentm's 233 research notes keep its map to one page, and it dates a record by created, so the enrichment stamp on updated does not reorder the map. Why not render a card over a record: a card render drops the twelve kinds of field the 291 records carry, a research bundle's source_url and fingerprint and a charter's kind among them, and a record is not filed. Why damp the others rather than boost the match: the clamp that keeps a penalty from promoting a negative score assumes no multiplier above 1.0. Re-audit trigger: an added section longer than its record, or a bound session whose own project's card still loses to an unrelated one. |
final |
| 2026-09-13 |
Amended as the maps and root notes landed (PR #620, PR #622, agentm-vault plan 07). Home.md retired, Filing.md folded into index.md, and the twelve numbered map pages went. As built: a type's page appears at the contract's moc_min_members of five and paginates into sections sized by moc_split_at, never a second file; moc-memory.md lists every type, by its page's link at or past the floor and with its members in full below it; moc-root.md lists every area map it finds, including each year's calendar map and the moc-*.md in diagnostics/, standards/ and Projects/, and is rewritten only when that list changes. group: drops from generated maps and stays on the calendar reviews. mocs/_index.md stays as the class directory's index record. A week or month review's day lines link each facet note of the day, never the bare-date day index, on the operator's ruling of 2026-09-13. _daily-template.md stays at the calendar root until plan 10 wires the diary facet, and the calendar gate allows it and a bare-date day note there until then. The unverified-edge marker stops being written instead of moving into review_flags. Why not keep group: on the maps: no reader tells it from its absence on a generated page, and the reviews keep it because the recorded Python parity pins their bytes. Why not route the marker into review_flags: it named no action a reviewer could take, and the refile job drops the whole review_flags key when a near-duplicate's twin vanishes. Why not keep linking the bare-date day: a day note that arrives by a move never gets a day index, so the link dangled, and the maps data run refused to finish on it. Re-audit if the root map grows past a screen, if a reader of group: on a generated page appears, or when the day-index writer, calendar_index.py, which still runs on facet appends, is retired. |
final |
| 2026-09-12 |
Amended as the card backfill's link rewrite narrowed before its data run (PR #605, agentm-vault plan 06). Every occurrence the merged migration planned to rewrite was read against the live vault before it ran. As built, renaming a counter slug rewrites links only in the navigation spaces, Agent/ and Calendar/, and repoints a path only where it names the renamed note under memory/<class>/ in the note's own class; a record under Projects/ or Personal/ keeps the name it was written with. Why: the reading found two harms a stem-wide rewrite would cause โ it would have edited ten project-space records, purge manifests and labelling results among them, that name what was measured under the old names, and it would have repointed a renamed card's own derived_from: [personal/_inbox/<stem>.md] at an inbox path that never existed. Why not rewrite every occurrence of the stem vault-wide, as planned: that rewrites history in spaces this design keeps permanent, and invents paths that were never real. Re-audit if a link in Agent/ or Calendar/ is ever found still pointing at a pre-rename name, or a project-space note starts navigating by a card's path. |
final |
| 2026-09-12 |
Amended as the card backfill landed (agentm-vault plan 06). The card's order has one definition on each side, every writer of a class card applies it, and three gates hold the corpus to it. As built: lifecycle_since sits beside lifecycle; filing_confidence is medium where nothing was ever scored; a card no pass has judged may wait for the deep pass's title; created takes the earliest evidence rather than captured alone; a project-space entry keeps group; review_flags kept its readers and excerpt_edges_unverified retired; a writer grows a taken name by the note's own words; the backfill names what it stamped in backfilled: and never writes the enrichment stamps; the six empty lane directories went. standards/ may hold a convention you confirm through the wiki plugin as a further file. Why not high for a card nothing scored: it would claim a judgment no pass made. Why not lifecycle_since beside related: the Go lifecycle job, its Python twin and the enrichment render all wrote it beside lifecycle, and the dreaming parity recording pins that. Why not trust captured alone: the ingest sweep's restamp had moved it to later writes on unfiled cards. Re-audit when a new writer of class cards lands, when the deep pass has judged the title-less cards, or when no reader of a project-space group is left. |
final |
| 2026-09-11 |
Amended as the cheap-tier audit was built (#598). The light pass's audit is no longer free: the stamped answer on disk is the deep pass's, post-gated and carried, so the strong tier is asked the light-pass question again beside the cheap tier, three calls per card. Agreement is a model's judgment rather than a string comparison โ the operator said they are a poor judge of it and asked for Fable: a judge is shown the card and both answers and says whether they would file and rank the card the same way, with a reason the report keeps on every disagreement. The cheap model is named at invocation (--cheap, or daemon.cheap_model) and never defaulted; Haiku 4.5 is the proposed candidate. The judge is a flag (--judge, default claude-fable-5-1). The command projects the calls and their cost and stops without --yes; every run lands in tier-audits.jsonl beside the enrichment record. Why not compare the JSON fields mechanically: a summary agrees when it says the same thing, and two tag lists can name the same things in different words; a byte rule would fail a cheap tier for its phrasing and pass one for its punctuation. Why not the operator as judge: they said so. Re-audit when the judge's reasons stop naming what would file differently, when a second job is audited (the judge's question is written for the light pass's fields), or when a cheap model is set in config and the equal token lines need their ruling. |
final |
| 2026-09-11 |
Amended as the operator raised the night's line and the backlog cleared (#595). The budget is one number: two million tokens a night on either tier, replacing a million strong or two million cheap. The night's allowance is therefore a count of tokens, and the tier decides what they cost rather than how many there are. Both constants stay separate so a later ruling can part them again. The first batch is recorded as it actually ran โ three invocations of one line each, 184 cards, 115 written, 46 refused, $62.80 โ rather than as the several nights it was planned over. Why not raise the strong line and leave the ratio: the ratio encoded equal money at two prices, and the operator asked for a pace, which is tokens. Re-audit when a cheap model is named in daemon.cheap_model, at which point equal token lines mean the cheap tier buys the same night for less money and whether that is the intent needs a ruling; and when a card's cost moves by more than half. |
final |
| 2026-09-11 | Amended after the first supervised batch measured two things before it wrote anything (#591, #592). On your ruling, the token line counts what a call adds: input, cache writes and output. Each call re-reads about 37,000 tokens of Claude Code's own cached baseline, so a card cost about 107,000 tokens, 74,000 of them that prefix twice. A line that counted cache reads stopped a night after nine cards of 181. A card adds about 33,000 tokens at steady state, about $0.39, and the run still reports everything it processed. The 1M strong, 2M cheap and 250-call numbers are unchanged. The Budget paragraph gives these figures in place of "a few thousand tokens a note" and "about half a million tokens", and the first batch now spans several nights under the strong line, as the first-batch risk also says. The risk's re-audit trigger now reads the new title or summary, since task 3's additive compose means a card's own text can no longer change. Two corrections from the same batch ride along. Each enrichment call now loads no MCP server, a third isolation measure beside the disabled hooks and the temporary working directory; your MCP servers had been most of the baseline, 113,509 input tokens a trivial call with them and 30,783 without. The deep pass's prose is now held to what the card and a neighbour already state between them, since the first four cards were refused, three by the grounding judge on inferred sentences and one on an alias that restated the filename; the Dreaming paragraph says so. Why not raise the line to fit the cache reads: counting them bounded a constant, and a higher line would have kept a meter that measured nothing about the night's work. Re-audit trigger: the CLI's baseline or the prompt's size changing materially, or a card's cost moving by more than half. Prose pass: Claude-only; the cross-model step degraded on its fact-guard check. | final |
| 2026-09-18 |
The sequence job is retired before its first run โ a project's documents are not numbered. It gave every file in a project's decisions/, designs/, research/ and drafts/ a three-digit prefix in creation order, so a directory listing showed the work in the order it happened. Its first run was a supervised data run by design; the operator read the report โ about 130 renames across nine projects โ and reversed the decision. The ordering is going to live in a set of sub-folders instead, designed once the series' fifteen plans are done, and a number in a filename would be a second scheme to hold in agreement with the first. No document was ever renamed, which is the whole reason that first run was supervised. sequence.go and its tests are gone; the three helpers it held that the projects pass still needs โ ProjectsRoot, relTo, and the move row, renamed from SequenceRow to MoveRow โ moved to projects_paths.go, which carries the reason in its header. The night's facet loses its ## Numbered section. Task directories keep their numbers: they are applied and lived with, and the operator held that question for the whole-layout pass after plan 15. Why not keep the job and switch it off: a nightly job expected to do nothing is a job nobody notices doing something. Re-audit trigger: the sub-folder scheme landing โ whatever carries the order then should be the only thing that carries it. |
final |
| 2026-09-18 |
Amended as plan 11's night jobs and weekly phase landed (tasks 5 and 7). The morning note now carries everything plan 04 marked pending except the mail line: the dreaming facet link with the night's counts, the two forward lists, lessons this week naming every note the weekly crystallize phase wrote, and a spend line per tier-table job. The archive-candidate list left what needs you โ the night moves those itself now, so the forward lists replaced a backlog with what is coming. The crystallize phase ships as agentmd crystallize and the crystallize-weekly runner job, registered-and-off behind its own daemon.crystallize_enabled switch, weekly, in the night window at order: 3, on the strong tier the table pins. Its bar is arithmetic and lives in code โ three sources, two sessions, seven days โ so nothing below it reaches a model and a run that finds nothing spends nothing; what clears it gets one call, and the model may answer skip. Sources that are cards are stamped consolidated_into and rank at x0.30 in both arms; trackers and traces are not stamped, because a tracker is the operator's living head with a locked schema and a trace is one session's record that several lessons may draw from. Why a verb of its own rather than a phase of agentmdream: the night's binary is free and declares no budget:, so folding a paid phase into it would make a free job a spending one with nothing in the manifest saying so. Re-audit trigger: the design's own โ after three runs, whether the phase wrote anything and what it cost, read from the morning note's crystallize line. |
final |
| 2026-09-19 |
Amended the day after plan 12 shipped: the write path is the inbox, not an email door, and the Claude Desktop surface is dropped. Part 12 built the door on the premise that a chat surface has no route to the machine. The premise was wrong and had been for as long as the vault existed: the vault root is a Google Drive mirror root (sync_type=MIRROR, verified live 2026-09-19), in Drive's Computers section, which is why it is absent from ~/Library/CloudStorage and why a filesystem check reads as "not in Drive" when it is. So a chat surface writes by dropping a card into agent/inbox/ over that mirror โ a fourth standard child of agent/ โ where it sits untouched by the sweep, enriched by the night, until the operator asks to look at the inbox and the two of them decide card by card where it goes. Nothing files an inbox card except the operator, at that pass. The rejection recorded above at "Chat surfaces write the vault through a Drive or filesystem connector" is reversed in the same change. The Desktop surface is dropped rather than deferred: a Code session on the machine already gets recall injected by hook, which beats a tool a model must choose to call, and the surfaces the operator actually uses are mobile and web, which no loopback client can reach. Why not keep the door as a second path: its whole security surface โ IMAP, TLS, the DMARC reader, the authserv-id check, the sender allow-list, the mailbox credential, nine rounds of adversarial review โ exists to authenticate a transport anyone can send to, and a Drive folder accepts writes only from the operator's own authenticated account. What the door contributed that survives is its filing half: card parsing, the size cap, trust stamping, daily_write_cap, and refusals counted rather than stored. Re-audit trigger: a Drive sync that silently stops, leaving dropped cards on the phone side with nothing on the machine saying so; or an inbox that is never drained, which would mean the review pass is too expensive and the auto-file option was the right one after all. Lands as part 16-the-inbox, sequenced ahead of part 13, which depends on it. |
final |
| 2026-09-19 |
Amended because "never indexed" was not what the code did. Lifecycle per space says the walled folder is never indexed, embedded or served, and the wall held at every door that leads to a ranked answer โ the walk, IndexFile, search, the embedding queue and the enrichment queue all refuse it, each with a test. What none of them held is the delete underneath. Delete cleared the lexical row, the vectors and the metadata row, and left the three derived tables that arrived after it was written: chunks, links and entities. Each carried a comment saying the metadata delete took its rows with it, and nothing made that true. Counted on the live index on 2026-09-19: 27,891 of 46,581 chunk rows, 11,898 entity rows and 8,145 link rows belonged to 4,209 documents that no longer existed โ the body of every note the wall removed, every note the purges deleted and every path the migrations retired, sitting in the index with nothing left to name them by. As built: one list of the tables a document owns, read by the delete and by an idempotent orphan sweep alike, so a table is cleared by both or by neither; the sweep runs in every reconcile, which is the daemon's startup pass, its five-minute pass and agentmd reindex; a link to a deleted note goes back to dangling and resolves again if the note returns; and the embedder refuses to store a vector for a document that left the index while its batch was running. The recall-wall tests now read the rows rather than asking search what it would serve, which is why they passed over this for as long as they did. Two walkers in the Python half had no wall at all: the personal-notes link audit read walled notes whole, scored them, named them in its report, embedded them into a cache on disk, and under --apply wrote into them; and the vault lint read four kilobytes of every file in the vault to harvest its aliases. The audit refuses the area at its walk now, --prune-cache empties what earlier runs left in the cache, and the lint names a walled note without opening it, so a link to one still resolves rather than reading as broken. Why a sweep as well as the fix: the index is a cache that outlives the binary that built it, so correcting the delete alone would have left every existing machine exactly as it was. Why not rebuild the index from scratch instead: the enrichment ledger and the work queue are tables in the same file, and discarding it would cost a ledger rebuild and a full re-embed to remove rows five statements remove. Re-audit trigger: a fourth derived table keyed by the document id โ the schema-reading test fails if it is not on the list, and that test is the guard, not this note. |
final |
| 2026-09-11 |
Amended as plan 04's morning note landed (task 6). The note is built with its four sections, and the daily email carries it at order 6. As built, what needs you lists the unfiled notes below the floor, the twins, shared keys and facets, the binary's archive candidates and what sank this week, and ends on the needs-review map. The dreaming facet link and the two forward lists are not built, and carry a [PENDING-IMPL] marker; plan 11 creates the facet. Monitoring marks the rest the note does not carry yet: the crystallized-note list and per-job spend (plan 11) and the mail line (plan 12). The dreaming scorecard and the daily digest's job retired, and an empty digest is never written. A night that ran past its window has no line of its own yet, so the window's re-audit and Monitoring now point at the note's footer, which gives the time it was written. The fixture risk now names its mitigation as built: the note reads only what was written since the window opened, and a guard test holds both test runners to a scratch engine state. Why not hold the note until the facet exists: the other lists already have readers, and the facet is one line in a section that works without it. Re-audit trigger: plan 11 landing, which should bring the facet link and the forward lists together. Prose pass: cross-model, fact-checked. |
final |
| 2026-09-11 |
Amended as plan 04's Python cycle landed (task 5). Session 3 kept the link sweep in the Python cycle until the first batch showed the deep pass filling related. The sweep was already gone: _stage_link_improvement left with the vector stack in PR #435, before this series, so plan 04 had nothing to keep or retire for it and there is nothing to re-audit after the first batch. As built, contradiction triage lands in its own Shared keys, different bodies section beside Possible twins. The Dreaming body now says both. Why not rebuild a sweep to honor the ruling: it ranked candidates out of an index that no longer exists, and the deep pass's related, chosen from the neighbours the batch offers, is the linking that remains. Re-audit trigger: a month after the first batch, if related on enriched cards is sparse enough that a sweep would add links you want. |
final |
| 2026-09-07 |
Amended after group 11a's check run, then narrowed by its re-run. index.md's self-description names standards/storage-rules.md as the file that decides where a capture goes; the routing table itself stays in the contract. The first amendment put the routing into the map, on evidence from a check run where the Gemini Gem failed check 3 and claude.ai passed it. That evidence did not hold: the Gem's standards/ had been attached as a folder without the file, and with storage-rules.md attached by name the Gem passed check 3 with the routing quoted correctly from the contract. The failing configuration was a surface missing a file it should have had, not a map missing a section โ and the payload's reading order gives a surface both. Why not copy the routing into the map anyway: it would be a second, ungated copy of the one thing check-storage-rules, the daemon's parser and the growth rule all guard in a single place. Re-audit trigger: a surface given index.md and standards/ that still cannot name the class a capture lands in. Method note: both outcomes of the re-run were written down before it ran, and both held โ check 3 passed once the file was attached, check 1 failed again because its note lives in agent/memory/semantic/, which no knowledge set reaches without search. |
final |
| 2026-09-07 | Sequenced into 14 plans via /design sequence; first active (PLAN-agentm-vault-00-paste.md), 13 queued in queued-plans/. | final |
| 2026-09-07 | Translated to 14 parts via /design translate: 00-paste, 01-hygiene, 02-purge, 03-capture-writers, 04-the-night, 05-memory-root-trims, 06-card-backfill, 07-maps-and-root-notes, 08-root-casing, 09-projects-writers, 10-projects-migration, 11-axis-per-space, 12-surfaces, 13-ideas. | final |
| 2026-09-07 | Approved as final via /design author review pass. | final |
| 2026-09-07 | Session 7 of the series: the close. The design read end to end; every reversal traced (session 4 over session 1's plans/ and session 3's crystallize trigger; session 5 over session 4's archive/tasks/, session 1's per-area opt-in and naming rule, and Filing v2's confirm gate and never-by-moving; session 6 over session 5's clock ruling and session 2's posture line) and fifteen sentences the reversals had left standing reconciled in place โ the handoff files' destination, the close step's move, _harness/ "becoming desk/", agent/'s third child, five "is session N's question" pointers, the tidying lane's reason, the machine fields owed a reader check, the Infrastructure table's sessions 4 and 5. Ideas.md ruled: idea cards at personal/ideas/ with area:, the one place in personal/ enrichment may write a body, Ideas.md generated over them with your preamble kept; Migrations gain group 12. Your steps written into Launch Plans in plan order. Design plugin note: its sibling lookup fails under the versioned plugin cache, so the gates ran through the crickets dist/ layout. |
final |
| 2026-09-07 | Session 6 of the series: one memory across every surface. The measurement first โ no client but Claude Code was registered against the daemon and the Claude desktop app held no server; claude.ai reaches the vault through the Drive connector alone, which searches the whole Drive and found two retired vault trees beside the live one; the Gemini rules file was from July and the September template already named eight things the series changes; the daemon's hit was a path and a snippet; the tier was 17 KB a session with the contract's block a third of it, and the prompt hook could inject the contract twice; the session's own first recall was five traces of the same brief. Fifteen rulings, taken one at a time: one memory as three reads on every surface; the payload layout-free, naming index.md, standards/ and moc-projects.md, in your words, pasted once and re-pasted only when its own sections change, the local copies derived under a gate and /memory payload printing it; index.md self-describing and the vault twin retired; four checks that prove a paste took; one Drive copy, the retired trees removed by you; the always-load tier capped at 40,000 tokens with the contract's block stripped; standards/ excluded from recall by always_load_areas:; traces served on time questions only; a hit as the card's readable head, never the body or why; chat surfaces named clock-blind, the daemon writing the clock for its own surfaces with a surface: field in the ledger; Claude Desktop registered against the daemon by you; the email door as every chat surface's write path and the Gem re-imagined around it; the deep search by request; the /memory subcommands; landing group 11 in two plans. Ideas.md as a list over idea cards recorded for a later ruling. |
draft |
| 2026-09-07 | Session 5 of the series: consolidation, retirement and forgetting, per space. The measurement first โ the axis had never moved a note; the daemon applied no decay because its switch is absent from the live config, the Python arm ran a thirty-day exponential, and the contract's decay_* lines were read by nothing; the recall clock had one writer and basename keys that collide; half the corpus had no anchor; Important Docs was servable into a prompt. Rulings over three reads: the machinery changes state only in the observational classes, the calendar and the diagnostics; the single-memory sequence (dormant 365 ยท archived 1,825 ยท deleted 2,555, traces 90 ยท 365 ยท 1,095), archive as a move to agent/archive/ and deletion both automatic with a manifest first, the deep search by request; the exemptions; one curve from the contract in both arms, cap 25, the clock reset by any surface and keyed by path, every note given a created; a lesson's sources demoted at once; diagnostics on a retention table; projects/ permanent with importance ร activity, tasks never archived and ordered by a three-digit prefix, project documents the same, <slug>/completed/ and projects/completed/<slug>/; personal/ permanent and readable by background models with Important Docs walled; calendar on the curve, deleted at five years, the dreaming facet as the night's record; the night following hand moves. Reverses Filing v2's never-by-moving for archive, session 4's archive/tasks/, session 1's per-area opt-in, and amends its naming rule. Migrations gain group 10. |
draft |
| 2026-09-06 | Session 4 of the series: projects and tasks as memory. The measurement first โ no tracker file exists and the plan's Status line does the job in nine spellings across seventy-eight files; zero memory notes carry a project: field and the trace's field is never filled; eight handoff files, the largest opening with banners saying it is finished; /orient reads fourteen progress tails and says nothing about where the project stands; 502 of 760 harness files are archive, all indexed at full rank; a closed task's log is median 2 KB. Twenty-four rulings taken: task and step as the words; the project skeleton with charter.md (renamed from _index.md), tracker.md and followups.md at the root, no plans/, desk/ for machine files; _harness/ dissolving by a mapping table rather than renaming; the tracker as its own file with one schema; five statuses and the transition table; close moving the directory to archive/tasks/; kind: decision, handoff as tracker; project: and task: on every card and trace with a recall boost; dreaming's deep pass additive on cards and on project records, never on trackers, plans or progress; crystallize as a weekly dreaming phase reading for recurrence (three across two sessions seven days apart), never a session's act โ amending session 3's close-time trigger; the twenty-line opening brief; three paired landings; roadmap.md; the daily note as the diary facet. Session 1's plans/ listing reversed. |
draft |
| 2026-09-06 | Session 3 of the series: dreaming, and where the tokens go. The measurement first โ no nightly step spends a token because enrichment, the only model-calling code, has no scheduler; every daily job fires at 13:07 because the runner's daily has no hour; a report-only pass resets the binary's clock; the dreaming scorecard named a test fixture as last night's run; promote would have crystallized eight recall-list targets including a test token. Seventeen rulings taken: the night's order (enrichment, binary, Python, scorecards) inside a 02:00โ06:00 window; the budget as a token line per night per tier (1M strong / 2M cheap) with a 250-call guard, usage printed; the first batch supervised with a twenty-pair sample; the deep pass strong with five recall neighbours as input, the light pass as the first cheap-tier audit; one prompt with two shapes, altitude dropped, importance_proposed on a contract rubric, why never written; the binary at -every 24h; crystallized as model syntheses at task close or on request, promote reading Captured and Candidates and writing semantic candidates, _crystallize-staging/ deleted; eight Python stages and the dedup confirm path retired; fuzzy pairs as a needs-review section; one morning note replacing the dreaming scorecard and the digest email, empty digests no longer written. Migrations gain group 9, the night. |
draft |
| 2026-09-06 | Session 2 of the series: initial capture. The measurement first โ enrichment had run once (every enriched_at dated 2026-08-27), the eager trigger had never been attached, the Stop hook's candidates landed active at low confidence where enrichment never looks, and 572 of 769 class notes were miner residue; the red queue was a pass nobody runs, not a pass behind. Seventeen rulings taken: the six purge manifests by count (572 out, 172 remain), the tally gate in the purge's landing group, no enrichment batch until session 3's prompt and budget; the in-session card as the primary capture with the Stop-hook model call named as fallback; why as what was happening and what it decides, written only by a knowing writer; one meaning for status; the trace as the handoff record (Asked ยท Outcome ยท Captured ยท Recalled ยท Candidates) and the miner filing HIGH only; the deep pass owed by stamp with importance_proposed guarding your edits; a second sub-floor verdict sinking to dormant; eager retired for the nightly batch; four optional fields on the tool. Migrations gain the capture-writers group. Capture reconciled to the write path in the same change. |
draft |
| 2026-09-06 | Created in session 1 of the vault-perfection series, authored from the crickets design template as the successor to Filing v2 (which is pointed here). The layout and the card are decided โ twenty-one rulings taken in conversation against the survey of the live vault and the work vault photographed the same evening: lowercase roots, agent/ trimmed to two children, memory/ to the classes, tasks nested under their project, crystallized/ flat, entities/ folded until written, maps named for what they map with Home.md retired, the calendar on a year map, the four-file standards/, one root map, kebab naming with a gate; the card's field order with why and importance added and altitude, group, always_load and the mining fields retired. Inputs for sessions 2 to 6 recorded in their sections: deep-once-then-light enrichment, the tracker definition, permanent spaces ranked by importance, personal files enriched in frontmatter only under a per-area opt-in. Prose pass: the cross-model step degraded (agy returned an empty result twice), so a Claude-only simplification pass ran against the fact-guard list. |
draft |