From 83ec300c0e1ece493a6e1cb33b3ca4d42576d862 Mon Sep 17 00:00:00 2001 From: openhands Date: Sat, 21 Mar 2026 08:57:06 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20feat:=20planner=20journal=20pattern=20?= =?UTF-8?q?=E2=80=94=20daily=20raw=20files=20+=20periodic=20summarization?= =?UTF-8?q?=20(#361)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 (1M context) --- formulas/run-planner.toml | 35 ++++++++++++++++++++++++++--------- planner/MEMORY.md | 1 + planner/planner-run.sh | 21 ++++++++++++++++++++- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/formulas/run-planner.toml b/formulas/run-planner.toml index c2ab01b..67ff914 100644 --- a/formulas/run-planner.toml +++ b/formulas/run-planner.toml @@ -17,6 +17,7 @@ model = "opus" [context] files = ["VISION.md", "AGENTS.md", "RESOURCES.md"] +# Recent planner/journal/*.md files are loaded by planner-run.sh (last 5 entries) [[steps]] id = "preflight" @@ -236,11 +237,11 @@ needs = ["prediction-triage"] [[steps]] id = "journal-and-memory" -title = "Write journal entry and update planner memory" +title = "Write journal entry and periodically update planner memory" description = """ -Two outputs from this step: +Two outputs from this step — journal is ALWAYS written, memory is PERIODIC. -### 1. Journal entry (committed to git) +### 1. Journal entry (always — committed to git) Create a daily journal file at: $FACTORY_ROOT/planner/journal/$(date -u +%Y-%m-%d).md @@ -267,22 +268,38 @@ Format: Keep each entry concise — 30-50 lines max. -### 2. Memory update (committed to git) +### 2. Memory update (periodic — every 5th run, committed to git) -Write to: $FACTORY_ROOT/planner/MEMORY.md (replace the entire file) +Decide whether to update memory: +1. Count the total number of run entries across ALL journal files in + planner/journal/*.md. Each "# Planner run —" header counts as one run. +2. Check the run count noted in MEMORY.md (look for the + "" marker at the top). + If the marker is missing, treat it as 0. +3. If (current_run_count - last_summarized_count) >= 5, OR if MEMORY.md + does not exist, perform the memory update below. +4. Otherwise, skip the memory update — MEMORY.md remains read-only context. + +When updating memory, write to: $FACTORY_ROOT/planner/MEMORY.md +(replace the entire file) + +Start the file with the run counter marker: + +where N is the current total run count. Include: -- Date of this run +- Date of this summarization +- Distilled patterns and learnings from recent journal entries - What was observed (resource state, metric trends, project progress) -- What was decided (issues created, predictions triaged, what was deferred) -- Patterns and learnings useful for future planning runs +- Strategic direction and watch list for future runs - Things to watch for next time Rules: - Keep under 100 lines total -- Replace the file contents — prune outdated entries from previous runs +- Replace the file contents — distill from journal, prune stale entries - Focus on PATTERNS and LEARNINGS, not transient state - Do NOT include specific issue counts or numbers that will be stale +- Read the recent journal files provided in context for source material - Most recent entries at top Format: simple markdown with dated sections. diff --git a/planner/MEMORY.md b/planner/MEMORY.md index 606a676..d4d724a 100644 --- a/planner/MEMORY.md +++ b/planner/MEMORY.md @@ -1,3 +1,4 @@ + # Planner Memory ## 2026-03-21 — Second planner run diff --git a/planner/planner-run.sh b/planner/planner-run.sh index 3ddb6c7..5737983 100755 --- a/planner/planner-run.sh +++ b/planner/planner-run.sh @@ -55,6 +55,25 @@ $(cat "$MEMORY_FILE") " fi +# ── Read recent journal files ────────────────────────────────────────── +JOURNAL_BLOCK="" +JOURNAL_DIR="$FACTORY_ROOT/planner/journal" +if [ -d "$JOURNAL_DIR" ]; then + # Load last 5 journal files (most recent first) for run history context + JOURNAL_FILES=$(find "$JOURNAL_DIR" -name '*.md' -type f | sort -r | head -5) + if [ -n "$JOURNAL_FILES" ]; then + JOURNAL_BLOCK=" +### Recent journal entries (planner/journal/) +" + while IFS= read -r jf; do + JOURNAL_BLOCK="${JOURNAL_BLOCK} +#### $(basename "$jf") +$(cat "$jf") +" + done <<< "$JOURNAL_FILES" + fi +fi + # ── Read scratch file (compaction survival) ─────────────────────────────── SCRATCH_CONTEXT=$(read_scratch_context "$SCRATCH_FILE") SCRATCH_INSTRUCTION=$(build_scratch_instruction "$SCRATCH_FILE") @@ -70,7 +89,7 @@ build_prompt_footer " PROMPT="You are the strategic planner for ${CODEBERG_REPO}. Work through the formula below. You MUST write PHASE:done to '${PHASE_FILE}' when finished — the orchestrator will time you out if you return to the prompt without signalling. ## Project context -${CONTEXT_BLOCK}${MEMORY_BLOCK} +${CONTEXT_BLOCK}${MEMORY_BLOCK}${JOURNAL_BLOCK} ${SCRATCH_CONTEXT:+${SCRATCH_CONTEXT} } ## Formula