@ai-dossier/sched 0.56.0 → 0.57.0

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/README.md CHANGED
@@ -985,14 +985,15 @@ A batch member that leaves its batch before landing is **parked**, never auto-re
985
985
  batch failure: its `evictions[]` record carries `kind: 'handed-back'` and it **never
986
986
  counts toward the dissolve threshold**. Journals `member-handed-back`.
987
987
  - **`evicted`** — an engine-decided failure (unverified exit, incremental-gate
988
- `task-failed`, landing conflict, worktree prep). Counts toward the threshold. Journals
989
- `unit-failed`.
988
+ `task-failed`, landing conflict, worktree prep, and — since #840 — an aggregate-suite
989
+ eviction after landing). Counts toward the threshold. Journals `unit-failed` (or
990
+ `member-evicted ... — parked on <branch>` for the post-landing case).
990
991
 
991
992
  Both keep `mode: slot` + `batch`, record the member branch (`evictions[].branch`,
992
993
  `failure_evidence.branch` — the pushed remote copy survives the member teardown) and stamp
993
994
  the batch's `dispatch_profile` onto the entry. Neither is runnable until an operator runs
994
- `sched requeue --issue <n>` (full-cycle on that profile; the cycle prompt gains a
995
- `PRIOR WORK` instruction to continue from the member branch) or `sched abandon --issue <n>`.
995
+ `sched requeue --issue <n>` (full-cycle on that profile, based on the member branch — see
996
+ below) or `sched abandon --issue <n>`.
996
997
  `sched status` lists them under `== Parked members ==` with reason, branch, profile and
997
998
  those exact commands (`parked_members` in `--json`).
998
999
 
@@ -1019,10 +1020,46 @@ Dissolve never throws validated work away:
1019
1020
  as before, except that in-flight members with a member branch are parked `evicted` and
1020
1021
  every requeue carries the batch's dispatch profile (`carryDispatchProfile: false` only
1021
1022
  for `dispatch-profile-missing:*`, where the profile itself is what broke).
1022
- - Not changed: the `halved` PR-conflict split still re-batches its members, and
1023
- aggregate-suite evictions (`evictMembers`, post-landing, member branch already deleted)
1024
- still requeue full-cycle — now on the batch profile. Both, plus an engine-set requeue base,
1025
- are tracked in #840.
1023
+ - #840: a PR-conflict give-up (`handlePrConflict`: a recurred conflict, a conflicting or
1024
+ failed rebase, a red suite after a clean rebase) never re-batches a validated member.
1025
+ Validated members stay landed in the batch; only the unshipped, UNVALIDATED members with
1026
+ no commits on the integration branch are split into half-batches (`batch-split`) and
1027
+ trimmed out of it. A clean rebase with a red
1028
+ suite re-runs the gate over the landed members (`re-validating → validating`,
1029
+ `batch-regate`, `executing_member` pinned to the end — the shape of `sched resume
1030
+ --batch`); anything else blocks `dissolve-refused:<reason>` (milestone `batch-ship`,
1031
+ `validated=`; the recorded PR can be resolved by hand, or closed before `sched resume
1032
+ --batch`). With no validated member it still dissolves into halves. **Library behaviour
1033
+ only:** the engine does not yet route a CONFLICTING batch PR into `handlePrConflict`
1034
+ (#867).
1035
+
1036
+ #### Member branches live until the batch ends; a requeue resumes on them (#840)
1037
+
1038
+ - A member's remote branch (`batch/<id>-m<n>-<issue>`) is **kept after it lands** — only
1039
+ its tree and local branch go. `teardownBatch` (batch `done`, or dissolved) deletes the
1040
+ batch's member branches from origin (`pruneMemberBranches`, one delete per ref,
1041
+ `member-branches-deleted`), except any a NON-terminal queue entry's
1042
+ `failure_evidence.branch` still names (a parked or branch-requeued member's work);
1043
+ `sched abandon --batch` prunes the same way (verified project repo only). A kept batch
1044
+ (`worktree_kept`) keeps them.
1045
+ - An aggregate-suite eviction (`evictMembers`, after `beginAttribution`) therefore PARKS the
1046
+ reverted member `evicted` with `branch=` recorded (`EvictionOutcome.parked`, milestone
1047
+ `parked=`), like a pre-landing eviction, instead of requeueing it from the base. A member
1048
+ whose branch is no longer on origin (a pre-#840 landing) still requeues full-cycle; when
1049
+ origin cannot be listed only a recorded branch is parked on (journaled `git-failed`).
1050
+ - `sched requeue` of a parked member is based on its branch **by the engine**: at the
1051
+ entry's first dispatch, `EngineDeps.resumeSeeder` (`createExecResumeSeeder`: `runstate
1052
+ mint` + `runstate post`) seeds the issue's trail with a `setup done` milestone
1053
+ (`branch=<member branch> base_branch=<batch base> pool_claimed=false remote=pushed
1054
+ seeded_by=sched from_batch=<id>`). The agent's gate (`runstate verify`) then resumes at
1055
+ `plan` on that branch, and full-cycle's Resuming path builds the worktree from it — the
1056
+ documented resume contract, no dossier change. The run id is stamped on
1057
+ `failure_evidence.resume_run` so a respawn never re-seeds; `resume-seeded` /
1058
+ `resume-seed-failed` journal it (a failure falls back to the `PRIOR WORK` prompt
1059
+ instruction, which now names the seeded run when there is one, and — for a post-landing
1060
+ eviction — the commits reverted on the integration branch, which a rebase onto a base
1061
+ carrying those reverts would silently drop; engine-side re-application is #866). A branch
1062
+ gone from origin makes `verify` answer `resume_from=setup` — a fresh run off the base.
1026
1063
 
1027
1064
  State schema 1.24.0: `IssueStatus` gains `handed-back`; `EvictionRecord` gains optional
1028
1065
  `kind`/`branch`, `FailureEvidence` optional `branch`.
@@ -1 +1 @@
1
- {"version":3,"file":"batch-dispatch.d.ts","sourceRoot":"","sources":["../src/batch-dispatch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"batch-dispatch.d.ts","sourceRoot":"","sources":["../src/batch-dispatch.ts"],"names":[],"mappings":"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"}
@@ -815,9 +815,11 @@ function landMemberBranch(deps, batchId, now) {
815
815
  * `-d` after a landing (fully merged into the integration branch), `-D` on
816
816
  * the eviction path (its commits never landed; since #810 the parked entry
817
817
  * records the branch and an operator requeue continues from the REMOTE copy).
818
- * The REMOTE member branch is deleted only on the landed path, and
819
- * deliberately KEPT on eviction — the pushed sha is the evicted work's only
820
- * recoverable copy.
818
+ * The REMOTE member branch is never deleted here (#840): on eviction the
819
+ * pushed sha is the evicted work's only recoverable copy, and after a landing
820
+ * it is what a later aggregate-suite eviction parks the member on. Batch
821
+ * teardown deletes it once the batch ships or dissolves
822
+ * (`deleteMemberBranches`).
821
823
  *
822
824
  * Best-effort and idempotent: null fields are a no-op, and a failed cleanup
823
825
  * journals `teardown-failed` rather than throwing into the caller's
@@ -903,9 +905,6 @@ issue) {
903
905
  deps.exec('git', ['branch', flag, branch], deps.repoDir) === null
904
906
  ? `failed-branch-delete-${flag}`
905
907
  : `branch-deleted-${flag}`;
906
- if (landed) {
907
- deps.exec('git', ['push', 'origin', '--delete', branch], deps.repoDir);
908
- }
909
908
  }
910
909
  const failed = !treeCleared || branchCleanup.startsWith('failed');
911
910
  journalEvent(deps, failed ? 'teardown-failed' : 'member-worktree-torn-down', unit(batchId), {
@@ -1705,7 +1704,7 @@ function evictOffender(deps, config, batchId, offender, attribution, now, result
1705
1704
  const rDeps = recoveryDeps(deps, config, batch, now);
1706
1705
  const outcome = (0, recovery_1.evictMembers)(state, batchId, { issues: [offender], reason: 'suite-red-after-fix', attribution, ranges: batch.ranges }, rDeps);
1707
1706
  deps.store.withLock((s) => ({
1708
- state: applyBatchAndIssues(s, outcome.state, batchId, [...outcome.requeued, ...(outcome.dissolve?.parked ?? [])], batch.members),
1707
+ state: applyBatchAndIssues(s, outcome.state, batchId, [...new Set([...outcome.requeued, ...outcome.parked, ...(outcome.dissolve?.parked ?? [])])], batch.members),
1709
1708
  result: undefined,
1710
1709
  }));
1711
1710
  // #810: `dissolve.blocked` — a full dissolve refused over validated
@@ -4021,6 +4020,7 @@ function teardownBatch(deps, batchId) {
4021
4020
  true;
4022
4021
  const serial = teardownMemberWorktree(deps, batchId, deps.now(), lastMemberLanded);
4023
4022
  teardownParallelRuns(deps, batchId, serial);
4023
+ deleteMemberBranches(deps, batchId);
4024
4024
  const state = deps.store.load();
4025
4025
  const batch = (0, state_1.findBatch)(state, batchId);
4026
4026
  if (!batch || batch.worktree === null)
@@ -4044,6 +4044,30 @@ function teardownBatch(deps, batchId) {
4044
4044
  worktree: batch.worktree,
4045
4045
  });
4046
4046
  }
4047
+ /**
4048
+ * #840: `teardownBatch`'s member-branch cleanup — `pruneMemberBranches`
4049
+ * (recovery.ts) plus the journal line. Best-effort: a failed listing or delete
4050
+ * is journaled, never thrown into the teardown path; a kept batch
4051
+ * (`worktree_kept`) never gets here.
4052
+ */
4053
+ function deleteMemberBranches(deps, batchId) {
4054
+ const pruned = (0, recovery_1.pruneMemberBranches)(deps.exec, deps.repoDir, deps.store.load(), batchId);
4055
+ if (pruned === null) {
4056
+ journalEvent(deps, 'teardown-failed', unit(batchId), {
4057
+ cleanup: 'member-branches-unlisted',
4058
+ detail: `could not list origin's batch/${batchId}-m* member branches — none deleted`,
4059
+ });
4060
+ return;
4061
+ }
4062
+ const { deleted, kept, failed } = pruned;
4063
+ if (deleted.length + kept.length + failed.length === 0)
4064
+ return;
4065
+ journalEvent(deps, failed.length === 0 ? 'member-branches-deleted' : 'teardown-failed', unit(batchId), {
4066
+ ...(failed.length === 0 ? {} : { cleanup: 'member-branches-delete-failed' }),
4067
+ detail: `deleted=${deleted.join(',') || 'none'} kept=${kept.join(',') || 'none'}` +
4068
+ (failed.length > 0 ? ` failed=${failed.join(',')}` : ''),
4069
+ });
4070
+ }
4047
4071
  // --- Parallel member dispatch (#809) ---
4048
4072
  /**
4049
4073
  * How a batch should dispatch its members (#809) — decided once, at the