2.1.0 — quick-wins train: brief load, offline-durable capture, session-end verb
Three independently useful changes (IMPROVEMENT-PLANS #1/#3/#7), no schema changes: - load --brief: token-budgeted cold-start digest (facts full, last-10 observations, scope+freshness, last session's key sections, agent-log lines, inbox count; ECHO_LOAD_BUDGET ~8000 chars, lowest-priority-first trimming). SessionStart hook injects the brief form; /echo-load keeps the full dump. All load reads (+ the sessions listing, which also feeds the heartbeat fallback) fetched in parallel. - Offline capture durability: a fully-offline capture queues the WHOLE op as one semantic record; flush replays it through capture so routing/gate/aliasing re-run against the current index; a gate stop on replay is kept + flagged (needs_attention, surfaced by flush and load), never landed blind; update-path and ensure_daily_log writes ride safe_request; same-args captures dedupe. - session-end: one call, one lock — session log -> agent-log line -> reflect proposals (gate-aware) -> optional scope set -> heartbeat LAST as the commit marker; dry-run default; ECHO_NOW pins HHMM; validation runs before any write. Stop hook nudge names the command and recognizes it as reflected. - Fix: main() now catches the __main__ twin-module EchoError (via RuntimeError + .code) so helper-module errors exit with their intended codes, not tracebacks. +19 e2e checks; all suites green. Plans renumbered: MCP container is 2.2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,63 @@
|
||||
# Changelog
|
||||
|
||||
## 2.1.0
|
||||
|
||||
The "quick-wins train" from the 2026-07-28 review (`docs/IMPROVEMENT-PLANS.md` #1,
|
||||
#3, #7). Three independently useful changes; no schema or layout changes.
|
||||
|
||||
### Added — `load --brief`: a token-budgeted cold-start digest
|
||||
|
||||
The SessionStart hook injected the full text of six files every session (measured
|
||||
15.9KB and growing without bound — Observations and Scope History never shrink).
|
||||
`load --brief` renders a digest instead: Fact / Pattern rules in full, the last ~10
|
||||
Observations (with a `+N older` note), scope + `scope_updated` + sessions-since,
|
||||
the heartbeat-pointed session log's key sections (Goal / Decisions Made / Open
|
||||
Threads / Suggested Next Step), today's Agent Log lines, and the inbox as a
|
||||
**count + oldest age** — everything the load-time reconcile needs. Over
|
||||
`ECHO_LOAD_BUDGET` (default ~8000 chars), sections trim lowest-priority-first
|
||||
(observations → agent log → session summary) with explicit `(truncated)` markers.
|
||||
The hook now injects the brief form; `/echo-load` and the manual procedure keep the
|
||||
full dump. All `load` reads (plus the sessions listing, which also feeds the
|
||||
heartbeat-absent fallback) are fetched **in parallel** over the pooled connections.
|
||||
|
||||
### Fixed — capture is now offline-durable (the write path's inversion bug)
|
||||
|
||||
Low-level verbs queued on an outage, but the *default* write (`capture`) died: the
|
||||
update path's POST/PATCH and `ensure_daily_log` bypassed the queue entirely, and an
|
||||
unreachable index aborted the whole op. Now: (1) a fully-offline `capture` queues
|
||||
the **whole operation as one semantic record** (title/kind/body/tags/…, plus the
|
||||
capture-time date); `flush` replays it **through `capture`** so create-vs-update,
|
||||
the duplicate gate, and aliasing re-run against the index as it is at replay time —
|
||||
byte-level replay would freeze a decision made blind. (2) A duplicate-gate stop on
|
||||
replay keeps the record, flags it `needs_attention` (surfaced by `flush` and
|
||||
`load`), and does NOT block later records. (3) Mid-capture outages: the update
|
||||
path and `ensure_daily_log` writes ride `safe_request` (accepted edge: a queued
|
||||
agent-log PATCH 400-drops loudly if the daily note never existed — the trace line,
|
||||
not the memory). Same-args offline captures dedupe by idem-key.
|
||||
|
||||
### Added — `session-end`: the one-call session close
|
||||
|
||||
`echo.py session-end <bundle.json> [--apply]` performs the whole end-of-session
|
||||
sequence under ONE lock acquisition, in order: session log PUT → Agent Log line →
|
||||
reflect proposals (via `capture`, gate-aware) → optional `scope set` → **heartbeat
|
||||
LAST as the commit marker** (a part-way failure leaves the previous pointer intact,
|
||||
never dangling). Dry-run by default previews the full plan including the reflect
|
||||
classification. Filename HHMM from `$ECHO_NOW` (else local clock), validated
|
||||
against the canonical session-log regex **before any write**. The Stop hook's nudge
|
||||
now names the command, and recognizes a `session-end` invocation as
|
||||
"already reflected".
|
||||
|
||||
### Fixed — helper-module errors exited 2 instead of their intended codes
|
||||
|
||||
When `echo.py` runs as `__main__`, helper modules' `import echo` creates a twin
|
||||
module whose `EchoError` is a different class object, so `main()`'s handler missed
|
||||
it and the raw traceback leaked. The handler now catches `RuntimeError` (both
|
||||
classes subclass it) and honors `.code`.
|
||||
|
||||
Tests: +19 end-to-end checks (brief-load digest/budget, offline-capture queue /
|
||||
replay-through-capture / gate-on-replay / idem-key dedup, session-end dry-run /
|
||||
apply / ordering / validation-abort). All suites green.
|
||||
|
||||
## 2.0.0
|
||||
|
||||
**Packaging & structure major — nothing about memory behavior changes.** The major
|
||||
|
||||
Reference in New Issue
Block a user