close · diff

git:20260707.2a2e857 to git:20260710.d9f833e

129 added, 169 removed. Audit C to A.

- Run the aigent-OS end-of-session memory commit. No sub-agents — the AIgent does all updates inline.
-
---
+ name: close
+ description: Commit the session to durable vault memory and prepare a clean resume point
+ trigger: /close
+ ---
- ## Step 0 — Discipline audit (HARD GATE — runs BEFORE daily note write)
+ # Session Close
- Before writing anything else, audit the discipline. If any of these gates trip, the AIgent must address them before proceeding to Step 1.
+ Run the aigent-OS end-of-session memory commit inline. The close must be idempotent: rerunning it after a partial failure must not duplicate ledger entries, capsules, or session summaries.
- ### Gate A — Honesty Ledger
- Scan the session for non-trivial work (any of: code edits >30 LOC, multi-file changes, completed task declarations, "shipped"/"done"/"complete"/"verified" claims).
+ All operator-owned durable state lives under `vault/`. Framework indexes such as `memory/SKILL_LEDGER.md` remain outside the vault and are not session memory.
- If non-trivial work happened AND `memory/HONESTY_LEDGER.md` was NOT modified this session:
- - Pause the close.
- - Run `/honesty-check` for the most consequential work block.
- - Append a structured entry to `memory/HONESTY_LEDGER.md` with:
- - Verified / Inferred / Guessed / Tradeoffs / Stopped short / Cost-implications / Self-rating / Resolution: OPEN.
- - Then continue.
+ ## Step 0: discipline audit
- ### Gate B — Trust Decay capture
- Scan the session for confident-verb claims by the AIgent or any agent: "fixed", "verified", "tested", "deployed", "complete", "shipped", "ready", "running", "merged", "passing".
+ Run these checks before writing the daily note.
- If any such claims were made about consequential work AND `memory/TRUST_DECAY.md` was NOT modified this session:
- - Pause the close.
- - Pick the 1-3 most consequential confident claims.
- - Append Phase 1 entries to `memory/TRUST_DECAY.md` (Open section).
- - Continue.
+ ### Gate A: honesty ledger
- ### Gate C — Failure Modes corpus
- If `/diagnose` ran AND verified a cause this session AND `memory/FAILURE_MODES.md` was NOT modified:
- - Pause.
- - Append Phase 1 entry per [[concepts/Common Failure Modes]] format.
- - Continue.
+ If the session included non-trivial work, completed-task claims, multi-file edits, or consequential decisions and `vault/memory/HONESTY_LEDGER.md` was not updated:
- ### Gate D — Decision aging follow-up
- If during this session Will answered any decision-aging prompt (HELD / DRIFTED / REVERSED / STILL UNCLEAR) AND `memory/DECISION_OUTCOMES.md` was NOT updated with the answer:
- - Pause.
- - Append the outcome to the corresponding decision entry.
- - Continue.
+ 1. Run `/honesty-check` on the most consequential work block.
+ 2. Append one structured entry covering verified, inferred, guessed, tradeoffs, stopped short, cost implications, self-rating, and resolution.
+ 3. Continue only after the entry is durable.
- ### Gate E — Drift report (Friday only)
- If today is Friday, output a one-line measurement summary at the top of the orientation:
- ```
- 📊 Week measurement: {N} honesty ledger entries / {M} trust-decay captures / {P} failure modes logged / {Q} decision outcomes resolved
- ```
- This is informational, not a gate — but if all numbers are 0 on a non-trivial week, that's signal that the discipline isn't firing and the audit gates aren't catching enough.
+ ### Gate B: trust-decay capture
- ### Why the gates are HARD
+ If consequential work was described as fixed, verified, tested, deployed, complete, shipped, ready, running, merged, or passing and `vault/memory/TRUST_DECAY.md` was not updated, append one to three open Phase 1 claims. Do not convert confident language into evidence after the fact.
- Will explicitly cannot rely on himself remembering to invoke these skills (his words: *"all the stuff that requires discipline I will never do"*). The discipline is the principal's, but the enforcement is the framework's. /close is the structural enforcement point because it always runs at session end. Skipping the audit means the measurement substrate stays empty, which means v0.3's analyzers will have no data, which means the entire calibration claim degrades from "we measure" to "we built scaffolding and never measured."
+ ### Gate C: failure corpus
- If the AIgent tries to skip the audit and proceed straight to Step 1 — that itself is a trust-decay event. Capture it (in TRUST_DECAY.md) and then run the audit anyway.
+ If `/diagnose` established a verified cause, append it to `vault/memory/FAILURE_MODES.md` unless an equivalent entry already exists.
- ---
+ ### Gate D: decision outcomes
- ## Step 0.5 — Somatic auto-integrations (v0.4.1)
+ If the operator answered a decision-aging prompt, record the result in `vault/memory/DECISION_OUTCOMES.md` before closing.
- Run before Step 1.
+ ### Gate E: weekly measurement
- **A. Auto-digest if candidates staged.**
- Read `memory/MEMORY_CANDIDATES.md`. If any rows have `status: staged`:
- - Run `/digest` interactively (do NOT auto-promote — `/digest` surfaces each with promote/skip/supersede; principal decides).
- - Continue once digest completes or principal defers.
+ On Friday, include one line summarizing honesty entries, trust-decay captures, failure modes, and decision outcomes for the week. Zero activity after a non-trivial week is a signal that the measurement loop did not fire.
- **B. Auto-create context-capsule when appropriate.**
- Read current body state (use cached `memory/BODY_STATE.json` from this session's `/body-check`, or compose if absent). Create a context-capsule when ANY of:
- - `context_pressure >= medium`
- - `delegation_open_count > 5`
- - a non-trivial task shipped this session (code change, doc shipped, decision held)
- - principal asks for one explicitly
+ ## Step 0.5: somatic integrations
- Capsule write rules:
- - Output to `memory/capsules/<capsule_id>.md` per `.claude/skills/context-capsule/SKILL.md` schema (frontmatter + body).
- - `status: active`, `created_at: <now>`, `resolved_at: null`.
- - If this session was itself a resume (BODY_STATE.json `last_capsule.status == resumed`), set `parent_capsule_id` to that capsule's id for chain lineage.
+ ### Review staged memory
- **C. Update BODY_STATE.json `last_capsule`.**
- After capsule creation, edit `memory/BODY_STATE.json` `state.last_capsule` to:
- ```json
- { "id": "...", "path": "memory/capsules/<id>.md", "objective": "...", "status": "active", "created_at": "...", "resolved_at": null }
- ```
- If a capsule was created and the *previous* `last_capsule.status` was `active`, demote the previous capsule's frontmatter to `status: resumed` (Edit the prior capsule file) so `/open` won't dual-offer next session.
+ Read `vault/memory/MEMORY_CANDIDATES.md`. If staged candidates exist, run `/digest`. Promotion remains human-gated; a close may record deferral but must not silently promote candidates.
- **D. Skip if neither applies.** Empty candidates + low pressure + no shipped work = no capsule. Don't manufacture state preservation.
+ ### Create a context capsule when needed
- ---
+ Create `vault/memory/capsules/<capsule_id>.md` when any of these are true:
- ## Step 1 — Identify what changed this session
+ - Context pressure is medium or higher.
+ - More than five delegations remain open.
+ - A non-trivial task shipped.
+ - The operator explicitly requested a capsule.
- Scan the session. For each area, decide: **did anything actually change?** If no, skip it. If yes, update the relevant vault note(s).
+ Use the context-capsule schema, set `status: active`, and connect resumed sessions with `parent_capsule_id`. If a previous capsule is still active, demote it to `resumed` before making the new one active.
- **Vault notes to consider updating:**
+ Update `vault/memory/BODY_STATE.json` at `state.last_capsule` only after the capsule file is durable.
- | Location | Update when... |
- |----------|----------------|
- | `memory/SESSION_LOG.md` | ALWAYS — write new entry |
- | `memory/DECISION_LOG.md` | A non-obvious decision was made with lasting impact |
- | `memory/ACTIVE_PRIORITIES.md` | A priority shifted, completed, was added, or dropped |
- | `memory/DELEGATION_TRACKER.md` | A delegation was opened, updated, or closed |
- | `projects/*.md` | Product state changed (e.g., the product pipeline status, project stats) |
- | `agents/*.md` | Agent status, scope, or capabilities changed |
- | `people/*.md` | New person introduced or relationship/role changed |
- | `concepts/*.md` | A concept was refined, new technique discovered, standing rule added |
- | `memory/PRODUCT_STATE.md` | Only if the MOC links need updating (new product, retired product) |
- | `memory/BUSINESS_CONTEXT.md` | Something material changed about a business |
- | `memory/PEOPLE_AND_ROLES.md` | Only if the MOC links need updating (new person, new agent) |
- | `memory/BOTTLENECK_PATTERNS.md` | A bottleneck appeared for 2nd+ time, or resolved |
- | `memory/IDEA_QUEUE.md` | An idea was raised that shouldn't die |
+ Skip capsule creation when there is no meaningful state to preserve.
- **Typical session: 2–6 vault notes need updating. Skip everything else.**
+ ## Step 1: identify durable changes
- **Creating new notes:** If the session introduced a new person, agent, project, or concept that doesn't have a vault note yet, CREATE one in the appropriate folder (people/, agents/, projects/, concepts/) with proper frontmatter, tags, and [[wikilinks]] to related notes. This is how the graph grows.
+ Update only files whose owned state changed. Typical sessions touch two to six notes.
- ---
+ | Location | Update when |
+ |---|---|
+ | `vault/memory/SESSION_LOG.md` | Always, with one idempotent entry per session |
+ | `vault/memory/DECISION_LOG.md` | A lasting, non-obvious decision was made |
+ | `vault/memory/ACTIVE_PRIORITIES.md` | Priority, mode, blocker, or completion changed |
+ | `vault/memory/DELEGATION_TRACKER.md` | A delegation opened, moved, blocked, or closed |
+ | `vault/projects/*.md` | Project state materially changed |
+ | `vault/agents/*.md` | Agent scope or capability changed |
+ | `vault/people/*.md` | A person or role changed |
+ | `vault/concepts/*.md` | Durable doctrine or a reusable technique changed |
+ | `vault/memory/PRODUCT_STATE.md` | Its map-of-content links changed |
+ | `vault/memory/BUSINESS_CONTEXT.md` | Material business context changed |
+ | `vault/memory/PEOPLE_AND_ROLES.md` | Its map-of-content links changed |
+ | `vault/memory/BOTTLENECK_PATTERNS.md` | A repeated bottleneck appeared or resolved |
+ | `vault/memory/IDEA_QUEUE.md` | A useful idea should survive the session |
- ## Step 2 — Make the edits (read → edit, one file at a time)
+ Create new notes with YAML frontmatter and relevant wikilinks. Do not manufacture notes merely to make the close look busy.
- For each note that needs updating:
- 1. Read it
- 2. Make the precise edit — no rewrites, no padding
- 3. Ensure [[wikilinks]] connect to relevant notes
- 4. Move on
+ ## Step 2: apply edits
- ---
+ For each file:
- ## Step 3 — Write daily note
+ 1. Read the current version.
+ 2. Make the smallest accurate change.
+ 3. Preserve user-authored material.
+ 4. Add relevant wikilinks.
+ 5. Avoid duplicate session IDs, claim IDs, fact IDs, and capsule IDs.
- Create (or update if exists) `daily/[DATE].md` with:
+ ## Step 3: daily note
+ Create or update `vault/daily/YYYY-MM-DD.md`:
+
```markdown
---
- title: "[DATE]"
+ title: "YYYY-MM-DD"
tags:
- daily
- date: [DATE]
+ date: YYYY-MM-DD
---
- # [DATE]
+ # YYYY-MM-DD
## Session Work
- - [Bullet list of everything done, with [[wikilinks]] to every note touched]
+ - Work completed, linked to notes touched
## Decisions
- - [Any decisions made, linked to relevant notes]
+ - Lasting decisions
## Comms
- - [Comms state — what was unread, what was acted on]
+ - Material communication state
## Open Threads
- - [Anything unresolved, linked to relevant notes]
+ - Unresolved work and owners
## Links
Previous: [[YYYY-MM-DD]]
```
- This is the temporal layer of the graph. Every daily note links to the people, projects, concepts, and agents involved that day.
-
- ---
+ Preserve an existing `## Session Captures` section written by hooks. Merge session prose around it rather than overwriting it.
- ## Step 4 — Write SESSION_LOG entry
+ ## Step 4: session log
- Read `memory/SESSION_LOG.md`. Add at the top of Recent Sessions:
+ Add one entry near the top of `vault/memory/SESSION_LOG.md`:
- ```
- ### [DATE] — [Session topic in 5–8 words]
+ ```markdown
+ ### YYYY-MM-DD: session topic
- **Worked on:** [One line]
- **Key conclusion:** [Main decision or output]
- **Next action:** [What happens next and who owns it]
- **Open thread:** [Anything unresolved, or "None"]
+ **Session ID:** <session_id>
+ **Worked on:** one line
+ **Key conclusion:** one line
+ **Next action:** action and owner
+ **Open thread:** unresolved item or None
+ See [[YYYY-MM-DD]].
```
- Include [[wikilinks]] in the entry so /open can follow graph links to relevant context. Link to the daily note: `See [[YYYY-MM-DD]]`.
-
- If more than 10 entries in Recent Sessions, move oldest to Archive as single lines.
+ Use `session_id` as the idempotency key. If the same session already exists, update it instead of appending another entry. Keep ten detailed recent entries and collapse older entries into the archive.
- ---
+ ## Step 5: rebuild memory heat
- ## Step 5 — Regenerate memory heat index (silent)
- Run silently so next `/open` has a fresh prioritization signal: `node "$AIGENT_VAULT/daemons/memory-heat/compute-heat.js" > /dev/null 2>&1`
- Output lands at `memory/HEAT_INDEX.json`. Replaces the need for a separate weekly cron — every /close refreshes it. See `concepts/Memory Decay Doctrine.md`.
+ Run:
- ## Step 6 — Usage sync (silent)
- Run silently: `bash "$AIGENT_VAULT/daemons/sync-usage.sh"`
+ ```bash
+ node "$AIGENT_ROOT/daemons/memory-heat/compute-heat.js"
+ ```
- ## Step 6.5 — Temporal fact capture (silent)
+ The output belongs at `vault/memory/HEAT_INDEX.json`. Surface failures; do not hide them behind unconditional `2>/dev/null`.
- Review the session for new facts worth recording. A "fact" is a concrete, verifiable assertion about the world — not an opinion or a task.
+ ## Step 6: usage sync
- Scan the session for:
- - New tool/API/service integrations ("the product now uses X")
- - State changes ("operating mode changed to BUILD")
- - Key decisions ("chose Vercel over Railway for the backend")
- - External facts learned ("a competitor raised $1M", "launch date moved")
+ Run, when present:
- For each new fact, append one JSONL line to `memory/facts/facts.jsonl`:
- ```json
- {"fact_id":"f{next_id}","subject":"...","predicate":"...","object":"...","valid_from":"YYYY-MM-DD","valid_until":null,"source":"daily/YYYY-MM-DD.md","confidence":0.9,"created_by":"aigent","superseded_by":null}
+ ```bash
+ bash "$AIGENT_ROOT/daemons/sync-usage.sh"
```
- If a new fact contradicts an existing fact in facts.jsonl, supersede the old one:
- 1. Edit old fact: set `superseded_by` to new fact_id, set `valid_until` to today
- 2. Append new fact with updated values
+ A missing optional daemon is a skip, not a successful run.
- If no new facts this session, skip silently. Do not force facts — only record what actually changed.
+ ## Step 6.5: temporal facts
- ---
+ Append concrete, verifiable state changes to `vault/memory/facts/facts.jsonl`. Facts need provenance, confidence, validity dates, and a stable ID. When a new fact contradicts an old one, close the old validity window and connect it with `superseded_by` before appending the replacement.
- ## Step 7 — REMINDB validation log (silent unless something to flag)
+ Skip this step when no verifiable fact changed.
- Read `$AIGENT_VAULT/memory/REMINDB_VALIDATION.md`.
+ ## Step 7: optional integration validation
- Answer two questions:
- 1. Did the AIgent call any remindb MCP tool (`MemorySearch`, `MemoryTree`, `MemoryFetch`, `MemoryDelta`, `MemoryWrite`, `MemorySummarize`, `MemoryCompile`, `MemoryHistory`) at least once this session? Y/N
- 2. Were any failures observed per the failure definitions in the ledger? Y/N + one-line description if yes.
+ Only update an integration validation ledger when that integration was configured and used. Do not claim an optional MCP, plugin, or connector was validated merely because its documentation exists in the repo.
- Then:
- - Append one row to the per-session log table: `| YYYY-MM-DD | Y/N | Y — {description} or N | {brief notes or —} |`
- - If remindb fired AND no failures: increment `Sessions logged` by 1
- - If failures observed: increment `Failures observed` by 1 AND reset `Sessions logged` to 0
- - If remindb did NOT fire this session: log as "not used", do not increment either counter
- - Update the `Phase 2 ready` field: YES if `Sessions logged >= 5` AND `Failures observed == 0` since last clean reset, otherwise NO
+ For remindb, use `vault/memory/REMINDB_VALIDATION.md` and record whether a memory tool ran and whether a defined failure occurred.
- Surface in commit summary ONLY if the Phase 2 ready threshold was just crossed this session: "remindb validated 5 sessions clean — phase 2 ready, will surface on next /open"
+ ## Step 7.5: system check
- ## Step 7.5 — Somatic /system-check audit (v0.5.2)
+ Run:
- Run `bash daemons/system-check.sh`, capture exit code + any FAIL/INFO lines.
+ ```bash
+ bash "$AIGENT_ROOT/daemons/system-check.sh"
+ ```
- - If exit 0 (all PASS): include a one-line `✓ /system-check: 6/6 PASS` in the commit summary.
- - If exit 1 (any FAIL): include the FAIL lines verbatim in the commit summary under a `⚠ /system-check FAIL` block, and surface to Will. Do NOT block /close — record and move on. The principal decides next-session whether to fix.
- - If INFO lines present (e.g., daemon error log entries since last sweep): include a one-line `ℹ /system-check INFO: N daemon log entries` and offer to surface details on request.
+ - PASS: include one concise line.
+ - FAIL: include the failure lines and continue closing.
+ - INFO: report the count and durable log location.
- This makes /close the natural smoke-test trigger — every session-end audits the wired Somatic stack. Catches silent breaks (e.g., a skill file deleted, a daemon syntax-broken, mirror discipline drift) before the next /open relies on them.
+ The audit does not block memory persistence, but failures must not be described as success.
- ## Step 8 — Recompute ACTIVE_STATE (v0.7+)
+ ## Step 8: recompute runtime state
- After all vault writes are complete, recompute runtime state:
+ After all vault writes:
- Run `python3 "$AIGENT_VAULT/daemons/runtime/update-active-state.py"`
+ ```bash
+ python3 "$AIGENT_ROOT/daemons/runtime/update-active-state.py"
+ ```
- This ensures the next `/open` reads fresh state. The daemon appends meaningful transitions to `STATE_EVENTS.jsonl` automatically (mode changes, objective changes).
+ Read `vault/memory/runtime/ACTIVE_STATE.json` and include active reflexes in the close summary when they require action.
- If `reflexes.should_skill_hunt` is true in the output, note it in the commit summary.
- If `reflexes.should_digest` is true, note it.
+ ## Step 9: output a brief commit summary
- ## Step 9 — Output commit summary (brief)
+ Report:
- - Notes updated: [list with one-line description of what changed]
- - Notes created: [any new vault notes added]
- - Notes skipped: [list]
- - Pick up next session: [one sentence on the most important open thread]
+ - Notes updated and why.
+ - Notes created.
+ - Checks that failed or were skipped.
+ - The single most important next-session pickup.
- ## Step 10 — Stamp the close marker
+ Do not list every file that was merely read.
- Write the current ISO timestamp to `.aigent/last-close` (create `.aigent/` if needed). This tells the next `/open` that this session was banked cleanly.
+ ## Step 10: stamp the close
+ Write the current UTC ISO timestamp to `.aigent/last-close` only after the durable memory writes complete:
+
```bash
- # bash / macOS / Linux
- mkdir -p .aigent && date -u +%Y-%m-%dT%H:%M:%SZ > .aigent/last-close
+ mkdir -p .aigent
+ date -u +%Y-%m-%dT%H:%M:%SZ > .aigent/last-close
```
+ On PowerShell:
+
```powershell
- # PowerShell (Windows)
New-Item -ItemType Directory -Force .aigent | Out-Null
(Get-Date -AsUTC).ToString('yyyy-MM-ddTHH:mm:ssZ') | Set-Content .aigent\last-close
```
+
+ If any required write failed, do not advance the close marker. State exactly which artifact remains incomplete so the next `/open` can recover it.