opencode-swarm 7.146.2 → 7.146.4

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 (86) hide show
  1. package/.opencode/skills/swarm-pr-review/SKILL.md +27 -44
  2. package/.opencode/skills/swarm-pr-review/references/findings-persistence-contract.md +52 -12
  3. package/.opencode/skills/swarm-pr-review/references/lane-output-recoverability.md +6 -3
  4. package/.opencode/skills/swarm-pr-review/references/parser-dry-run.md +19 -1
  5. package/.opencode/skills/swarm-pr-review/references/verdict-settlement-contract.md +41 -0
  6. package/dist/agents/council-prompts.d.ts +3 -3
  7. package/dist/background/candidate-contract.d.ts +21 -1
  8. package/dist/background/candidate-parser.d.ts +21 -1
  9. package/dist/background/pending-delegations.d.ts +8 -1
  10. package/dist/background/pr-review-collection-receipt.d.ts +70 -0
  11. package/dist/cli/{config-doctor-vstrprja.js → config-doctor-578ebqhn.js} +2 -2
  12. package/dist/cli/{core-3wzpwe5z.js → core-2ne03a43.js} +1 -1
  13. package/dist/cli/{curation-policy-x19e8bqc.js → curation-policy-g353f457.js} +6 -6
  14. package/dist/cli/{curator-llm-factory-6bra0bfd.js → curator-llm-factory-6hgn7p6n.js} +27 -27
  15. package/dist/cli/{curator-cvy1s7wd.js → curator-w52frg17.js} +27 -27
  16. package/dist/cli/{evidence-summary-service-yhap2xph.js → evidence-summary-service-nj4p6a0d.js} +11 -11
  17. package/dist/cli/{gate-evidence-vxbyq5sb.js → gate-evidence-4vnjdh9y.js} +6 -6
  18. package/dist/cli/{guardrail-explain-h8cnwa02.js → guardrail-explain-rq01z1yz.js} +28 -28
  19. package/dist/cli/{guardrail-log-syb7tz2w.js → guardrail-log-ratb651f.js} +3 -3
  20. package/dist/cli/{hive-promoter-3tex870c.js → hive-promoter-pbm9kee1.js} +27 -27
  21. package/dist/cli/{index-yxhcy5cm.js → index-1mbdwy12.js} +55 -1
  22. package/dist/cli/{index-01ybcsa5.js → index-3neh2mxk.js} +2 -2
  23. package/dist/cli/{index-5e5a1y2r.js → index-3p4wgm0d.js} +1 -1
  24. package/dist/cli/{index-4vwn66wk.js → index-5cbbtbvf.js} +3 -3
  25. package/dist/cli/{index-z5ppkn8y.js → index-6eycwm3v.js} +6 -6
  26. package/dist/cli/{index-bghwrr59.js → index-6q35swn2.js} +1 -1
  27. package/dist/cli/{index-qbpxrw95.js → index-8py21zn6.js} +2 -2
  28. package/dist/cli/{index-tj861zhd.js → index-96zkay2e.js} +4 -4
  29. package/dist/cli/{index-y3hmyvt6.js → index-bq4mvwht.js} +2 -2
  30. package/dist/cli/{index-rfph0nhf.js → index-brb64k96.js} +1426 -635
  31. package/dist/cli/{index-p0m03xa6.js → index-df8xj9hr.js} +4 -4
  32. package/dist/cli/{index-cr90rcg3.js → index-dp5w9s5z.js} +7 -7
  33. package/dist/cli/{index-w0cj7zyd.js → index-f75qjtn5.js} +1 -1
  34. package/dist/cli/{index-vmfaafte.js → index-ffqdah8s.js} +5 -5
  35. package/dist/cli/{index-f3x2gsby.js → index-fp2d44f5.js} +1 -1
  36. package/dist/cli/{index-jv9xs6mb.js → index-g2r8nknz.js} +2 -2
  37. package/dist/cli/{index-n4k0pt5f.js → index-g335vrc7.js} +4 -4
  38. package/dist/cli/{index-z9ed68jt.js → index-gr3zfcsh.js} +18 -4
  39. package/dist/cli/{index-w5r84rd1.js → index-hcb25p12.js} +1 -1
  40. package/dist/cli/{index-ycgm9pzg.js → index-hw1yghpg.js} +7 -6
  41. package/dist/cli/{index-a1febb2k.js → index-jgwhpza8.js} +2 -2
  42. package/dist/cli/{index-cx67qa9g.js → index-kjmcp9mf.js} +1 -1
  43. package/dist/cli/{index-42nq97rb.js → index-kv2j4cnq.js} +6 -6
  44. package/dist/cli/{index-zkaz3fhw.js → index-p3k155dv.js} +2 -2
  45. package/dist/cli/{index-qyvjp0bq.js → index-q81s0m8k.js} +66 -37
  46. package/dist/cli/{index-97psh79d.js → index-rpy0bent.js} +178 -18
  47. package/dist/cli/{index-r46q6996.js → index-t798v5pq.js} +29 -29
  48. package/dist/cli/{index-e1hjd15c.js → index-tp5ytzzg.js} +1 -1
  49. package/dist/cli/{index-vj9bba5k.js → index-vdrwj7z0.js} +4 -4
  50. package/dist/cli/{index-46cypnz3.js → index-wesj94x0.js} +4 -4
  51. package/dist/cli/{index-c9jr4j2q.js → index-xsxj4vbf.js} +1 -1
  52. package/dist/cli/index.js +27 -27
  53. package/dist/cli/{knowledge-escalator-mn4sx4qd.js → knowledge-escalator-jbazxmk5.js} +11 -11
  54. package/dist/cli/{knowledge-events-x975ngy4.js → knowledge-events-jyqy3st8.js} +9 -9
  55. package/dist/cli/{knowledge-link-8pr02pza.js → knowledge-link-jkx8xjxp.js} +5 -5
  56. package/dist/cli/{knowledge-store-33p762ey.js → knowledge-store-e2defagd.js} +6 -6
  57. package/dist/cli/{knowledge-validator-q5jc0scs.js → knowledge-validator-pnmdsw2b.js} +8 -8
  58. package/dist/cli/{pending-delegations-kkrczqv7.js → pending-delegations-k2yqg1sj.js} +3 -3
  59. package/dist/cli/{pr-subscriptions-2xn238xt.js → pr-subscriptions-js5v2xr6.js} +3 -3
  60. package/dist/cli/{runner-e7z9cf5y.js → runner-q7d22d1w.js} +6 -6
  61. package/dist/cli/{scan-cursor-p7t5mb4x.js → scan-cursor-snx85enn.js} +7 -7
  62. package/dist/cli/{schema-t8bmshhj.js → schema-6rmxzg6g.js} +1 -1
  63. package/dist/cli/{scope-persistence-2kyrgsca.js → scope-persistence-23cqafkx.js} +7 -7
  64. package/dist/cli/{skill-generator-fwvmcv8m.js → skill-generator-980zjk9q.js} +13 -13
  65. package/dist/cli/{telemetry-t109dhv7.js → telemetry-xzy0qeap.js} +1 -1
  66. package/dist/cli/{worktree-collision-ownership-2jtg2my1.js → worktree-collision-ownership-xj0bsg92.js} +3 -3
  67. package/dist/cli/{worktree-isolation-87j70zg1.js → worktree-isolation-4d0nc04c.js} +27 -27
  68. package/dist/commands/close.d.ts +1 -0
  69. package/dist/commands/context-map-stats.d.ts +5 -0
  70. package/dist/config/schema.d.ts +16 -0
  71. package/dist/context-map/telemetry.d.ts +168 -26
  72. package/dist/council/council-evidence-writer.d.ts +2 -1
  73. package/dist/council/council-freshness.d.ts +49 -0
  74. package/dist/council/council-review-identity.d.ts +133 -0
  75. package/dist/council/council-round-state.d.ts +27 -3
  76. package/dist/council/disagreement-detector.d.ts +12 -2
  77. package/dist/council/general-council-types.d.ts +32 -0
  78. package/dist/council/types.d.ts +43 -7
  79. package/dist/hooks/pr-workflow-gate.d.ts +58 -5
  80. package/dist/index.js +177 -152
  81. package/dist/observability/catalog.d.ts +7 -5
  82. package/dist/telemetry.d.ts +22 -1
  83. package/dist/tools/dispatch-lanes.d.ts +30 -8
  84. package/dist/tools/phase-complete/gates/types.d.ts +7 -0
  85. package/dist/tools/write-final-council-evidence.d.ts +1 -7
  86. package/package.json +2 -1
@@ -8,6 +8,13 @@ export type CouncilVerdict = 'APPROVE' | 'CONCERNS' | 'REJECT';
8
8
  export type CouncilFindingSeverity = 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';
9
9
  export type CouncilFindingCategory = 'logic' | 'edge_case' | 'error_handling' | 'spec_compliance' | 'security' | 'maintainability' | 'naming' | 'domain' | 'test_gap' | 'test_quality' | 'mutation_gap' | 'adversarial_gap' | 'slop_pattern' | 'hallucinated_api' | 'lazy_abstraction' | 'cargo_cult' | 'spec_drift' | 'other';
10
10
  export type CouncilAgent = 'critic' | 'reviewer' | 'sme' | 'test_engineer' | 'explorer';
11
+ /**
12
+ * The canonical five-member council role set (issue #2102 contract H).
13
+ * Writers, gates, and quorum checks must import this constant instead of
14
+ * re-declaring the list, so the role policy can never drift between the
15
+ * write path and the gate path.
16
+ */
17
+ export declare const COUNCIL_MEMBER_ROLES: readonly CouncilAgent[];
11
18
  export interface CouncilFinding {
12
19
  severity: CouncilFindingSeverity;
13
20
  category: CouncilFindingCategory;
@@ -145,12 +152,25 @@ export interface CouncilCriteria {
145
152
  /** ISO 8601 */
146
153
  declaredAt: string;
147
154
  }
155
+ /** Normalized final-council completion policy (issue #2102 contract C). */
156
+ export interface FinalCompletionPolicyConfig {
157
+ /** 'all_required' (default, strict legacy) or explicit 'quorum' weakening. */
158
+ mode: 'all_required' | 'quorum';
159
+ /** Required when mode is 'quorum'; bounded 3..5 distinct canonical members. */
160
+ minimumMembers?: number;
161
+ }
148
162
  /** Config shape — matched in schema.ts via CouncilConfigSchema. */
149
163
  export interface CouncilConfig {
150
164
  enabled: boolean;
151
165
  /** Default 3 */
152
166
  maxRounds: number;
153
- /** Default 30_000 */
167
+ /**
168
+ * @deprecated Inert — declared for parse compatibility only. No runtime
169
+ * consumer exists: council tools consume already-returned verdict
170
+ * submissions and there is no member-dispatch cancellation seam. Config
171
+ * doctor warns when this is explicitly set; the field will be removed in
172
+ * a future release. Dispatch timeouts are governed by the agent host.
173
+ */
154
174
  parallelTimeoutMs: number;
155
175
  /** Default true — any REJECT blocks */
156
176
  vetoPriority: boolean;
@@ -159,15 +179,31 @@ export interface CouncilConfig {
159
179
  /** Default 3 — minimum distinct council members required for quorum. requireAllMembers: true overrides this to 5. */
160
180
  minimumMembers: number;
161
181
  /**
162
- * Optional webhook URL or handler name for auto-escalation when maxRounds is
163
- * reached without APPROVE. Reserved for forward compatibility — NOT yet
164
- * implemented. Currently, maxRounds exhaustion surfaces a user-facing message
165
- * via `buildUnifiedFeedbackMd` in council-service.ts (see the "Escalate to
166
- * user" block), and the architect must relay it to the user. Future wiring
167
- * options: critic_oversight agent, HTTP webhook, or configurable handler.
182
+ * Optional webhook URL or handler name declared for escalation when
183
+ * maxRounds is reached without APPROVE. REMAINS INERT: no handler,
184
+ * webhook, or outbound execution exists or is invoked. Config doctor
185
+ * visibly warns when it is explicitly set (issue #1650), and max-rounds
186
+ * exhaustion emits a durable structured event plus a user escalation
187
+ * message. Wiring real escalation requires a separate security review.
168
188
  */
169
189
  escalateOnMaxRounds?: string;
170
190
  /** Default true — CONCERNS verdict with only MEDIUM/LOW findings does NOT block completion (advisory). Set false to make all CONCERNS block like REJECT. Note: HIGH/CRITICAL findings from CONCERNS members are always promoted to requiredFixes and block at the tool level regardless of this setting. */
171
191
  phaseConcernsAllowComplete: boolean;
192
+ /**
193
+ * Final-council completion policy. Missing/default `all_required`
194
+ * preserves the exact legacy requirement (all five canonical roles,
195
+ * five distinct members, zero absentees). `quorum` is an explicit,
196
+ * bounded weakening: it requires `minimumMembers` between 3 and 5, and
197
+ * only distinct members of the canonical five-role set count. The
198
+ * normalized policy is part of the council policy digest, so any change
199
+ * invalidates previously accepted final-council evidence.
200
+ */
201
+ finalCompletionPolicy: FinalCompletionPolicyConfig;
202
+ /**
203
+ * Default 24 — maximum age (hours) of phase-council, architecture-
204
+ * supervisor, and final-council evidence. Bounded 1..720. Part of the
205
+ * council policy digest, so changing it invalidates prior evidence.
206
+ */
207
+ freshnessMaxAgeHours: number;
172
208
  }
173
209
  export declare const COUNCIL_DEFAULTS: CouncilConfig;
@@ -1,6 +1,6 @@
1
1
  import * as fsp from 'node:fs/promises';
2
2
  import { z } from 'zod';
3
- import { type CandidateSeverity, type RowFormatFamily } from '../background/candidate-contract.js';
3
+ import { type CandidateSeverity, type FindingsSeverity, type RowFormatFamily } from '../background/candidate-contract.js';
4
4
  import { type LaneOutputArtifact } from '../background/lane-output-store.js';
5
5
  import { type BackgroundDelegationRecord, type BackgroundDelegationResult, type BackgroundDelegationWorkflowLaneRecovery, findByBatchId, sweepStaleDelegations } from '../background/pending-delegations.js';
6
6
  import { type PrReviewInlineTriggerRow } from '../background/pr-review-trigger-contract.js';
@@ -11,7 +11,7 @@ export declare const PR_REVIEW_BASE_DIMENSION_IDS: readonly ["intent-architectur
11
11
  export declare const PR_REVIEW_REQUIRED_MICRO_LANE_IDS: ("auth-identity-secrets" | "untrusted-input-boundaries" | "subprocess-platform" | "concurrency-state" | "dependencies-build-release" | "api-schema-migrations" | "test-infrastructure" | "ui-accessibility-i18n" | "privacy-observability" | "generated-provenance" | "unclassified-risk")[];
12
12
  export type PrReviewBaseDimensionId = (typeof PR_REVIEW_BASE_DIMENSION_IDS)[number];
13
13
  export type PrWorkflowMode = 'PR_REVIEW' | 'PR_FEEDBACK';
14
- export type PrReviewLaneValidationPredicate = 'batch.validated_at' | 'batch.expected_lane_unique' | 'record.missing' | 'record.duplicate_lane' | 'record.subagent_session_id' | 'record.duplicate_subagent_session_id' | 'record.forbidden_subagent_session_id' | 'record.created_at' | 'record.workflow_lane' | 'record.owned_workflow_lanes' | 'record.mode' | 'record.pr_head_sha' | 'record.git_head' | 'record.status' | 'result.output_degraded' | 'result.transcript_incomplete' | 'result.chars' | 'result.digest' | 'result.output_ref' | 'artifact.readable' | 'artifact.ref' | 'artifact.batch_id' | 'artifact.lane_id' | 'artifact.mode' | 'artifact.session_id' | 'artifact.parent_session_id' | 'artifact.agent' | 'artifact.role' | 'artifact.source' | 'artifact.workflow_lane_record' | 'artifact.workflow_lane_expected' | 'artifact.pr_head_sha' | 'artifact.git_head' | 'artifact.revision_digest' | 'record.scope' | 'artifact.scope' | 'artifact.digest' | 'artifact.chars' | 'discovery.header' | 'discovery.row' | 'discovery.coverage' | 'discovery.duplicate_evidence';
14
+ export type PrReviewLaneValidationPredicate = 'batch.validated_at' | 'batch.expected_lane_unique' | 'record.missing' | 'record.duplicate_lane' | 'record.subagent_session_id' | 'record.duplicate_subagent_session_id' | 'record.forbidden_subagent_session_id' | 'record.created_at' | 'record.workflow_lane' | 'record.owned_workflow_lanes' | 'record.mode' | 'record.pr_head_sha' | 'record.git_head' | 'record.status' | 'result.output_degraded' | 'result.transcript_incomplete' | 'result.chars' | 'result.digest' | 'result.output_ref' | 'artifact.readable' | 'artifact.ref' | 'artifact.batch_id' | 'artifact.lane_id' | 'artifact.mode' | 'artifact.session_id' | 'artifact.parent_session_id' | 'artifact.agent' | 'artifact.role' | 'artifact.source' | 'artifact.workflow_lane_record' | 'artifact.workflow_lane_expected' | 'artifact.pr_head_sha' | 'artifact.git_head' | 'artifact.revision_digest' | 'record.scope' | 'artifact.scope' | 'artifact.digest' | 'artifact.chars' | 'discovery.header' | 'discovery.row' | 'discovery.coverage' | 'discovery.duplicate_evidence' | 'reviewer.verdict_rows' | 'critic.verdict_rows';
15
15
  export interface PrReviewLaneValidationFailure {
16
16
  predicate: PrReviewLaneValidationPredicate;
17
17
  expected: string;
@@ -54,12 +54,20 @@ export interface PrWorkflowTransportRecoveryValidationInput {
54
54
  artifact: LaneOutputArtifact | null;
55
55
  revisionDigest: string;
56
56
  }
57
+ export interface PrReviewVerdictCollectionReceipt {
58
+ assignedReviewItemIds: string[];
59
+ acceptedReviewItemIds: string[];
60
+ rejectedReviewItemIds: string[];
61
+ }
57
62
  export type PrWorkflowTransportRecoveryValidationResult = {
58
63
  ok: true;
59
64
  recoveries?: readonly BackgroundDelegationWorkflowLaneRecovery[];
65
+ receipt?: PrReviewVerdictCollectionReceipt;
60
66
  } | {
61
67
  ok: false;
62
68
  reason: string;
69
+ failure?: PrReviewLaneValidationFailure;
70
+ receipt?: PrReviewVerdictCollectionReceipt;
63
71
  };
64
72
  export interface PrWorkflowCheckoutRecoveryRecord {
65
73
  code: 'UNMERGED_INDEX' | 'GIT_OPERATION_IN_PROGRESS' | 'DIRTY_SUBMODULE' | 'SWARM_STATE_TRACKING_ERROR' | 'GIT_STATE_INDETERMINATE';
@@ -258,7 +266,14 @@ type PrReviewArtifactRecord = {
258
266
  finding_id: string;
259
267
  status: 'PENDING' | 'CONFIRMED' | 'DISPROVED' | 'PRE_EXISTING';
260
268
  next_action: 'route_to_reviewer' | 'route_to_critic' | 'report' | 'suppress_with_reason' | 'handoff_to_feedback';
261
- severity?: CandidateSeverity;
269
+ /**
270
+ * Optional in the TYPE only so a legacy findings row persisted before
271
+ * required-severity landed still loads (`readFindings` JSON-parses without
272
+ * re-validating). Presence is REQUIRED by
273
+ * `assertPrReviewArtifactRecordsMatchAuthoritativeVerdicts`, which treats an
274
+ * omitted severity as a mismatch rather than skipping the check (issue #2279).
275
+ */
276
+ severity?: FindingsSeverity;
262
277
  };
263
278
  interface PrFeedbackScopeDeclarationRecord {
264
279
  taskId: string;
@@ -292,8 +307,9 @@ interface PrReviewValidationBatchRecord {
292
307
  interface PrReviewBatchCoherenceRecord {
293
308
  /**
294
309
  * The exact candidate/critic inventory this batch's ownership was validated
295
- * against at record time (the same set `assertExactStringSet` compared the
296
- * declared lane items to).
310
+ * against at record time. A batch may own a subset of this inventory; retaining
311
+ * the full set here prevents stale partial batches from contributing after the
312
+ * mechanically derived inventory changes.
297
313
  */
298
314
  validatedInventory: string[];
299
315
  /**
@@ -305,6 +321,8 @@ interface PrReviewBatchCoherenceRecord {
305
321
  * claims it invalidated and leaves its siblings intact.
306
322
  */
307
323
  reviewerItemBindings?: Record<string, string>;
324
+ /** Key encoding for reviewerItemBindings; absent means legacy raw item IDs. */
325
+ reviewerItemBindingKeyEncoding?: 'prefixed-v1';
308
326
  }
309
327
  export interface PrWorkflowGateState {
310
328
  schemaVersion: 1;
@@ -888,6 +906,12 @@ export declare const _test_exports: {
888
906
  resolveRemoteRefsContainingHead: typeof resolveRemoteRefsContainingHead;
889
907
  resolveRemoteRefsContainingHeadAsync: typeof resolveRemoteRefsContainingHeadAsync;
890
908
  parseCriticVerdict: typeof parseCriticVerdict;
909
+ /**
910
+ * Exact production verdict-row analysis and item composition parsers. Exposed
911
+ * so the assignment-boundary regression can prove both paths remain linear.
912
+ */
913
+ analyzePrReviewVerdictRowContract: typeof analyzePrReviewVerdictRowContract;
914
+ parseLaneItemVerdicts: typeof parseLaneItemVerdicts;
891
915
  /**
892
916
  * Read-only view of the item-keyed composition for one session, including
893
917
  * the diagnostics that settlement only logs (abandoned declared lanes,
@@ -994,6 +1018,12 @@ interface PrReviewGateContext {
994
1018
  reviewer?: PrReviewPhaseComposition;
995
1019
  critic?: PrReviewPhaseComposition;
996
1020
  candidateInventory?: string[];
1021
+ /**
1022
+ * candidate_id -> the severity its `[CANDIDATE]` row declared. Populated
1023
+ * as a by-product of deriving the inventory, so it is exactly as
1024
+ * authoritative and as scoped as the inventory itself (issue #2320).
1025
+ */
1026
+ candidateSeverities?: Map<string, CandidateSeverity>;
997
1027
  }
998
1028
  /**
999
1029
  * Extract candidate ids from a discovery artifact's [CANDIDATE] rows. When
@@ -1006,6 +1036,13 @@ interface PrReviewGateContext {
1006
1036
  interface CanonicalCandidateArtifactRow {
1007
1037
  candidateId: string;
1008
1038
  workflowLane: string;
1039
+ /**
1040
+ * The row's declared severity, already validated against
1041
+ * `CANDIDATE_SEVERITIES` by `analyzeCandidateFields` (so never `NONE`).
1042
+ * Carried so the `post_explorer` findings boundary can compare a record's
1043
+ * severity against the candidate row that produced it (issue #2320).
1044
+ */
1045
+ severity: CandidateSeverity | null;
1009
1046
  evidence: string;
1010
1047
  lineNumber: number;
1011
1048
  }
@@ -1133,6 +1170,22 @@ export declare function prReviewDiscoveryArtifactCoversLane(text: string, expect
1133
1170
  * `pipeFields` can never produce, so no field boundary is forgeable.
1134
1171
  */
1135
1172
  declare function reviewerVerdictRowDigest(fields: readonly string[]): string;
1173
+ /**
1174
+ * Per-item verdicts an artifact actually carries, as a map rather than a
1175
+ * boolean. This is the granularity the composition needs: one unparseable item
1176
+ * must not discard its healthy siblings in the same lane.
1177
+ */
1178
+ declare function parseLaneItemVerdicts(text: string, itemIds: readonly string[], phase: PrReviewComposablePhase, reviewerClaims?: ReadonlyMap<string, PrReviewItemClaim>): Map<string, {
1179
+ classification: string;
1180
+ severity: string;
1181
+ rowDigest?: string;
1182
+ }>;
1183
+ /** Exact assigned-row contract used by both normal and recovered collection. */
1184
+ declare function analyzePrReviewVerdictRowContract(text: string, itemIds: readonly string[], phase: PrReviewComposablePhase, reviewerClaims?: ReadonlyMap<string, PrReviewItemClaim>): {
1185
+ ok: boolean;
1186
+ expected: string;
1187
+ actual: string;
1188
+ };
1136
1189
  declare function parseCriticVerdict(text: string, itemId: string, reviewerSeverity?: string): {
1137
1190
  status: string;
1138
1191
  severity: string;