Merge pull request 'fix: feat: planner triages prediction/unreviewed issues alongside gap analysis (#142)' (#358) from fix/issue-142 into main

This commit is contained in:
johba 2026-03-20 10:44:02 +01:00
commit ff32124508
2 changed files with 99 additions and 22 deletions

View file

@ -153,10 +153,13 @@ Phase 0 (preflight): pull latest code, load persistent memory from
`planner/MEMORY.md`. Phase 1: update the AGENTS.md documentation tree to `planner/MEMORY.md`. Phase 1: update the AGENTS.md documentation tree to
reflect recent code changes (fast-track PR). Phase 1.5: triage reflect recent code changes (fast-track PR). Phase 1.5: triage
`prediction/unreviewed` issues filed by the [Predictor](#predictor-planner) — `prediction/unreviewed` issues filed by the [Predictor](#predictor-planner) —
accept as action/backlog issues or dismiss as noise. Phase 2: strategic planning for each prediction: promote to action, promote to backlog, watch (relabel to
prediction/backlog), or dismiss with reasoning. Promoted predictions compete
with vision gaps for the per-cycle issue limit. Phase 2: strategic planning
via resource+leverage gap analysis — reasons about VISION.md, RESOURCES.md, via resource+leverage gap analysis — reasons about VISION.md, RESOURCES.md,
formula catalog, and project state to create up to 5 backlog issues prioritized formula catalog, and project state to create up to 5 total issues (including
by leverage. Phase 3: persist learnings to `planner/MEMORY.md`. promotions) prioritized by leverage. Phase 3: persist learnings to
`planner/MEMORY.md`.
**Trigger**: `planner-poll.sh` runs weekly via cron. It files an `action` **Trigger**: `planner-poll.sh` runs weekly via cron. It files an `action`
issue referencing `formulas/run-planner.toml`; the [action-agent](#action-action) issue referencing `formulas/run-planner.toml`; the [action-agent](#action-action)
@ -165,7 +168,7 @@ picks it up and executes the planning steps in an interactive Claude tmux sessio
**Key files**: **Key files**:
- `planner/planner-poll.sh` — Cron wrapper: memory guard, dedup check, files action issue - `planner/planner-poll.sh` — Cron wrapper: memory guard, dedup check, files action issue
- `formulas/run-planner.toml` — Execution spec: five steps (preflight, agents-update, - `formulas/run-planner.toml` — Execution spec: five steps (preflight, agents-update,
prediction-triage, strategic-planning, memory-update) with `needs` dependencies. triage-predictions, strategic-planning, memory-update) with `needs` dependencies.
Steps 2 and 3 are independent; step 4 depends on both. Claude executes all steps Steps 2 and 3 are independent; step 4 depends on both. Claude executes all steps
in a single interactive session with tool access in a single interactive session with tool access
- `planner/MEMORY.md` — Persistent memory across runs (gitignored, local only) - `planner/MEMORY.md` — Persistent memory across runs (gitignored, local only)
@ -308,6 +311,10 @@ Issues flow through these states:
| `tech-debt` | Pre-existing issue flagged by AI reviewer, not introduced by a PR. | review-pr.sh (auto-created follow-ups) | | `tech-debt` | Pre-existing issue flagged by AI reviewer, not introduced by a PR. | review-pr.sh (auto-created follow-ups) |
| `underspecified` | Dev-agent refused the issue as too large or vague. | dev-poll.sh (on preflight `too_large`), dev-agent.sh (on mid-run `too_large` refusal) | | `underspecified` | Dev-agent refused the issue as too large or vague. | dev-poll.sh (on preflight `too_large`), dev-agent.sh (on mid-run `too_large` refusal) |
| `vision` | Goal anchors — high-level objectives from VISION.md. | Planner, humans | | `vision` | Goal anchors — high-level objectives from VISION.md. | Planner, humans |
| `prediction/unreviewed` | Unprocessed prediction filed by predictor. | prediction-agent.sh |
| `prediction/backlog` | Prediction triaged as WATCH — not urgent, tracked. | Planner (triage-predictions step) |
| `prediction/actioned` | Prediction promoted or dismissed by planner. | Planner (triage-predictions step) |
| `action` | Operational task for the action-agent to execute via formula. | Planner, humans |
### Dependency conventions ### Dependency conventions

View file

@ -89,10 +89,12 @@ Do NOT let an AGENTS.md failure prevent prediction triage or strategic planning.
needs = ["preflight"] needs = ["preflight"]
[[steps]] [[steps]]
id = "prediction-triage" id = "triage-predictions"
title = "Triage prediction/unreviewed issues" title = "Triage prediction/unreviewed issues"
description = """ description = """
Triage prediction issues filed by the predictor (goblin). Triage prediction issues filed by the predictor (goblin).
Evidence from the preflight step informs whether each prediction is valid
(e.g. "red-team stale since March 12" is confirmed by evidence/ timestamps).
1. Fetch unreviewed predictions: 1. Fetch unreviewed predictions:
curl -sf -H "Authorization: token $CODEBERG_TOKEN" \ curl -sf -H "Authorization: token $CODEBERG_TOKEN" \
@ -107,21 +109,87 @@ Triage prediction issues filed by the predictor (goblin).
curl -sf -H "Authorization: token $CODEBERG_TOKEN" \ curl -sf -H "Authorization: token $CODEBERG_TOKEN" \
"$CODEBERG_API/issues?state=open&type=issues&limit=50" "$CODEBERG_API/issues?state=open&type=issues&limit=50"
4. For each prediction, read the title and body. Decide: 3b. Resolve label IDs needed for triage (fetch via $CODEBERG_API/labels):
- ACCEPT_ACTION: maps to an available formula -> create an action issue - <unreviewed_label_id> prediction/unreviewed
with YAML front matter referencing the formula name and vars - <prediction_backlog_label_id> prediction/backlog
- ACCEPT_BACKLOG: warrants dev work -> create a backlog issue - <actioned_label_id> prediction/actioned (create if missing,
- DISMISS: noise, already covered by an open issue, or not actionable -> color #c2e0c6, description "Prediction triaged by planner")
post an explanation comment, then close the prediction issue - <backlog_label_id> backlog
- <action_label_id> action
These are DISTINCT labels do not reuse IDs across them.
5. For each accepted prediction: 4. For each prediction, read the title and body. Choose one action:
- Create the new issue with the 'backlog' label (or 'action' label for
formula-matching actions)
- Remove 'prediction/unreviewed' label from the original prediction
- Add 'prediction/backlog' label to the original prediction
- Note what you accepted you will need it for strategic-planning
6. Validation: if you reference a formula, verify it exists on disk. - PROMOTE_ACTION: maps to an available formula create an action issue
with YAML front matter referencing the formula name and vars.
Relabel prediction/unreviewed prediction/actioned, then close
with comment "Actioned as #NNN — <reasoning>".
- PROMOTE_BACKLOG: warrants dev work create a backlog issue.
Relabel prediction/unreviewed prediction/actioned, then close
with comment "Actioned as #NNN — <reasoning>".
- WATCH: not urgent but worth tracking post a comment explaining
why it is not urgent, then relabel from prediction/unreviewed to
prediction/backlog. Do NOT close.
- DISMISS: noise, already covered by an open issue, or not actionable
relabel prediction/unreviewed prediction/actioned, post a comment
with explicit reasoning, then close the prediction.
Every decision MUST include reasoning in a comment on the prediction issue.
5. Executing triage decisions via API:
For PROMOTE_ACTION / PROMOTE_BACKLOG:
a. Create the new issue with the 'action' or 'backlog' label:
curl -sf -X POST -H "Authorization: token $CODEBERG_TOKEN" \
-H "Content-Type: application/json" "$CODEBERG_API/issues" \
-d '{"title":"...","body":"...","labels":[<label_id>]}'
b. Comment on the prediction with "Actioned as #NNN — <reasoning>":
curl -sf -X POST -H "Authorization: token $CODEBERG_TOKEN" \
-H "Content-Type: application/json" \
"$CODEBERG_API/issues/<pred_num>/comments" \
-d '{"body":"Actioned as #NNN — <reasoning>"}'
c. Relabel: remove prediction/unreviewed, add prediction/actioned:
curl -sf -X DELETE -H "Authorization: token $CODEBERG_TOKEN" \
"$CODEBERG_API/issues/<pred_num>/labels/<unreviewed_label_id>"
curl -sf -X POST -H "Authorization: token $CODEBERG_TOKEN" \
-H "Content-Type: application/json" \
"$CODEBERG_API/issues/<pred_num>/labels" \
-d '{"labels":[<actioned_label_id>]}'
d. Close the prediction:
curl -sf -X PATCH -H "Authorization: token $CODEBERG_TOKEN" \
-H "Content-Type: application/json" \
"$CODEBERG_API/issues/<pred_num>" \
-d '{"state":"closed"}'
For WATCH:
a. Comment with reasoning why not urgent
b. Replace prediction/unreviewed label with prediction/backlog:
curl -sf -X DELETE -H "Authorization: token $CODEBERG_TOKEN" \
"$CODEBERG_API/issues/<pred_num>/labels/<unreviewed_label_id>"
curl -sf -X POST -H "Authorization: token $CODEBERG_TOKEN" \
-H "Content-Type: application/json" \
"$CODEBERG_API/issues/<pred_num>/labels" \
-d '{"labels":[<prediction_backlog_label_id>]}'
For DISMISS:
a. Comment with explicit reasoning
b. Relabel: remove prediction/unreviewed, add prediction/actioned:
curl -sf -X DELETE -H "Authorization: token $CODEBERG_TOKEN" \
"$CODEBERG_API/issues/<pred_num>/labels/<unreviewed_label_id>"
curl -sf -X POST -H "Authorization: token $CODEBERG_TOKEN" \
-H "Content-Type: application/json" \
"$CODEBERG_API/issues/<pred_num>/labels" \
-d '{"labels":[<actioned_label_id>]}'
c. Close the prediction issue
6. Track promoted predictions they compete with vision gaps in the
strategic-planning step for the per-cycle 5-issue limit.
Record each promotion (issue number, title, type) for hand-off.
7. Validation: if you reference a formula, verify it exists on disk.
Fall back to a freeform backlog issue for unknown formulas. Fall back to a freeform backlog issue for unknown formulas.
Be decisive the predictor intentionally over-signals; your job is to filter. Be decisive the predictor intentionally over-signals; your job is to filter.
@ -145,7 +213,8 @@ Read these inputs:
- Open issues (fetched via API) what's already planned - Open issues (fetched via API) what's already planned
- $FACTORY_ROOT/metrics/supervisor-metrics.jsonl operational trends (may not exist) - $FACTORY_ROOT/metrics/supervisor-metrics.jsonl operational trends (may not exist)
- Planner memory (loaded in preflight) - Planner memory (loaded in preflight)
- Accepted predictions from the triage step - Promoted predictions from triage-predictions (these count toward the
per-cycle issue limit they compete with vision gaps for priority)
Reason through these five questions: Reason through these five questions:
@ -169,7 +238,8 @@ Reason through these five questions:
Things that depend on blocked resources or aren't high-leverage Things that depend on blocked resources or aren't high-leverage
right now. Do NOT create issues for these. right now. Do NOT create issues for these.
Then create up to 5 issues, prioritized by leverage: Then create up to 5 issues total (including promotions from triage-predictions),
prioritized by leverage:
For formula-matching gaps, include YAML front matter in the body: For formula-matching gaps, include YAML front matter in the body:
--- ---
@ -190,7 +260,7 @@ Create each issue via the API with the 'backlog' label:
-d '{"title":"...","body":"...","labels":[<backlog_label_id>]}' -d '{"title":"...","body":"...","labels":[<backlog_label_id>]}'
Rules: Rules:
- Max 5 new issues highest leverage first - Max 5 new issues total (promoted predictions + vision gaps) highest leverage first
- Do NOT create issues that overlap with ANY existing open issue - Do NOT create issues that overlap with ANY existing open issue
- Do NOT create issues for items you identified as "deferred" - Do NOT create issues for items you identified as "deferred"
- Each body: what's missing, why it matters, rough approach - Each body: what's missing, why it matters, rough approach
@ -201,7 +271,7 @@ Rules:
If there are no gaps, note that the backlog is aligned with the vision. If there are no gaps, note that the backlog is aligned with the vision.
""" """
needs = ["agents-update", "prediction-triage"] needs = ["agents-update", "triage-predictions"]
[[steps]] [[steps]]
id = "memory-update" id = "memory-update"