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:
@@ -345,6 +345,63 @@ def main():
|
||||
check("v1.5 session-start hook stays quiet on resume",
|
||||
r.returncode == 0 and not r.stdout.strip(), r.stdout)
|
||||
|
||||
# 18. (2.1.0) brief load: digest form, budget respected, key facts present.
|
||||
h.seed("_agent/memory/semantic/operator-preferences.md",
|
||||
"---\ntype: semantic-memory\ncreated: 2026-06-01\n---\n# Operator Preferences\n\n"
|
||||
"## Fact / Pattern\n- prefers concise output\n\n## Observations\n"
|
||||
+ "\n".join(f"- 2026-06-{i:02d}: observation {i}" for i in range(1, 15)) + "\n")
|
||||
h.seed("inbox/captures/inbox.md", "- 2026-06-01: old capture\n- 2026-06-20: new capture\n")
|
||||
r = h.echo(ECHO, "load", "--brief")
|
||||
check("v2.1 brief load renders the digest header",
|
||||
"ECHO load (brief)" in r.stdout, r.stdout[:200])
|
||||
check("v2.1 brief load keeps Fact / Pattern",
|
||||
"prefers concise output" in r.stdout, r.stdout[:800])
|
||||
check("v2.1 brief load trims observations to the last 10",
|
||||
"last 10 of 14" in r.stdout and "observation 14" in r.stdout
|
||||
and "observation 2" not in r.stdout.replace("observation 2026", ""), r.stdout[-1200:])
|
||||
check("v2.1 brief load reports inbox as a count",
|
||||
"inbox: 2 capture(s), oldest 20d" in r.stdout, r.stdout[-400:])
|
||||
check("v2.1 brief load includes the marker line",
|
||||
"echo-vault.md" in r.stdout and "marker" in r.stdout, r.stdout[:300])
|
||||
|
||||
# 19. (2.1.0) session-end: dry-run writes nothing; apply lands all steps with
|
||||
# the heartbeat LAST; a bad bundle aborts before any write.
|
||||
se_env = dict(os.environ, ECHO_BASE=base, ECHO_KEY=KEY, ECHO_VERIFY="1",
|
||||
ECHO_TODAY="2026-06-21", ECHO_NOW="2359")
|
||||
bundle = {"slug": "quickwins-ship",
|
||||
"log_body": "---\ntype: session-log\nstatus: complete\ncreated: 2026-06-21\n---\n"
|
||||
"# Session Log\n\n## Goal\nShip the quick wins.\n",
|
||||
"agent_log_line": "- 2026-06-21: shipped the quick wins",
|
||||
"reflect": [{"title": "Quark Preference", "kind": "semantic",
|
||||
"body": "The operator prefers quark.", "confidence": 0.9}]}
|
||||
bfile = HERE / "_session_bundle.json"
|
||||
bfile.write_text(json.dumps(bundle), encoding="utf-8")
|
||||
sess_path = "_agent/sessions/2026-06-21-2359-quickwins-ship.md"
|
||||
r = subprocess.run([sys.executable, str(ECHO), "session-end", str(bfile)],
|
||||
capture_output=True, text=True, env=se_env)
|
||||
check("v2.1 session-end dry-run previews the plan",
|
||||
"dry-run" in r.stdout and sess_path in r.stdout, r.stdout)
|
||||
check("v2.1 session-end dry-run writes nothing", h.ground(sess_path) is None)
|
||||
r = subprocess.run([sys.executable, str(ECHO), "session-end", str(bfile), "--apply"],
|
||||
capture_output=True, text=True, env=se_env)
|
||||
check("v2.1 session-end apply lands the session log",
|
||||
"Ship the quick wins" in (h.ground(sess_path) or ""), r.stdout + r.stderr)
|
||||
check("v2.1 session-end apply routes the reflect proposal",
|
||||
h.ground("_agent/memory/semantic/quark-preference.md") is not None)
|
||||
check("v2.1 session-end apply writes the heartbeat last (commit marker)",
|
||||
sess_path in (h.ground("_agent/heartbeat/last-session.md") or ""))
|
||||
daily = h.ground("journal/daily/2026-06-21.md") or ""
|
||||
check("v2.1 session-end apply appends the agent-log line",
|
||||
"shipped the quick wins" in daily, daily[-300:])
|
||||
bad = dict(bundle, slug="Bad_Slug!")
|
||||
bfile.write_text(json.dumps(bad), encoding="utf-8")
|
||||
r = subprocess.run([sys.executable, str(ECHO), "session-end", str(bfile), "--apply"],
|
||||
capture_output=True, text=True, env=se_env)
|
||||
bfile.unlink()
|
||||
check("v2.1 session-end rejects a bad slug before any write",
|
||||
r.returncode == 2 and sess_path in (h.ground("_agent/heartbeat/last-session.md") or ""),
|
||||
r.stderr)
|
||||
|
||||
print(f"\n{len(failures)} failure(s)" if failures else "\nall feature tests passed")
|
||||
return 1 if failures else 0
|
||||
finally:
|
||||
|
||||
Reference in New Issue
Block a user