disinto/formulas/run-planner.toml
johba 71fe89cdd0 fix: {project}-ops repo — separate operations from code (#757) (#767)
Fixes #757

## Changes
Separate operations from code into {project}-ops repo pattern. Added OPS_REPO_ROOT infrastructure (env.sh, load-project.sh, formula-session.sh with ensure_ops_repo helper). Updated all 8 agent scripts and 7 formulas to read/write vault items, journals, evidence, prerequisites, RESOURCES.md, and knowledge from the ops repo. Added setup_ops_repo() to disinto init for automatic ops repo creation and seeding. Removed migrated data from code repo (vault data dirs, planner journal/memory/prerequisites, supervisor journal/best-practices, evidence, RESOURCES.md). Updated all documentation. 55 files changed, ShellCheck clean, all 38 phase tests pass.

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/767
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-26 19:55:12 +01:00

282 lines
11 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 and prerequisites.md loaded from ops repo (ops: prefix)
# Recent journal/planner/*.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: $OPS_REPO_ROOT/knowledge/planner-memory.md
If it does not exist, this is the first planning run.
5. Read the prerequisite tree at: $OPS_REPO_ROOT/prerequisites.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 of two actions (no fence-sitting):
- ACTION: agree with the prediction -> create a backlog or action issue,
relabel to prediction/actioned, close the prediction
- DISMISS: disagree or noise -> comment reasoning, relabel to
prediction/dismissed, close the prediction
If a dismissed prediction is real, the predictor will re-file it with
stronger evidence next run. The issue history is the predictor's memory.
5. Execute triage using tea helpers:
- Create issues: tea_file_issue "<title>" "<body>" "backlog" (or "action")
- Relabel: tea_relabel <num> "prediction/actioned" (or "prediction/dismissed")
- 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
- Portfolio: ## Addressables and ## Observables tables in AGENTS.md —
use these as the concrete inventory of what the factory has produced.
Plan toward making addressables observable (measurement wired).
Vision changes (#733) should trigger a review of these tables.
- 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: $OPS_REPO_ROOT/vault/pending/*.md + $OPS_REPO_ROOT/vault/approved/*.md (blocked-on-vault), $OPS_REPO_ROOT/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),
LABEL_CHURN (3+ relabels between backlog/underspecified).
If an issue needs a human decision or external resource, it is HUMAN_BLOCKED.
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 ($OPS_REPO_ROOT/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"
- HUMAN_BLOCKED (needs human decision or external resource): file a vault
procurement item instead of skipping. First check for duplicates across ALL
vault directories (pending/, approved/, fired/) if a file with the same
slug already exists in any of them, do NOT create a new one.
Naming: $OPS_REPO_ROOT/vault/pending/<project>-<slug>.md (e.g. disinto-github-org.md).
Write with this template:
# Request: <short description>
## What
<description of the resource or decision needed>
## Why
Blocks #<issue> (<title>), which blocks <downstream objective>.
Waiting since <date constraint was first identified>.
## Human action
1. <concrete step>
2. <concrete step>
3. Paste result here or in #<issue>
## Factory will then
- <what the factory does once the resource is available>
- <downstream work that unblocks>
## Unblocks
- #<issue> — <title>
Then mark the prerequisite in the tree as "blocked-on-vault ($OPS_REPO_ROOT/vault/pending/<id>.md)".
Do NOT skip or mark as "awaiting human decision" the vault owns the human interface.
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 $OPS_REPO_ROOT/vault/pending/<project>-<slug>.md instead of an issue.
Use the same template as HUMAN_BLOCKED above (What/Why/Human action/Factory will then/Unblocks).
Dedup: check $OPS_REPO_ROOT/vault/pending/ + $OPS_REPO_ROOT/vault/approved/ + $OPS_REPO_ROOT/vault/fired/ before creating.
Rules:
- Action budget: the planner may create at most (predictions_addressed + 1)
new issues per run if any predictions were triaged, or 4 if no predictions.
This covers issues from Part A promotions + Part C constraint filing 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: $OPS_REPO_ROOT/prerequisites.md
### 2. Write journal entry
Create/append to: $OPS_REPO_ROOT/journal/planner/$(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")
## Vault items filed
- $OPS_REPO_ROOT/vault/pending/<id>.md <what> blocks #NNN
(or "No vault items filed")
## 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 planner-memory.md.
If (count - N) >= 5 or planner-memory.md missing, write to:
$OPS_REPO_ROOT/knowledge/planner-memory.md
Include: run counter marker, date, constraint focus, patterns, direction.
Keep under 100 lines. Replace entire file.
### 4. Commit ops repo changes
Commit the ops repo changes (prerequisites, journal, memory, vault items):
cd "$OPS_REPO_ROOT"
git add prerequisites.md journal/planner/ knowledge/planner-memory.md vault/pending/
git add -u
if ! git diff --cached --quiet; then
git commit -m "chore: planner run $(date -u +%Y-%m-%d)"
git push origin "$PRIMARY_BRANCH"
fi
cd "$PROJECT_REPO_ROOT"
"""
needs = ["triage-and-plan"]