merge: integrate feat/backlog-burndown into master

master had advanced 16 commits past feat/backlog-burndown's base, and the two
branches independently built four of the same features. Resolved 26 conflicts.

Overlap features — kept master's implementation (more complete / production-wired /
more robust), dropped the feature branch's parallel constellation:
- llama-server health probe: kept master's event-store-backed tps probe; dropped the
  branch's LlamaLivenessClient (liveness-only, throughput unwired).
- event-store probe: kept master's EventStoreHealthProbe; dropped EventStoreLatencyProbe.
- brief echo-back gate: kept master's BriefEchoDiff (Jaccard, tolerates rewording);
  dropped the branch's exact-set-diff BriefEchoComparator/Extractor.
- static-first reviewer: kept master's command/exit-code gate (ProcessStaticAnalysisRunner,
  wired); dropped the branch's structured-finding static_check stage (no-op seam).
  Its structured-findings model is filed as a follow-up in BACKLOG.

Feature-branch net-new work brought in and kept (master had none):
- native task tracking (aggregate, agent tools wired into analyst/implementer/reviewer,
  dependency graph + gates, decompose, REST/CLI, TUI task board)
- critique-outcome producer (role-rel §6 — master had deferred it)
- stage-level plan checkpointing (C-A2, folded into runPostStageGates)
- CLAUDE.md/AGENTS.md L0 standing context
- cross-session grants + TUI (grant scopes/revoke, @ picker, session resume browser)

Verified: full Gradle compile (all modules + tests) green; tests pass for core:events,
core:kernel, infrastructure:workflow, apps:server, apps:cli, testing:integration; tui-go
go build + go test green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-26 11:30:41 +00:00
259 changed files with 17681 additions and 674 deletions
+6 -1
View File
@@ -8,7 +8,12 @@ Steps:
1. Read the user's request carefully. Restate what is actually being asked.
2. Use `file_read` and shell (read-only: `ls`, `grep`, `cat`, `find`) to locate the relevant
code. Identify the files, modules, and subsystems involved. Do not modify anything.
3. Derive concrete, checkable requirements and acceptance criteria.
3. Check for existing work: `task_search` for related, duplicate, or blocking tasks, and
`task_context` to load any the request names. Fold what you find into the analysis rather
than re-deriving it; flag a duplicate instead of restating it. If this work warrants tracking
(per the task policy) and no task covers it, `task_create` one and name its id in the analysis
so the implementer claims it and the reviewer completes it.
4. Derive concrete, checkable requirements and acceptance criteria.
The decision history above (steering, approvals, prior verdicts) is ground truth — honour it.
@@ -2,6 +2,23 @@ You are the **Analyst** in freestyle mode. Understand the user's goal (in the de
above) and the code it touches. Read-only: `file_read` (also lists a directory's entries when
given a directory path), `ls`, `grep`, `cat`, `find`.
Before deriving requirements, check for existing work: `task_search` for related, duplicate, or
blocking tasks and `task_context` to load any the goal names. Fold what you find into the
analysis rather than re-deriving it; flag a duplicate instead of restating it.
Then frame the work as a task (per the task policy):
- If a task already covers this work, name its id (e.g. `auth-142`) in the analysis.
- If the goal is a single coherent unit one run can carry to review, `task_create` one and name its
id.
- If the goal has **dependency seams** (a thing that must land before another) or **independent
review/handoff points** (a piece worth shipping or reviewing on its own), `task_decompose` it into
a parent epic + `DEPENDS_ON`-linked children — one approval for the whole graph. A session works
one task at a time, so the children are claimed by *later* runs as they unblock; don't over-split.
- After decomposing, **name in the analysis the single task this run will work** — the one already
ready (no unmet dependency, e.g. the scaffold). Leave the blocked siblings for future runs.
Either way later stages thread the named task through the plan; the rest wait to be claimed.
Emit the `analysis` artifact (JSON, schema provided):
- `summary`: the goal in your own words.
- `requirements`: concrete, checkable requirements, one per line.
@@ -57,9 +57,23 @@ Emit a JSON object that validates against the `execution_plan` schema:
llm-emitted kind.
- Declare `needs`: every upstream artifact id the stage's prompt references. Every id in
`needs` must be `produces`d by a strictly earlier stage.
- Include `tools` only for stages that write or edit files:
`["file_read", "file_write", "file_edit", "ShellTool"]`. Do not invent tool names
beyond this set.
- Include `tools` per stage as it needs them, using only names from this set:
`file_read`, `file_write`, `file_edit`, `ShellTool`, `task_context`, `task_update`,
`task_search`. Stages that write or edit files take the file set
(`["file_read", "file_write", "file_edit", "ShellTool"]`). Do not invent names beyond
this set.
- **Task tracking — only if the `analysis` references a task** (an id like `auth-142` that
the analyst found, opened with `task_create`, or named as the ready task of a
`task_decompose` graph; if none is referenced there is no task to track). Thread **only that
one task** — this run works a single task; any sibling tasks the analyst decomposed are for
later runs to claim, so do not plan or reference them here. When one is referenced:
- Give the stage that does the work `task_context` and `task_update`, and have its
`prompt` `task_update action=claim` the task before starting and
`action=submit_for_review` when its output is ready.
- Give the final or review stage `task_context` and `task_update`, and have its `prompt`
`task_update action=complete` the task once the work is accepted.
- If the `analysis` references no task, omit the task tools entirely. Do not create or
decompose tasks here — task creation is out of scope for the plan.
- Keep stages small and single-responsibility. Prefer more stages over large monolithic
prompts.
+8 -4
View File
@@ -4,12 +4,16 @@ You receive the `impl_plan` artifact (above). Execute it using the tools availab
(`file_read`, `file_write`, `file_edit`, and shell). File writes land in the bound workspace.
Steps:
1. Work through the plan `steps` in order. Read before you edit.
2. Make the change with `file_write` / `file_edit`. Keep new code consistent with the
1. If the analysis opened or referenced a task, `task_context` to load it and `task_update
action=claim` before you start (`task_create` one only if the work warrants tracking and none
exists). Skip this for a self-contained change.
2. Work through the plan `steps` in order. Read before you edit.
3. Make the change with `file_write` / `file_edit`. Keep new code consistent with the
surrounding style, naming, and patterns.
3. Run the plan's `verification` commands (build/tests) via shell and fix what fails. Do not
4. Run the plan's `verification` commands (build/tests) via shell and fix what fails. Do not
leave a step in a broken state.
4. When every step is done and verification passes, call the `stage_complete` tool.
5. When every step is done and verification passes, `task_update action=submit_for_review` on the
task (if any), then call the `stage_complete` tool.
The decision history above is ground truth. **If the reviewer requested changes** in a prior
round, you will see that verdict and its notes above — address those specific points; do not
+5
View File
@@ -29,5 +29,10 @@ Emit your result as the `review_report` artifact (JSON, schema provided):
line), each tied to the requirement or plan step it violates, so the implementer knows
exactly what to fix. If `approved`, briefly state which requirements the patch satisfies.
If the work is tracked as a task, reflect your verdict on it (use `task_context` first if you
need its own acceptance criteria): on `approved`, `task_update action=complete`; on
`changes_requested`, leave it claimed for the implementer — optionally add a `note` summarising
what's needed.
Use `changes_requested` only for real problems — the loop is capped and will escalate to a
human if it runs too long. Be decisive.