Rewrite run-planner.toml from 648 lines (6 steps) to 243 lines (3 steps): - preflight → triage-and-plan → journal-and-commit - Graph report (build-graph.py) replaces manual repo scanning - tea CLI helpers replace inline curl commands - One issue body template instead of three copies - Graph bottlenecks + thin objectives replace hardcoded constraint patterns Update planner-run.sh to generate and inject graph report (same pattern as predictor-run.sh). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
243 lines
9.1 KiB
TOML
243 lines
9.1 KiB
TOML
# formulas/run-planner.toml — Strategic planning formula (v4: graph-driven)
|
|
#
|
|
# Executed directly by planner-run.sh via cron — no action issues.
|
|
# planner-run.sh creates a tmux session with Claude (opus) and injects
|
|
# this formula as context, plus the graph report from build-graph.py.
|
|
#
|
|
# Steps: preflight → triage-and-plan → journal-and-commit
|
|
#
|
|
# v4 changes from v3:
|
|
# - Graph report (orphans, cycles, thin objectives, bottlenecks) replaces
|
|
# manual repo scanning and hardcoded constraint patterns.
|
|
# - tea CLI helpers replace inline curl commands.
|
|
# - 3 steps instead of 6.
|
|
#
|
|
# AGENTS.md maintenance is handled by the gardener (#246).
|
|
# All git writes (tree, journal, memory) happen in one commit at the end.
|
|
|
|
name = "run-planner"
|
|
description = "Planner v4: graph-driven planning with tea helpers"
|
|
version = 4
|
|
model = "opus"
|
|
|
|
[context]
|
|
files = ["VISION.md", "AGENTS.md", "RESOURCES.md", "planner/prerequisite-tree.md"]
|
|
# Recent planner/journal/*.md files + graph report loaded by planner-run.sh
|
|
|
|
[[steps]]
|
|
id = "preflight"
|
|
title = "Pull latest code, run graph, load context"
|
|
description = """
|
|
1. Change to the project repository:
|
|
cd "$PROJECT_REPO_ROOT"
|
|
|
|
2. Pull the latest code:
|
|
git fetch origin "$PRIMARY_BRANCH" --quiet
|
|
git checkout "$PRIMARY_BRANCH" --quiet
|
|
git pull --ff-only origin "$PRIMARY_BRANCH" --quiet
|
|
|
|
3. Record the current HEAD SHA:
|
|
HEAD_SHA=$(git rev-parse HEAD)
|
|
echo "$HEAD_SHA" > /tmp/planner-head-sha
|
|
|
|
4. Read the planner memory file at: $PROJECT_REPO_ROOT/planner/MEMORY.md
|
|
If it does not exist, this is the first planning run.
|
|
|
|
5. Read the prerequisite tree at: $PROJECT_REPO_ROOT/planner/prerequisite-tree.md
|
|
If it does not exist, create an initial tree from VISION.md in the next step.
|
|
|
|
6. Read the graph report injected into the prompt (## Structural analysis).
|
|
This JSON contains: orphans, cycles, disconnected clusters, thin_objectives,
|
|
bottlenecks (by betweenness centrality). Use it instead of manual file scanning.
|
|
"""
|
|
|
|
[[steps]]
|
|
id = "triage-and-plan"
|
|
title = "Triage predictions, update tree, file at constraints"
|
|
description = """
|
|
One unified step replacing the former prediction-triage, update-prerequisite-tree,
|
|
and file-at-constraints steps.
|
|
|
|
### Part A: Triage predictions
|
|
|
|
1. Fetch unreviewed predictions:
|
|
curl -sf -H "Authorization: token $FORGE_TOKEN" \
|
|
"$FORGE_API/issues?state=open&type=issues&labels=prediction%2Funreviewed&limit=50"
|
|
If none, skip to Part B.
|
|
|
|
2. Fetch all open issues (for overlap check):
|
|
curl -sf -H "Authorization: token $FORGE_TOKEN" \
|
|
"$FORGE_API/issues?state=open&type=issues&limit=50"
|
|
|
|
3. Read available formulas: $FACTORY_ROOT/formulas/*.toml and $PROJECT_REPO_ROOT/formulas/*.toml
|
|
|
|
4. For each prediction, choose one action:
|
|
- PROMOTE_ACTION: maps to a formula -> create action issue, close prediction
|
|
- PROMOTE_BACKLOG: warrants dev work -> create backlog issue, close prediction
|
|
- WATCH: not urgent -> comment why, relabel to prediction/backlog, keep open
|
|
- DISMISS: noise or covered -> comment reasoning, close prediction
|
|
|
|
5. Execute triage using tea helpers:
|
|
- Create issues: tea_file_issue "<title>" "<body>" "backlog" (or "action")
|
|
- Relabel: tea_relabel <num> "prediction/actioned" (or "prediction/backlog")
|
|
- Comment: tea_comment <num> "<reasoning>"
|
|
- Close: tea_close <num>
|
|
|
|
Issue body template (gardener quality gate requires these sections):
|
|
## Problem
|
|
<what the prediction identified>
|
|
|
|
## Proposed solution
|
|
<approach>
|
|
|
|
## Affected files
|
|
- <file1>
|
|
|
|
## Acceptance criteria
|
|
- [ ] <criterion>
|
|
- [ ] CI green
|
|
|
|
Every decision MUST include reasoning in a comment on the prediction issue.
|
|
|
|
### Part B: Update prerequisite tree
|
|
|
|
Read these inputs:
|
|
- VISION.md, RESOURCES.md, planner memory (from preflight)
|
|
- Graph report: orphans, cycles, thin_objectives, bottlenecks, disconnected
|
|
- Open issues (from Part A or fresh fetch)
|
|
- Recently closed issues:
|
|
curl -sf -H "Authorization: token $FORGE_TOKEN" \
|
|
"$FORGE_API/issues?state=closed&type=issues&limit=50&sort=updated&direction=desc"
|
|
|
|
Update the tree:
|
|
1. Mark resolved prerequisites ([x]) — check if issue closed or capability present
|
|
2. Recalculate objective status (READY/BLOCKED/DONE)
|
|
3. Add new prerequisites discovered from graph report
|
|
4. Add new objectives from VISION.md not yet in tree
|
|
5. Check vault state: vault/pending/*.md (blocked-on-vault), vault/fired/*.md (resolved?)
|
|
6. Check RESOURCES.md for newly available capabilities
|
|
|
|
Bounce/stuck detection — for issues in the tree, fetch recent comments:
|
|
curl -sf -H "Authorization: token $FORGE_TOKEN" \
|
|
"$FORGE_API/issues/<number>/comments?limit=10"
|
|
Signals: BOUNCED (too_large, underspecified), ESCALATED (needs human decision),
|
|
LABEL_CHURN (3+ relabels between backlog/underspecified).
|
|
Track as stuck_issues[] for constraint filing below.
|
|
|
|
Hold the updated tree in memory — written to disk in journal-and-commit.
|
|
|
|
Tree format:
|
|
# Prerequisite Tree
|
|
<!-- Last updated: YYYY-MM-DD -->
|
|
|
|
## Objective: <name> (#issue or description)
|
|
- [x] Resolved prerequisite (reference)
|
|
- [ ] Unresolved prerequisite (#issue or description)
|
|
- [ ] Resource need blocked-on-vault (vault/pending/<id>.md)
|
|
Status: READY | BLOCKED — <reason> | DONE
|
|
|
|
### Part C: File at constraints
|
|
|
|
From the updated tree + graph bottlenecks, identify the top 5 constraints.
|
|
A constraint is an unresolved prerequisite blocking the most downstream objectives.
|
|
Graph bottlenecks (high betweenness centrality) and thin objectives inform ranking.
|
|
|
|
Stuck issue handling:
|
|
- BOUNCED/LABEL_CHURN: do NOT re-promote. Dispatch groom-backlog formula instead:
|
|
tea_file_issue "chore: break down #<N> — bounced <count>x" "<body>" "action"
|
|
- ESCALATED: skip, mark in tree as "escalated — awaiting human decision"
|
|
|
|
Filing gate (for non-stuck constraints):
|
|
1. Check if issue already exists (match by #number in tree or title search)
|
|
2. If no issue, create one with tea_file_issue using the template above
|
|
3. If issue exists and is open, skip — no duplicates
|
|
|
|
Priority label sync:
|
|
- Add priority to current top-5 constraint issues (if missing):
|
|
tea_relabel <num> "backlog,priority"
|
|
- Remove priority from issues no longer in top 5:
|
|
curl -sf -X DELETE -H "Authorization: token $FORGE_TOKEN" \
|
|
"$FORGE_API/issues/<num>/labels/<priority_label_id>"
|
|
|
|
Vault procurement: if a constraint needs a resource not in RESOURCES.md with
|
|
recurring cost, create vault/pending/<resource-id>.md instead of an issue.
|
|
|
|
Rules:
|
|
- Maximum 5 items per run (issues + procurement combined)
|
|
- No issues filed past the bottleneck
|
|
- Leave existing premature issues as-is
|
|
- Only reference formulas that exist on disk
|
|
- Do NOT file issues for objectives blocked on pending vault items
|
|
- Promoted predictions may become constraints — rank them equally
|
|
|
|
CRITICAL: If any part of this step fails, log the failure and continue.
|
|
"""
|
|
needs = ["preflight"]
|
|
|
|
[[steps]]
|
|
id = "journal-and-commit"
|
|
title = "Write tree, journal, optional memory; commit and PR"
|
|
description = """
|
|
### 1. Write prerequisite tree
|
|
Write to: $PROJECT_REPO_ROOT/planner/prerequisite-tree.md
|
|
|
|
### 2. Write journal entry
|
|
Create/append to: $PROJECT_REPO_ROOT/planner/journal/$(date -u +%Y-%m-%d).md
|
|
|
|
Format:
|
|
# Planner run — YYYY-MM-DD HH:MM UTC
|
|
|
|
## Predictions triaged
|
|
- #NNN: ACTION — reasoning (or "No unreviewed predictions")
|
|
|
|
## Prerequisite tree updates
|
|
- Resolved: <list> - Discovered: <list> - Proposed: <list>
|
|
|
|
## Top 5 constraints
|
|
1. <prerequisite> — blocks N objectives — #NNN (existing|filed)
|
|
|
|
## Stuck issues detected
|
|
- #NNN: BOUNCED (Nx) — dispatched groom-backlog as #MMM
|
|
(or "No stuck issues detected")
|
|
|
|
## Issues created
|
|
- #NNN: title — why (or "No new issues")
|
|
|
|
## Priority label changes
|
|
- Added/removed priority: #NNN (or "No priority changes")
|
|
|
|
## Observations
|
|
- Key patterns noticed this run
|
|
|
|
## Deferred
|
|
- Items in tree beyond top 5, why not filed
|
|
|
|
Keep concise — 30-50 lines max.
|
|
|
|
### 3. Memory update (every 5th run)
|
|
Count "# Planner run —" headers across all journal files.
|
|
Check "<!-- summarized-through-run: N -->" in MEMORY.md.
|
|
If (count - N) >= 5 or MEMORY.md missing, write to:
|
|
$PROJECT_REPO_ROOT/planner/MEMORY.md
|
|
Include: run counter marker, date, constraint focus, patterns, direction.
|
|
Keep under 100 lines. Replace entire file.
|
|
|
|
### 4. Commit and PR
|
|
If no file changes (git status --porcelain), skip.
|
|
Otherwise:
|
|
BRANCH="chore/planner-$(date -u +%Y%m%d-%H%M)"
|
|
git checkout -B "$BRANCH"
|
|
git add planner/prerequisite-tree.md planner/journal/ planner/MEMORY.md
|
|
git add -u
|
|
git diff --cached --quiet && skip
|
|
git commit -m "chore: planner run $(date -u +%Y-%m-%d)"
|
|
git push -u origin "$BRANCH"
|
|
Create PR via forge API:
|
|
curl -sf -X POST -H "Authorization: token $FORGE_TOKEN" \
|
|
-H "Content-Type: application/json" "$FORGE_API/pulls" \
|
|
-d '{"title":"chore: planner run — prerequisite tree update",
|
|
"head":"<branch>","base":"<primary-branch>",
|
|
"body":"Automated planner run — prerequisite tree update and journal entry."}'
|
|
git checkout "$PRIMARY_BRANCH"
|
|
"""
|
|
needs = ["triage-and-plan"]
|