From c64f6e33da0eb362c285615c08b993c713f4fc8a Mon Sep 17 00:00:00 2001 From: jason Date: Sat, 6 Jun 2026 23:34:55 -0500 Subject: [PATCH] ver 0.4 effiency pass --- echo-memory.plugin | Bin 16761 -> 19700 bytes .../.claude-plugin/plugin.json | 2 +- .../skills/echo-memory/SKILL.md | 159 ++++++++++++------ .../echo-memory/references/api-reference.md | 4 +- .../references/session-log-template.md | 2 + .../echo-memory/references/vault-layout.md | 28 +-- 6 files changed, 132 insertions(+), 63 deletions(-) diff --git a/echo-memory.plugin b/echo-memory.plugin index 931bea0eec4d11b239891edaf5ff367feebbcc57..0f9bf93aa1996f62889b665e6607efc96b594a5e 100644 GIT binary patch literal 19700 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 diff --git a/echo-memory.plugin.src/.claude-plugin/plugin.json b/echo-memory.plugin.src/.claude-plugin/plugin.json index 087d60f..69ad35c 100644 --- a/echo-memory.plugin.src/.claude-plugin/plugin.json +++ b/echo-memory.plugin.src/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "echo-memory", - "version": "0.3.0", + "version": "0.4.0", "description": "Persistent memory via the ECHO Obsidian vault over the Local REST API. Reads and writes notes across Claude/CoWork sessions using direct REST calls \u2014 no MCP server required. Jason's personal memory vault.", "author": { "name": "Jason" diff --git a/echo-memory.plugin.src/skills/echo-memory/SKILL.md b/echo-memory.plugin.src/skills/echo-memory/SKILL.md index 0a7929e..fc9ea9a 100644 --- a/echo-memory.plugin.src/skills/echo-memory/SKILL.md +++ b/echo-memory.plugin.src/skills/echo-memory/SKILL.md @@ -28,58 +28,52 @@ Full API reference with every endpoint pattern and the memory routing map: `refe Load at the start of any substantive conversation — anything beyond a single quick factual question. The signal: Jason is starting work, planning, asking for help with something that has state, or referencing prior discussions. -Do NOT narrate this loading. Reading memory is expected behavior. - ### Loading procedure -**Step 1 — Confirm the vault is bootstrapped:** +The cold-start reads are independent — **issue them in parallel** (one batch of 4–5 GETs), not sequentially. Parallel loading is ~3× faster wall-clock for the same call count. + +| # | GET | Notes | +|---|-----|-------| +| 1 | `/vault/BOOTSTRAP.md` | 404 → vault not set up; follow `references/bootstrap.md` | +| 2 | `/vault/_agent/memory/semantic/operator-preferences.md` | Jason's profile | +| 3 | `/vault/_agent/context/current-context.md` | Active scope + Scope History | +| 4 | `/vault/_agent/sessions/` (listing) | Pick the ~5 most recent by reverse lex sort (filenames `YYYY-MM-DD-HHMM-.md`, so lex == chrono); only read the ones whose slugs look relevant | +| 5 | `/vault/journal/daily/YYYY-MM-DD.md` | Today's note; 404 is fine — it's created on first agent activity | + +Do not read every session log — older sessions are reachable via `POST /search/simple/?query=...` when needed. + +**If a specific project is in play**, follow up with a **search across all lifecycle subfolders** (`active/`, `incubating/`, `on-hold/`, `archived/`) — searching one folder at a time misses notes filed elsewhere. Search by **both the slug AND any human title** Jason used in this conversation: ```bash -curl -s \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - "https://echoapi.alwisp.com/vault/BOOTSTRAP.md" -``` - -If this returns 404, the vault is not set up. Follow `references/bootstrap.md` before doing anything else. - -**Step 2 — Read operator preferences (the profile):** - -```bash -curl -s \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - "https://echoapi.alwisp.com/vault/_agent/memory/semantic/operator-preferences.md" -``` - -**Step 3 — Read active context and the most recent session logs:** - -```bash -# Current task-scoped context bundle -curl -s -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - "https://echoapi.alwisp.com/vault/_agent/context/current-context.md" - -# List session logs — read only the last ~5 by reverse lexical sort. -# Filenames use YYYY-MM-DD-HHMM-.md, so lex sort == chrono sort. -curl -s -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - "https://echoapi.alwisp.com/vault/_agent/sessions/" -``` - -The listing endpoint returns the full session set with no pagination. Do not read all of them — pick the ~5 most recent by filename and only read the ones whose slugs look relevant. Older sessions are reachable via `POST /search/simple/?query=...` when you need them. - -**Step 4 — If a specific project is in play, SEARCH for it first across all lifecycle subfolders, then read the best match:** - -Projects can live in `active/`, `incubating/`, `on-hold/`, or `archived/`. Search by slug first so you don't miss a note in a non-active subfolder: - -```bash -curl -s -X POST \ - -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ +# slug +curl -s -X POST -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ "https://echoapi.alwisp.com/search/simple/?query=" -# Then read the match wherever it lives, e.g.: -curl -s -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - "https://echoapi.alwisp.com/vault/projects//.md" +# human title (avoids missing notes filed under a different name) +curl -s -X POST -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ + "https://echoapi.alwisp.com/search/simple/?query=" ``` -Optionally read today's daily note at `/vault/journal/daily/YYYY-MM-DD.md` for current priorities and open loops. +Then read whichever match lives at `projects//.md`. + +Do NOT narrate this loading. Reading memory is expected behavior. + +## Inbox Triage + +`inbox/captures/inbox.md` is the catch-all for "save this somewhere — figure out where later." Without triage it grows forever and durable facts get stranded there. + +At the start of a substantive session, GET `inbox/captures/inbox.md`. If it contains lines older than ~7 days that haven't been routed elsewhere, surface them once: + +> "Three captures from last week are still in the inbox — want to route them now or leave them?" + +When routing accepted items, send each to its proper home: + +- Preference / pattern → PATCH-append under `operator-preferences.md::Observations` +- Project idea → PUT `projects/incubating/.md` +- Durable fact → PUT `_agent/memory/semantic/.md` +- Person fact → PUT/PATCH `resources/people/.md` + +Then record the move in `inbox/processing-log/YYYY-MM-DD.md` (one line per item: `- `). Don't delete the original capture unless Jason explicitly asks — the processing log is the audit trail. ## Project Lifecycle @@ -122,8 +116,22 @@ If a match is found: - In the same folder you intended to write: **update in place** (PATCH or merged PUT). Never silently overwrite — fold the existing content in first. - Elsewhere (e.g. a stale duplicate under `resources/`): tell Jason and ask which should be canonical before writing. +**Search both the slug AND any human title** Jason used (e.g. slug `echo-memory` and title `ECHO plugin`). Slug-only searches miss notes filed under a different naming scheme. Two cheap `POST /search/simple/?query=...` calls beat one expensive cleanup pass later. + Only after the search comes back empty (or you've decided to merge) is it safe to create a new note. This rule prevents the most common duplication bug: a note exists in `on-hold/` but the agent only checked `active/` and created a parallel record. +### Before you append — read first (idempotency) + +POST appends to the end of a file. It is **not idempotent** — running the same write twice (network retry, replay, re-trigger) produces duplicate lines that grow files silently. Before any POST that adds an entry to: + +- `inbox/captures/inbox.md` +- a daily note's `## Agent Log` section +- a `## Fact / Pattern` / `## Observations` / `## Log` heading + +…GET the target file (or the heading, via `/heading/...`) and substring-search for the exact line you're about to write. If present, skip the POST. The extra GET is cheap and pays for itself within a few sessions. + +This rule does **not** apply to PUT (which is fully replacing the file) or PATCH `replace` (which is overwriting a section by design). + ### Append to a file (default — additive entries) Write content to a temp file first to handle multi-line markdown cleanly, then POST: @@ -144,7 +152,19 @@ POST appends to the end of a file (creating it if absent). Use it for inbox capt ### Patch a specific heading (targeted update) -**Heading targets use the FULL heading path, `::`-delimited from the top-level heading** — a bare subheading name fails with `invalid-target`. For example, `## Fact / Pattern` under the `# Operator Preferences` H1 is targeted as `Operator Preferences::Fact / Pattern`. When unsure of the exact path, read the document map first (see below). +**Heading targets use the FULL heading path, `::`-delimited from the top-level heading** — a bare subheading name fails with `400 invalid-target` and the write is lost. For example, `## Fact / Pattern` under the `# Operator Preferences` H1 is targeted as `Operator Preferences::Fact / Pattern`. + +**Default: GET the document map first** (every first PATCH to a file in a session — cache the result mentally for subsequent PATCHes to the same file). This eliminates the most common failure mode of PATCH: + +```bash +curl -s -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ + -H "Accept: application/vnd.olrapi.document-map+json" \ + "https://echoapi.alwisp.com/vault/_agent/memory/semantic/operator-preferences.md" +``` + +Returns `{ "headings": [...], "blocks": [...], "frontmatterFields": [...] }`. Copy the heading string verbatim into `Target`. Only skip the doc-map GET if you wrote the file yourself in this session (you already know its structure). + +Then PATCH: ```bash cat > /tmp/obs_patch.md << 'OBSEOF' @@ -163,15 +183,19 @@ curl -s -X PATCH \ Use `Operation: replace` to overwrite a section entirely (e.g. a project's `Project Name::Current status`). Percent-encode non-ASCII characters in the `Target` header; spaces are fine. -**Discover exact heading paths** when unsure — GET the note with the document-map Accept header: +### Bump `updated:` after meaningful changes + +When a PATCH or PUT changes meaningful content (status update, decision recorded, current-status replacement, scope switch), also PATCH the frontmatter `updated:` field to today's date. This keeps stale-detection queries honest. ```bash -curl -s -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ - -H "Accept: application/vnd.olrapi.document-map+json" \ - "https://echoapi.alwisp.com/vault/_agent/memory/semantic/operator-preferences.md" +curl -s -X PATCH \ + -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \ + -H "Operation: replace" -H "Target-Type: frontmatter" -H "Target: updated" \ + -H "Content-Type: application/json" --data '"2026-06-06"' \ + "https://echoapi.alwisp.com/vault/projects/active/.md" ``` -It returns `{ "headings": [...], "blocks": [...], "frontmatterFields": [...] }` — copy the heading string verbatim into `Target`. +Skip the bump for **routine log appends** — adding an Agent Log line, an inbox capture, or a timestamped Observations bullet doesn't constitute a meaningful content change. Bump on substance, not on heartbeat. ### Create or overwrite a file (PUT) @@ -213,6 +237,31 @@ curl -s -X POST \ "https://echoapi.alwisp.com/search/simple/?query=your+search+terms" ``` +## Scope Switching (`current-context.md`) + +`_agent/context/current-context.md` tracks a single active scope. Jason routinely shifts scope within a day (echo plugin → MPM brand → WISP docs). + +When scope changes: + +1. PATCH `prepend` a dated bullet to `## Scope History` capturing the **prior** scope (one line: `- 2026-06-06: `). If `## Scope History` doesn't exist yet, POST the heading first, same pattern as the daily-note Agent Log. +2. PATCH `replace` `## Scope` with the new scope. +3. PATCH the frontmatter `updated:` field. + +This keeps a rolling trail of recent scopes in one file instead of spawning separate stash notes. Trim Scope History to the last ~10 entries when it grows past that. + +## Vault Health (monthly) + +On the first substantive session of a calendar month, run a quick health pass and write findings to `reviews/monthly/YYYY-MM-vault-health.md`. Don't auto-fix without asking. + +Checks: + +1. **Stale active projects** — for each note in `projects/active/`, check `updated:` >30 days. Likely belongs in `on-hold/`. +2. **Unprocessed inbox** — GET `inbox/captures/inbox.md`. List items older than 14 days that never moved through the triage protocol. +3. **Duplicate slugs across lifecycle folders** — any slug appearing in more than one of `active/`, `incubating/`, `on-hold/`, `archived/` is broken state. +4. **Broken-heading risk** — sample 2–3 frequently-PATCHed files; confirm `## Agent Log`, `## Scope`, `## Fact / Pattern`, `## Observations` headings still exist. + +The pass is cheap (a few searches + a directory listing) and pays for itself by catching drift before it requires a reorg. + ## Daily Note — Agent Log After substantive activity, write a one-line entry to today's daily note's `## Agent Log` heading. The daily-note **template** (`journal/templates/daily-note-template.md`) defines this heading, but ad-hoc daily notes created without the template don't have it — so PATCH can fail with `invalid-target` if the note exists but lacks the heading. @@ -308,6 +357,7 @@ If the API returns a connection error, timeout, or `502`, tell Jason once that t - Write in third person about Jason: "Jason prefers X", not "I prefer X". - Jason is both operator and architect here — unlike goldbrain (Bryan's vault, which Jason architected). Do not cross-write: Bryan's preferences belong in goldbrain, Jason's belong here. +- **Anchor relative dates on the conversation's `currentDate`** before writing. "Today" → `currentDate`. "Thursday" / "next week" → resolve to an absolute `YYYY-MM-DD`. Never guess from training-data knowledge of the current year. - Every memory file has canonical YAML frontmatter — see `references/vault-layout.md`. - Set `agent_written: true` on agent-generated notes and list `source_notes` (plain relative paths, not links). - **`created:` is the earliest known date the entity was tracked anywhere in the vault, not "today".** When merging notes (e.g. promoting `on-hold/` → `active/`), preserve the earliest `created:` and only bump `updated:`. @@ -317,6 +367,15 @@ If the API returns a connection error, timeout, or `502`, tell Jason once that t - Keep entries short and focused. Fewer, sharper entries beat many noisy ones — Jason explicitly prefers concision. - About to write something large or sensitive? Show Jason the content first and confirm. +## operator-preferences.md — Rules vs Observations + +`_agent/memory/semantic/operator-preferences.md` separates two kinds of content: + +- `## Fact / Pattern` — **promoted, deduped rules.** No date prefix. These are timeless: "Jason prefers concise communication." Append here only when a rule is stable. +- `## Observations` — **timestamped raw observations.** Date-prefixed: `- 2026-06-06: Jason chose X over Y because Z.` This is where new evidence goes by default. + +During monthly Vault Health or when an observation stabilizes, promote it from `## Observations` into `## Fact / Pattern` (drop the date) and remove the duplicate from Observations. Trim Observations to the last ~30 entries when it grows past that — the rest live in session logs. + ## What This Skill Does Not Do - Does not replace reasoning. The vault is reference material — apply judgment. diff --git a/echo-memory.plugin.src/skills/echo-memory/references/api-reference.md b/echo-memory.plugin.src/skills/echo-memory/references/api-reference.md index 8f782ff..da54504 100644 --- a/echo-memory.plugin.src/skills/echo-memory/references/api-reference.md +++ b/echo-memory.plugin.src/skills/echo-memory/references/api-reference.md @@ -197,8 +197,8 @@ Only on explicit operator request. Deletion is destructive. | Short-lived, time-boxed state | `_agent/memory/working/.md` | PUT | | Task-scoped context / focus | `_agent/context/current-context.md` | PATCH / PUT | | Working-session log | `_agent/sessions/YYYY-MM-DD-HHMM-.md` | PUT | -| Long-running project state | `projects/active/.md` | PUT + PATCH | -| Non-obvious decision (ADR) | `decisions/by-date/YYYY-MM-DD-.md` (mirror only into an existing project note's Key Decisions; otherwise skip) | PUT | +| Long-running project state | `projects//.md` (lifecycle: `incubating` → `active` → `on-hold`/`archived`; folder and `status:` MUST agree) | PUT + PATCH | +| Non-obvious decision (ADR) | `decisions/by-date/YYYY-MM-DD-.md` (mirror only into an existing project note's `## Decisions`; otherwise skip) | PUT | | Person context | `resources/people/.md` | PUT / PATCH | | Concept / reference note | `resources/concepts/` or `resources/references/` | PUT | | Daily activity / Agent Log | `journal/daily/YYYY-MM-DD.md` | POST / PATCH | diff --git a/echo-memory.plugin.src/skills/echo-memory/references/session-log-template.md b/echo-memory.plugin.src/skills/echo-memory/references/session-log-template.md index c6807d3..1592c1f 100644 --- a/echo-memory.plugin.src/skills/echo-memory/references/session-log-template.md +++ b/echo-memory.plugin.src/skills/echo-memory/references/session-log-template.md @@ -2,6 +2,8 @@ Session logs go in: `_agent/sessions/YYYY-MM-DD-HHMM-.md` +**Filename format is canonical and not optional.** The four-digit local-time HHMM component is what makes session filenames lex-sort in true chronological order — the loading procedure depends on it. Before PUT-ing a new session log, validate the filename matches `^\d{4}-\d{2}-\d{2}-\d{4}-[a-z0-9-]+\.md$`. Legacy session logs without HHMM exist in the vault; do not edit their names, but every new write must use the full form. + The slug describes what the session was about in 2–5 words, kebab-case. Examples: `2026-06-05-1430-echo-plugin-build.md`, `2026-05-14-0900-q1-review-prep.md`. diff --git a/echo-memory.plugin.src/skills/echo-memory/references/vault-layout.md b/echo-memory.plugin.src/skills/echo-memory/references/vault-layout.md index ca512ba..9192204 100644 --- a/echo-memory.plugin.src/skills/echo-memory/references/vault-layout.md +++ b/echo-memory.plugin.src/skills/echo-memory/references/vault-layout.md @@ -29,9 +29,10 @@ Mirrors the canonical conventions defined in the vault's own `STRUCTURE.md` and │ ├── concepts/ references/ meetings/ source-material/ │ └── people/ ← .md ├── decisions/ -│ ├── by-date/ ← YYYY-MM-DD-.md (ADR-style) -│ ├── by-project/ ← mirror by project +│ ├── by-date/ ← YYYY-MM-DD-.md (ADR-style) — the canonical home │ └── decision-template.md +│ (decisions/by-project/ exists in the legacy scaffold but is not used — +│ mirror an ADR into a project's `## Decisions` heading instead) ├── reviews/ ← weekly / monthly / quarterly / annual ├── archive/ ← notes / projects / imports └── _agent/ @@ -44,9 +45,11 @@ Mirrors the canonical conventions defined in the vault's own `STRUCTURE.md` and ├── templates/ ← canonical note templates ├── outputs/ ← briefs / drafts / summaries / synthesis ├── skills/ ← active / archived - └── heartbeat/ + └── heartbeat/ ← single-line pointers (e.g. last-session.md → most-recent session log path) ``` +**Heartbeat:** `_agent/heartbeat/last-session.md` is a one-line pointer file an agent MAY write at session end (` @ `). Reading it at session start is cheaper than listing the sessions directory; use it as a hint, not a source of truth — fall back to the directory listing if it's missing or stale. + **Slug rules:** kebab-case, ASCII only, truncate to ~40 chars. --- @@ -97,10 +100,16 @@ not rewrite frontmatter — the append goes after existing content. To change ### operator-preferences.md (`_agent/memory/semantic/`) -The profile analog. Headings include `Operator`, `Fact / Pattern`, `Evidence`, -`Recommendation or Implication`, `Review Notes`. Append observed facts under the -right heading via PATCH. "The operator" is Jason — he is both -operator and architect of this vault. +The profile analog. Canonical headings: + +- `## Operator` — who Jason is (one paragraph) +- `## Fact / Pattern` — **promoted, deduped rules.** No date prefix. Timeless. +- `## Observations` — **timestamped raw observations.** Date-prefixed lines (`- 2026-06-06: ...`). Default landing zone for new evidence. +- `## Evidence` — citations/links supporting the rules +- `## Recommendation or Implication` — how the rules should shape behavior +- `## Review Notes` — confidence / last review date + +Append observed facts under `## Observations` by default. Promote to `## Fact / Pattern` (dropping the date) once a pattern stabilizes. "The operator" is Jason — he is both operator and architect of this vault. ### projects/active/\.md @@ -135,12 +144,11 @@ One paragraph, kept fresh via PATCH replace. ### sessions/YYYY-MM-DD-HHMM-\.md -See `session-log-template.md`. Note ECHO uses an **HHMM time component** in the -filename (unlike a date-only convention). +See `session-log-template.md`. ECHO uses an **HHMM time component** in the filename — this is **canonical, not optional**. The four-digit local-time component makes filenames lex-sort in true chronological order, which the loading procedure relies on. Older session logs without HHMM exist; leave them alone, but every new one must use the full `YYYY-MM-DD-HHMM-.md` form. ### decisions/by-date/YYYY-MM-DD-\.md -ADR-style: Context → Decision → Consequences. Mirror a link into `by-project/`. +ADR-style: Context → Decision → Consequences. If the decision belongs to an existing project, PATCH-append the wikilink into that project's `## Decisions` heading. Don't use `decisions/by-project/` — it's legacy scaffolding that's intentionally left empty. ### people/\.md