opencode-swarm 7.178.0 → 7.179.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.
Files changed (117) hide show
  1. package/.opencode/skills/deep-dive/SKILL.md +1 -1
  2. package/.opencode/skills/running-tests/SKILL.md +30 -24
  3. package/.opencode/skills/swarm-plan/SKILL.md +1 -1
  4. package/binaries/win32-arm64/swarm-sandbox-runner.exe +0 -0
  5. package/binaries/win32-x64/swarm-sandbox-runner.exe +0 -0
  6. package/dist/agents/critic.d.ts +6 -6
  7. package/dist/agents/explorer.d.ts +1 -1
  8. package/dist/cli/{coder-settlement-d2bfb25j.js → coder-settlement-7pt3a0y0.js} +12 -12
  9. package/dist/cli/{config-doctor-905x2s1c.js → config-doctor-82w4bp4b.js} +3 -3
  10. package/dist/cli/{core-k7wfx1wx.js → core-9rqzs794.js} +4 -4
  11. package/dist/cli/{curation-policy-n4hd2wsa.js → curation-policy-c7mdsf7m.js} +5 -5
  12. package/dist/cli/{curator-drift-smqmej5v.js → curator-drift-d93pwt8h.js} +5 -5
  13. package/dist/cli/curator-llm-factory-cbm1ny30.js +72 -0
  14. package/dist/cli/{curator-wyadq69k.js → curator-m8act07j.js} +40 -40
  15. package/dist/cli/{dispatch-9yqqqfr6.js → dispatch-3rwdxpp2.js} +1 -1
  16. package/dist/cli/{evidence-summary-service-r3wcprfk.js → evidence-summary-service-a99bgje1.js} +17 -17
  17. package/dist/cli/{explorer-2cv64zfj.js → explorer-z0cf5cz0.js} +1 -1
  18. package/dist/cli/{gate-evidence-tq9rb2aj.js → gate-evidence-yssmxba5.js} +7 -7
  19. package/dist/cli/guardrail-explain-ffwmhf7s.js +73 -0
  20. package/dist/cli/{guardrail-log-m6twga6x.js → guardrail-log-j2wtq7p2.js} +8 -8
  21. package/dist/cli/{guardrail-reset-86esv8cr.js → guardrail-reset-07byr7nr.js} +40 -40
  22. package/dist/cli/{hive-promoter-s87hkb40.js → hive-promoter-ewrz7vh1.js} +40 -40
  23. package/dist/cli/{index-ke3m026z.js → index-09wm3963.js} +14 -7
  24. package/dist/cli/{index-vfc7d22n.js → index-0bc8jdnv.js} +2 -2
  25. package/dist/cli/{index-ffqy30e5.js → index-0h3cr7pn.js} +1 -1
  26. package/dist/cli/{index-fyfbpz4f.js → index-1c1dbwze.js} +1 -0
  27. package/dist/cli/{index-zex7644g.js → index-1rwyfvq2.js} +2 -2
  28. package/dist/cli/{index-18hjycr1.js → index-1sz02k85.js} +30 -2
  29. package/dist/cli/{index-pm7c6f66.js → index-2b0ktpbf.js} +2 -2
  30. package/dist/cli/{index-yj1kr0ft.js → index-34bwqcea.js} +1 -1
  31. package/dist/cli/{index-wkde35ej.js → index-3hne91yd.js} +8 -8
  32. package/dist/cli/{index-2b1whj28.js → index-3pzwsesm.js} +2 -2
  33. package/dist/cli/{index-y74n1sy8.js → index-6r92fw88.js} +7 -7
  34. package/dist/cli/{index-p27az2hc.js → index-6tnkvqr9.js} +4 -4
  35. package/dist/cli/{index-qs8eth8h.js → index-7zmbtxw1.js} +4 -4
  36. package/dist/cli/{index-azy3tw6c.js → index-80q47hpw.js} +2 -2
  37. package/dist/cli/{index-zsm8h8y1.js → index-8815e95e.js} +4 -4
  38. package/dist/cli/{index-gg44hytk.js → index-9p1pqykb.js} +33 -8
  39. package/dist/cli/{index-w4yjy3vp.js → index-a11ztzs5.js} +19 -2
  40. package/dist/cli/{index-sqngtwyq.js → index-amf88k1e.js} +1 -1
  41. package/dist/cli/{index-y6a2bkp1.js → index-cvg402ha.js} +2 -2
  42. package/dist/cli/{index-heg4em8j.js → index-d66zb40k.js} +3499 -2832
  43. package/dist/cli/{index-swxaa0zs.js → index-etmwjgre.js} +40 -40
  44. package/dist/cli/{index-j3rkh9mp.js → index-f2v90gfc.js} +2 -2
  45. package/dist/cli/{index-mpcp6rmj.js → index-g6nyk713.js} +1 -1
  46. package/dist/cli/{index-bfz1jvcn.js → index-h4nh6s8b.js} +1 -1
  47. package/dist/cli/{index-j1v54ahd.js → index-h59vsbch.js} +2 -2
  48. package/dist/cli/{index-29begjkp.js → index-hwcra3y9.js} +8 -8
  49. package/dist/cli/{index-2vhkwy6v.js → index-kanxpgf8.js} +3 -3
  50. package/dist/cli/{index-kfk403mc.js → index-kmhnkn6t.js} +4 -4
  51. package/dist/cli/{index-2mdk6nt9.js → index-ndwbb3xm.js} +7 -7
  52. package/dist/cli/{index-zsp9de3k.js → index-ne9zamcs.js} +7 -7
  53. package/dist/cli/{index-tnjmn0dn.js → index-nzekzzs2.js} +4 -4
  54. package/dist/cli/{index-q9vb5e7n.js → index-pskba939.js} +1 -1
  55. package/dist/cli/{index-qk29b7s4.js → index-pxtye2ng.js} +42 -42
  56. package/dist/cli/{index-wfbh1bx8.js → index-qt0793qm.js} +7 -7
  57. package/dist/cli/{index-at0ygwwp.js → index-qxk5qkfh.js} +5 -5
  58. package/dist/cli/{index-zmb8fjp5.js → index-s4bkey0q.js} +1 -1
  59. package/dist/cli/{index-rp0jk48x.js → index-sv4y1cma.js} +7 -7
  60. package/dist/cli/{index-2bmhe2jn.js → index-tmy46dtd.js} +4 -4
  61. package/dist/cli/{index-wbkxbgk8.js → index-twtez316.js} +2 -2
  62. package/dist/cli/{index-m2n1rhgv.js → index-w872yykk.js} +1 -1
  63. package/dist/cli/{index-jzxeymr0.js → index-wvpsm8ja.js} +93 -227
  64. package/dist/cli/{index-d5dexrv1.js → index-yagqxt2p.js} +4 -4
  65. package/dist/cli/{index-yeh78c1g.js → index-yfpswnjt.js} +2 -2
  66. package/dist/cli/{index-hnvmj9wx.js → index-zgvzbz48.js} +14 -4
  67. package/dist/cli/index.js +41 -41
  68. package/dist/cli/{knowledge-escalator-rgz471df.js → knowledge-escalator-yx97q9c1.js} +13 -13
  69. package/dist/cli/{knowledge-events-4mq0ypx9.js → knowledge-events-p269fyvv.js} +11 -11
  70. package/dist/cli/{knowledge-link-npk50523.js → knowledge-link-gfz47ves.js} +4 -4
  71. package/dist/cli/{knowledge-store-gft25s5t.js → knowledge-store-36zemyqa.js} +5 -5
  72. package/dist/cli/{knowledge-validator-ejqacbx4.js → knowledge-validator-rd20yq41.js} +7 -7
  73. package/dist/cli/{mcp-emaeeq4s.js → mcp-sg9zrkz2.js} +1 -1
  74. package/dist/cli/{model-preflight-kh9dwts2.js → model-preflight-61xgqwcs.js} +1 -1
  75. package/dist/cli/{pending-delegations-4bhkcykk.js → pending-delegations-8p2gf4kt.js} +12 -12
  76. package/dist/cli/{pr-subscriptions-h1n6dbds.js → pr-subscriptions-4dj9r71h.js} +12 -12
  77. package/dist/cli/{pr-workflow-gate-wn6v5za8.js → pr-workflow-gate-8dgz5z1h.js} +42 -40
  78. package/dist/cli/{runner-ffy5ahhz.js → runner-16b691ba.js} +5 -5
  79. package/dist/cli/{scan-cursor-e63t0g5b.js → scan-cursor-nx0jv9ya.js} +6 -6
  80. package/dist/cli/{schema-4k4hr33y.js → schema-q6gsrxwz.js} +2 -2
  81. package/dist/cli/{scope-persistence-qcw3rtxq.js → scope-persistence-1k4xsyh7.js} +20 -16
  82. package/dist/cli/{server-58s1wwap.js → server-shhxq34t.js} +47 -45
  83. package/dist/cli/{skill-generator-fhj13jmq.js → skill-generator-6j7tq2tb.js} +15 -15
  84. package/dist/cli/{snapshot-coordination-init-5fawrj35.js → snapshot-coordination-init-h8n8w1cm.js} +40 -40
  85. package/dist/cli/{telemetry-ca8dmn26.js → telemetry-qxav5cdk.js} +1 -1
  86. package/dist/cli/{workspace-snapshot-v5qyjxg0.js → workspace-snapshot-rfnn80dg.js} +3 -3
  87. package/dist/cli/{worktree-collision-ownership-hjk0jx19.js → worktree-collision-ownership-97jzh4ra.js} +13 -13
  88. package/dist/cli/{worktree-isolation-aj20bs6q.js → worktree-isolation-g4w74ccb.js} +40 -40
  89. package/dist/commands/registry.d.ts +3 -3
  90. package/dist/config/plan-schema.d.ts +23 -0
  91. package/dist/db/coordination-store.d.ts +10 -0
  92. package/dist/evidence/phase-participation.d.ts +3 -2
  93. package/dist/hooks/delegation-gate.d.ts +1 -1
  94. package/dist/hooks/extractors.d.ts +5 -1
  95. package/dist/hooks/pr-workflow-gate.d.ts +15 -6
  96. package/dist/index.js +535 -520
  97. package/dist/memory/index.d.ts +1 -0
  98. package/dist/memory/memory-family-migration.d.ts +35 -3
  99. package/dist/mutation/engine.d.ts +6 -0
  100. package/dist/mutation/equivalence.d.ts +12 -1
  101. package/dist/plan/ledger.d.ts +14 -0
  102. package/dist/plan/manager.d.ts +0 -2
  103. package/dist/plan/parallel-verdict.d.ts +28 -14
  104. package/dist/pr-review/circuit.d.ts +3 -3
  105. package/dist/pr-review/legacy-transcript-adapter.d.ts +7 -10
  106. package/dist/pr-review/persistence.d.ts +36 -0
  107. package/dist/retention/sweep.d.ts +4 -0
  108. package/dist/scope/scope-persistence.d.ts +41 -0
  109. package/dist/tools/mutation-test.d.ts +6 -0
  110. package/dist/tools/plan-conflict-check.d.ts +7 -6
  111. package/dist/tools/prepare-pr-workflow-checkout.d.ts +19 -0
  112. package/dist/tools/repo-map-action-dispositions.d.ts +23 -0
  113. package/dist/tools/test-runner.d.ts +17 -2
  114. package/package.json +1 -1
  115. package/dist/cli/curator-llm-factory-qhhxev17.js +0 -72
  116. package/dist/cli/guardrail-explain-kvgejh24.js +0 -73
  117. package/dist/pr-review/guardrails.d.ts +0 -67
@@ -10,6 +10,7 @@ export { createMemoryLifecycleHooks, type MemoryLifecycleHookOptions, type Memor
10
10
  export { backupLegacyJsonl, getLegacyJsonlFileStatus, getLegacyOutcomeJsonlSignature, type JsonlBackupResult, type JsonlImportPayload, type JsonlInvalidRow, type JsonlMigrationReport, LEGACY_JSONL_MIGRATION_NAME, LEGACY_JSONL_MIGRATION_VERSION, LEGACY_JSONL_OUTCOME_META_KEY, readLegacyJsonl, readMigrationReport, resolveMemoryStorageDir, resolveSqliteDatabasePath, writeJsonlExport, writeMigrationReport, } from './jsonl-migration';
11
11
  export { LocalJsonlMemoryProvider } from './local-jsonl-provider';
12
12
  export { buildMemoryMaintenanceReport, type MemoryMaintenanceReport, type MemoryMaintenanceReportOptions, type MemoryRecallUsageByMemory, type MemoryRecallUsageByRole, type MemorySupersededChain, shouldCompactMemory, } from './maintenance';
13
+ export { MemoryMigrationLockError } from './memory-family-migration';
13
14
  export { invalidateMemoryStoreDirCache, isMemoryLinked, MEMORY_LINK_POINTER_FILENAME, type MemoryLinkPointer, readMemoryLinkPointer, removeMemoryLinkPointer, resolveMemoryStoreDir, writeMemoryLinkPointer, } from './memory-link';
14
15
  export type { MemoryOutcomeEvent } from './outcome-events';
15
16
  export { computePiiScore, createPiiDetector, type PiiDetector, type PiiFinding, type PiiType, RegexPiiDetector, summarizePiiFindings, } from './pii';
@@ -18,15 +18,46 @@
18
18
  * (`handleMemoryLinkCommand`), so a mid-migration failure leaves the worktree
19
19
  * in its prior link state and a retry is idempotent.
20
20
  *
21
- * Lock discipline: `proper-lockfile` on the destination cohort dir with a
22
- * bumped `stale` (30s) for the migration critical section — reused from the
23
- * knowledge family so there is one source of truth for the lock config.
21
+ * Lock discipline: `proper-lockfile` on the destination storage dir (cohort
22
+ * OR local — both directions) with a bumped `stale` (30s) for the migration
23
+ * critical section — reused from the knowledge family so there is one source
24
+ * of truth for the lock config. `realpath: false` keeps the lock identity on
25
+ * the literal path so it is the SAME lock the local JSONL provider takes on
26
+ * this directory (PRR-U1): symlinked roots (e.g. macOS /var → /private/var)
27
+ * must not split the exclusion into two identities.
28
+ * Admission is fail-closed (#2577): if the destination lock cannot be
29
+ * acquired (a legitimate concurrent writer holds it, or acquisition fails for
30
+ * a storage reason), the migration throws a typed
31
+ * {@link MemoryMigrationLockError} and never runs unlocked.
24
32
  *
25
33
  * No writes happen here on the plugin-init path (invariant 1). Called only
26
34
  * from the `/swarm memory link` / `/swarm memory unlink` command handlers.
27
35
  */
28
36
  import { type MemoryOutcomeEvent } from './outcome-events.js';
29
37
  import type { VettedMemoryRoot } from './storage-root.js';
38
+ /**
39
+ * Minimal typing for the async `proper-lockfile` API this engine uses,
40
+ * exposed through {@link _internals} so tests can classify acquisition
41
+ * failures deterministically (same DI pattern as `src/full-auto/state.ts`).
42
+ */
43
+ type MigrationLockFile = {
44
+ lock: typeof import('proper-lockfile')['lock'];
45
+ };
46
+ /** Failure category for destination-lock admission (#2577, #2575 contract). */
47
+ export type MemoryMigrationLockErrorCategory = 'contention' | 'storage';
48
+ /**
49
+ * Typed failure for acquiring the destination migration lock. Thrown BEFORE
50
+ * the merge loop opens, so no destination or source write ever happens on a
51
+ * failed admission. Mirrors `FullAutoStateLockError` in
52
+ * `src/full-auto/state.ts` (#2575): stable category + code, cause preserved
53
+ * for diagnostics, and messages that never echo absolute host paths.
54
+ */
55
+ export declare class MemoryMigrationLockError extends Error {
56
+ readonly category: MemoryMigrationLockErrorCategory;
57
+ readonly cause: unknown;
58
+ readonly code: `MEMORY_MIGRATION_LOCK_${Uppercase<MemoryMigrationLockErrorCategory>}`;
59
+ constructor(category: MemoryMigrationLockErrorCategory, message: string, cause?: unknown);
60
+ }
30
61
  export interface MemoryFamilyMigrationCounts {
31
62
  readonly perMember: ReadonlyArray<{
32
63
  filename: string;
@@ -102,5 +133,6 @@ export declare const _internals: {
102
133
  stageSqliteDb: typeof stageSqliteDb;
103
134
  mergeStagedSqlite: typeof mergeStagedSqlite;
104
135
  countRowsSafe: typeof countRowsSafe;
136
+ lockfile: MigrationLockFile;
105
137
  };
106
138
  export {};
@@ -98,5 +98,11 @@ export declare const _internals: {
98
98
  };
99
99
  export declare function executeMutation(patch: MutationPatch, testCommand: string[], testFiles: string[], workingDir: string, options?: MutationExecutionOptions): Promise<MutationResult>;
100
100
  export declare function computeReport(results: MutationResult[], durationMs: number, budgetMs?: number): MutationReport;
101
+ /**
102
+ * Apply a unified diff's hunks to the original file text, producing the full
103
+ * mutated file. Returns null when the diff does not parse or does not apply
104
+ * cleanly to the original (context mismatch), so callers can fall back.
105
+ */
106
+ export declare function applyUnifiedDiff(originalCode: string, patchText: string): string | null;
101
107
  export declare function executeMutationSuite(patches: MutationPatch[], testCommand: string[], testFiles: string[], workingDir: string, budgetMs?: number, onProgress?: (completed: number, total: number, result: MutationResult) => void, sourceFiles?: Map<string, string>, options?: MutationExecutionOptions): Promise<MutationReport>;
102
108
  export {};
@@ -18,7 +18,17 @@ export type LLMJudgeCallback = (original: string, mutated: string, context: stri
18
18
  * Strips comments (single-line // and multi-line /* *\/), console.log/debugger statements,
19
19
  * trailing whitespace, and blank lines. Returns true if the stripped versions are identical.
20
20
  */
21
- export declare function isStaticallyEquivalent(originalCode: string, mutatedCode: string): boolean;
21
+ /**
22
+ * Comment syntax family for a language hint (a file path or language id).
23
+ * The default family preserves the historical 2-argument behavior exactly:
24
+ * // line comments plus slash-star block comments (TS/JS/Go/PHP/Java/Kotlin/C/C++/Rust).
25
+ */
26
+ interface CommentSyntaxFamily {
27
+ lineTokens: string[];
28
+ blockComments: boolean;
29
+ }
30
+ export declare function commentFamilyForLanguage(languageHint?: string): CommentSyntaxFamily;
31
+ export declare function isStaticallyEquivalent(originalCode: string, mutatedCode: string, languageHint?: string): boolean;
22
32
  export declare const _internals: {
23
33
  isStaticallyEquivalent: typeof isStaticallyEquivalent;
24
34
  checkEquivalence: typeof checkEquivalence;
@@ -38,3 +48,4 @@ export declare function batchCheckEquivalence(patches: Array<{
38
48
  originalCode: string;
39
49
  mutatedCode: string;
40
50
  }>, llmJudge?: LLMJudgeCallback): Promise<EquivalenceResult[]>;
51
+ export {};
@@ -163,6 +163,20 @@ export declare function computePlanLedgerHash(plan: Plan): string;
163
163
  * any structural change (description, acceptance, dependencies, files, added
164
164
  * or removed tasks/phases) always must.
165
165
  *
166
+ * DELIBERATE exception, recorded with #2532 (PLAN-4): `current_phase` — the
167
+ * execution cursor — IS included in this hash (and in
168
+ * {@link computePlanLedgerHash}). Unlike task/phase statuses, a cursor
169
+ * advance therefore DOES change the baseline hash: bindings and approved
170
+ * snapshots declared against the pre-advance plan stop matching, exactly as
171
+ * they already do for any save_plan revision. This is intentional — the
172
+ * hash bytes are persisted on every live binding (`planStructureHash`,
173
+ * verified with strict equality) and every critic-approved snapshot
174
+ * (`payload_hash`), so changing the normalization would silently invalidate
175
+ * all pre-existing state at upgrade. The bounded safety property: only a
176
+ * phase-boundary advancement moves the cursor (task-status churn inside a
177
+ * phase is hash-excluded), so mid-phase parallel siblings keep their
178
+ * bindings across ordinary task completion.
179
+ *
166
180
  * This mirrors {@link computePlanLedgerHash}'s normalization byte-for-byte
167
181
  * EXCEPT it omits the two status fields from the hashed payload. The two
168
182
  * functions are deliberately distinct: {@link computePlanLedgerHash} is
@@ -44,7 +44,6 @@ import { getWorktreeMergeFailure } from '../hooks/delegation-gate/worktree-merge
44
44
  import { recordTaskAttempt } from '../services/run-memory.js';
45
45
  import { isEpicModeActiveForProject } from '../turbo/epic/state.js';
46
46
  import { commitTaskCompletion } from '../turbo/epic/task-commit.js';
47
- import { readTaskScopes } from '../turbo/lean/conflicts.js';
48
47
  import { type LedgerEvent, type LedgerEventInput, ledgerExists, loadLastApprovedPlan, readLedgerEventsWithIntegrity, replayFromLedger, takeSnapshotWithRetry } from './ledger';
49
48
  /** Reset the startup ledger check flag. For testing only. */
50
49
  export declare function resetStartupLedgerCheck(): void;
@@ -69,7 +68,6 @@ export declare const _internals: {
69
68
  regeneratePlanMarkdown: typeof regeneratePlanMarkdown;
70
69
  isGitRepo: typeof isGitRepo;
71
70
  isEpicModeActiveForProject: typeof isEpicModeActiveForProject;
72
- readTaskScopes: typeof readTaskScopes;
73
71
  commitTaskCompletion: typeof commitTaskCompletion;
74
72
  getWorktreeMergeFailure: typeof getWorktreeMergeFailure;
75
73
  recordTaskAttempt: typeof recordTaskAttempt;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Plan-time parallel-execution verdict helper (#1656 / #1674 v8 flagship).
3
3
  *
4
- * Pure, synchronous, side-effect-free pairwise conflict analysis for N proposed
4
+ * Pure, side-effect-free pairwise conflict analysis for N proposed
5
5
  * parallel task groups. Used by BOTH:
6
6
  * - the `plan_conflict_check` tool (architect-facing advisory — see
7
7
  * `src/tools/plan-conflict-check.ts`), and
@@ -14,23 +14,30 @@
14
14
  * means.
15
15
  *
16
16
  * Design notes:
17
- * - Sync by design: it reads only `.swarm/scopes/scope-<taskId>.json` via
18
- * the hardened persisted-scope reader (sync + fail-closed). The gate runs in
19
- * `toolBefore` on every tool call and must stay bounded; an async/gitten
20
- * helper would violate the bounded-gate spirit.
17
+ * - Sync by design: it reads only the authoritative v2 scope-binding store
18
+ * (the same authority `declare_scope` writes) via the hardened
19
+ * fail-closed readers. The gate runs in `toolBefore` on every tool call
20
+ * and must stay bounded; an async helper would violate the bounded-gate
21
+ * spirit. One binding-set scan is hoisted per verdict, never per task.
22
+ * - #2532 (PARALLEL-4): scope resolution deliberately does NOT consult the
23
+ * legacy v1 `.swarm/scopes/scope-<taskId>.json` projection — no production
24
+ * code writes it in the project root (its one writer targets lane
25
+ * worktrees), so v2-declared disjoint scopes used to be reported as
26
+ * `unknown_scopes` and parallel-first could never engage.
21
27
  * - The helper itself NEVER calls `getCoChangePairs` (async + `git log`).
22
28
  * Co-change signal is opt-in and supplied by the caller (the tool) via
23
29
  * `options.cochangePairs`. The gate never supplies it, keeping the
24
30
  * enforcement path git-free and fast.
25
- * - Fail-closed: a missing/malformed scope `unknown_scope`, which conflicts
26
- * with everything, so `verdict` can never be `all_disjoint` while any task
27
- * lacks a declared scope. This is the v8 safety guarantee.
31
+ * - Fail-closed: a task with no single live exact-plan v2 binding →
32
+ * `unknown`, which conflicts with everything, so `verdict` can never be
33
+ * `all_disjoint` while any task lacks a declared scope. This is the v8
34
+ * safety guarantee.
28
35
  * - Writes nothing. Honors issue #1656's "read-only (writes nothing)" tool
29
36
  * acceptance criterion.
30
37
  */
38
+ import { type Plan } from '../config/plan-schema.js';
31
39
  import type { CoChangeEntry } from '../tools/co-change-analyzer.js';
32
40
  import { type CoChangeThreshold } from '../turbo/epic/cochange-conflict.js';
33
- import { normalizePath, pathsConflict, readTaskScopes } from '../turbo/lean/conflicts.js';
34
41
  /**
35
42
  * Per-pair conflict classification. Mirrors `EpicPairVerdict`'s signal
36
43
  * decomposition but flattens `none` into `disjoint` for the plan-level view.
@@ -70,14 +77,22 @@ export interface ComputeParallelVerdictOptions {
70
77
  cochangePairs?: CoChangeEntry[];
71
78
  /** Override the co-change threshold. Defaults to `DEFAULT_PARALLEL_COCHANGE_THRESHOLD`. */
72
79
  cochangeThreshold?: CoChangeThreshold;
80
+ /**
81
+ * The plan the verdict is computed against (issue #2532). Bindings must
82
+ * match its exact identity (`planId` + `planStructureHash`). When omitted,
83
+ * the helper synchronously reads `<directory>/.swarm/plan.json`; a missing
84
+ * or unparseable plan resolves every task to `unknown` (fail-closed).
85
+ */
86
+ plan?: Plan;
73
87
  }
74
88
  /**
75
89
  * Compute a pairwise conflict verdict for the given task ids.
76
90
  *
77
- * Pure + synchronous. Reads only `.swarm/scopes/`. Writes nothing. Fail-closed
78
- * on any read/parse error (treats the task as `unknown`).
91
+ * Pure + synchronous. Reads only the authoritative v2 binding store (plus a
92
+ * bounded plan.json read when `options.plan` is omitted). Writes nothing.
93
+ * Fail-closed on any read/parse error (treats the task as `unknown`).
79
94
  *
80
- * @param directory Project root (for `.swarm/scopes/` reads).
95
+ * @param directory Project root (for the binding store and plan.json reads).
81
96
  * @param taskIds Task ids to analyze. Caller is responsible for min-length
82
97
  * validation (the tool requires ≥2; the gate only calls this
83
98
  * with ≥2 pending tasks).
@@ -90,5 +105,4 @@ export declare function computeParallelVerdict(directory: string, taskIds: strin
90
105
  * Equivalent to `computeParallelVerdict(...).verdict === 'all_disjoint'` but
91
106
  * exposed as a named predicate so the gate reads as intent.
92
107
  */
93
- export declare function isProvablyDisjoint(directory: string, taskIds: string[]): boolean;
94
- export { normalizePath, pathsConflict, readTaskScopes };
108
+ export declare function isProvablyDisjoint(directory: string, taskIds: string[], options?: ComputeParallelVerdictOptions): boolean;
@@ -22,9 +22,9 @@
22
22
  * Issue #2385 additionally makes this module the ONLY authority that may
23
23
  * construct or transition circuit records: policy snapshot resolution, the
24
24
  * re-enable reset, and the rolled-back-probe transition live here (previously
25
- * inline record constructions in the gate). The parallel-rule guardrail
26
- * (`src/pr-review/guardrails.ts`) enforces that no circuit record is built
27
- * outside `src/pr-review/`.
25
+ * inline record constructions in the gate). The source-tree regression tests
26
+ * enforce that no circuit record is built outside `src/pr-review/`; this pure
27
+ * state-machine module remains the production construction authority.
28
28
  */
29
29
  import { z } from 'zod';
30
30
  import type { BackgroundDelegationRecord } from '../background/pending-delegations.js';
@@ -4,12 +4,10 @@
4
4
  *
5
5
  * This is the ONLY module allowed to convert raw transcript / artifact text
6
6
  * into canonical PR-review data (verdict rows, per-item verdicts, feedback
7
- * classifications). The locality contract is enforced mechanically by
8
- * `scanTranscriptParsingOutsideAdapter` in `src/pr-review/guardrails.ts`:
9
- * every identifier in `TRANSCRIPT_CONVERSION_SYMBOLS` may appear only in this
10
- * file across `src/`. The gate therefore consumes this boundary through the
11
- * `legacy*`-prefixed aliases and the test surface exported below — never
12
- * through the conversion identifiers themselves.
7
+ * classifications). This module is the sole owner of the transcript
8
+ * conversion identifiers across `src/`; the gate therefore consumes this
9
+ * boundary through the `legacy*`-prefixed aliases and the test surface
10
+ * exported below never through the conversion identifiers themselves.
13
11
  *
14
12
  * Compat gating: the settlement path that accepts legacy (pre-structured-
15
13
  * receipt) transcript text is governed by the delegation record's
@@ -252,10 +250,9 @@ export declare function feedbackArtifactTextCoversItems(text: string, itemIds: r
252
250
  */
253
251
  export declare function readSettledFeedbackClassifications(directory: string, state: PrReviewTranscriptState): Map<string, string>;
254
252
  /**
255
- * Issue #2385 guardrail aliases: the transcript-conversion identifiers may
256
- * appear only in this module (`scanTranscriptParsingOutsideAdapter` in
257
- * `src/pr-review/guardrails.ts`), so the owning gate imports these aliases
258
- * instead of the canonical names.
253
+ * Issue #2385 guardrail aliases: transcript-conversion identifiers are owned
254
+ * only by this module, so the owning gate imports these aliases instead of
255
+ * the canonical names.
259
256
  */
260
257
  export declare const analyzeLegacyVerdictRowContract: typeof analyzePrReviewVerdictRowContract;
261
258
  export declare const legacyArtifactHasExactPositiveVerdictRow: typeof artifactHasExactPositiveVerdictRow;
@@ -55,6 +55,10 @@ export interface PrReviewPersistenceHooks {
55
55
  beforeSafeDirectoryCreate?: (parentPath: string, nextPath: string) => Promise<void>;
56
56
  beforeAtomicTempWrite?: () => Promise<void>;
57
57
  beforeAtomicRename?: () => Promise<void>;
58
+ /** Test-only interleave point immediately before terminal CAS deletion. */
59
+ beforeTerminalizationDelete?: () => Promise<void>;
60
+ /** Test-only unlink seam for partial-shadow cleanup recovery tests. */
61
+ removeShadowProjection?: (filePath: string) => Promise<void>;
58
62
  }
59
63
  export declare const defaultPersistenceHooks: PrReviewPersistenceHooks;
60
64
  /**
@@ -94,6 +98,28 @@ export declare function readPrWorkflowGateStateFromDisk<S extends PrWorkflowPers
94
98
  export declare function readPrWorkflowGateStateFileRawFromDisk<S extends PrWorkflowPersistedStateBase>(filePath: string, stateLabel: string): Promise<S | null>;
95
99
  export declare function readPrWorkflowGateStateFileFromDisk<S extends PrWorkflowPersistedStateBase>(filePath: string, stateLabel: string): Promise<S | null>;
96
100
  export declare function readPrWorkflowGateStateFromCoordination<S extends PrWorkflowPersistedStateBase>(directory: string, sessionID: string): Promise<S | null>;
101
+ export type PrWorkflowGateCoordinationRecovery<S extends PrWorkflowPersistedStateBase> = {
102
+ kind: 'absent';
103
+ } | {
104
+ kind: 'valid';
105
+ rowRevision: number;
106
+ generation: number;
107
+ state: S;
108
+ } | {
109
+ kind: 'corrupt';
110
+ rowRevision: number;
111
+ generation: number;
112
+ reason: string;
113
+ } | {
114
+ kind: 'invalid';
115
+ reason: string;
116
+ };
117
+ /**
118
+ * Inspect one workflow coordination row for recovery without trusting payload
119
+ * bytes. Only payload JSON/codec/generation failures are recoverable with a
120
+ * matching shadow projection. Database open/query errors intentionally escape.
121
+ */
122
+ export declare function readPrWorkflowGateStateCoordinationForRecovery<S extends PrWorkflowPersistedStateBase>(directory: string, sessionID: string): PrWorkflowGateCoordinationRecovery<S>;
97
123
  /** Persist one CAS-checked state replacement while the session lock is held. */
98
124
  export declare function writeStateWhileLocked<S extends PrWorkflowPersistedStateBase>(directory: string, state: S, options?: {
99
125
  replaceWorkflowInstanceId?: string;
@@ -103,6 +129,16 @@ export declare function deleteStateWhileLocked(directory: string, sessionID: str
103
129
  expectedStateRevision?: number;
104
130
  allowSalvagedRead?: boolean;
105
131
  }): Promise<void>;
132
+ /**
133
+ * Terminalize one session's gate on exact owner lifecycle deletion.
134
+ *
135
+ * This is deliberately independent of abort policy: it serializes the exact
136
+ * normalized session, removes that session's shadow projection before its
137
+ * CAS-delete, then forgets the cache entry. A missing row/projection is an
138
+ * idempotent successful terminal; retaining the row across partial cleanup
139
+ * prevents a legacy shadow from being imported as resurrected state.
140
+ */
141
+ export declare function terminalizePrWorkflowGateForSession(directory: string, sessionID: string): Promise<void>;
106
142
  /** A bounded checkout-mutation refusal that never permits unsafe late overlap. */
107
143
  export declare class PrWorkflowCheckoutMutationTimeoutError extends Error {
108
144
  readonly phase: 'queue' | 'action';
@@ -23,6 +23,10 @@
23
23
  * - authoritative streams (plan ledger, knowledge store, council, evidence,
24
24
  * scopes, swarm.db, telemetry) are NOT in any family and are never
25
25
  * touched (negative test).
26
+ * - checkout-preparation receipts remain recovery material: the checkout
27
+ * family only removes old, strictly validated applied+verified receipts
28
+ * (and abandoned atomic-write temporary files), never a pending receipt or
29
+ * its stash.
26
30
  */
27
31
  /** Default age horizon for keyspace families (30 days). */
28
32
  export declare const DEFAULT_FAMILY_AGE_DAYS = 30;
@@ -117,6 +117,47 @@ export declare function readScopeBindingFromDisk(input: {
117
117
  requireDispatchCorrelation?: boolean;
118
118
  requireDeclaration?: boolean;
119
119
  }): ScopeBinding | null;
120
+ /**
121
+ * Resolve the currently-declared scope FILES for a task from the authoritative
122
+ * v2 binding store (issue #2532 / PARALLEL-4).
123
+ *
124
+ * Scheduling/conflict consumers (the v8 parallel verdict, Rule-2 auto-commit)
125
+ * must resolve task scopes from the same authority `declare_scope` writes —
126
+ * never from the legacy v1 `scope-<taskId>.json` projection, which no
127
+ * production code writes in the project root. This is a scheduling read, NOT
128
+ * write authorization: it deliberately does not require owner-session or
129
+ * dispatch correlation, but it DOES require an exact `planStructureHash`
130
+ * match so a declaration made against an older plan revision cannot certify
131
+ * disjointness for the current one.
132
+ *
133
+ * Fail-closed: zero live candidates (undeclared or store failure), live
134
+ * candidates that DISAGREE on the file set, or an empty file list all return
135
+ * `null`, which callers treat as "unknown scope" → serial. Multiple live
136
+ * candidates that AGREE on the exact same file set are NOT ambiguous: the
137
+ * delegation gate mints a dispatch-correlated binding (activation 'active',
138
+ * child owner) alongside the architect's declaration binding for the same
139
+ * task with the same files, and the scheduling question — "what is this
140
+ * task's currently-declared scope?" — has one answer whenever they agree.
141
+ *
142
+ * `bindingSet` lets a multi-task caller hoist ONE
143
+ * `readAllAuthoritativeScopeBindings` scan for the whole verdict (pass the
144
+ * result of {@link readAuthoritativeScopeBindingSet}); omit it for a
145
+ * single-task read.
146
+ */
147
+ export declare function readDeclaredScopeFilesFromBindings(input: {
148
+ directory: string;
149
+ taskId: string;
150
+ plan: Plan;
151
+ bindingSet?: ScopeBinding[] | null;
152
+ }): string[] | null;
153
+ /**
154
+ * Hoisted single read of the authoritative v2 binding set for multi-task
155
+ * scheduling consumers (issue #2532): one bounded scan shared by every
156
+ * per-task {@link readDeclaredScopeFilesFromBindings} call in a verdict.
157
+ * Returns `null` when the store is unreadable/overloaded so callers fail
158
+ * closed to "unknown scope" per task.
159
+ */
160
+ export declare function readAuthoritativeScopeBindingSet(directory: string): ScopeBinding[] | null;
120
161
  export declare function resolveScopeBindingFromDisk(input: {
121
162
  directory: string;
122
163
  taskId: string;
@@ -1,2 +1,8 @@
1
+ import { analyzeImpact } from '../test-impact/analyzer.js';
1
2
  import { createSwarmTool } from './create-tool';
2
3
  export declare const mutation_test: ReturnType<typeof createSwarmTool>;
4
+ export declare const _internals: {
5
+ mutationInternals: {
6
+ analyzeImpact: typeof analyzeImpact;
7
+ };
8
+ };
@@ -7,10 +7,10 @@
7
7
  *
8
8
  * READ-ONLY CONTRACT (issue #1656 acceptance): this tool writes NOTHING — not
9
9
  * to `.swarm/`, not to the source tree. It calls no other tools. The only I/O
10
- * is reading `.swarm/plan.json` (via `loadPlanJsonOnly`) and
11
- * `.swarm/scopes/scope-<taskId>.json` (via `readTaskScopes` inside
12
- * `computeParallelVerdict`), plus an optional `git log` (only when the caller
13
- * opts in via `use_cochange: true`).
10
+ * is reading `.swarm/plan.json` (via `loadPlanJsonOnly`) and the
11
+ * authoritative v2 scope-binding store (via `readDeclaredScopeFilesFromBindings`
12
+ * inside `computeParallelVerdict`, #2532), plus an optional `git log` (only
13
+ * when the caller opts in via `use_cochange: true`).
14
14
  *
15
15
  * Why this tool exists alongside the gate: the gate (`delegation-gate.ts`)
16
16
  * independently recomputes the verdict INLINE at coder-dispatch time via the
@@ -50,8 +50,9 @@ export interface PlanConflictCheckResult {
50
50
  /**
51
51
  * Pure executor (no createSwarmTool wrapper) so it is directly unit-testable.
52
52
  *
53
- * Reads `.swarm/plan.json` (to confirm the task ids exist) and
54
- * `.swarm/scopes/scope-*.json` (via `computeParallelVerdict`). Writes nothing.
53
+ * Reads `.swarm/plan.json` (to confirm the task ids exist) and the
54
+ * authoritative v2 scope-binding store (via `computeParallelVerdict`,
55
+ * #2532). Writes nothing.
55
56
  */
56
57
  export declare function executePlanConflictCheck(args: {
57
58
  task_ids: string[];
@@ -1,9 +1,26 @@
1
+ import { appendCoreEventSync } from '../events/core-events.js';
1
2
  import { classifyPrWorkflowGitState } from '../git/pr-workflow-state.js';
2
3
  import { createSwarmTool } from './create-tool.js';
3
4
  export interface PrWorkflowCheckoutRestoreInventoryItem {
4
5
  stash_oid: string;
5
6
  stash_present: boolean | null;
6
7
  }
8
+ export interface PrWorkflowCheckoutReconciliationSummary {
9
+ /** The exact owner session whose receipt directory was inspected. */
10
+ sessionID: string;
11
+ /** Number of validated receipt files considered in this bounded pass. */
12
+ inspectedReceiptCount: number;
13
+ /** Verified receipt OIDs whose marked stash was collected and verified absent. */
14
+ collectedStashOids: string[];
15
+ /** Missing-stash receipt OIDs with bounded core-event evidence and receipt retirement. */
16
+ retiredMissingStashOids: string[];
17
+ /** Receipt/stash OIDs deliberately preserved (pending, unknown, or failed cleanup). */
18
+ preservedStashOids: string[];
19
+ /** Cleanup failures; no corresponding receipt is retired when this is non-empty. */
20
+ failures: string[];
21
+ /** True when all inspected inventory stayed within the hard bounds. */
22
+ bounded: boolean;
23
+ }
7
24
  /**
8
25
  * Preserve explicit dirty tracked files before the unbound PR checkout.
9
26
  *
@@ -27,6 +44,7 @@ declare function runGit(directory: string, args: string[], options?: {
27
44
  declare function readBoundedGitStdout(stream: {
28
45
  getReader(): ReadableStreamDefaultReader<Uint8Array>;
29
46
  }, onOverflow: () => void): Promise<string>;
47
+ export declare function reconcilePrWorkflowCheckoutReceipts(directory: string, rawSessionID: string): Promise<PrWorkflowCheckoutReconciliationSummary>;
30
48
  declare function removeCheckoutRestoreReceipt(receiptPath: string): Promise<void>;
31
49
  export declare function listPendingPrWorkflowCheckoutRestores(directory: string, sessionID: string): Promise<PrWorkflowCheckoutRestoreInventoryItem[]>;
32
50
  /**
@@ -40,6 +58,7 @@ export declare const _internals: {
40
58
  readBoundedGitStdout: typeof readBoundedGitStdout;
41
59
  classifyGitState: typeof classifyPrWorkflowGitState;
42
60
  removeCheckoutRestoreReceipt: typeof removeCheckoutRestoreReceipt;
61
+ appendCoreEventSync: typeof appendCoreEventSync;
43
62
  };
44
63
  export declare const prepare_pr_workflow_checkout: ReturnType<typeof createSwarmTool>;
45
64
  export {};
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Disposition registry for repo_map actions audited as unreferenced (issue #2540).
3
+ *
4
+ * Every entry in VALID_ACTIONS must be reachable from a real workflow surface
5
+ * (agent prompt, skill, or command) or be deliberately retired. This registry
6
+ * records the per-action disposition for the six audit actions from
7
+ * REPOGRAPH-11 (docs/audits/swarm-plugin-review-2026-09.md): each is retained
8
+ * and wired to the listed consumers. The controls wired by #2516
9
+ * (route_trace, test_pack) and the two additional contextually-unreferenced
10
+ * entries the ratchet surfaced (callers, retrieve) are intentionally NOT
11
+ * subjects here — they already had, or gained independently, their own
12
+ * consumers and are enforced by the VALID_ACTIONS↔consumer ratchet test
13
+ * (tests/unit/config/repo-map-action-consumer-ratchet.test.ts).
14
+ */
15
+ export interface RepoMapActionDisposition {
16
+ /** retained = wired to real consumers; retired = removed from the advertised surface */
17
+ disposition: 'retained' | 'retired';
18
+ /** repo-relative workflow-surface files containing a repo_map-contextual reference (required when retained) */
19
+ consumers?: string[];
20
+ /** surfaces scrubbed of the action (required when retired: schema, help, prompts, inventory) */
21
+ removedFrom?: string[];
22
+ }
23
+ export declare const REPO_MAP_ACTION_DISPOSITIONS: Record<string, RepoMapActionDisposition>;
@@ -12,7 +12,6 @@ export declare const MAX_COMMAND_LENGTH = 500;
12
12
  export declare const DEFAULT_TIMEOUT_MS = 60000;
13
13
  export declare const MAX_TIMEOUT_MS = 300000;
14
14
  export declare const MAX_SAFE_TEST_FILES = 50;
15
- export declare const MAX_SAFE_SOURCE_FILES = 1;
16
15
  /**
17
16
  * Estimate the fan-out (number of unique test files) for given source files
18
17
  * by reading the cached impact map without spawning a subprocess.
@@ -35,7 +34,14 @@ export interface TestRunnerArgs {
35
34
  timeout_ms?: number;
36
35
  bail?: boolean;
37
36
  }
38
- export type RegressionOutcome = 'pass' | 'skip' | 'regression' | 'scope_exceeded' | 'error';
37
+ export type RegressionOutcome = 'pass' | 'skip' | 'no_impacted_tests' | 'regression' | 'scope_exceeded' | 'error';
38
+ /** Binding cap decision reported on every discovery-scope test_runner response. */
39
+ export interface CapDecision {
40
+ decision: 'within_cap' | 'cap_exceeded';
41
+ resolved_test_count: number;
42
+ limit: number;
43
+ source_file_count?: number;
44
+ }
39
45
  export interface TestTotals {
40
46
  passed: number;
41
47
  failed: number;
@@ -64,6 +70,12 @@ export interface TestSuccessResult {
64
70
  testCases?: ParsedTestCaseResult[];
65
71
  message?: string;
66
72
  outcome?: RegressionOutcome;
73
+ /** Post-resolution deduplicated test-file set (discovery scopes only). */
74
+ resolved_test_files?: string[];
75
+ /** Binding cap decision — the post-resolution count, never an estimate. */
76
+ cap_decision?: CapDecision;
77
+ /** Non-empty exactly when resolution fell back to a narrower discovery scope. */
78
+ fallback_reason?: string;
67
79
  }
68
80
  export interface TestErrorResult {
69
81
  success: false;
@@ -80,6 +92,9 @@ export interface TestErrorResult {
80
92
  message?: string;
81
93
  outcome?: RegressionOutcome;
82
94
  attempted_scope?: 'graph';
95
+ resolved_test_files?: string[];
96
+ cap_decision?: CapDecision;
97
+ fallback_reason?: string;
83
98
  }
84
99
  export type TestResult = TestSuccessResult | TestErrorResult;
85
100
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.178.0",
3
+ "version": "7.179.0",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,72 +0,0 @@
1
- // @bun
2
- import {
3
- createCuratorLLMDelegate
4
- } from "./index-heg4em8j.js";
5
- import"./index-hnvmj9wx.js";
6
- import"./index-q9vb5e7n.js";
7
- import"./index-qs8eth8h.js";
8
- import"./index-bfz1jvcn.js";
9
- import"./index-vfc7d22n.js";
10
- import"./index-jzxeymr0.js";
11
- import"./index-mpcp6rmj.js";
12
- import"./index-txdagbh7.js";
13
- import"./index-n1tcj1q7.js";
14
- import"./index-6b295cas.js";
15
- import"./index-zsm8h8y1.js";
16
- import"./index-at0ygwwp.js";
17
- import"./index-zex7644g.js";
18
- import"./index-fyfbpz4f.js";
19
- import"./index-y74n1sy8.js";
20
- import"./index-549wxbe1.js";
21
- import"./index-zsrtt42s.js";
22
- import"./index-wkde35ej.js";
23
- import"./index-pm7c6f66.js";
24
- import"./index-2b1whj28.js";
25
- import"./index-pt7h91zc.js";
26
- import"./index-q7sjgr1y.js";
27
- import"./index-kfk403mc.js";
28
- import"./index-p27az2hc.js";
29
- import"./index-rp0jk48x.js";
30
- import"./index-29begjkp.js";
31
- import"./index-zmb8fjp5.js";
32
- import"./index-2s7dvzff.js";
33
- import"./index-d5dexrv1.js";
34
- import"./index-ffqy30e5.js";
35
- import"./index-rtry5xyf.js";
36
- import"./index-2vhkwy6v.js";
37
- import"./index-frcemc0b.js";
38
- import"./index-wrt875kh.js";
39
- import"./index-gg44hytk.js";
40
- import"./index-ke3m026z.js";
41
- import"./index-j1v54ahd.js";
42
- import"./index-y6a2bkp1.js";
43
- import"./index-w4yjy3vp.js";
44
- import"./index-tnjmn0dn.js";
45
- import"./index-rdm3px0g.js";
46
- import"./index-ry16d01s.js";
47
- import"./index-yeh78c1g.js";
48
- import"./index-2mdk6nt9.js";
49
- import"./index-vzm6zre7.js";
50
- import"./index-ae75rja9.js";
51
- import"./index-yj1kr0ft.js";
52
- import"./index-j3rkh9mp.js";
53
- import"./index-7g4c7s5r.js";
54
- import"./index-wfbh1bx8.js";
55
- import"./index-zsp9de3k.js";
56
- import"./index-1xnse449.js";
57
- import"./index-c1ggtmpm.js";
58
- import"./index-18hjycr1.js";
59
- import"./index-zz7gzw57.js";
60
- import"./index-4ddpvd5c.js";
61
- import"./index-wbkxbgk8.js";
62
- import"./index-m2n1rhgv.js";
63
- import"./index-bk5tah7q.js";
64
- import"./index-gknz3bv1.js";
65
- import"./index-zpsr8rpc.js";
66
- import"./index-wvghb3x6.js";
67
- import"./index-9rwhas09.js";
68
- import"./index-zgwm4ryv.js";
69
- import"./index-a76rekgs.js";
70
- export {
71
- createCuratorLLMDelegate
72
- };