lobstah 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -11363,16 +11363,23 @@ function rebaseBrief(pr, id, trunk) {
11363
11363
  conflictUpdate(pr.baseRef, pr.headRef, standalone),
11364
11364
  pushRule(pr.headRef, id, standalone ? "merge" : "rebase"),
11365
11365
  `Do not merge the PR. Do not change anything beyond conflict resolution.`,
11366
- // A reviewed PR's review goes stale at the new head: ask its reviewers again and park.
11367
- pr.reviews.length > 0 ? rerequestReview({ url: pr.url, number: pr.number }, id, [...new Set(pr.reviews.map((r) => r.author))]) : `When pushed, report status done.`
11366
+ `When pushed, report status done.`
11368
11367
  ].join(" ");
11369
11368
  }
11370
- function choreVerdict(uuid) {
11369
+ function choreVerdict(uuid, pr) {
11370
+ const last = readStatusLog(uuid, "chore").at(-1);
11371
+ const pausedOnReview = last?.verb === "paused" && last.waitingOn === "review";
11372
+ if (last?.verb === "done" || pausedOnReview) {
11373
+ const startedHead = storedDescriptor(uuid, "chore")?.pr?.headSha;
11374
+ const unchangedConflict = pr.mergeableState === "dirty" && startedHead === pr.headSha;
11375
+ return { state: unchangedConflict ? "failed" : "done", pausedOnReview };
11376
+ }
11377
+ if (last?.verb === "paused")
11378
+ return { state: "active" };
11371
11379
  const d = laneDirs("chore");
11372
11380
  if (fs46.existsSync(path41.join(d.active, uuid)) || fs46.existsSync(path41.join(d.queue, `${uuid}.json`)))
11373
- return "active";
11374
- const last = readStatusLog(uuid, "chore").at(-1)?.verb;
11375
- return last === "done" ? "done" : "failed";
11381
+ return { state: "active" };
11382
+ return { state: "failed" };
11376
11383
  }
11377
11384
  async function mergeLoop(ms, policy, state, log = () => {
11378
11385
  }) {
@@ -11416,12 +11423,12 @@ async function mergeLoop(ms, policy, state, log = () => {
11416
11423
  observe(candidate, "rebase-failed");
11417
11424
  continue;
11418
11425
  }
11419
- const verdict = choreVerdict(rebase.uuid);
11420
- if (verdict === "active") {
11426
+ const verdict = choreVerdict(rebase.uuid, candidate);
11427
+ if (verdict.state === "active") {
11421
11428
  observe(candidate, `conflict-chore:${rebase.uuid}`);
11422
11429
  continue;
11423
11430
  }
11424
- if (verdict === "failed") {
11431
+ if (verdict.state === "failed") {
11425
11432
  await ms.comment(candidate.number, `Automated rebase failed (dispatch ${rebase.uuid}) \u2014 needs a human.`);
11426
11433
  await ms.addLabel(candidate.number, "needs-human");
11427
11434
  state.failRebase(prKey);
@@ -11429,6 +11436,8 @@ async function mergeLoop(ms, policy, state, log = () => {
11429
11436
  observe(candidate, "rebase-failed");
11430
11437
  continue;
11431
11438
  }
11439
+ if (verdict.pausedOnReview)
11440
+ log(`${prKey}: rebase chore ${rebase.uuid} paused on review \u2014 treating as finished; the merge gate owns the review wait`);
11432
11441
  state.clearRebase(prKey);
11433
11442
  }
11434
11443
  const provisional = qualifiedApproval(policy, candidate);
package/docs/pickup.md CHANGED
@@ -282,7 +282,7 @@ A PR behind its base splits deterministically:
282
282
  | Condition | Action |
283
283
  |---|---|
284
284
  | Behind, no conflict | Update the branch through the forge API, re-enter the gate next tick |
285
- | Behind, real conflict | Write a rebase chore — brief: rebase onto base, resolve, push to the PR's branch — and re-enter the gate when it completes |
285
+ | Behind, real conflict | Write a rebase chore — resolve, push to the PR's branch, report `done` — then re-enter the gate, which re-requests stale review once per head |
286
286
 
287
287
  Rebase chores go through the **chore lane** (`~/.lobstah/chores/`, defined in
288
288
  the [design's queue contract](design.md#queue-contract)), never the primary queue. Same descriptor schema,
@@ -293,6 +293,12 @@ queue, and `lobstah ls` stays a list of things a human asked for.
293
293
  Chores report to no tracker. The merge loop consumes the chore's status file
294
294
  directly, holds its own PR-to-chore mapping, and bounds the attempt at one: a
295
295
  failed rebase comments on the PR, applies the `needs-human` label, and stops.
296
+ A rebase chore reports `done` after its push, even on a reviewed PR; the gate
297
+ re-requests stale review once per head. Older chores parked on review are
298
+ treated as finished by the gate and finish their own wait when the PR merges
299
+ or closes. They hold no chore slot while parked. A reported push that leaves
300
+ the original head unchanged and still conflicting fails the one attempt,
301
+ whether the report was `done` or a legacy review pause.
296
302
  A rebase chore's descriptor names its PR (`pr`): the runner pushes no branch
297
303
  and opens no PR for it. The brief tells the worker to push to the PR's head
298
304
  branch only and, on a non-fast-forward rejection, to fetch, rebase onto the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lobstah",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Harness-agnostic, token-efficient supervision framework for coding agents",
5
5
  "license": "MIT",
6
6
  "author": "aequitas labs LLC",