Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .claude/gh-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,8 @@ or summarise any of it.
the last 10, whichever is more.
- **Attention** fires on exactly three signals: an unread PM inbox, a finished
review on a still-open PR that the PM has not answered, and a worker in
`awaiting`. The `awaiting` signal is claude-only for now.
`awaiting`. The `awaiting` signal is claude-only: kiro-cli (checked on
2.32.0) has no hook that fires while it waits on the user (#278).

```bash
task-monitor-snapshot --json # this repo
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
## [Unreleased]

### Changed
- **kiro has no `awaiting` signal, and now the docs say why (#278, epic #272 6/6).** Investigated against kiro-cli 2.32.0, with the outcome that there is nothing to wire. An agent config's `hooks` field accepts only `agentSpawn`, `userPromptSubmit`, `preToolUse`, `postToolUse` and `stop`, with no permission or notification trigger. kiro has no ask-the-user tool, and its one confirm tool, `switch_to_execution`, belongs to the built-in `kiro_planner` agent, which no task-force agent includes. No hook payload field marks a tool as waiting for approval. So a kiro worker waiting on the user never shows `❓` and never trips the monitor's `worker-awaiting` signal: it reads `idle` after a question, and most likely `busy` during a tool-approval prompt. That second case is unverified, because the live probe (scratch `HOME` and `TASK_FORCE_HOME`) hit the account's monthly usage limit before the model replied. Docs: a new "No awaiting state on kiro" section in the README's kiro delivery part, plus a row in its kiro hook table; the README's monitor Attention paragraph, `docs/task-monitor-schema.md`, `.claude/gh-workflow.md` and all seven steering templates now name the gap and the kiro-cli version checked instead of "claude-only for now". No code changes. A doc test in `tests/task_monitor_snapshot.bats` pins the wording and the version in every workflow doc, the schema doc and the README's section and anchor; restoring one old doc and breaking the anchor each turned it red. **Upgrading:** nothing to run. Re-run `task-init <loadout>` only if you want the refreshed wording in your workflow doc.

- **Worker PR bodies open with a plain-language `## Summary` (#274, part of #272).** With ten or more tickets a session, a PR number stops meaning anything to the person driving the PM, and nothing said in plain words what a merged PR did. Every worker prompt — the four claude loadouts, the dogfood copy and the three kiro agents — now opens the PR with `gh pr create … --fill --body-file - <<'BODY'` and a body whose first section is `## Summary`: two or three plain sentences, written for the user rather than a reviewer, saying what changed and why. The tracker's `Closes` line follows it (`Closes #<N>` on gh, the issue key on jira, the page URL on notion, the task file on local), then the rest of the description. `--fill` still supplies the title; before this it supplied the body too, from commit messages. The step also tells the worker to write the body flush left, since GitHub renders an indented `## Summary` as code. Every reviewer prompt (the four claude loadouts, the dogfood copy, kiro-gh) now calls a missing `## Summary` a nit that never blocks on its own. Docs: a `### PR Body` section in `.claude/gh-workflow.md` and all seven steering templates, and the README's PR step. `tests/worker_checklist.bats` pins, on all 8 worker prompts, that the example body's first line is `## Summary` and that the loadout's own `Closes` line follows it, and that no prompt keeps a bare `--fill`. It also pins the rule's wording as identical across the claude loadouts, the nit on all 6 reviewer prompts, and the section in every workflow doc and the README. **Upgrading: re-run `task-init <loadout>`** on every loadout to pick up the new `commands/worker.md` / `commands/reviewer.md` (kiro: `agents/worker.json`, and `agents/reviewer.json` on kiro-gh) and the workflow doc.

- **kiro-gh's `task-reviewer` is folded onto the canonical `bin/task-reviewer`; `kiro-gh/bin/task-reviewer` is gone (#146, #147).** It was the last per-loadout copy #170 did not reach, and it had drifted on three axes the canonical body had already fixed. The canonical script now branches on the agent (`${IMPL%%-*}`) for the parts that are the agent's: the flags (claude's `--auto` / `--no-auto`; kiro's `-m` / `--model`, `-a` / `--trust-all`, `--no-trust-all`, `TASK_WORK_TRUST_ALL`), kiro's #218 agent preflight and its #157 / #257 startup-gate warnings, and the launch line, `kiro-cli chat --agent reviewer … "Review PR <url> [against spec issue <url>]"`. Spec resolution is the tracker module's on both, so kiro-gh calls `lib/trackers/gh.sh`'s `aw_tracker_review_spec` rather than its own `parse_issue_number` + PR-body scan. Declared behaviour changes on kiro-gh:
Expand Down
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ task-monitor-snapshot --local # disk only: no forge calls, merged with

**In flight** is every worktree whose `.<slug>.info` sidecar exists — not every fresh heartbeat, so a resumed or roleless worker still shows — with its session state, its PR and a status word (`implementing`, `pr-open`, `under-review`, `changes-requested`, `re-review`, `waiting-merge`, `merged`) derived from the latest review intent. **Next** is the PM's queue, written with [`task-monitor-queue`](#task-monitor-queue--the-pms-queue), else the tracker's backlog. **Done** is the merged PRs that delivered an item in the last 24 hours, or the last 10, whichever is more; merged PRs are fetched once and cached for good.

**Attention** fires on exactly three signals and nothing else: an unread PM inbox (`--also` aliases count toward the primary), a finished review on a still-open PR the PM has not answered, and a worker in `awaiting`. The third is claude-only for now: only the claude loadouts wire `radio awaiting`.
**Attention** fires on exactly three signals and nothing else: an unread PM inbox (`--also` aliases count toward the primary), a finished review on a still-open PR the PM has not answered, and a worker in `awaiting`. The third is claude-only: only the claude loadouts wire `radio awaiting`, and kiro-cli has no hook to wire it to (see [no awaiting state on kiro](#no-awaiting-state-on-kiro)).

`--local` exists so a front end can refresh on every filesystem event without waiting on GitHub: it shadows `gh` with a function that fails, so every forge read falls back to the cache under `$TASK_FORCE_HOME/monitor/<repo>/`. The schema (`"schema": 1`) is documented in [`docs/task-monitor-schema.md`](docs/task-monitor-schema.md), with a full example beside it.

Expand Down Expand Up @@ -721,6 +721,7 @@ kiro-cli actually looks:
| `userPromptSubmit` | `radio busy` | State flip only. Not `prompt-hook` — that is a deliberate hold, not a limitation (#221). |
| `stop` | `radio ready` | State flip back to idle, once per turn. No block-and-drain: whether kiro honours Stop-hook block JSON is a separate contract from stdout injection and is untested (#221). |
| — | *(no session-end trigger)* | Unchanged: nothing unregisters on tab close except `task-done`. `radio orphans` is the cleanup (#98). |
| — | *(no waiting-on-user trigger)* | No `radio awaiting`, so a kiro tab never shows `❓`. See [below](#no-awaiting-state-on-kiro) (#278). |

**kiro does inject hook stdout into the model's context.** This README asserted the
opposite for months, citing an issue that was about something else entirely. The
Expand All @@ -745,6 +746,44 @@ register report — and the other two are open questions rather than dead ends:
in the prompt box for a human Enter. It does not touch kiro's permission model — that
is still `-a/--trust-all`.

#### No awaiting state on kiro

On claude, `radio awaiting` paints the tab `❓` and trips the monitor's
`worker-awaiting` signal. Three hooks call it: `PermissionRequest`, and a
`PreToolUse` matcher on each of `AskUserQuestion` and `ExitPlanMode`. kiro-cli
offers none of the three, so the kiro loadouts don't wire `radio awaiting` at
all (#278). Checked against kiro-cli 2.32.0:

- **No trigger.** An agent config's `hooks` field accepts exactly `agentSpawn`,
`userPromptSubmit`, `preToolUse`, `postToolUse` and `stop`. There is no
permission or notification trigger.
- **No tool to match.** kiro has no ask-the-user tool, so a question is plain
prose that ends the turn. Its one confirm-before-proceeding tool,
`switch_to_execution` (the "Ready to exit [plan] agent" prompt), belongs to
kiro's built-in `kiro_planner` agent. No task-force kiro agent lists it in
`tools`, and inside `kiro_planner` none of radio's hooks run, so a
`preToolUse` matcher on it would never fire for a task-force role.
- **No payload field.** A hook receives `hook_event_name`, `cwd`, `session_id`,
`tool_name`, `tool_input`, `tool_response` and `assistant_response`. Nothing
says a tool is waiting for approval, so `preToolUse` can't tell an approval
prompt from a tool that is about to run.

So a kiro worker that is waiting on you shows one of the states it already has.
A question asked in prose ends the turn, so `stop` marks it `idle` (`⏸️`). A
tool-approval prompt comes mid-turn, so the tab should stay `busy` (`▶️`). That
one is unverified: whether kiro fires `stop` before an approval prompt could not
be observed, because the live probe hit the account's monthly usage limit before
the model replied. Either way, neither trips `worker-awaiting`. A worker launched
with `--trust-all` never sees an approval prompt, which leaves only the question
case.

No file is a substitute either. The `sessions/cli/` log the live kiro sessions on
this machine write holds only finished prompts, replies and tool results. kiro's
V3 engine does keep an `awaiting_approval` status on a tool call in its own
session files, but whether that is written while the prompt is still up is
unverified, and reading it would mean polling files instead of running a hook.
Re-check when kiro-cli adds a trigger.

Re-deriving what kiro can now support — prompt-hook, the Stop drain, and whether
#190's "declare kiro best-effort" decision still holds — is tracked in **#221**.
A heartbeat-driven unregister for the missing session-end trigger is #127.
Expand Down
3 changes: 2 additions & 1 deletion claude-gh/steering/gh-workflow.example.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,8 @@ or summarise any of it.
the last 10, whichever is more.
- **Attention** fires on exactly three signals: an unread PM inbox, a finished
review on a still-open PR that the PM has not answered, and a worker in
`awaiting`. The `awaiting` signal is claude-only for now.
`awaiting`. The `awaiting` signal is claude-only: kiro-cli (checked on
2.32.0) has no hook that fires while it waits on the user (#278).

```bash
task-monitor-snapshot --json # this repo
Expand Down
3 changes: 2 additions & 1 deletion claude-jira/steering/jira-workflow.example.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,8 @@ or summarise any of it.
the last 10, whichever is more.
- **Attention** fires on exactly three signals: an unread PM inbox, a finished
review on a still-open PR that the PM has not answered, and a worker in
`awaiting`. The `awaiting` signal is claude-only for now.
`awaiting`. The `awaiting` signal is claude-only: kiro-cli (checked on
2.32.0) has no hook that fires while it waits on the user (#278).

```bash
task-monitor-snapshot --json # this repo
Expand Down
3 changes: 2 additions & 1 deletion claude-local/steering/local-workflow.example.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,8 @@ or summarise any of it.
the last 10, whichever is more.
- **Attention** fires on exactly three signals: an unread PM inbox, a finished
review on a still-open PR that the PM has not answered, and a worker in
`awaiting`. The `awaiting` signal is claude-only for now.
`awaiting`. The `awaiting` signal is claude-only: kiro-cli (checked on
2.32.0) has no hook that fires while it waits on the user (#278).

```bash
task-monitor-snapshot --json # this repo
Expand Down
3 changes: 2 additions & 1 deletion claude-notion/steering/notion-workflow.example.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,8 @@ or summarise any of it.
the last 10, whichever is more.
- **Attention** fires on exactly three signals: an unread PM inbox, a finished
review on a still-open PR that the PM has not answered, and a worker in
`awaiting`. The `awaiting` signal is claude-only for now.
`awaiting`. The `awaiting` signal is claude-only: kiro-cli (checked on
2.32.0) has no hook that fires while it waits on the user (#278).

```bash
task-monitor-snapshot --json # this repo
Expand Down
7 changes: 5 additions & 2 deletions docs/task-monitor-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,11 @@ radio id cannot order two messages from the same second: after the timestamp it
holds the sender and a random suffix. So messages sort by `created_at`, then by
their position among the log's `send id=` lines, then by id.

`worker-awaiting` is claude-only for now. Only the claude loadouts wire
`radio awaiting`, and #272's sub-issue 6 looks into a kiro equivalent.
`worker-awaiting` is claude-only. Only the claude loadouts wire
`radio awaiting`. kiro-cli (checked on 2.32.0) has no hook that fires while it
waits on the user, so a waiting kiro worker reads `idle` after a question, and
most likely `busy` during a tool-approval prompt. The README's "No awaiting
state on kiro" section has the evidence (#278).

A role belongs to the longest repo name it starts with, so
`worker-task-force-x` is `task-force`'s even when a repo named `task` exists.
Expand Down
3 changes: 2 additions & 1 deletion kiro-gh/steering/gh-workflow.example.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,8 @@ or summarise any of it.
the last 10, whichever is more.
- **Attention** fires on exactly three signals: an unread PM inbox, a finished
review on a still-open PR that the PM has not answered, and a worker in
`awaiting`. The `awaiting` signal is claude-only for now.
`awaiting`. The `awaiting` signal is claude-only: kiro-cli (checked on
2.32.0) has no hook that fires while it waits on the user (#278).

```bash
task-monitor-snapshot --json # this repo
Expand Down
3 changes: 2 additions & 1 deletion kiro-local/steering/local-workflow.example.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,8 @@ or summarise any of it.
the last 10, whichever is more.
- **Attention** fires on exactly three signals: an unread PM inbox, a finished
review on a still-open PR that the PM has not answered, and a worker in
`awaiting`. The `awaiting` signal is claude-only for now.
`awaiting`. The `awaiting` signal is claude-only: kiro-cli (checked on
2.32.0) has no hook that fires while it waits on the user (#278).

```bash
task-monitor-snapshot --json # this repo
Expand Down
3 changes: 2 additions & 1 deletion kiro-notion/steering/notion-workflow.example.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,8 @@ or summarise any of it.
the last 10, whichever is more.
- **Attention** fires on exactly three signals: an unread PM inbox, a finished
review on a still-open PR that the PM has not answered, and a worker in
`awaiting`. The `awaiting` signal is claude-only for now.
`awaiting`. The `awaiting` signal is claude-only: kiro-cli (checked on
2.32.0) has no hook that fires while it waits on the user (#278).

```bash
task-monitor-snapshot --json # this repo
Expand Down
29 changes: 29 additions & 0 deletions tests/task_monitor_snapshot.bats
Original file line number Diff line number Diff line change
Expand Up @@ -671,3 +671,32 @@ project_page() {
run bash -c "source '$lib'; printf '%s\n' 'just this' | tm_pr_summary"
assert_output "just this"
}

# #278: kiro-cli has no hook for "waiting on the user", so worker-awaiting is
# claude-only. Every doc that describes the signal says so and names the
# kiro-cli version that was checked, so the claim can be re-tested later.
@test "every doc describing worker-awaiting names the kiro gap and the kiro-cli version" {
local docs=(
"$REPO_ROOT_REAL/.claude/gh-workflow.md"
"$REPO_ROOT_REAL/claude-gh/steering/gh-workflow.example.md"
"$REPO_ROOT_REAL/claude-jira/steering/jira-workflow.example.md"
"$REPO_ROOT_REAL/claude-local/steering/local-workflow.example.md"
"$REPO_ROOT_REAL/claude-notion/steering/notion-workflow.example.md"
"$REPO_ROOT_REAL/kiro-gh/steering/gh-workflow.example.md"
"$REPO_ROOT_REAL/kiro-local/steering/local-workflow.example.md"
"$REPO_ROOT_REAL/kiro-notion/steering/notion-workflow.example.md"
)
local f
for f in "${docs[@]}"; do
run grep -qF 'The `awaiting` signal is claude-only: kiro-cli (checked on' "$f"
assert_success
run grep -q 'claude-only for now' "$f"
assert_failure
done
run grep -qF 'kiro-cli (checked on 2.32.0) has no hook that fires while it' "$REPO_ROOT_REAL/docs/task-monitor-schema.md"
assert_success
run grep -qF '#### No awaiting state on kiro' "$REPO_ROOT_REAL/README.md"
assert_success
run grep -qF '(#no-awaiting-state-on-kiro)' "$REPO_ROOT_REAL/README.md"
assert_success
}
Loading