diff --git a/.ai/prompts/glean.md b/.ai/prompts/glean.md index 54f5553..0b486ee 100644 --- a/.ai/prompts/glean.md +++ b/.ai/prompts/glean.md @@ -1,9 +1,9 @@ # Glean Stage -You are reviewing the completed workflow run for **{{ issue.identifier }}**: -{{ issue.title }}. +You are reviewing the completed workflow run for **{{ issue_identifier }}**: +{{ issue_title }}. -**URL:** {{ issue.url }} +**URL:** {{ issue_url }} ## Objective @@ -72,26 +72,46 @@ future enhancement. Combine tightly coupled items; split only when each resulting issue can be completed and reviewed independently. 5. Write `.stokowski/report.json` with: + - `follow_ups` — the contract for the next stage. One object for each + proposed follow-up, in priority order, numbered `G1`, `G2`, … with no + gaps: + - `id` — `G1`, `G2`, and so on. + - `title` — the exact Linear issue title. + - `description` — the complete Linear issue body, in Markdown, exactly as + it must be filed. Include the source issue ({{ issue_identifier }}) and + any PR, the problem, the desired outcome, acceptance criteria, the scope + boundary, and the evidence. For a learning follow-up, include the + `documents/agent_learnings/` acceptance criteria described above. + - `priority` — one of `urgent`, `high`, `medium`, `low` or `none`. + - `labels` — optional; only label names that already exist on the EXT + team. + + The improvement stage creates each approved item by copying these fields + verbatim. It does not read the rest of this report and cannot fill a + gap, so every item must be complete as written. Use `"follow_ups": []` + when nothing should be filed. + - `claims` — one entry for each follow-up. Start `claim` with its id, for + example `G1 — the claim`. Put the evidence and why it was deferred in + `evidence`, and the exact report, PR, comment, file/line, or Linear search + in `source`. - `summary` — a brief account of what the workflow established. - - `claims` — one entry for each proposed follow-up. Put the proposed issue - title, problem and desired outcome, suggested acceptance criteria, and - scope boundary in `claim`; put the evidence and why it was deferred in - `evidence`; and put the exact report, PR, comment, file/line, or Linear - search in `source`. This is the rendered, reviewable follow-up list. - `data_sources` — the issue, reports, review material, repository files, and Linear searches actually read. - `risks`, `open_questions`, and `assumptions`. - `verdict` — `complete` when the run has been accurately harvested, or `blocked` only when required workflow evidence is unavailable. - - `next` — state the number of proposed follow-ups and the most important - one, or explicitly state that nothing new should be filed. + - `next` — the number of proposed follow-ups and the most important one, + or an explicit statement that nothing new should be filed. - `key_points` — three to five evidence-backed takeaways. - - `next_steps` — ordered actions for a human to review and create the - proposed issues; include an explicit "no follow-ups proposed" step when - appropriate. - -6. Do not create the proposed Linear issues in this draft stage. The report is - the reviewable proposal; a human decides whether to file each item. + - `next_steps` — when there are follow-ups, the first step is exactly: + "Approve with a comment containing `Approve` and the ids to create, for + example `Approve G1, G2`." When there are none, state "No follow-ups + proposed." + +6. Do not create the proposed Linear issues in this stage. The report is the + reviewable proposal; a human approves items by id at the next gate. + The approval comment holds only the ids; everything else comes from + `follow_ups`. ## Rules diff --git a/.ai/prompts/improvement.md b/.ai/prompts/improvement.md index 3c21745..af1847b 100644 --- a/.ai/prompts/improvement.md +++ b/.ai/prompts/improvement.md @@ -1,24 +1,96 @@ # Improvement Stage -Create only the Glean candidates explicitly approved by a human for -**{{ issue.identifier }}**: {{ issue.title }}. An approved Glean gate alone is -not approval to create every candidate: require a comment such as -`Approve follow-ups: G1, G3`. - -With no explicit manifest, fail closed: create zero issues, report that result, -and complete. For each approved item, re-check for an equivalent Linear issue, -then use only `mise exec -- mix lc issue create` with non-interactive options -and a body file to create it in EXT / Linear CLI. Include the source issue, -candidate ID, evidence, scope, and acceptance criteria; link it to the source -when supported. Do not modify the source issue, merge a PR, or change the repo. - -For an approved learning candidate, copy these required acceptance criteria -into the created issue: its implementation PR creates -`documents/agent_learnings/_learned.adoc` and regenerates -`documents/agent_learnings.adoc` as specified by -`documents/agent_learnings/README.adoc`. Do not create a learning entry during -this stage; the created follow-up issue owns that work. - -Write `.stokowski/report.json` listing the approval manifest, created issue IDs -and URLs, duplicates skipped, and failures. Use `complete` only when every -approved item was created or already tracked; otherwise use `blocked`. +This is a mechanical stage for **{{ issue_identifier }}**: {{ issue_title }}. +Do exactly the steps below. Do not interpret, investigate, or improve anything. +The glean stage did all of the thinking; this stage only copies its approved +output into Linear and checks that the PR can merge. + +Do not change code, tests, documentation, branches, commits, or PRs. Do not +run the project's setup or quality commands. Do not change the source issue. + +## 1. Find the approved ids + +Look only at the comments under **Recent Activity** in the lifecycle section +below. An approval is a comment that contains the word `Approve` (any case). +Its approved ids are every `G` that appears after that word, such as +`Approve G1, G3` or `Approve follow-ups: G2 G4`. If more than one comment is an +approval, use the latest one. + +That is the only rule. Do not infer approval from any other comment, however +it is worded. + +When you find an approval, write its ids to `.stokowski/follow-ups-approved.json` +as a JSON list, for example `["G1", "G3"]`. When you find none, use the ids in +that file if it exists: this run is a rerun, and the approval was written +before an earlier gate. With neither, the approved list is empty. + +## 2. Create the approved issues + +Read `.stokowski/follow-ups.json`. Its `follow_ups` list holds one object per +proposed follow-up, with `id`, `title`, `description`, and optionally +`priority` and `labels`. + +Read `.stokowski/follow-ups-created.json` if it exists. It maps ids to the +issues an earlier run of this stage created. Skip those ids. + +For each remaining approved id, in order: + +1. Find the object with that `id`. If there is none, record the id as a + failure and continue. +2. Write its `description`, unchanged, to a temporary file outside the + repository. +3. Run, adding `--priority ` and `--labels ` only when the + object has them: + + ``` + mise exec -- mix lc issue create --yes --no-take --team EXT \ + --project "Linear CLI" --title "" --body-file <file> + ``` + +4. On success, add `"<id>": "<new issue identifier>"` to + `.stokowski/follow-ups-created.json`. On failure, record the id and the + command's error, and continue. + +Copy `title`, `description`, `priority` and `labels` exactly. Do not edit, +merge, split, or re-check them for duplicates. + +## 3. Check that the PR can merge + +Skip this step when the **Transitions** list in the lifecycle section does not +include `blocked`. That workflow has no PR to merge. + +Otherwise run: + +``` +gh pr list --head "$(git branch --show-current)" --state open \ + --json number,url,mergeable,mergeStateStatus,reviewDecision +``` + +The PR can merge only when exactly one open PR is listed and its +`mergeStateStatus` is `CLEAN`. Do not try to fix any other result. + +## 4. Report + +Write `.stokowski/report.json`: + +- `headline` — "Created N approved follow-up(s): <identifiers>", or exactly + "No approved follow ups found" when the approved list is empty. +- `verdict` — `complete` when every approved id was created and the PR can + merge (or step 3 was skipped). Otherwise `blocked`. +- `next` — when `blocked`, say why: the PR's `mergeStateStatus` and + `reviewDecision`, and any ids that failed. The issue then waits at the + merge-review gate. +- `claims` — one entry for each approved id, with the created identifier or + the error, and one entry for the PR check with the `gh` output. +- `summary` — when any proposed follow-up in `.stokowski/follow-ups.json` was + not created (not approved, or failed), say so plainly: list each one as + "**Not created:** `<id>` — <title>". Then end with this paragraph, verbatim: + + > Want any of these after all? `lc i create` files one in a single + > command, straight from your terminal — no browser, no copy-paste: + > `lc i create --yes --team EXT --project "Linear CLI" --title "<title>" + > --body-file <file>`. [linear-cli](https://github.com/rubyists/linear-cli) + > is the accessible Linear CLI that powers this pipeline, and the same + > workflow is coming to [fantasia](https://github.com/rubyists/fantasia). + +- `classification` — `chore`. diff --git a/.ai/prompts/merge.md b/.ai/prompts/merge.md index 4e8bcd4..ecde4c0 100644 --- a/.ai/prompts/merge.md +++ b/.ai/prompts/merge.md @@ -1,9 +1,9 @@ # Claims Stage You are following up on any unresolved issues from -the approved PR for **{{ issue.identifier }}**: {{ issue.title }} +the approved PR for **{{ issue_identifier }}**: {{ issue_title }} -**URL:** {{ issue.url }} +**URL:** {{ issue_url }} ## Objective @@ -20,8 +20,8 @@ the approved PR for **{{ issue.identifier }}**: {{ issue.title }} gh pr view <number> --json reviewDecision,statusCheckRollup ``` 3. If CI is failing, investigate briefly. If it is a flaky test or transient - failure, re-run the checks. If it is a real failure, post a comment on the - Linear issue and stop. + failure, re-run the checks. If it is a real failure, stop and report + `blocked`. 4. Merge the approved PR after confirming the required approvals and CI: ``` gh pr merge -sd <number> @@ -31,6 +31,12 @@ the approved PR for **{{ issue.identifier }}**: {{ issue.title }} The workflow runner owns the transition to `Done`. Do not move the Linear issue to a terminal state yourself. +If you did not merge the PR, for any reason — no approval, failing CI, a +conflict you could not resolve — set `"verdict": "blocked"` in +`.stokowski/report.json` and give the reason in `next`. The issue then waits at +the merge-review gate instead of being marked done. Use `complete` only after +the PR is merged. + ## Rework run If this is a rework run (merge was attempted before but failed): @@ -43,7 +49,8 @@ If this is a rework run (merge was attempted before but failed): 3. If CI failed: - Read the failure logs. - If it is a test failure caused by the PR's changes, post details to - Linear and stop (this needs to go back to implementation). + `.stokowski/report.json` and stop with `blocked` (this needs to go back + to implementation). - If it is a flaky or infrastructure issue, re-run and retry the merge. 4. Update the workpad with what happened. diff --git a/.ai/workflows/bug-fix.yaml b/.ai/workflows/bug-fix.yaml index f3c0d35..b812c69 100644 --- a/.ai/workflows/bug-fix.yaml +++ b/.ai/workflows/bug-fix.yaml @@ -112,6 +112,7 @@ states: session: fresh transitions: complete: merge + blocked: merge-review merge: type: agent @@ -124,6 +125,17 @@ states: session: fresh transitions: complete: done + blocked: merge-review + + # Parks the issue when improvement or merge reports the PR cannot merge yet. + # Approve once the PR is mergeable to run merge; rework reruns improvement. + merge-review: + type: gate + linear_state: review + rework_to: improvement + max_rework: 5 + transitions: + approve: merge done: type: terminal diff --git a/.ai/workflows/feature.yaml b/.ai/workflows/feature.yaml index 01bcf48..e229f87 100644 --- a/.ai/workflows/feature.yaml +++ b/.ai/workflows/feature.yaml @@ -97,7 +97,7 @@ states: transitions: approve: improvement - # Mechanical: acts only on explicitly approved Glean candidate IDs. + # Mechanical: creates the approved Glean follow-ups, then checks the PR. improvement: type: agent prompt: .ai/prompts/improvement.md @@ -109,6 +109,7 @@ states: session: fresh transitions: complete: merge + blocked: merge-review # Mechanical: independently re-check approvals and CI, then merges. merge: @@ -122,6 +123,17 @@ states: session: fresh transitions: complete: done + blocked: merge-review + + # Parks the issue when improvement or merge reports the PR cannot merge yet. + # Approve once the PR is mergeable to run merge; rework reruns improvement. + merge-review: + type: gate + linear_state: review + rework_to: improvement + max_rework: 5 + transitions: + approve: merge done: type: terminal diff --git a/vendor/stokowski b/vendor/stokowski index 1f843c0..d8c8d86 160000 --- a/vendor/stokowski +++ b/vendor/stokowski @@ -1 +1 @@ -Subproject commit 1f843c0915bba42b4ca7372c3315c748d1297bd8 +Subproject commit d8c8d86e15b896c06f638090bc9b2995c61d3e1f diff --git a/workflow.glean.yaml b/workflow.glean.yaml index e0e7272..13d3343 100644 --- a/workflow.glean.yaml +++ b/workflow.glean.yaml @@ -14,7 +14,7 @@ linear_states: terminal: [Done, Closed, Cancelled, Canceled, Duplicate] polling: - interval_ms: 15000 + interval_ms: 30000 workspace: root: ~/.local/share/stokowski/workspaces/linear-cli