From 49603b600229a6e8b59692c8aec1e5db2c29b9df Mon Sep 17 00:00:00 2001 From: mchwang Date: Sat, 26 Sep 2026 11:02:53 -0700 Subject: [PATCH] Design: a task closes on merge or cancel; reject with feedback requeues L1 listed "rejected" as a way a task closes, which contradicted step 8 (Reject with feedback creates the next revision and requeues the task). The F1 contract already followed step 8; drop its interim note now that the design agrees. Co-Authored-By: Claude Opus 5.5 --- docs/designs/codeboost-plan-indexed-review.md | 2 +- docs/implementation/runner-lifecycle.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/designs/codeboost-plan-indexed-review.md b/docs/designs/codeboost-plan-indexed-review.md index 7af9a85..da06414 100644 --- a/docs/designs/codeboost-plan-indexed-review.md +++ b/docs/designs/codeboost-plan-indexed-review.md @@ -540,7 +540,7 @@ If codeboost is stopped or crashes during a rebase, it always cancels the rebase Added by the engineering review (L1 to L4). The agent tools cannot be retrained, so codeboost learns by adding approved lessons to its prompts. **How a lesson is made (L1).** -1. A task closes: it is merged, cancelled, or rejected. +1. A task closes: it is merged, or you cancel it. "Reject with feedback" does not close a task: it creates the next plan revision and puts the task back in the queue (step 8). Each reject round's feedback stays with the task and is included when the task finally closes. 2. An agent reads your feedback on that task: rejection notes, change requests, and your accept, assign, and "accepted finding" choices. It never reads issue text or comments from other people. 3. It writes short lessons, such as "In this repo, every retry change needs a test for the 5xx path." Each lesson links to the feedback it came from. diff --git a/docs/implementation/runner-lifecycle.md b/docs/implementation/runner-lifecycle.md index 841574e..c506b05 100644 --- a/docs/implementation/runner-lifecycle.md +++ b/docs/implementation/runner-lifecycle.md @@ -396,7 +396,7 @@ A merged v5 task also gets its `task-closed` event, keyed by the merge attempt I | `user_actions` | `plan_key`, `action_id` (together the primary key), `kind`, `request_hash`, `response` (JSON, bounded), `created_at` | | `feedback_events` | the fields listed above, with `id` as primary key, with a unique index on `(plan_key, kind, action_id)` | -`tasks.status` holds the product states from the design (queued, running, needs human, needs amendment, needs approval, possibly already fixed, in review, approved but merge blocked, merged, cancelled). **Closed** means `merged` or `cancelled` (by the user's cancel task); a closed status never changes again. **Reject with feedback is not a closed status.** Following the design's step 8, it creates the next plan revision, marks the affected items to run again, and moves the task from `in review` to `queued`, in one transaction with its `reject` event. The design's learning section (L1) also lists "rejected" as a way a task closes. That conflicts with step 8, and this contract follows step 8. **Until the design is reconciled, this contract governs** when a task closes and when J may read its feedback, for lanes F and J. The design is owned by the plan's documentation owner (rule 3 of "Ownership and integration rules"), so this PR does not edit it. Reconciling line 533 is tracked as a follow-up for that owner. J therefore distills a task's feedback, including every reject round, when it closes by merge or cancel. **Human-gated** means `needs human`, `needs amendment`, `needs approval` or `possibly already fixed`. F1 defines the list and its invariants. F2 adds the per-item transitions. I1 adds queue admission and scheduling. +`tasks.status` holds the product states from the design (queued, running, needs human, needs amendment, needs approval, possibly already fixed, in review, approved but merge blocked, merged, cancelled). **Closed** means `merged` or `cancelled` (by the user's cancel task); a closed status never changes again. **Reject with feedback is not a closed status.** Following the design's step 8, it creates the next plan revision, marks the affected items to run again, and moves the task from `in review` to `queued`, in one transaction with its `reject` event. The design's learning section (L1) agrees: a task closes only when it is merged or cancelled, and reject rounds stay with the task. J therefore distills a task's feedback, including every reject round, when it closes by merge or cancel. **Human-gated** means `needs human`, `needs amendment`, `needs approval` or `possibly already fixed`. F1 defines the list and its invariants. F2 adds the per-item transitions. I1 adds queue admission and scheduling. **Where the current context lives.** The `Current` check reads two rows in one transaction: `plans` (plan revision, snapshot ID) and `tasks` (assignment ID, referenced-code hash, context generation). The plan ID comes from the plan key. Every `Store` method that changes any of these fields increases `tasks.context_generation` **in the same transaction**. That covers `importRevision`, `applySuggestion`, `recordHistory`, `recordRebase`, and any new method that reassigns work or changes the referenced code. A regression test lists these methods and fails if one of them changes a context field without increasing the generation. An assignment change that keeps the same plan revision and snapshot therefore still makes old attempts non-current.