@ai-dossier/sched 0.48.1 → 0.50.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
@@ -28,7 +28,7 @@ ai-dossier sched enqueue --issues 101,105..109 --deps 100 --tier strong # flag
28
28
  ai-dossier sched enqueue --from-manifest batch-prep.json # batch-prep output
29
29
  ai-dossier sched start # the dispatch engine: spawn, verify, escalate, watch parked PRs (Ctrl-C stops it)
30
30
  ai-dossier sched start --once # a single reconcile+refill tick (cron-style)
31
- ai-dossier sched status # queue (+pr/cleanup), engine lease, slots, batches, blocked/failed; --anchors adds the open-batch-anchor sweep (#768)
31
+ ai-dossier sched status # queue (+pr/cleanup), engine lease, slots, batches, blocked/failed; --anchors adds the ledger anchor sweep (#768) plus orphaned anchors no longer in state.batches (#790)
32
32
  ai-dossier sched pause # prevent every new agent process; live units keep running
33
33
  ai-dossier sched resume
34
34
  ai-dossier sched stop --issue 42 # terminate one full-cycle agent and record it stopped (no recovery)
@@ -1040,7 +1040,9 @@ import {
1040
1040
  // runBatchCapability — #523)
1041
1041
  createSpawnDeps, // real detached-spawn process I/O
1042
1042
  createExecGroundTruth, // runstate/gh/git ground truth via subprocesses (injectable exec);
1043
- // since #468 also gh pr view PR state + setup info from comments
1043
+ // since #468 also gh pr view PR state + setup info from comments;
1044
+ // since #789 also mergedPrForBranch when constructed with a
1045
+ // verified `repo` (resolveProjectRepo)
1044
1046
  resolveDispatch, // config → resolved command/prompt/report-prompt/tier-models/timers/
1045
1047
  // per-tier spawn specs (tiers — #527)
1046
1048
  buildTierCommand, // resolved dispatch + tier + issue → argv, using that tier's OWN
@@ -1068,6 +1070,12 @@ import {
1068
1070
  prOfMilestone, // a milestone's pr= key as a positive integer
1069
1071
  parsePrViewJson, // gh pr view --json → PR truth (mergedAt/mergeable/blocked label)
1070
1072
  parseOpenPrListJson, // gh pr list --head <b> --state open → the open PR we opened (#596)
1073
+ parseMergedPrListJson, // gh pr list --head <b> --base <base> --state merged → MergedPrLookup
1074
+ // found/none/ambiguous — a hand-opened batch PR the ledger never
1075
+ // recorded (#789)
1076
+ type MergedPrLookup, // { kind: 'found', pr, mergedAt } | { kind: 'none' } |
1077
+ // { kind: 'ambiguous', matches } — GroundTruth.mergedPrForBranch's
1078
+ // own return type (#789)
1071
1079
  parseSetupInfo, // gh issue view --json comments → teardown inputs
1072
1080
  runTeardown, // #468 script teardown for a merged unit (pool return / worktree remove)
1073
1081
  isSafeWorktree, // worktree-path containment check (CWE-22)
@@ -1123,17 +1131,22 @@ import {
1123
1131
  // so batch-dispatch.ts can share it.
1124
1132
  TRANSITIONS, // the transition tables themselves (for previews)
1125
1133
  buildStatusReport, // machine-readable status incl. blocked/failed sets
1126
- // (+ optional `anchorSweep` → `anchors`, #768; null without it)
1134
+ // (+ optional `anchorSweep` → `anchors`/`orphan_anchors`, #768/#790)
1127
1135
  // (+ optional `worktreeReader` → `kept-worktree` warnings, #791)
1128
1136
  keptWorktreeCandidates, buildKeptWorktreeWarnings, defaultKeptWorktreeReader, // #791
1129
1137
  sweepAnchors, classifyAnchor, membersShippedVerdict, anchorLedgerBlockers,
1130
1138
  shippingEvidence, // #768 anchor-close predicate (pure; readers injected)
1131
1139
  closeAnchor, // #768 idempotent comment-then-close, `-R <repo>` explicit
1132
1140
  anchorCloseMarker, renderAnchorCloseComment, openAnchorBatches, formatBatchStatus,
1141
+ sweepOrphanAnchors, classifyOrphanAnchor, parseOrphanAnchorBody, batchAnchorStillOpen,
1142
+ // #790 orphan sweep — batches gone from state.batches entirely;
1143
+ // pure, GitHub/git only via the injected list/read (never exec)
1144
+ ORPHAN_SWEEP_MAX_ANCHORS, ORPHAN_SWEEP_MAX_MEMBERS, DEFAULT_ORPHAN_BASE_BRANCH, // #790
1145
+ BATCH_ANCHOR_LABEL, // #790, also used by cli/src/batch-compose.ts (single source)
1133
1146
  issueCloseReader, parseIssueCloseTruthJson, parseRepoName,
1134
1147
  resolveProjectRepo, // #768 owner/name of the cwd repo only when it IS the project's
1135
1148
  hasLabel, // case-insensitive label match (#768)
1136
- validateState, // strict persisted-state validation (1.0.0-1.13.0 files migrate)
1149
+ validateState, // strict persisted-state validation (1.0.0-1.23.0 files migrate)
1137
1150
  DEFAULT_ISSUE_PRIORITY, DEFAULT_BATCH_PRIORITY, // priority defaults (0 / 10, #565)
1138
1151
  IllegalTransitionError, EnqueueError, CorruptStateError, LockTimeoutError,
1139
1152
  SchedNotFoundError,
@@ -1301,8 +1314,9 @@ after-the-fact recovery, not a missing-data bug.
1301
1314
  queue data.
1302
1315
  - **Schema**: state/config files from #460 (schema 1.0.0), #464 (1.1.0), #468 (1.2.0),
1303
1316
  #472 (1.3.0), #500 (1.4.0), #505 (1.5.0), #504 (1.6.0), #523 (1.7.0) and #524 (1.8.0)
1304
- load and migrate to the current schema (1.24.0 — #810: no backfill, `kind`/`branch`
1305
- optional, absent = an `evicted` record with no branch) automatically (slot `branch`/`last_head`/`pid_start`, slot `role` (inferred from the
1317
+ load and migrate to the current schema (1.25.0 — 1.24.0 was #810: no backfill,
1318
+ `kind`/`branch` optional, absent = an `evicted` record with no branch) automatically
1319
+ (slot `branch`/`last_head`/`pid_start`, slot `role` (inferred from the
1306
1320
  unit's queue entry, with the persisted `phase` as a fallback — #500), entry
1307
1321
  `pr`/`cleanup`/`failure_evidence`, batch `anchor`/`branch`/`run_id`/`eviction_groups`/
1308
1322
  `evictions`/`fix_attempts`/`rebase_attempts`, state-level `last_pr_poll_at` backfill to
@@ -1315,7 +1329,10 @@ after-the-fact recovery, not a missing-data bug.
1315
1329
  `consecutive_dispatch_api_errors`/`dispatch_pause_reset_at` backfill to `0`/`null` —
1316
1330
  #629; batch `anchor_closed_at` and `anchor_close_failed_reason`/`_since`/`_ticks`
1317
1331
  backfill to `null`/`null`/`null`/`0` — #768, schema 1.22.0; batch `member_dispatch`/`member_runs`
1318
- backfill to `null`/`[]` — #809, schema 1.23.0 — a null mode past `ready` runs serially).
1332
+ backfill to `null`/`[]` — #809, schema 1.23.0 — a null mode past `ready` runs serially;
1333
+ `IssueStatus` gains `handed-back`, `EvictionRecord`/`FailureEvidence` gain optional
1334
+ `kind`/`branch` — #810, schema 1.24.0; batch `pr_detect_ambiguous_reason`/`_since`/`_ticks`
1335
+ backfill to `null`/`null`/`0` — #789, schema 1.25.0).
1319
1336
  - **`max_slots`** bounds live units (`assigned | running | recovering`); dependency
1320
1337
  edges gate readiness — an issue with an unmerged dependency, and a batch behind an
1321
1338
  unmerged batch, are never runnable.
@@ -1408,6 +1425,31 @@ predicate in `anchor-close.ts`) over `blocked`/`done` batches touched within the
1408
1425
  the journal line says the worktree was kept, and `sched status` then raises a
1409
1426
  `kept-worktree` warning for it on every run until the ledger field clears — see
1410
1427
  above and `reconcileKeptWorktrees` (#791).
1428
+ - **PR-detection evidence (#789).** When `batch.pr` was never recorded at all — a PR
1429
+ opened by hand, e.g. imboard#4255 — the stale-blocked reconcile also looks for
1430
+ exactly one MERGED pull request whose head is the batch branch, based against
1431
+ `batch.base_branch`, created at or after the batch's own `created_at`, and not from a
1432
+ fork (`GroundTruth.mergedPrForBranch`: `gh pr list -R <repo> --head <branch> --base
1433
+ <base> --state merged`, gated on the same verified `resolveProjectRepo` #768 uses —
1434
+ absent entirely without one). Positive evidence only: zero candidates records
1435
+ nothing and falls through to the branch/members evidence below; two or more is
1436
+ `ambiguous` — no PR is recorded, and only when no OTHER evidence reconciles the
1437
+ batch that same tick is the ambiguity journaled (`pr-detect-ambiguous`, deduped like
1438
+ `pr-watch-failed`: once per `blocked` stretch, re-announced every
1439
+ `JOURNAL_DEDUP_REANNOUNCE_TICKS`; a batch that leaves `blocked` any way — this
1440
+ reconcile's own success, `sched resume --batch`, `sched abandon` — clears the marker,
1441
+ so a later re-block never inherits a stale streak). A batch that still reconciles via
1442
+ `commits-in-base`/`members-closed` does so without a PR and finishes inline, same as
1443
+ before #789. On a match, `batch.pr` is recorded as part of the SAME `blocked →
1444
+ merged` transition (the `stale-failure-reconciled` line then also carries
1445
+ `pr_detected: true`), so the ordinary `deployed` machinery (item 6, "Report dispatch",
1446
+ under "The PR watcher + tail work (#468)" below — shared infrastructure, not
1447
+ per-issue-only despite the section's origin) dispatches the report agent exactly as if the
1448
+ fleet had opened the PR itself, and `sched status`'s existing `pr` column shows it.
1449
+ Recording `batch.pr` never closes the anchor by itself — that stays #768's own
1450
+ evidence-gated `reconcileAnchorClosure`, unchanged. An ambiguous match with no
1451
+ explicit way to resolve it today (#824 tracks a `sched attach-pr` verb) still lets the
1452
+ batch reconcile via its other evidence, or falls to `sched abandon --batch`.
1411
1453
 
1412
1454
  Everything else is surfaced, never closed: `sched status --anchors` (opt-in; `status`
1413
1455
  makes no GitHub call without it) lists each still-open anchor of a batch no longer in
@@ -1419,6 +1461,51 @@ Journal: `anchor-closed` (including "found already closed") and `anchor-close-fa
1419
1461
  (deduped like `pr-watch-failed`: once per streak, re-announced every
1420
1462
  `JOURNAL_DEDUP_REANNOUNCE_TICKS`).
1421
1463
 
1464
+ ### Orphaned anchors — batches dropped from the ledger entirely (#790)
1465
+
1466
+ The sweep above only ever walks `state.batches` (`openAnchorBatches`) — an anchor whose
1467
+ batch fell out of the ledger ENTIRELY (a lost or reset `state.json`; imboard#4244/#4253
1468
+ were exactly this shape: `sched status --json` showed `batches: []` with both anchors
1469
+ still open) is invisible to it. The same `--anchors` flag also runs a GitHub-only sweep
1470
+ for exactly that: `gh issue list --label batch-epic --state open` for the pinned
1471
+ project repo, excluding anchors the ledger sweep already covers, recovering each
1472
+ orphan's members from its own issue-body checklist (`parseOrphanAnchorBody`) and
1473
+ classifying with the same shipping-evidence logic (`classifyOrphanAnchor`, sharing
1474
+ `readMembersShipping`/`anchorGroundVerdict` with `classifyAnchor` above) — minus the
1475
+ ledger check, which cannot apply to something not in the ledger. Reported under
1476
+ `== Orphaned batch anchors (not in ledger) ==` (`orphan_anchors` in `--json`, `null` when
1477
+ the sweep did not run OR the GitHub list call itself failed — rendered `(unavailable)`,
1478
+ never silently as `(none)`) as `orphan-closable-candidate`, `orphan-needs-operator`, or
1479
+ `orphan-unknown` — deliberately never the ledger sweep's bare `closable`: without a
1480
+ ledger there is no eviction/requeue trail to rule out, so even a clean read is a
1481
+ CANDIDATE for a human to confirm. Capped at `ORPHAN_SWEEP_MAX_ANCHORS` (20) classified
1482
+ per run — ledger-tracked anchors are excluded BEFORE that cap, from a GitHub fetch
1483
+ (`ORPHAN_LIST_FETCH_LIMIT`, 100) wider than it, so a busy repo's tracked anchors cannot
1484
+ crowd real orphans out; `orphan_anchors_truncated` (`StatusReport`) and a rendered
1485
+ truncation line fire when candidates still exceeded the cap. The anchor body is
1486
+ untrusted input (anyone who can edit an open `batch-epic` issue controls it): member
1487
+ numbers outside the valid GitHub issue range are dropped, a body over
1488
+ `ORPHAN_SWEEP_MAX_MEMBERS` (50) refuses with NO reads at all (`members-over-cap`), and
1489
+ `base_branch` is checked twice — syntactically (`SAFE_REF_RE`, falling back to
1490
+ `DEFAULT_ORPHAN_BASE_BRANCH`/`main` when unsafe) and then against the expected/configured
1491
+ base (`expectedBaseBranch`, default `main`): a value that names a DIFFERENT — even
1492
+ syntactically valid — branch can never produce `orphan-closable-candidate`, only
1493
+ `orphan-needs-operator` with reason `base-branch-nonstandard:<value>`, since it decides
1494
+ what counts as shipped and an editable issue field is not trusted to pick that
1495
+ unsupervised. Report-only by construction, exactly like the ledger sweep — `list`/`read`
1496
+ are pure lookups with no write capability, proven by a recording-`ExecFn` test over the
1497
+ real gh-argv-building path (`anchor-close.test.ts`).
1498
+
1499
+ Separately, `sched abandon --batch` warns — stderr line plus a journaled
1500
+ `batch-anchor-open-on-abandon` event, and an additive `anchor_open` field on
1501
+ `abandon --json` — rather than refuses, when it dissolves a batch whose anchor is still
1502
+ open on GitHub. Nothing in this codebase currently removes a batch row from
1503
+ `state.batches` (`abandonBatch` dissolves in place, status `dissolved`, still
1504
+ ledger-swept above), so this is a courtesy at the one real moment an operator ends a
1505
+ batch's active lifecycle — never a gate, and never a substitute for the orphan sweep. The
1506
+ CLI's repo-verification exec is timed (10s) on this path too, so an abandon that used to
1507
+ make no network calls at all cannot hang on an unresponsive `gh`.
1508
+
1422
1509
  ## Hard-block labels are re-read every tick (#544)
1423
1510
 
1424
1511
  #507's enqueue pre-screen resolves an issue's GitHub labels in the CLI and lands the
@@ -169,4 +169,164 @@ export declare function sweepAnchors(state: SchedState, read: IssueCloseReader,
169
169
  repo?: string;
170
170
  commitInBase?: CommitInBase;
171
171
  }): AnchorReportItem[];
172
+ /** The base branch `parseOrphanAnchorBody` falls back to, and `classifyOrphanAnchor` treats as the expected/project-standard base absent an `expectedBaseBranch` override — what `gate-issue` itself defaults to. */
173
+ export declare const DEFAULT_ORPHAN_BASE_BRANCH = "main";
174
+ /**
175
+ * #790 (security review): the anchor body is untrusted input — anyone who can
176
+ * comment-and-edit an open `batch-epic` issue controls it. Without a cap, a
177
+ * body with thousands of checklist lines would cost thousands of GraphQL
178
+ * reads per sweep (`classifyOrphanAnchor` runs `exhaustive: true`), and one
179
+ * crafted out-of-range member number would error that member's read,
180
+ * `orphan-unknown` it, and abort {@link sweepOrphanAnchors}'s reads for every
181
+ * later anchor. Both are answered the same way: a body over the cap is
182
+ * reported `orphan-needs-operator` (reason `members-over-cap`) with NO reads
183
+ * performed at all — see {@link classifyOrphanAnchor}.
184
+ */
185
+ export declare const ORPHAN_SWEEP_MAX_MEMBERS = 50;
186
+ /**
187
+ * Recover a batch anchor's members and base branch from its own issue body —
188
+ * the only record left once the batch has dropped out of `state.batches`.
189
+ * The body is the batch-compose format (RFC-0001): one member checklist line
190
+ * per issue, then metadata lines including `base_branch: <name>`. Nothing in
191
+ * this codebase edits an anchor's body after creation (verified: no
192
+ * `gh issue edit ... --body` targets an anchor), so the checklist is already
193
+ * the complete, stable membership — a `batch-setup` runstate milestone would
194
+ * only repeat the same list less reliably (missing entirely for an anchor
195
+ * that predates runstate, or belonging to a requeued run's earlier attempt).
196
+ *
197
+ * Both fields are untrusted (#790 security review) and validated before use:
198
+ * a member number outside `1..MAX_GITHUB_ISSUE_NUMBER` is dropped (never sent
199
+ * to `read`), and `base_branch` falls back to `main` — never propagating a
200
+ * string {@link SAFE_REF_RE} would reject as a git ref — when the metadata
201
+ * line is missing OR unsafe. `main` is what `gate-issue` defaults to, so it
202
+ * is what `shippingEvidence` checks a closer against either way.
203
+ * `members_over_cap` is set (members truncated to {@link ORPHAN_SWEEP_MAX_MEMBERS})
204
+ * rather than silently proceeding on a partial list — the caller reports it,
205
+ * never reads a partial membership as if it were the whole batch.
206
+ */
207
+ export declare function parseOrphanAnchorBody(body: string): {
208
+ members: number[];
209
+ base_branch: string;
210
+ members_over_cap: boolean;
211
+ };
212
+ /** A batch-epic anchor recovered from GitHub, with no `state.batches` row behind it. */
213
+ export interface OrphanAnchorCandidate {
214
+ anchor: number;
215
+ members: number[];
216
+ base_branch: string;
217
+ /** Set when {@link parseOrphanAnchorBody} truncated the member list at {@link ORPHAN_SWEEP_MAX_MEMBERS} — `classifyOrphanAnchor` refuses to read a partial membership. */
218
+ members_over_cap?: boolean;
219
+ }
220
+ /**
221
+ * {@link classifyOrphanAnchor}'s answer. Deliberately its own vocabulary —
222
+ * `orphan-closable-candidate`, never bare `closable` — because without a
223
+ * ledger there is no failure-trail evidence (no eviction/requeue record to
224
+ * rule out, the operator's rule from #768 is POSITIVE evidence only): even a
225
+ * verdict with zero disqualifying reasons is a CANDIDATE for a human to
226
+ * confirm, not the ledger-backed `sweepAnchors`' stronger `closable`.
227
+ */
228
+ export type OrphanAnchorVerdict = {
229
+ kind: 'orphan-closable-candidate' | 'orphan-needs-operator' | 'orphan-unknown';
230
+ reasons: string[];
231
+ members: AnchorMemberReport[];
232
+ };
233
+ /**
234
+ * Classify one orphan anchor candidate, or `null` when it turns out not to be
235
+ * an orphan at all — the anchor CLOSED between the GitHub list and this read
236
+ * (the caller only ever lists open anchors), the same list-then-read race
237
+ * `sweepAnchors` answers by `continue`-ing past a freshly `anchor-closed`
238
+ * verdict rather than reporting one. Deliberately NOT `classifyAnchor` /
239
+ * `membersShippedVerdict` verbatim: those consult `anchorLedgerBlockers`,
240
+ * which pushes `member-not-in-ledger:#N` for every member of ANY batch not
241
+ * in `state.batches` — for an orphan that is true by construction, so the
242
+ * ledger-backed predicate would answer `needs-operator` unconditionally and
243
+ * this sweep could never report a clean batch as a candidate. This reuses
244
+ * the SAME shipping-evidence logic ({@link readMembersShipping}, which is
245
+ * {@link shippingEvidence} plus the open/not-completed/handed-back checks)
246
+ * and the SAME anchor-level ground truth ({@link anchorGroundVerdict}) that
247
+ * `classifyAnchor` uses — the ledger check is the one piece structurally
248
+ * inapplicable to something not in the ledger.
249
+ */
250
+ export declare function classifyOrphanAnchor(candidate: OrphanAnchorCandidate, read: IssueCloseReader, opts?: {
251
+ repo?: string;
252
+ commitInBase?: CommitInBase;
253
+ expectedBaseBranch?: string;
254
+ }): OrphanAnchorVerdict | null;
255
+ /** One open `batch-epic` anchor issue, as listed from GitHub. */
256
+ export interface OpenAnchorIssue {
257
+ number: number;
258
+ title: string;
259
+ body: string;
260
+ }
261
+ /** Lists open `batch-epic` anchor issues for the pinned project repo, or `undefined` on a failed read (unverified repo, `gh` unreachable). */
262
+ export type OpenAnchorLister = () => OpenAnchorIssue[] | undefined;
263
+ /**
264
+ * The exact `gh issue list` argv for the #790 orphan lister — exported so
265
+ * the CLI's real lister (`orphanAnchorListerFor`, `cli/src/commands/sched.ts`)
266
+ * and this package's own tests build the SAME command from ONE definition
267
+ * (#790 review: the earlier AC6 test built its own copy of this argv, so a
268
+ * future change to the production command would not have been caught by
269
+ * it). Read-only by construction — `gh issue list` never writes.
270
+ */
271
+ export declare function orphanAnchorListArgs(repo: string, limit: number): string[];
272
+ /** `sched status --anchors`' orphan sweep (#790): bounded read cost per run — a GitHub-side sweep must never grow with the repo's total anchor count. */
273
+ export declare const ORPHAN_SWEEP_MAX_ANCHORS = 20;
274
+ /** One `sched status --anchors` orphan-sweep row. */
275
+ export interface OrphanAnchorReportItem {
276
+ anchor: number;
277
+ title: string;
278
+ verdict: OrphanAnchorVerdict['kind'];
279
+ reasons: string[];
280
+ members: AnchorMemberReport[];
281
+ }
282
+ /**
283
+ * {@link sweepOrphanAnchors}'s result: the classified rows plus whether the
284
+ * cap left anything unprobed. `truncated` distinguishes "these are ALL the
285
+ * open orphans" from "more may exist beyond what was classified" — silently
286
+ * capping without saying so would read as a complete, clean sweep on a busy
287
+ * repo where it is neither.
288
+ */
289
+ export interface OrphanAnchorSweepResult {
290
+ items: OrphanAnchorReportItem[];
291
+ /** True when more ledger-unbound open `batch-epic` anchors existed than {@link ORPHAN_SWEEP_MAX_ANCHORS} could classify this run. */
292
+ truncated: boolean;
293
+ }
294
+ /**
295
+ * `sched status --anchors`' orphan sweep (#790): every open `batch-epic`
296
+ * anchor in the pinned project repo whose batch is no longer in
297
+ * `state.batches` — invisible to {@link sweepAnchors}, which only walks the
298
+ * ledger. Report-only by construction, exactly like `sweepAnchors`: `list`
299
+ * and `read` are both pure lookups with no write capability, so this
300
+ * function has no way to close, comment on, label, or edit anything — it
301
+ * only ever builds and returns {@link OrphanAnchorReportItem} rows.
302
+ *
303
+ * `null` means the list itself failed (an unverified repo, or `gh`
304
+ * unreachable) — distinct from `{items: [], truncated: false}` ("asked,
305
+ * found zero orphans"), the same null-vs-empty convention
306
+ * `StatusReport.anchors`/`orphan_anchors` already use for "the sweep did not
307
+ * run at all". Ledger-tracked anchors are excluded BEFORE the
308
+ * {@link ORPHAN_SWEEP_MAX_ANCHORS} cap is applied — a busy repo with 20+ open
309
+ * ledger-tracked `batch-epic` anchors must not let them crowd out the
310
+ * orphans this sweep exists to find; `truncated=true` when the cap still
311
+ * left real orphan candidates unprobed. Classifying stops at the first
312
+ * failed member/anchor read (the same fail-closed posture as
313
+ * `sweepAnchors`): every anchor after that point is reported `orphan-unknown`
314
+ * without a further call.
315
+ */
316
+ export declare function sweepOrphanAnchors(state: SchedState, list: OpenAnchorLister, read: IssueCloseReader, opts?: {
317
+ repo?: string;
318
+ commitInBase?: CommitInBase;
319
+ expectedBaseBranch?: string;
320
+ }): OrphanAnchorSweepResult | null;
321
+ /**
322
+ * Whether dissolving `batch` (`sched abandon --batch`) should warn an
323
+ * operator: its anchor is set and, per `read`, still OPEN. Pure predicate —
324
+ * the CLI performs the actual GitHub read and the print/journal side effect
325
+ * (`sched abandon --batch`'s handler). `null` covers both "no anchor to warn
326
+ * about" and "read failed / anchor already closed or missing" alike: this
327
+ * function only ever tells the caller whether to warn, never why not to —
328
+ * `abandonBatch` itself must NEVER refuse over this (#790: refusing would
329
+ * wedge exactly the cleanup `abandon` exists for).
330
+ */
331
+ export declare function batchAnchorStillOpen(batch: Pick<BatchEntry, 'anchor'>, read: IssueCloseReader): number | null;
172
332
  //# sourceMappingURL=anchor-close.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"anchor-close.d.ts","sourceRoot":"","sources":["../src/anchor-close.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"anchor-close.d.ts","sourceRoot":"","sources":["../src/anchor-close.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAOxC,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEhF,qFAAqF;AACrF,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,eAAe,GAAG,SAAS,CAAC;AAE9E;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;AAgBxE;;;GAGG;AACH,eAAO,MAAM,2BAA2B,EAAE,WAAW,CAAC,WAAW,CAAgC,CAAC;AAkBlG;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,WAAW,CAAC,WAAW,CAAC,GACjC,KAAK,CAAC,UAAU,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAKxC;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAG,gBAAgB,CAAC,GAAG,MAAM,CAI9F;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,CAsBnF;AAED,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,aAAa,EAAE,WAAW,GAAG,IAAI,CAAC;IAClC,sEAAsE;IACtE,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAClD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gFAAgF;IAChF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IACE,IAAI,EAAE,UAAU,GAAG,gBAAgB,GAAG,SAAS,CAAC;IAChD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B,CAAC;AAEN,mDAAmD;AACnD,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,aAAa,EAAE;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,CAAC,CAAC;AAElF;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,eAAe,EACtB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,YAAY,EAAE,YAAY,GAAG,SAAS,GACrC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAkC3C;AAED,MAAM,WAAW,qBAAqB;IACpC,uFAAuF;IACvF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mFAAmF;IACnF,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA0ED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,gBAAgB,EACtB,IAAI,GAAE,qBAA0B,GAC/B,iBAAiB,CAiCnB;AAmBD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,gBAAgB,EACtB,IAAI,GAAE,IAAI,CAAC,qBAAqB,EAAE,cAAc,CAAM,GACrD,aAAa,CAYf;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,4DAA4D;AAC5D,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,kBAAkB,EAAE,GAAG,MAAM,CAWjG;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAC1B,QAAQ,GACR,qBAAqB,GACrB,gBAAgB,GAChB,cAAc,CAAC;AAKnB;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,UAAU,EACjB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,kBAAkB,EAAE,GAC5B,kBAAkB,CAqCpB;AAED,4FAA4F;AAC5F,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACnC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,gBAAgB,EACtB,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,YAAY,CAAA;CAAO,GACxD,gBAAgB,EAAE,CAmBpB;AAwBD,qNAAqN;AACrN,eAAO,MAAM,0BAA0B,SAAS,CAAC;AAKjD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG;IACnD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;CAC3B,CAUA;AAED,wFAAwF;AACxF,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,0KAA0K;IAC1K,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,2BAA2B,GAAG,uBAAuB,GAAG,gBAAgB,CAAC;IAC/E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE,gBAAgB,EACtB,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAO,GACrF,mBAAmB,GAAG,IAAI,CA6D5B;AAED,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,8IAA8I;AAC9I,MAAM,MAAM,gBAAgB,GAAG,MAAM,eAAe,EAAE,GAAG,SAAS,CAAC;AAEnE;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAe1E;AAED,yJAAyJ;AACzJ,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,qDAAqD;AACrD,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACrC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAChC,qIAAqI;IACrI,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,gBAAgB,EACtB,IAAI,EAAE,gBAAgB,EACtB,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAO,GACrF,uBAAuB,GAAG,IAAI,CA8BhC;AAID;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,EACjC,IAAI,EAAE,gBAAgB,GACrB,MAAM,GAAG,IAAI,CAOf"}