opencode-swarm 7.144.2 → 7.144.3

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.
Files changed (61) hide show
  1. package/.opencode/skills/swarm-pr-review/references/lane-output-recoverability.md +96 -0
  2. package/dist/background/pending-delegations.d.ts +20 -0
  3. package/dist/cli/{config-doctor-7dfvxwjb.js → config-doctor-pkr9w2nv.js} +3 -3
  4. package/dist/cli/{core-dwmwdc4y.js → core-7pymdx0b.js} +2 -2
  5. package/dist/cli/{curation-policy-pkb2eeb1.js → curation-policy-y1pqpztb.js} +5 -5
  6. package/dist/cli/curator-drift-2jbjv03a.js +1 -1
  7. package/dist/cli/{curator-llm-factory-rrs1q4hg.js → curator-llm-factory-7are9wjh.js} +32 -32
  8. package/dist/cli/{curator-w213v33y.js → curator-wbzcjd0q.js} +32 -32
  9. package/dist/cli/{evidence-summary-service-t7n2h1he.js → evidence-summary-service-rcgrdm52.js} +13 -13
  10. package/dist/cli/{gate-evidence-xvxn603y.js → gate-evidence-jmzctnhg.js} +6 -6
  11. package/dist/cli/{guardrail-explain-v1mwsnkq.js → guardrail-explain-brgw4sve.js} +33 -33
  12. package/dist/cli/{guardrail-log-dn03dpz2.js → guardrail-log-k1s9xf3h.js} +4 -4
  13. package/dist/cli/{hive-promoter-asjtj7ga.js → hive-promoter-vcj5h0e3.js} +34 -34
  14. package/dist/cli/{index-jsfghpy2.js → index-06cn7haa.js} +2 -2
  15. package/dist/cli/{index-tq5s07ta.js → index-0fgwdtvp.js} +1 -1
  16. package/dist/cli/{index-h3z64mhz.js → index-1brb14xc.js} +1 -1
  17. package/dist/cli/{index-nretd4qn.js → index-247wf23m.js} +363 -182
  18. package/dist/cli/{index-jb4tchvy.js → index-2en8s72h.js} +1 -1
  19. package/dist/cli/{index-gdd4jt6b.js → index-584grrwn.js} +1 -1
  20. package/dist/cli/{index-dhh2j2nd.js → index-6s2q144w.js} +1 -1
  21. package/dist/cli/{index-g2ajae1z.js → index-7554tecy.js} +1 -1
  22. package/dist/cli/{index-k92cagmt.js → index-8214dd7j.js} +2 -2
  23. package/dist/cli/{index-y95nwsge.js → index-8hkjk37c.js} +1 -1
  24. package/dist/cli/{index-ne8cfgw5.js → index-b227mpnk.js} +4 -4
  25. package/dist/cli/{index-w7x7qxz2.js → index-dpfphnmy.js} +1 -1
  26. package/dist/cli/{index-333kvewd.js → index-ep14xc5z.js} +3 -3
  27. package/dist/cli/{index-av0f6mm0.js → index-eya357bk.js} +9 -9
  28. package/dist/cli/{index-tg9fn2dy.js → index-ghzvxj3g.js} +35 -35
  29. package/dist/cli/{index-g1c5fgaw.js → index-j6mfyy0a.js} +3 -3
  30. package/dist/cli/{index-4fda8kkw.js → index-krxcxkdq.js} +13 -3
  31. package/dist/cli/{index-zr370283.js → index-p7hbphaq.js} +3 -3
  32. package/dist/cli/{index-hqvt3mhk.js → index-p863y7xx.js} +1 -1
  33. package/dist/cli/{index-7ca3a6gj.js → index-pag8nsb1.js} +10 -10
  34. package/dist/cli/{index-p3tnmkvc.js → index-pr8vhj6j.js} +12 -12
  35. package/dist/cli/{index-dg2w0wr4.js → index-qj22wyw2.js} +2 -2
  36. package/dist/cli/{index-qpt8ahph.js → index-satc0vs6.js} +11 -11
  37. package/dist/cli/{index-m6wv2qdr.js → index-wck434f8.js} +2 -2
  38. package/dist/cli/{index-d55crzd4.js → index-x68tw7v3.js} +5 -5
  39. package/dist/cli/{index-ckrasab9.js → index-xwpmxpb7.js} +9 -9
  40. package/dist/cli/{index-erfnw81g.js → index-zswmbm15.js} +1 -1
  41. package/dist/cli/{index-4q9vfav6.js → index-zwrqe065.js} +1 -1
  42. package/dist/cli/index.js +33 -33
  43. package/dist/cli/{knowledge-escalator-cg19dhe5.js → knowledge-escalator-x6jrcrwj.js} +12 -12
  44. package/dist/cli/{knowledge-events-yzvysaqd.js → knowledge-events-aw22r72m.js} +10 -10
  45. package/dist/cli/{knowledge-link-fn5j3r4q.js → knowledge-link-bntppte4.js} +4 -4
  46. package/dist/cli/{knowledge-store-6f77xpmm.js → knowledge-store-19xg1rw1.js} +6 -6
  47. package/dist/cli/{knowledge-validator-4b28zdxa.js → knowledge-validator-8wh82z0a.js} +8 -8
  48. package/dist/cli/{pending-delegations-thy8g30k.js → pending-delegations-1y303j3k.js} +3 -3
  49. package/dist/cli/{pr-subscriptions-jyav582d.js → pr-subscriptions-wvd041rp.js} +3 -3
  50. package/dist/cli/{runner-pde6b5sx.js → runner-jn55k8xb.js} +5 -5
  51. package/dist/cli/{scan-cursor-nqbb1xt6.js → scan-cursor-429r5db9.js} +7 -7
  52. package/dist/cli/{schema-jj2pb6zp.js → schema-jdwjcby0.js} +1 -1
  53. package/dist/cli/{scope-persistence-63nasq0z.js → scope-persistence-s0s1bz15.js} +6 -6
  54. package/dist/cli/{skill-generator-nsymtdqm.js → skill-generator-ffbj0ye5.js} +15 -15
  55. package/dist/cli/{worktree-collision-ownership-j6d33p49.js → worktree-collision-ownership-z5ftwjz3.js} +6 -6
  56. package/dist/cli/{worktree-isolation-g54kxw6x.js → worktree-isolation-y2p93438.js} +32 -32
  57. package/dist/commands/registry.d.ts +1 -1
  58. package/dist/hooks/pr-workflow-gate.d.ts +132 -3
  59. package/dist/index.js +289 -289
  60. package/package.json +1 -1
  61. package/dist/cli/{index-k31en0ja.js → index-wd24zn2e.js} +3 -3
@@ -2,7 +2,7 @@ import * as fsp from 'node:fs/promises';
2
2
  import { z } from 'zod';
3
3
  import { type CandidateSeverity, type RowFormatFamily } from '../background/candidate-contract.js';
4
4
  import { type LaneOutputArtifact } from '../background/lane-output-store.js';
5
- import { type BackgroundDelegationRecord, type BackgroundDelegationResult, findByBatchId } from '../background/pending-delegations.js';
5
+ import { type BackgroundDelegationRecord, type BackgroundDelegationResult, findByBatchId, sweepStaleDelegations } from '../background/pending-delegations.js';
6
6
  import { type PrReviewInlineTriggerRow } from '../background/pr-review-trigger-contract.js';
7
7
  import { type RevisionDigestResult, resolveCommitCountSince, resolveCommitCountSinceAsync, resolveCurrentGitHead, resolveCurrentGitHeadAsync, resolveCurrentUpstreamPushTarget, resolveCurrentUpstreamPushTargetAsync, resolveCurrentUpstreamRemoteRef, resolveExactRemoteBranchHead, resolveExactRemoteBranchHeadAsync, resolveIsExactSingleChildCommit, resolveIsExactSingleChildCommitAsync, resolveIsWorkingTreeClean, resolveIsWorkingTreeCleanAsync, resolvePrReviewDiffStats, resolvePrReviewDiffStatsAsync, resolvePrWorkflowRevisionDigest, resolvePrWorkflowRevisionDigestDetailed, resolveRemoteRefsContainingHead, resolveRemoteRefsContainingHeadAsync } from '../background/workspace-snapshot.js';
8
8
  import { classifyPrWorkflowGitState, type PrWorkflowGitState } from '../git/pr-workflow-state.js';
@@ -408,13 +408,99 @@ export declare function withInactivePrWorkflowCheckoutRestoreLock<T>(directory:
408
408
  export declare function clearPrWorkflowGateState(directory: string, sessionID: string, expectedRevision?: number, options?: {
409
409
  allowSalvagedRead?: boolean;
410
410
  }): Promise<void>;
411
+ /**
412
+ * The single session operation the liveness probe needs.
413
+ *
414
+ * Deliberately a narrow LOCAL structural type rather than a type-only import of
415
+ * `SessionOps` from `src/tools/dispatch-lanes.ts`: that module's
416
+ * `isLaneReadyForCollection` is the fail-CLOSED counterpart of this probe, and
417
+ * keeping the two textually independent removes any invitation to "share" the
418
+ * predicate. A type-only import would be erased either way; this is about
419
+ * preventing the wrong reuse, not about module graph cost.
420
+ */
421
+ interface PrWorkflowLaneLivenessSessionOps {
422
+ status?: (args: {
423
+ query?: {
424
+ directory?: string;
425
+ };
426
+ }) => Promise<{
427
+ data?: Record<string, {
428
+ type?: string;
429
+ }> | null;
430
+ error?: unknown;
431
+ }>;
432
+ }
433
+ /** Why a probe produced no evidence of life. Absent means the probe ran. */
434
+ export type PrWorkflowLaneProbeDegradedReason = 'probe-unavailable' | 'probe-error' | 'probe-timeout' | 'probe-no-data';
435
+ /**
436
+ * Probe which of `records` have a session the host affirmatively reports as
437
+ * still running (issue #2251).
438
+ *
439
+ * **FAIL-OPEN, by design.** For its ERROR and NO-DATA cases this is the exact
440
+ * inverse of `isLaneReadyForCollection` (`src/tools/dispatch-lanes.ts`), which
441
+ * returns `false` on a truthy `error`, on missing `data`, and on a throw —
442
+ * because a lane it cannot verify must not be collected. The two agree, rather
443
+ * than invert, on ONE case: a host that exposes no `status` function at all.
444
+ * There the collector returns `true` (`dispatch-lanes.ts`, the `typeof
445
+ * session.status !== 'function'` guard) and this probe reports
446
+ * `probe-unavailable`, so both fall through to proceeding — an unprobeable host
447
+ * must not wedge either side.
448
+ *
449
+ * Here the default outcome must be "settle": an unavailable, erroring,
450
+ * timing-out or empty probe returns the empty set, so age alone decides and the
451
+ * reachability floor this whole subsystem exists to preserve is untouched. Only
452
+ * a probe that RAN and affirmatively named a live session may contradict
453
+ * staleness.
454
+ *
455
+ * The returned set is built only from a fully-read response — a mid-iteration
456
+ * throw yields the empty set rather than a partial spare list, so a malformed
457
+ * response can never spare an arbitrary subset of lanes.
458
+ *
459
+ * Keys are `subagentSessionId`s. A record without one is unprobeable and is
460
+ * simply never added (it settles), which is the fail-open direction.
461
+ */
462
+ declare function probeAlivePrWorkflowLaneSessions(directory: string, records: BackgroundDelegationRecord[]): Promise<{
463
+ alive: Set<string>;
464
+ degradedReason?: PrWorkflowLaneProbeDegradedReason;
465
+ }>;
411
466
  export interface PrWorkflowStaleLaneSettlement {
412
- /** Lanes still genuinely in flight (fresh `updatedAt`). These still block. */
467
+ /**
468
+ * Every lane that still blocks: lanes with a fresh `updatedAt` PLUS lanes
469
+ * past the horizon whose session the liveness probe reported still running.
470
+ */
413
471
  openLaneIds: string[];
414
472
  openLanes: number;
473
+ /**
474
+ * Open lanes that block on FRESHNESS alone (age below the horizon).
475
+ *
476
+ * Separated from `openLanes` because the human-only `force` abort override
477
+ * (issue #2251 S3) must distinguish "blocked only by probe retention", which
478
+ * an operator may override, from "blocked by a lane that is genuinely young",
479
+ * which stays fail-closed. Deriving it by subtraction or by comparing lane
480
+ * LABELS would be wrong: `prWorkflowLaneLabel` falls back to `'unknown'`, so
481
+ * labels are not unique.
482
+ */
483
+ freshOpenLanes: number;
415
484
  /** Lanes stale past the horizon, treated as settled with disclosure. */
416
485
  presumedStaleLaneIds: string[];
417
- /** Operator-facing disclosure; `undefined` when nothing was presumed stale. */
486
+ /**
487
+ * Lanes past the horizon that the probe spared. Present only when non-empty.
488
+ */
489
+ probedAliveLaneIds?: string[];
490
+ /**
491
+ * The SAME records as {@link probedAliveLaneIds}, in the same order, keyed by
492
+ * `correlationId` instead of by display label.
493
+ *
494
+ * Both are needed and neither substitutes for the other: `prWorkflowLaneLabel`
495
+ * falls back to `'unknown'` and is not unique, so it cannot address a durable
496
+ * record — while `correlationId` is the ledger's primary key and is what the
497
+ * human-only `force` override must name to finalize exactly these records and
498
+ * nothing else. Present only when non-empty.
499
+ */
500
+ probeRetainedCorrelationIds?: string[];
501
+ /** Set when the probe could not produce evidence; absent when it ran. */
502
+ probeDegradedReason?: PrWorkflowLaneProbeDegradedReason;
503
+ /** Operator-facing disclosure; `undefined` when nothing was settled or retained. */
418
504
  disclosure?: string;
419
505
  }
420
506
  /**
@@ -439,6 +525,13 @@ export interface PrWorkflowStaleLaneSettlement {
439
525
  *
440
526
  * A lane with a RECENT `updatedAt` still blocks: a re-verification that CAN run
441
527
  * and reports "still progressing" contradicts settlement and fails closed.
528
+ *
529
+ * Issue #2251 adds the second, stronger contradiction: a lane PAST the horizon
530
+ * whose session the host affirmatively reports as `busy`/`retry` is genuinely
531
+ * running (nothing heartbeats `updatedAt`, so age alone cannot see this) and is
532
+ * retained instead of discarded. The probe is fail-open — see
533
+ * {@link probeAlivePrWorkflowLaneSessions} — so an unavailable, erroring or
534
+ * empty probe leaves the age-only behaviour exactly as it was.
442
535
  */
443
536
  export declare function settlePresumedStalePrWorkflowLanes(directory: string, sessionID: string): Promise<PrWorkflowStaleLaneSettlement>;
444
537
  /**
@@ -480,6 +573,16 @@ export declare function abortPrWorkflow(directory: string, sessionID: string, op
480
573
  openLanes: number;
481
574
  presumedStaleLanes?: string[];
482
575
  presumedStaleDisclosure?: string;
576
+ /** Lanes past the horizon the liveness probe reported as still running. */
577
+ probeRetainedLanes?: string[];
578
+ /**
579
+ * Present ONLY when a human `force` abort cleared the gate while those
580
+ * probe-retained lanes were the sole remaining reason it was blocked
581
+ * (issue #2251 S3).
582
+ */
583
+ probeRetentionOverrideDisclosure?: string;
584
+ /** Why the liveness probe produced no evidence, when it could not run. */
585
+ probeDegradedReason?: PrWorkflowLaneProbeDegradedReason;
483
586
  stateSalvaged?: boolean;
484
587
  stateSalvageDisclosure?: string;
485
588
  casEscapeDisclosure?: string;
@@ -652,6 +755,32 @@ export declare const _test_exports: {
652
755
  removeCheckoutLock: typeof removeCheckoutLockFile;
653
756
  checkoutMutationActionTimeoutMs: number;
654
757
  classifyPrWorkflowGitStateAsync: typeof classifyPrWorkflowGitState;
758
+ /**
759
+ * The durability sweep, reached through a seam so a test can prove that a
760
+ * failing sweep cannot un-settle the decision `settlePresumedStalePrWorkflow-
761
+ * Lanes` already made in memory. It cannot throw today (it catches internally
762
+ * and returns 0) — the seam is what makes that guarantee testable rather than
763
+ * merely asserted.
764
+ */
765
+ sweepStaleDelegationsAsync: typeof sweepStaleDelegations;
766
+ /** The fail-open liveness probe (issue #2251). */
767
+ probeLaneLivenessAsync: typeof probeAlivePrWorkflowLaneSessions;
768
+ /**
769
+ * Session handle for the liveness probe.
770
+ *
771
+ * A seam rather than a direct `swarmState.opencodeClient` read at the call
772
+ * site because 20+ test files mutate that field; without this, this suite and
773
+ * the stale-lane suite would be order-dependent in bun's shared process.
774
+ * Mirrors `_internals.getSessionOps` in `src/tools/dispatch-lanes.ts`.
775
+ */
776
+ getSessionOps: () => PrWorkflowLaneLivenessSessionOps | null;
777
+ /**
778
+ * Probe deadline, read through the seam at CALL time. `freezeClock` patches
779
+ * `Date.now()`, not `setTimeout`, so a test that must reach the timeout branch
780
+ * has to shorten the real deadline. Same precedent as
781
+ * `checkoutMutationActionTimeoutMs` above.
782
+ */
783
+ laneLivenessProbeTimeoutMs: number;
655
784
  resolveCurrentGitHead: typeof resolveCurrentGitHead;
656
785
  resolveCurrentGitHeadAsync: typeof resolveCurrentGitHeadAsync;
657
786
  resolveCurrentUpstreamPushTarget: typeof resolveCurrentUpstreamPushTarget;