ver 1.5.0 — six-improvement pass: retention, routing, self-firing memory
1. capture-update keeps the whole body (was truncating to first line) 2. frontmatter completeness: kind-default status + kind-seeded tags at capture, fm create-or-replace, incomplete-frontmatter lint, sweep backfill (one data source: KIND_STATUS/KIND_REQUIRED_FM) 3. pre-write duplicate gate (exit 76, --merge-into/--force) 4. recall corpus + ranking: sessions/journal indexed (down-weighted), BM25 x freshness x status fusion, recall --json, index schema 2 5. session hooks: SessionStart auto-load, Stop reflection nudge 6. one-tap triage verb with processing-log audit; --json on read verbs +22 mock end-to-end tests; all suites green. Docs current (README, CHANGELOG, SKILL.md, commands, references, MAINTENANCE, eval README). Drops tracked .DS_Store (gitignored); retires README-gretchen.md (moved to gitignored dist/); adds the field report that drove item 2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,4 +16,6 @@ python3 "$ECHO" recall "$ARGUMENTS"
|
||||
# Windows: use `python` or `py -3` if `python3` is not on PATH.
|
||||
```
|
||||
|
||||
The corpus spans the entity graph **plus session logs and journal notes**, ranked by relevance × freshness × status — each hit shows its `updated:`/`status:`, so prefer fresh/active hits and treat stale ones as history. Add `--json` for structured hits (`path/score/type/updated/status/excerpt`) when you need to act on the results programmatically.
|
||||
|
||||
Then answer from the assembled context. If you only need the canonical path for one entity, use `echo.py resolve "<title>"` instead. Don't narrate the retrieval.
|
||||
|
||||
@@ -10,7 +10,7 @@ things worth remembering across sessions, then propose them — don't write blin
|
||||
commitments, people/companies/projects introduced, and anything the operator said to remember.
|
||||
Skip the ephemeral. Anchor relative dates on the conversation's `currentDate`.
|
||||
2. **Emit a JSON array** of proposals (one per item), each:
|
||||
`{"title","kind","body","aliases","sources","confidence"}` — `kind` ∈
|
||||
`{"title","kind","body","aliases","tags","sources","confidence"}` — `kind` ∈
|
||||
`person, company, concept, reference, meeting, project, area, semantic, episodic,
|
||||
working, skill, decision`; set `"inbox": true` when the home is genuinely unknown;
|
||||
`confidence` 0–1 (items below 0.6 are dropped — send those to the inbox instead).
|
||||
|
||||
@@ -7,15 +7,17 @@ Use the **echo-memory** skill to persist this to the ECHO vault:
|
||||
|
||||
> $ARGUMENTS
|
||||
|
||||
Prefer the one-call **`capture`** — it routes (via the entity index), derives the canonical path, stamps frontmatter, indexes, auto-links mentioned entities, and writes the Agent-Log line. Pick the `--kind` from the content (`person, company, concept, reference, meeting, project, area, semantic, episodic, working, skill, decision`); use `--inbox` only when the home is genuinely unknown. Write multi-line bodies to a file with the Write tool (cross-platform, no heredoc).
|
||||
Prefer the one-call **`capture`** — it routes (via the entity index), derives the canonical path, stamps complete frontmatter (kind-default `status`, the kind seeded into `tags`), indexes, auto-links mentioned entities, and writes the Agent-Log line. Pick the `--kind` from the content (`person, company, concept, reference, meeting, project, area, semantic, episodic, working, skill, decision`); add `--tags` when obvious; use `--inbox` only when the home is genuinely unknown. Write multi-line bodies to a file with the Write tool (cross-platform, no heredoc) — updates to an existing entity preserve the whole body, so don't pre-trim it.
|
||||
|
||||
```bash
|
||||
ECHO="${CLAUDE_PLUGIN_ROOT}/skills/echo-memory/scripts/echo.py" # run with: python3 "$ECHO" ... (Windows: python / py -3)
|
||||
[ -f "$ECHO" ] || ECHO=$(ls /sessions/*/mnt/.remote-plugins/*/skills/echo-memory/scripts/echo.py 2>/dev/null | head -1) # CoWork sandbox fallback
|
||||
python3 "$ECHO" capture "<title>" <bodyfile> --kind <kind> [--aliases a,b] [--source p1,p2]
|
||||
python3 "$ECHO" capture "<title>" <bodyfile> --kind <kind> [--aliases a,b] [--tags t1,t2] [--source p1,p2]
|
||||
python3 "$ECHO" capture "<title>" --inbox # unknown home -> idempotent inbox line
|
||||
```
|
||||
|
||||
**If capture exits `76` (duplicate gate):** the title strongly resembles an existing entity — do NOT retry blindly. Show the operator the printed candidates and either update the existing note (`capture ... --merge-into <slug>`) or, only after they confirm it's genuinely distinct, re-run with `--force`.
|
||||
|
||||
Drop to the low-level verbs only for shapes `capture` doesn't model (a project `## Status` replace, an ADR mirror, a daily-note edit):
|
||||
|
||||
```bash
|
||||
|
||||
@@ -2,13 +2,22 @@
|
||||
description: Triage the ECHO inbox — route aging captures to their canonical homes and log the moves
|
||||
---
|
||||
|
||||
Use the **echo-memory** skill to run **Inbox Triage**. GET `inbox/captures/inbox.md`, list captures older than ~7 days that were never routed, and offer to route them.
|
||||
Use the **echo-memory** skill to run **one-tap Inbox Triage** via the `triage` verb (it reuses the reflect pipeline: classify against the entity index → preview → apply via `capture`, and writes the audit log for you).
|
||||
|
||||
```bash
|
||||
ECHO="${CLAUDE_PLUGIN_ROOT}/skills/echo-memory/scripts/echo.py"
|
||||
[ -f "$ECHO" ] || ECHO=$(ls /sessions/*/mnt/.remote-plugins/*/skills/echo-memory/scripts/echo.py 2>/dev/null | head -1) # CoWork sandbox fallback
|
||||
python3 "$ECHO" get inbox/captures/inbox.md
|
||||
python3 "$ECHO" triage --list --json
|
||||
# Windows: use `python` or `py -3` if `python3` is not on PATH.
|
||||
```
|
||||
|
||||
For each capture the operator accepts: send it to its proper home per the routing map (preference → `operator-preferences.md::Observations`; project idea → `projects/incubating/`; durable fact → `_agent/memory/semantic/`; person → `resources/people/`), then record the move in `inbox/processing-log/YYYY-MM-DD.md` (`- <original> → <destination>`). Do **not** delete the original capture unless the operator explicitly asks — the processing log is the audit trail.
|
||||
1. **List** — the JSON gives each capture as `{line, date, text, age_days}`. Surface the aging ones (≥ ~7 days) to the operator and ask which to route.
|
||||
2. **Propose** — for accepted items, write a proposals JSON with the Write tool (reflect schema: `{"title","kind","body",...}` **plus `"line"`: the original inbox line**, echoed into the audit log). Route per the map: preference/pattern → `semantic` (or a direct PATCH to `operator-preferences.md::Observations`); project idea → `project` with `--status incubating`; durable fact → `semantic`; person fact → `person`.
|
||||
3. **Preview, then apply** with the operator's go-ahead:
|
||||
|
||||
```bash
|
||||
python3 "$ECHO" triage proposals.json # dry-run: classify + preview, writes nothing
|
||||
python3 "$ECHO" triage proposals.json --apply # route via capture + log each move
|
||||
```
|
||||
|
||||
`--apply` records every move in `inbox/processing-log/YYYY-MM-DD.md` (`- <original> → <destination>`) automatically. Do **not** delete the original captures unless the operator explicitly asks — the processing log is the audit trail. A proposal that stops at the duplicate gate (exit note in the summary) should be re-proposed with the existing entity's title.
|
||||
|
||||
Reference in New Issue
Block a user