From d193b6277de26538b031c28ecb102f85c9eb152d Mon Sep 17 00:00:00 2001 From: safishamsi Date: Wed, 24 Jun 2026 12:26:39 +0100 Subject: [PATCH] feat(reflect): --if-stale to skip redundant runs; agent uses it at session start Both the agent (session start) and the post-commit hook can run reflect; the runs are deterministic and idempotent, but back-to-back ones are wasted work. Add `graphify reflect --if-stale`, which no-ops when LESSONS.md is already at least as new as every input (the memory docs and the graph). The skill's session-start guidance now uses `--if-stale`, so when the hook just refreshed the file the agent's run costs almost nothing, while a skill-only install still refreshes on demand. New lessons_fresh() helper + 5 tests (mtime freshness in each direction, and the CLI skip/run behavior). Regenerated per-host references + re-blessed expected/; all five skillgen guards pass; full suite 2388 passed. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 2 +- graphify/__main__.py | 39 ++++++----- graphify/reflect.py | 33 +++++++++ graphify/skills/agents/references/query.md | 2 +- graphify/skills/amp/references/query.md | 2 +- graphify/skills/claude/references/query.md | 2 +- graphify/skills/claw/references/query.md | 2 +- graphify/skills/codex/references/query.md | 2 +- graphify/skills/copilot/references/query.md | 2 +- graphify/skills/droid/references/query.md | 2 +- graphify/skills/kilo/references/query.md | 2 +- graphify/skills/kiro/references/query.md | 2 +- graphify/skills/opencode/references/query.md | 2 +- graphify/skills/pi/references/query.md | 2 +- graphify/skills/trae/references/query.md | 2 +- graphify/skills/vscode/references/query.md | 2 +- graphify/skills/windows/references/query.md | 2 +- tests/test_reflect.py | 67 +++++++++++++++++++ ...hify__skills__agents__references__query.md | 2 +- ...raphify__skills__amp__references__query.md | 2 +- ...hify__skills__claude__references__query.md | 2 +- ...aphify__skills__claw__references__query.md | 2 +- ...phify__skills__codex__references__query.md | 2 +- ...ify__skills__copilot__references__query.md | 2 +- ...phify__skills__droid__references__query.md | 2 +- ...aphify__skills__kilo__references__query.md | 2 +- ...aphify__skills__kiro__references__query.md | 2 +- ...fy__skills__opencode__references__query.md | 2 +- ...graphify__skills__pi__references__query.md | 2 +- ...aphify__skills__trae__references__query.md | 2 +- ...hify__skills__vscode__references__query.md | 2 +- ...ify__skills__windows__references__query.md | 2 +- .../fragments/references/query/default.md | 2 +- 33 files changed, 153 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a5306a..480e0ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ Full release notes with details on each version: [GitHub Releases](https://githu ## Unreleased -- Fix: the work-memory loop no longer depends on the git hook. The skill now tells the agent to run `graphify reflect` itself at the start of graph work (it is cheap, deterministic, and a no-op when no outcomes have been saved), then read `LESSONS.md`. Previously a skill-only install (without `graphify hook install`) would keep recording outcomes via `save-result` but never regenerate `LESSONS.md`, so the lessons never surfaced. The post-commit hook is now an optimization for between-session freshness rather than a requirement. +- Fix: the work-memory loop no longer depends on the git hook. The skill now tells the agent to run `graphify reflect --if-stale` itself at the start of graph work (cheap, deterministic, a no-op when no outcomes have been saved), then read `LESSONS.md`. Previously a skill-only install (without `graphify hook install`) would keep recording outcomes via `save-result` but never regenerate `LESSONS.md`, so the lessons never surfaced. The post-commit hook is now an optimization for between-session freshness rather than a requirement. The new `--if-stale` flag skips the run when `LESSONS.md` is already newer than every input (the memory docs and the graph), so when the hook just refreshed it the agent's session-start run costs almost nothing. ## 0.8.47 (2026-06-24) diff --git a/graphify/__main__.py b/graphify/__main__.py index 9434519..1a153d4 100644 --- a/graphify/__main__.py +++ b/graphify/__main__.py @@ -2957,8 +2957,11 @@ def main() -> None: help="signal weight halves every N days (default 30)") p.add_argument("--min-corroboration", type=int, default=2, help="distinct useful results to promote a node to preferred (default 2)") + p.add_argument("--if-stale", action="store_true", + help="skip when LESSONS.md is already newer than every input " + "(e.g. the git hook just refreshed it)") opts = p.parse_args(sys.argv[2:]) - from graphify.reflect import reflect as _reflect + from graphify.reflect import reflect as _reflect, lessons_fresh as _lessons_fresh graph_arg = opts.graph if graph_arg is None: @@ -2966,21 +2969,25 @@ def main() -> None: if default_graph.exists(): graph_arg = str(default_graph) - out_path, agg = _reflect( - memory_dir=Path(opts.memory_dir), - out_path=Path(opts.out), - graph_path=Path(graph_arg) if graph_arg else None, - analysis_path=Path(opts.analysis) if opts.analysis else None, - labels_path=Path(opts.labels) if opts.labels else None, - half_life_days=opts.half_life_days, - min_corroboration=opts.min_corroboration, - ) - c = agg["counts"] - print( - f"Reflected {agg['total']} memories " - f"({c['useful']} useful, {c['dead_end']} dead ends, " - f"{c['corrected']} corrected) -> {out_path}" - ) + _gp = Path(graph_arg) if graph_arg else None + if opts.if_stale and _lessons_fresh(Path(opts.out), Path(opts.memory_dir), _gp): + print(f"Lessons already up to date -> {opts.out} (skipped; omit --if-stale to force)") + else: + out_path, agg = _reflect( + memory_dir=Path(opts.memory_dir), + out_path=Path(opts.out), + graph_path=_gp, + analysis_path=Path(opts.analysis) if opts.analysis else None, + labels_path=Path(opts.labels) if opts.labels else None, + half_life_days=opts.half_life_days, + min_corroboration=opts.min_corroboration, + ) + c = agg["counts"] + print( + f"Reflected {agg['total']} memories " + f"({c['useful']} useful, {c['dead_end']} dead ends, " + f"{c['corrected']} corrected) -> {out_path}" + ) elif cmd == "path": if len(sys.argv) < 4: print( diff --git a/graphify/reflect.py b/graphify/reflect.py index 1c697a3..b5498b4 100644 --- a/graphify/reflect.py +++ b/graphify/reflect.py @@ -485,6 +485,39 @@ def render_lessons_md(agg: dict[str, Any]) -> str: # --- orchestrator -------------------------------------------------------------- +def lessons_fresh(out_path: Path, memory_dir: Path, + graph_path: Path | None = None) -> bool: + """True if ``out_path`` exists and is at least as new as every input that + feeds it (the memory docs, and the graph when one is used). + + Lets ``graphify reflect --if-stale`` skip a redundant run — e.g. when the git + post-commit hook just regenerated ``LESSONS.md`` and an agent then runs reflect + again at the start of a session. A missing output is never fresh (it must be + built). Mtime-based and best-effort; it only gates whether to *recompute*, not + what the recomputation produces (that stays deterministic). + """ + out_path = Path(out_path) + try: + out_mtime = out_path.stat().st_mtime + except OSError: + return False # missing/unreadable -> must build + newest = 0.0 + md = Path(memory_dir) + if md.is_dir(): + for f in md.glob("*.md"): + try: + newest = max(newest, f.stat().st_mtime) + except OSError: + pass + if graph_path is not None: + gp = Path(graph_path) + try: + newest = max(newest, gp.stat().st_mtime) + except OSError: + pass + return out_mtime >= newest + + def reflect(memory_dir: Path, out_path: Path, graph_path: Path | None = None, analysis_path: Path | None = None, diff --git a/graphify/skills/agents/references/query.md b/graphify/skills/agents/references/query.md index 71dfedd..52321f1 100644 --- a/graphify/skills/agents/references/query.md +++ b/graphify/skills/agents/references/query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/graphify/skills/amp/references/query.md b/graphify/skills/amp/references/query.md index 71dfedd..52321f1 100644 --- a/graphify/skills/amp/references/query.md +++ b/graphify/skills/amp/references/query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/graphify/skills/claude/references/query.md b/graphify/skills/claude/references/query.md index 71dfedd..52321f1 100644 --- a/graphify/skills/claude/references/query.md +++ b/graphify/skills/claude/references/query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/graphify/skills/claw/references/query.md b/graphify/skills/claw/references/query.md index 71dfedd..52321f1 100644 --- a/graphify/skills/claw/references/query.md +++ b/graphify/skills/claw/references/query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/graphify/skills/codex/references/query.md b/graphify/skills/codex/references/query.md index 71dfedd..52321f1 100644 --- a/graphify/skills/codex/references/query.md +++ b/graphify/skills/codex/references/query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/graphify/skills/copilot/references/query.md b/graphify/skills/copilot/references/query.md index 71dfedd..52321f1 100644 --- a/graphify/skills/copilot/references/query.md +++ b/graphify/skills/copilot/references/query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/graphify/skills/droid/references/query.md b/graphify/skills/droid/references/query.md index 71dfedd..52321f1 100644 --- a/graphify/skills/droid/references/query.md +++ b/graphify/skills/droid/references/query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/graphify/skills/kilo/references/query.md b/graphify/skills/kilo/references/query.md index 71dfedd..52321f1 100644 --- a/graphify/skills/kilo/references/query.md +++ b/graphify/skills/kilo/references/query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/graphify/skills/kiro/references/query.md b/graphify/skills/kiro/references/query.md index 71dfedd..52321f1 100644 --- a/graphify/skills/kiro/references/query.md +++ b/graphify/skills/kiro/references/query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/graphify/skills/opencode/references/query.md b/graphify/skills/opencode/references/query.md index 71dfedd..52321f1 100644 --- a/graphify/skills/opencode/references/query.md +++ b/graphify/skills/opencode/references/query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/graphify/skills/pi/references/query.md b/graphify/skills/pi/references/query.md index 71dfedd..52321f1 100644 --- a/graphify/skills/pi/references/query.md +++ b/graphify/skills/pi/references/query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/graphify/skills/trae/references/query.md b/graphify/skills/trae/references/query.md index 71dfedd..52321f1 100644 --- a/graphify/skills/trae/references/query.md +++ b/graphify/skills/trae/references/query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/graphify/skills/vscode/references/query.md b/graphify/skills/vscode/references/query.md index 71dfedd..52321f1 100644 --- a/graphify/skills/vscode/references/query.md +++ b/graphify/skills/vscode/references/query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/graphify/skills/windows/references/query.md b/graphify/skills/windows/references/query.md index 71dfedd..52321f1 100644 --- a/graphify/skills/windows/references/query.md +++ b/graphify/skills/windows/references/query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tests/test_reflect.py b/tests/test_reflect.py index 2a7660a..8cd581d 100644 --- a/tests/test_reflect.py +++ b/tests/test_reflect.py @@ -22,6 +22,7 @@ import pytest from graphify.ingest import save_query_result from graphify.reflect import ( aggregate_lessons, + lessons_fresh, load_memory_docs, parse_memory_doc, reflect, @@ -564,3 +565,69 @@ def _make_graph(tmp_path: Path) -> Path: json.dumps({str(cid): f"Community {cid}" for cid in communities}) ) return out + + +# --- lessons_fresh / `reflect --if-stale` ------------------------------------- + +def test_lessons_fresh_missing_output_is_not_fresh(tmp_path): + mem = tmp_path / "memory"; mem.mkdir() + (mem / "q.md").write_text("x", encoding="utf-8") + assert lessons_fresh(tmp_path / "LESSONS.md", mem) is False # must build + + +def test_lessons_fresh_true_when_output_newer_than_inputs(tmp_path): + import os + mem = tmp_path / "memory"; mem.mkdir() + doc = mem / "q.md"; doc.write_text("x", encoding="utf-8") + out = tmp_path / "LESSONS.md"; out.write_text("y", encoding="utf-8") + os.utime(doc, (1000, 1000)) + os.utime(out, (2000, 2000)) + assert lessons_fresh(out, mem) is True + + +def test_lessons_fresh_false_when_memory_newer(tmp_path): + import os + mem = tmp_path / "memory"; mem.mkdir() + doc = mem / "q.md"; doc.write_text("x", encoding="utf-8") + out = tmp_path / "LESSONS.md"; out.write_text("y", encoding="utf-8") + os.utime(out, (1000, 1000)) + os.utime(doc, (2000, 2000)) # a new outcome was saved after the last reflect + assert lessons_fresh(out, mem) is False + + +def test_lessons_fresh_false_when_graph_newer(tmp_path): + import os + mem = tmp_path / "memory"; mem.mkdir() + (mem / "q.md").write_text("x", encoding="utf-8") + out = tmp_path / "LESSONS.md"; out.write_text("y", encoding="utf-8") + graph = tmp_path / "graph.json"; graph.write_text("{}", encoding="utf-8") + os.utime(mem / "q.md", (1000, 1000)) + os.utime(out, (1500, 1500)) + os.utime(graph, (2000, 2000)) # graph rebuilt since last reflect -> stale + assert lessons_fresh(out, mem, graph) is False + + +def test_cli_reflect_if_stale_skips_when_fresh(tmp_path): + """`reflect --if-stale` skips the rebuild when LESSONS.md is already current, + and still runs when a new outcome arrives.""" + out = _make_graph(tmp_path) + real = json.loads((out / "graph.json").read_text())["nodes"][0]["label"] + _run(["save-result", "--question", "q", "--answer", "a", + "--nodes", real, "--outcome", "useful"], tmp_path) + first = _run(["reflect"], tmp_path) + assert first.returncode == 0 + lessons = out / "reflections" / "LESSONS.md" + body_before = lessons.read_text(encoding="utf-8") + + # Second call with --if-stale: nothing changed -> skipped, file untouched. + skipped = _run(["reflect", "--if-stale"], tmp_path) + assert skipped.returncode == 0 + assert "up to date" in (skipped.stdout + skipped.stderr).lower() + assert lessons.read_text(encoding="utf-8") == body_before + + # A new outcome makes it stale -> --if-stale runs again. + _run(["save-result", "--question", "q2", "--answer", "a", + "--nodes", real, "--outcome", "useful"], tmp_path) + ran = _run(["reflect", "--if-stale"], tmp_path) + assert ran.returncode == 0 + assert "up to date" not in (ran.stdout + ran.stderr).lower() diff --git a/tools/skillgen/expected/graphify__skills__agents__references__query.md b/tools/skillgen/expected/graphify__skills__agents__references__query.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/expected/graphify__skills__agents__references__query.md +++ b/tools/skillgen/expected/graphify__skills__agents__references__query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tools/skillgen/expected/graphify__skills__amp__references__query.md b/tools/skillgen/expected/graphify__skills__amp__references__query.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/expected/graphify__skills__amp__references__query.md +++ b/tools/skillgen/expected/graphify__skills__amp__references__query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tools/skillgen/expected/graphify__skills__claude__references__query.md b/tools/skillgen/expected/graphify__skills__claude__references__query.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/expected/graphify__skills__claude__references__query.md +++ b/tools/skillgen/expected/graphify__skills__claude__references__query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tools/skillgen/expected/graphify__skills__claw__references__query.md b/tools/skillgen/expected/graphify__skills__claw__references__query.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/expected/graphify__skills__claw__references__query.md +++ b/tools/skillgen/expected/graphify__skills__claw__references__query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tools/skillgen/expected/graphify__skills__codex__references__query.md b/tools/skillgen/expected/graphify__skills__codex__references__query.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/expected/graphify__skills__codex__references__query.md +++ b/tools/skillgen/expected/graphify__skills__codex__references__query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tools/skillgen/expected/graphify__skills__copilot__references__query.md b/tools/skillgen/expected/graphify__skills__copilot__references__query.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/expected/graphify__skills__copilot__references__query.md +++ b/tools/skillgen/expected/graphify__skills__copilot__references__query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tools/skillgen/expected/graphify__skills__droid__references__query.md b/tools/skillgen/expected/graphify__skills__droid__references__query.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/expected/graphify__skills__droid__references__query.md +++ b/tools/skillgen/expected/graphify__skills__droid__references__query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tools/skillgen/expected/graphify__skills__kilo__references__query.md b/tools/skillgen/expected/graphify__skills__kilo__references__query.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/expected/graphify__skills__kilo__references__query.md +++ b/tools/skillgen/expected/graphify__skills__kilo__references__query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tools/skillgen/expected/graphify__skills__kiro__references__query.md b/tools/skillgen/expected/graphify__skills__kiro__references__query.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/expected/graphify__skills__kiro__references__query.md +++ b/tools/skillgen/expected/graphify__skills__kiro__references__query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tools/skillgen/expected/graphify__skills__opencode__references__query.md b/tools/skillgen/expected/graphify__skills__opencode__references__query.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/expected/graphify__skills__opencode__references__query.md +++ b/tools/skillgen/expected/graphify__skills__opencode__references__query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tools/skillgen/expected/graphify__skills__pi__references__query.md b/tools/skillgen/expected/graphify__skills__pi__references__query.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/expected/graphify__skills__pi__references__query.md +++ b/tools/skillgen/expected/graphify__skills__pi__references__query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tools/skillgen/expected/graphify__skills__trae__references__query.md b/tools/skillgen/expected/graphify__skills__trae__references__query.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/expected/graphify__skills__trae__references__query.md +++ b/tools/skillgen/expected/graphify__skills__trae__references__query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tools/skillgen/expected/graphify__skills__vscode__references__query.md b/tools/skillgen/expected/graphify__skills__vscode__references__query.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/expected/graphify__skills__vscode__references__query.md +++ b/tools/skillgen/expected/graphify__skills__vscode__references__query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tools/skillgen/expected/graphify__skills__windows__references__query.md b/tools/skillgen/expected/graphify__skills__windows__references__query.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/expected/graphify__skills__windows__references__query.md +++ b/tools/skillgen/expected/graphify__skills__windows__references__query.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. --- diff --git a/tools/skillgen/fragments/references/query/default.md b/tools/skillgen/fragments/references/query/default.md index 71dfedd..52321f1 100644 --- a/tools/skillgen/fragments/references/query/default.md +++ b/tools/skillgen/fragments/references/query/default.md @@ -179,7 +179,7 @@ Replace `ORIGINAL_QUESTION` with the user's verbatim question, `ANSWER` with you - `dead_end` — the question/path led nowhere; don't re-derive it next time. - `corrected` — the saved answer was wrong; `--correction` records what was right. -At the **start** of graph work, refresh and read the lessons: run `graphify reflect` (cheap, deterministic, no LLM, and a no-op when no outcomes have been saved yet), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself means the lessons stay current even without the git hook installed; if the post-commit hook *is* installed, it also refreshes the file automatically after each rebuild. +At the **start** of graph work, refresh and read the lessons: run `graphify reflect --if-stale` (cheap, deterministic, no LLM; `--if-stale` makes it a no-op when `LESSONS.md` is already newer than every input, e.g. when the git hook just refreshed it), then read `graphify-out/reflections/LESSONS.md`. It lists **preferred sources** (start there), **known dead ends** (skip them), and prior **corrections**. Running `reflect` yourself keeps the lessons current even without the git hook installed; if the post-commit hook *is* installed, `--if-stale` means your session-start run costs almost nothing. ---