fix: feat: planner journal pattern — daily raw files + periodic summarization (#361)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
openhands 2026-03-21 08:57:06 +00:00
parent a698b8e540
commit 83ec300c0e
3 changed files with 47 additions and 10 deletions

View file

@ -17,6 +17,7 @@ model = "opus"
[context] [context]
files = ["VISION.md", "AGENTS.md", "RESOURCES.md"] files = ["VISION.md", "AGENTS.md", "RESOURCES.md"]
# Recent planner/journal/*.md files are loaded by planner-run.sh (last 5 entries)
[[steps]] [[steps]]
id = "preflight" id = "preflight"
@ -236,11 +237,11 @@ needs = ["prediction-triage"]
[[steps]] [[steps]]
id = "journal-and-memory" id = "journal-and-memory"
title = "Write journal entry and update planner memory" title = "Write journal entry and periodically update planner memory"
description = """ 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: Create a daily journal file at:
$FACTORY_ROOT/planner/journal/$(date -u +%Y-%m-%d).md $FACTORY_ROOT/planner/journal/$(date -u +%Y-%m-%d).md
@ -267,22 +268,38 @@ Format:
Keep each entry concise 30-50 lines max. 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
"<!-- summarized-through-run: N -->" 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:
<!-- summarized-through-run: N -->
where N is the current total run count.
Include: 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 observed (resource state, metric trends, project progress)
- What was decided (issues created, predictions triaged, what was deferred) - Strategic direction and watch list for future runs
- Patterns and learnings useful for future planning runs
- Things to watch for next time - Things to watch for next time
Rules: Rules:
- Keep under 100 lines total - 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 - Focus on PATTERNS and LEARNINGS, not transient state
- Do NOT include specific issue counts or numbers that will be stale - 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 - Most recent entries at top
Format: simple markdown with dated sections. Format: simple markdown with dated sections.

View file

@ -1,3 +1,4 @@
<!-- summarized-through-run: 1 -->
# Planner Memory # Planner Memory
## 2026-03-21 — Second planner run ## 2026-03-21 — Second planner run

View file

@ -55,6 +55,25 @@ $(cat "$MEMORY_FILE")
" "
fi 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) ─────────────────────────────── # ── Read scratch file (compaction survival) ───────────────────────────────
SCRATCH_CONTEXT=$(read_scratch_context "$SCRATCH_FILE") SCRATCH_CONTEXT=$(read_scratch_context "$SCRATCH_FILE")
SCRATCH_INSTRUCTION=$(build_scratch_instruction "$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. 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 ## Project context
${CONTEXT_BLOCK}${MEMORY_BLOCK} ${CONTEXT_BLOCK}${MEMORY_BLOCK}${JOURNAL_BLOCK}
${SCRATCH_CONTEXT:+${SCRATCH_CONTEXT} ${SCRATCH_CONTEXT:+${SCRATCH_CONTEXT}
} }
## Formula ## Formula