@ai-dossier/cli 0.55.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.
@@ -0,0 +1,395 @@
1
+ "use strict";
2
+ /**
3
+ * `ai-dossier batch compose` (#773, #770 P3) — preview which issues may share a batch PR, with
4
+ * zero model tokens. Runs prescreen:v2 + the deterministic readiness screen over the operator's
5
+ * picks and/or the backlog and proposes a composition honouring the scheduler's batch invariants
6
+ * (≤ `max_full_review_members` review=full members, one base branch, 3–6 members), listing ranked
7
+ * backfill candidates when the picks fall short.
8
+ *
9
+ * I/O only: `gh` (issue reads), and a READ-ONLY look at the local sched queue/config. Never a
10
+ * model call, never a write (no labels, comments, or queue changes) — composing is a preview;
11
+ * batch-issues-preparation (or the operator) acts on it. Exits 0 once arguments validate; the
12
+ * `status` field is the payload, not a pass/fail gate (same contract as `classify prescreen`).
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.registerBatchCommand = registerBatchCommand;
16
+ const sched_1 = require("@ai-dossier/sched");
17
+ const batch_compose_1 = require("../batch-compose");
18
+ const gh_1 = require("../gh");
19
+ const issue_selection_1 = require("../issue-selection");
20
+ const plan_artifact_1 = require("../plan-artifact");
21
+ const prescreen_1 = require("../prescreen");
22
+ const runstate_1 = require("../runstate");
23
+ /** Default backlog page — one `gh issue list` call, bodies and comments included. */
24
+ const DEFAULT_BACKLOG_LIMIT = 100;
25
+ /** Hard ceiling on the backlog page (each issue's comments ride along in the one call). */
26
+ const MAX_BACKLOG_LIMIT = 500;
27
+ /** stdout ceiling for the backlog page — bodies and comments of up to MAX_BACKLOG_LIMIT issues. */
28
+ const BACKLOG_MAX_BUFFER = 256 * 1024 * 1024;
29
+ /** Fields every issue read requests — `comments` carries plan:v1 artifacts and runstate milestones. */
30
+ const ISSUE_FIELDS = 'number,title,body,labels,assignees,state,comments';
31
+ function names(value, key) {
32
+ if (!Array.isArray(value))
33
+ return [];
34
+ return value
35
+ .map((v) => (v && typeof v === 'object' ? v[key] : undefined))
36
+ .filter((v) => typeof v === 'string');
37
+ }
38
+ function commentBodies(value) {
39
+ if (!Array.isArray(value))
40
+ return [];
41
+ return value.map((c) => c && typeof c === 'object' && typeof c.body === 'string'
42
+ ? c.body
43
+ : '');
44
+ }
45
+ /** A `gh` issue object → the core's input (dependencies and sched status filled in later). */
46
+ function toInput(raw, source) {
47
+ const bodies = commentBodies(raw.comments);
48
+ const plan = (0, plan_artifact_1.findLatestPlan)(bodies);
49
+ const milestones = (0, runstate_1.parseMilestones)(bodies);
50
+ return {
51
+ issue: Number(raw.number),
52
+ source,
53
+ title: (0, gh_1.asString)(raw.title),
54
+ body: (0, gh_1.asString)(raw.body),
55
+ labels: names(raw.labels, 'name'),
56
+ state: (0, gh_1.asString)(raw.state),
57
+ assignees: names(raw.assignees, 'login'),
58
+ predictedFiles: plan?.artifact.predictedFiles,
59
+ latestPhase: milestones.length > 0 ? milestones[milestones.length - 1].phase : null,
60
+ };
61
+ }
62
+ function fetchPick(issue, repo) {
63
+ const res = (0, gh_1.exec)('gh', [
64
+ 'issue',
65
+ 'view',
66
+ String(issue),
67
+ '--json',
68
+ ISSUE_FIELDS,
69
+ ...(0, gh_1.repoArgs)(repo),
70
+ ]);
71
+ const unreadable = (error) => ({
72
+ issue,
73
+ source: 'pick',
74
+ error,
75
+ title: '',
76
+ body: '',
77
+ labels: [],
78
+ state: '',
79
+ assignees: [],
80
+ });
81
+ if (!res.ok)
82
+ return unreadable((0, gh_1.ghFailure)(`Could not read issue #${issue}`, res.error, repo));
83
+ const parsed = (0, gh_1.parseGhJson)(res.stdout);
84
+ if (parsed === null)
85
+ return unreadable(`Could not read issue #${issue}: gh did not print JSON.`);
86
+ return toInput({ ...parsed, number: issue }, 'pick');
87
+ }
88
+ function fetchBacklog(opts, repo, warnings) {
89
+ const args = ['issue', 'list', '--state', 'open', '--limit', String(opts.limit)];
90
+ for (const label of opts.labels)
91
+ args.push(`--label=${label}`);
92
+ if (opts.search !== undefined)
93
+ args.push(`--search=${opts.search}`);
94
+ args.push('--json', ISSUE_FIELDS, ...(0, gh_1.repoArgs)(repo));
95
+ const res = (0, gh_1.exec)('gh', args, { maxBuffer: BACKLOG_MAX_BUFFER });
96
+ if (!res.ok) {
97
+ warnings.push((0, gh_1.ghFailure)('Could not list the backlog — no backfill proposed', res.error, repo));
98
+ return [];
99
+ }
100
+ const parsed = (0, gh_1.parseGhJson)(res.stdout);
101
+ if (!Array.isArray(parsed)) {
102
+ warnings.push('Could not list the backlog: gh did not print a JSON array — no backfill proposed.');
103
+ return [];
104
+ }
105
+ return parsed
106
+ .filter((r) => Number.isSafeInteger(Number(r.number)) && Number(r.number) > 0)
107
+ .map((r) => toInput(r, 'backlog'));
108
+ }
109
+ /** The sched project slug: explicit `--project`, else `--repo` as `owner-name`, else the cwd's repo. */
110
+ function resolveProject(opts) {
111
+ if (opts.project)
112
+ return opts.project;
113
+ if (opts.repo)
114
+ return (0, sched_1.sanitizeSlug)(opts.repo.replace('/', '-'));
115
+ return (0, sched_1.resolveProjectSlug)(sched_1.defaultExec);
116
+ }
117
+ /** Read-only sched queue + config. A missing state is an empty queue; an unreadable one is a warning. */
118
+ function readSched(project, warnings) {
119
+ const store = new sched_1.SchedStore((0, sched_1.schedStateDir)(project));
120
+ let state = null;
121
+ let config = null;
122
+ try {
123
+ state = store.load();
124
+ }
125
+ catch (err) {
126
+ warnings.push(`Could not read the sched queue for '${project}' — the sched-active check was skipped: ${err.message}`);
127
+ }
128
+ try {
129
+ config = store.loadConfig();
130
+ }
131
+ catch (err) {
132
+ warnings.push(`Could not read the sched config for '${project}' — using the default review=full cap: ${err.message}`);
133
+ }
134
+ return { state, config };
135
+ }
136
+ /** Status of the issue's live queue entry (not terminal, not already merged), or null. */
137
+ function activeSchedStatus(state, issue) {
138
+ const entry = state?.entries.find((e) => e.issue === issue &&
139
+ !sched_1.TERMINAL_ISSUE_STATUSES.has(e.status) &&
140
+ !sched_1.SATISFIED_ISSUE_STATUSES.has(e.status));
141
+ return entry ? entry.status : null;
142
+ }
143
+ function positiveInt(raw, flag, { min = 1, max = Number.MAX_SAFE_INTEGER } = {}) {
144
+ const n = Number(raw);
145
+ if (!/^\d+$/.test(raw.trim()) || !Number.isSafeInteger(n) || n < min || n > max) {
146
+ (0, gh_1.fail)([`${flag} must be an integer between ${min} and ${max}, got '${raw}'.`]);
147
+ }
148
+ return n;
149
+ }
150
+ /** Terminal control characters — issue titles and label names are untrusted, network-sourced text. */
151
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: matching (and stripping) control characters is exactly this regex's job
152
+ const TERMINAL_CONTROL_RE = /[\u0000-\u0009\u000b-\u001f\u007f-\u009f]/g;
153
+ function renderText(r) {
154
+ // Every text line goes through one strip, so an ANSI/OSC escape in an issue title can never
155
+ // reach the operator's terminal raw. (JSON mode is safe: JSON.stringify escapes them.)
156
+ const line = (s = '') => console.log(s.replace(TERMINAL_CONTROL_RE, ''));
157
+ line(`batch compose — ${r.repo ?? r.project} (base ${r.base_branch}, rules ${r.rules})`);
158
+ line(`status: ${r.status} — ${r.members.length} member(s), ${r.members.filter((m) => m.review === 'full').length}/${r.params.max_full_review} review=full, min ${r.params.min_members}, max ${r.params.max_members}`);
159
+ line(`→ ${r.recommendation}`);
160
+ line();
161
+ line('Members:');
162
+ if (r.members.length === 0)
163
+ line(' (none)');
164
+ for (const m of r.members) {
165
+ const pk = m.packages.length > 0 ? ` [${m.packages.join(', ')}]` : '';
166
+ line(` #${m.issue} review=${m.review} (${m.source})${pk} ${m.title}`);
167
+ for (const why of m.review_reasons)
168
+ line(` full because: ${why}`);
169
+ }
170
+ if (r.shared_packages.length > 0)
171
+ line(` shared packages: ${r.shared_packages.join(', ')}`);
172
+ if (r.held.length > 0) {
173
+ line();
174
+ line('Admissible but held out:');
175
+ for (const h of r.held)
176
+ line(` #${h.issue} review=${h.review} ${h.reason} ${h.title}`);
177
+ }
178
+ if (r.excluded.length > 0) {
179
+ line();
180
+ line('Excluded:');
181
+ for (const e of r.excluded) {
182
+ line(` #${e.issue} ${e.reasons.map((x) => x.code).join(', ')} ${e.title}`);
183
+ for (const x of e.reasons)
184
+ line(` ${x.message}`);
185
+ }
186
+ }
187
+ if (r.backfill.length > 0) {
188
+ line();
189
+ line('Backfill candidates (ranked):');
190
+ for (const b of r.backfill.slice(0, 10)) {
191
+ const sh = b.shared_packages.length > 0 ? ` shares ${b.shared_packages.join(', ')}` : '';
192
+ line(` ${b.rank}. #${b.issue} review=${b.review}${b.selected ? ' ← selected' : ''}${sh} ${b.title}`);
193
+ }
194
+ if (r.backfill.length > 10)
195
+ line(` … ${r.backfill.length - 10} more (see --json)`);
196
+ }
197
+ for (const w of r.warnings)
198
+ console.error(`⚠ ${w.replace(TERMINAL_CONTROL_RE, '')}`);
199
+ }
200
+ function runCompose(opts) {
201
+ if (opts.repo)
202
+ (0, gh_1.requireRepoSlug)(opts.repo);
203
+ if (!sched_1.SAFE_REF_RE.test(opts.base))
204
+ (0, gh_1.fail)([`--base must be a valid git ref name, got '${opts.base}'.`]);
205
+ if (opts.rules !== 'v2' && opts.rules !== 'legacy') {
206
+ (0, gh_1.fail)([`--rules must be 'v2' or 'legacy', got '${opts.rules}'.`]);
207
+ }
208
+ const rules = opts.rules;
209
+ if (!opts.issues && !opts.backlog) {
210
+ (0, gh_1.fail)([
211
+ 'Nothing to compose.',
212
+ 'Fix: pass --issues <selection> (e.g. 4,5,9..12) and/or --backlog.',
213
+ ]);
214
+ }
215
+ let picks = [];
216
+ if (opts.issues) {
217
+ try {
218
+ picks = (0, issue_selection_1.parseIssueSelection)(opts.issues);
219
+ }
220
+ catch (err) {
221
+ (0, gh_1.fail)([`--issues: ${err.message}`]);
222
+ }
223
+ }
224
+ const limit = positiveInt(opts.limit, '--limit', { max: MAX_BACKLOG_LIMIT });
225
+ const minMembers = positiveInt(opts.minMembers, '--min-members', { max: batch_compose_1.DEFAULT_MAX_MEMBERS });
226
+ const maxMembers = positiveInt(opts.maxMembers, '--max-members', { max: batch_compose_1.DEFAULT_MAX_MEMBERS });
227
+ if (minMembers > maxMembers)
228
+ (0, gh_1.fail)(['--min-members may not exceed --max-members.']);
229
+ const warnings = [];
230
+ const project = resolveProject(opts);
231
+ const sched = readSched(project, warnings);
232
+ const maxFullReview = opts.maxFullReview !== undefined
233
+ ? positiveInt(opts.maxFullReview, '--max-full-review', { min: 0, max: batch_compose_1.DEFAULT_MAX_MEMBERS })
234
+ : (sched.config?.max_full_review_members ?? sched_1.MAX_FULL_REVIEW_MEMBERS);
235
+ const inputs = picks.map((n) => fetchPick(n, opts.repo));
236
+ const pickSet = new Set(picks);
237
+ // Backlog: explicitly requested, or automatic backfill when the picks fall short.
238
+ const labels = opts.label ?? [];
239
+ let backlogQueried = false;
240
+ // Dependency state lookups, cached across issues (backlog issues are known OPEN for free).
241
+ const knownState = new Map();
242
+ const unresolved = new Set();
243
+ const depCache = new Map();
244
+ /** Pick → the other picks it depends on (checked after assessment, see applyPickDependencies). */
245
+ const pickDeps = new Map();
246
+ function withDeps(input) {
247
+ const cached = depCache.get(input.issue);
248
+ if (cached)
249
+ return cached;
250
+ if (input.error !== undefined)
251
+ return input;
252
+ const open = [];
253
+ const unknown = [];
254
+ const onPicks = [];
255
+ for (const dep of (0, prescreen_1.extractDependencyRefs)(`${input.title}\n${input.body}`)) {
256
+ if (dep === input.issue)
257
+ continue;
258
+ if (pickSet.has(dep)) {
259
+ onPicks.push(dep);
260
+ continue;
261
+ }
262
+ let state = knownState.get(dep);
263
+ if (state === undefined) {
264
+ const res = (0, gh_1.tryFetchIssueState)(String(dep), opts.repo);
265
+ if (!res.ok) {
266
+ unresolved.add(dep);
267
+ unknown.push(dep);
268
+ continue;
269
+ }
270
+ state = res.state;
271
+ knownState.set(dep, state);
272
+ }
273
+ if (state.toUpperCase() === 'OPEN')
274
+ open.push(dep);
275
+ }
276
+ if (onPicks.length > 0)
277
+ pickDeps.set(input.issue, onPicks);
278
+ const full = {
279
+ ...input,
280
+ openDependencies: open,
281
+ unknownDependencies: unknown,
282
+ schedStatus: activeSchedStatus(sched.state, input.issue),
283
+ };
284
+ depCache.set(input.issue, full);
285
+ return full;
286
+ }
287
+ const isOpen = (issue) => (knownState.get(issue) ?? 'OPEN').toUpperCase() === 'OPEN';
288
+ const assessAll = (list) => (0, batch_compose_1.applyPickDependencies)(list.map((i) => (0, batch_compose_1.assessIssue)(withDeps(i), rules)), pickDeps, isOpen);
289
+ const composeOpts = {
290
+ rules,
291
+ baseBranch: opts.base,
292
+ minMembers,
293
+ maxMembers,
294
+ maxFullReview,
295
+ picksMode: picks.length > 0,
296
+ };
297
+ // Backlog: explicitly requested, or automatic backfill when the picks alone cannot compose
298
+ // min_members (counted after the caps — five admissible review=full picks compose only two).
299
+ const wantBacklog = () => {
300
+ if (opts.backlog)
301
+ return true;
302
+ if (opts.backfill === false)
303
+ return false;
304
+ return (0, batch_compose_1.composeBatch)(assessAll(inputs), composeOpts).members.length < minMembers;
305
+ };
306
+ for (const i of inputs)
307
+ if (i.error === undefined)
308
+ knownState.set(i.issue, i.state);
309
+ if (wantBacklog()) {
310
+ backlogQueried = true;
311
+ const backlog = fetchBacklog({ limit, labels, search: opts.search }, opts.repo, warnings);
312
+ for (const b of backlog)
313
+ knownState.set(b.issue, b.state);
314
+ for (const b of backlog)
315
+ if (!pickSet.has(b.issue))
316
+ inputs.push(b);
317
+ }
318
+ const assessed = assessAll(inputs);
319
+ for (const a of assessed) {
320
+ const input = inputs.find((i) => i.issue === a.issue);
321
+ if (input?.error !== undefined)
322
+ warnings.push(input.error);
323
+ }
324
+ if (unresolved.size > 0) {
325
+ warnings.push(`Could not resolve open/closed state for dependency issue(s) ${[...unresolved].map((n) => `#${n}`).join(', ')} — those issues were excluded as open-dependency (fail closed).`);
326
+ }
327
+ const composition = (0, batch_compose_1.composeBatch)(assessed, composeOpts);
328
+ const excluded = assessed
329
+ .filter((a) => !a.admissible)
330
+ .map((a) => ({ issue: a.issue, title: a.title, source: a.source, reasons: a.excluded }));
331
+ const report = {
332
+ schema: batch_compose_1.COMPOSE_SCHEMA,
333
+ repo: opts.repo ?? null,
334
+ project,
335
+ base_branch: opts.base,
336
+ rules,
337
+ params: {
338
+ min_members: minMembers,
339
+ max_members: maxMembers,
340
+ max_full_review: maxFullReview,
341
+ picks,
342
+ backlog: { queried: backlogQueried, labels, search: opts.search ?? null, limit },
343
+ },
344
+ ...composition,
345
+ manifest_entries: composition.members.map((m) => ({
346
+ issue: m.issue,
347
+ mode: 'slot',
348
+ review: m.review,
349
+ base_branch: opts.base,
350
+ })),
351
+ excluded,
352
+ counts: {
353
+ assessed: assessed.length,
354
+ admissible: assessed.length - excluded.length,
355
+ excluded: excluded.length,
356
+ },
357
+ model_calls: 0,
358
+ degraded: warnings.length > 0,
359
+ warnings,
360
+ };
361
+ if (opts.json) {
362
+ console.log(JSON.stringify(report, null, 2));
363
+ }
364
+ else {
365
+ renderText(report);
366
+ }
367
+ }
368
+ function collect(value, previous = []) {
369
+ return [...previous, value];
370
+ }
371
+ /** Registers the `batch` command tree (currently just `compose`). */
372
+ function registerBatchCommand(program) {
373
+ const batch = program
374
+ .command('batch')
375
+ .description('Batch-cycle helpers — deterministic, zero-token batch composition');
376
+ batch
377
+ .command('compose')
378
+ .description('Preview an admissible batch composition from operator picks and/or the backlog (prescreen + readiness, no model call)')
379
+ .option('--issues <selection>', `Operator picks, fleet grammar (e.g. "4114,4178" or "10..14"; at most ${issue_selection_1.MAX_ISSUE_SELECTION})`)
380
+ .option('--backlog', 'Also draw candidates from the open backlog (implied for backfill when picks fall short)')
381
+ .option('--no-backfill', 'Never query the backlog to backfill short picks')
382
+ .option('--label <name>', 'Backlog filter: only issues with this label (repeatable)', collect)
383
+ .option('--search <query>', 'Backlog filter: GitHub search query (gh issue list --search)')
384
+ .option('--limit <n>', `Backlog issues to read (max ${MAX_BACKLOG_LIMIT})`, String(DEFAULT_BACKLOG_LIMIT))
385
+ .option('--repo <owner/name>', 'Target repository (defaults to the current one)')
386
+ .option('--project <slug>', 'sched project whose queue/config to read (defaults to the repo slug)')
387
+ .option('--base <branch>', 'Base branch every member shares', 'main')
388
+ .option('--min-members <n>', 'Minimum viable batch; fewer ⇒ backfill proposed', String(batch_compose_1.DEFAULT_MIN_MEMBERS))
389
+ .option('--max-members <n>', 'Member ceiling', String(batch_compose_1.DEFAULT_MAX_MEMBERS))
390
+ .option('--max-full-review <n>', `Per-batch review=full cap (default: sched config max_full_review_members, else ${sched_1.MAX_FULL_REVIEW_MEMBERS})`)
391
+ .option('--rules <rules>', "Admission rules: 'v2' (prescreen:v2 + review=full members) or 'legacy' (pre-#770: any risk keyword excludes)", 'v2')
392
+ .option('--json', `Machine-readable output (schema ${batch_compose_1.COMPOSE_SCHEMA})`)
393
+ .action((opts) => runCompose(opts));
394
+ }
395
+ //# sourceMappingURL=batch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.js","sourceRoot":"","sources":["../../src/commands/batch.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sched.d.ts","sourceRoot":"","sources":["../../src/commands/sched.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAGV,oBAAoB,EAIrB,MAAM,mBAAmB,CAAC;AA0D3B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkCzC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,CAAC,EAAE;IACjD,yGAAyG;IACzG,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,oBAAoB,CAiEnE;AA2yDD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgB3D"}
1
+ {"version":3,"file":"sched.d.ts","sourceRoot":"","sources":["../../src/commands/sched.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAKV,oBAAoB,EAIrB,MAAM,mBAAmB,CAAC;AA+D3B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkCzC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,CAAC,EAAE;IACjD,yGAAyG;IACzG,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,oBAAoB,CAiEnE;AAw3DD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgB3D"}
@@ -364,7 +364,7 @@ function renderReport(report, staleness) {
364
364
  'pr',
365
365
  ], report.batches.map((b) => [
366
366
  b.id,
367
- b.status === 'blocked' && b.blocked_reason ? `blocked (${b.blocked_reason})` : b.status,
367
+ (0, sched_1.formatBatchStatus)(b),
368
368
  String(b.priority),
369
369
  b.members.length > 0 ? b.members.map((m) => `#${m}`).join(',') : '-',
370
370
  b.executing_member > 0 ? `${b.executing_member}/${b.members.length}` : '-',
@@ -410,8 +410,54 @@ function renderReport(report, staleness) {
410
410
  lines.push(stopped.length > 0
411
411
  ? stopped.map((entry) => `#${entry.issue} — ${entry.reason ?? entry.status}`).join('\n')
412
412
  : '(none)');
413
+ // #768: report-only anchor sweep — never closes anything. Omitted entirely
414
+ // when the report was built without GitHub (`--no-anchors`).
415
+ if (report.anchors !== null) {
416
+ lines.push('');
417
+ lines.push('== Open batch anchors ==');
418
+ lines.push(report.anchors.length > 0 ? report.anchors.map(renderAnchorItem).join('\n') : '(none)');
419
+ }
413
420
  return lines.join('\n');
414
421
  }
422
+ /** Per-call budget for the sweep's reads — `status` must never hang for minutes. */
423
+ const ANCHOR_SWEEP_TIMEOUT_MS = 10_000;
424
+ /**
425
+ * `sched status --anchors`' readers (#768), or `undefined` (with a stderr
426
+ * line) when the cwd is not `project`'s repository — the sweep never reads
427
+ * another repository's issue numbers as if they were this project's.
428
+ */
429
+ function anchorSweepFor(project) {
430
+ const repo = (0, sched_1.resolveProjectRepo)(project, sched_1.defaultExec);
431
+ if (repo === null) {
432
+ process.stderr.write(`⚠ sched status: anchor sweep skipped — the current directory is not ${project}'s GitHub repository\n`);
433
+ return undefined;
434
+ }
435
+ const exec = (0, sched_1.createExecFn)(ANCHOR_SWEEP_TIMEOUT_MS, {
436
+ onError: (file, args, err) => process.stderr.write(`⚠ sched anchor sweep: '${file} ${args.join(' ')}' failed: ${err.message}\n`),
437
+ });
438
+ const read = (0, sched_1.issueCloseReader)((0, sched_1.createExecGroundTruth)(exec, { repoDir: process.cwd(), repo }));
439
+ if (read === undefined)
440
+ return undefined;
441
+ return {
442
+ read,
443
+ repo,
444
+ // Read-only reachability probe against the already-fetched remote ref.
445
+ commitInBase: (oid, base) => sched_1.GIT_OID_RE.test(oid) &&
446
+ sched_1.SAFE_REF_RE.test(base) &&
447
+ exec('git', ['merge-base', '--is-ancestor', oid, `origin/${base}`], process.cwd()) !== null,
448
+ };
449
+ }
450
+ /** One `== Open batch anchors ==` row (#768): the anchor, its verdict and why, then its members. */
451
+ function renderAnchorItem(a) {
452
+ const reasons = a.reasons.length > 0 ? ` — ${a.reasons.join(', ')}` : '';
453
+ return (`#${a.anchor} (batch ${a.batch}, ${a.batch_status}) [${a.verdict}]${reasons}\n` +
454
+ ` members: ${a.members.map(renderAnchorMember).join(', ')}`);
455
+ }
456
+ /** `#4146 CLOSED/COMPLETED (ledger in-work)` — GitHub state beside the ledger's. */
457
+ function renderAnchorMember(m) {
458
+ const github = m.state_reason ? `${m.github}/${m.state_reason}` : m.github;
459
+ return `#${m.issue} ${github} (ledger ${m.ledger_status ?? 'none'})`;
460
+ }
415
461
  /** `5m ago` / `2h ago` — compact last-progress rendering for the slot table. */
416
462
  function relativeTime(iso, now = Date.now()) {
417
463
  const then = Date.parse(iso);
@@ -919,10 +965,11 @@ function registerStatusSubcommand(cmd) {
919
965
  .description('Render the queue, slots, batches, and blocked/failed sets')
920
966
  .option('--project <slug>', 'Project slug (default: owner-repo of the current directory)')
921
967
  .option('--json', 'Output the report as JSON')
968
+ .option('--anchors', "Also sweep open batch anchors (reads issue state from GitHub; run from the project's repository)")
922
969
  .action(async (opts) => {
923
970
  const { store, project } = resolveStore(opts);
924
971
  try {
925
- const report = (0, sched_1.buildStatusReport)(store.load(), store.loadConfig(), project, store.engineLeaseStatus());
972
+ const report = (0, sched_1.buildStatusReport)(store.load(), store.loadConfig(), project, store.engineLeaseStatus(), new Date(), opts.anchors === true ? anchorSweepFor(project) : undefined);
926
973
  // Cache-only (#537): `status` is a fast, offline-friendly diagnostic
927
974
  // — it reads whatever `sched start` last cached rather than risking
928
975
  // a multi-second hang on an unreachable npm registry.
@@ -1548,10 +1595,20 @@ function registerStartSubcommand(cmd) {
1548
1595
  console.log(`▶ sched profile ${name}: ${(0, sched_1.dispatchSummary)((0, sched_1.tierExecutors)((0, sched_1.resolveProfiledDispatch)(engineConfig, name)))}`);
1549
1596
  }
1550
1597
  }
1598
+ // #768: the anchor close writes to GitHub, so it runs only against the
1599
+ // repository verified to BE this project's — never whatever the cwd is.
1600
+ const anchorRepo = (0, sched_1.resolveProjectRepo)(project, sched_1.defaultExec) ?? undefined;
1601
+ if (anchorRepo === undefined && !(opts.once && opts.json)) {
1602
+ console.log(`▶ sched anchor close: off — the current directory is not ${project}'s GitHub repository`);
1603
+ }
1551
1604
  const deps = {
1552
1605
  store,
1553
1606
  journal: new sched_1.Journal(store.dir),
1554
- groundTruth: (0, sched_1.createExecGroundTruth)(undefined, { repoDir: process.cwd() }),
1607
+ groundTruth: (0, sched_1.createExecGroundTruth)(undefined, {
1608
+ repoDir: process.cwd(),
1609
+ ...(anchorRepo !== undefined ? { repo: anchorRepo } : {}),
1610
+ }),
1611
+ ...(anchorRepo !== undefined ? { anchorRepo } : {}),
1555
1612
  spawnDeps: (0, sched_1.createSpawnDeps)(process.cwd()),
1556
1613
  now: () => new Date(),
1557
1614
  repoDir: process.cwd(),