opencode-swarm 7.159.3 → 7.160.1

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 (107) hide show
  1. package/.opencode/skills/swarm-pr-review/SKILL.md +28 -29
  2. package/.opencode/skills/swarm-pr-review/references/prompt-templates.md +21 -5
  3. package/dist/background/delegation-health.d.ts +1 -1
  4. package/dist/background/pending-delegations.d.ts +46 -1
  5. package/dist/background/pr-review-contract.d.ts +245 -2
  6. package/dist/cli/{coder-settlement-50p7dsya.js → coder-settlement-678ccmnf.js} +11 -10
  7. package/dist/cli/{config-doctor-a7drgs33.js → config-doctor-fr8dfrt2.js} +3 -3
  8. package/dist/cli/{core-madqgdsc.js → core-4j1hbhey.js} +2 -2
  9. package/dist/cli/{curation-policy-ray8h55z.js → curation-policy-47przjwg.js} +6 -6
  10. package/dist/cli/{curator-3sz7refy.js → curator-85d97240.js} +33 -32
  11. package/dist/cli/curator-llm-factory-s9s4s0q3.js +67 -0
  12. package/dist/cli/{evidence-summary-service-cwyjkdsa.js → evidence-summary-service-9dyt2kzh.js} +15 -14
  13. package/dist/cli/{gate-evidence-95k5ap1z.js → gate-evidence-a6paafg8.js} +7 -7
  14. package/dist/cli/guardrail-explain-4a2xdtew.js +68 -0
  15. package/dist/cli/{guardrail-log-nerqk9qb.js → guardrail-log-27nkntrx.js} +9 -6
  16. package/dist/cli/{guardrail-reset-chbc0mep.js → guardrail-reset-xn7k3hn8.js} +33 -32
  17. package/dist/cli/{hive-promoter-4rtxhw7n.js → hive-promoter-k57j3kp6.js} +33 -32
  18. package/dist/cli/{index-515nwvdp.js → index-497a3hhj.js} +19 -10
  19. package/dist/cli/{index-h96xp4t0.js → index-61c3d769.js} +875 -37
  20. package/dist/cli/{index-ve0xj03m.js → index-7ezv5j23.js} +4 -4
  21. package/dist/cli/{index-0zerbq1v.js → index-7h2armwf.js} +23 -14
  22. package/dist/cli/{index-ebxmfr4j.js → index-7npz9n4s.js} +5 -4
  23. package/dist/cli/{index-m9m3emns.js → index-7v0ex0jt.js} +2 -2
  24. package/dist/cli/{index-ebz97mks.js → index-8c9qzpy7.js} +1 -0
  25. package/dist/cli/{index-5hfqc3h3.js → index-98jmggma.js} +24 -7
  26. package/dist/cli/{index-8fyebh3w.js → index-awjx0wgk.js} +1 -1
  27. package/dist/cli/{index-av3gnekk.js → index-b5adxpy6.js} +1 -1
  28. package/dist/cli/{index-t3wk7q51.js → index-bqxffayb.js} +1 -1
  29. package/dist/cli/{index-yt75r1er.js → index-c9zp4xwc.js} +13 -2
  30. package/dist/cli/{index-9qw4sbg1.js → index-dh5q6z7y.js} +7 -7
  31. package/dist/cli/{index-prknc0xn.js → index-dke4wzkn.js} +108 -44
  32. package/dist/cli/{index-nvz4mp5w.js → index-dq93ar40.js} +6 -6
  33. package/dist/cli/{index-zswy6xgb.js → index-drqvph47.js} +7 -7
  34. package/dist/cli/{index-sn6mtxxc.js → index-e1ygmd4q.js} +35 -34
  35. package/dist/cli/{index-6jp5yxye.js → index-f72612zc.js} +16 -2
  36. package/dist/cli/{index-y2d381ce.js → index-gjx53y3c.js} +1 -1
  37. package/dist/cli/{index-xs32znyz.js → index-j3ss86kf.js} +1 -1
  38. package/dist/cli/{index-p3ym3y8b.js → index-jszabr0r.js} +4 -4
  39. package/dist/cli/{index-wwpe4am7.js → index-m1cw9fsh.js} +8 -8
  40. package/dist/cli/{index-8zw60wya.js → index-m84z3aa8.js} +13 -4
  41. package/dist/cli/index-mmr96pwr.js +785 -0
  42. package/dist/cli/{index-gk6gpe7r.js → index-nk498mx6.js} +2 -2
  43. package/dist/cli/{index-2jzmg2km.js → index-nnzdayvk.js} +6 -6
  44. package/dist/cli/{index-fnxmg8sz.js → index-ny0g8fdg.js} +5 -5
  45. package/dist/cli/{index-40t6s98s.js → index-pkz91fwm.js} +3 -3
  46. package/dist/cli/{index-bxpqq9th.js → index-pqjcyj0p.js} +3 -3
  47. package/dist/cli/{index-nhhek8yw.js → index-prv20xq6.js} +1 -1
  48. package/dist/cli/{index-mqfs5f8a.js → index-qc53dfzh.js} +2 -2
  49. package/dist/cli/{index-xqjhbfbx.js → index-v8dsmee1.js} +4 -4
  50. package/dist/cli/{index-qxpfmryw.js → index-wccdm7jv.js} +5 -5
  51. package/dist/cli/{index-rq4jcw64.js → index-z0bxbb9g.js} +4 -4
  52. package/dist/cli/{index-txwx9p21.js → index-zdv914xa.js} +585 -471
  53. package/dist/cli/{index-2fq4a3vk.js → index-znf683sm.js} +1 -1
  54. package/dist/cli/{index-v3ybemb1.js → index-zpzvpybn.js} +2 -2
  55. package/dist/cli/index.js +33 -32
  56. package/dist/cli/{knowledge-escalator-f80n84ch.js → knowledge-escalator-3q2x34cg.js} +14 -13
  57. package/dist/cli/{knowledge-events-1d7v2krw.js → knowledge-events-5y34w84b.js} +12 -11
  58. package/dist/cli/{knowledge-link-vm4caewt.js → knowledge-link-xezm8hr3.js} +5 -5
  59. package/dist/cli/{knowledge-store-66yxeet7.js → knowledge-store-fqv89q5k.js} +6 -6
  60. package/dist/cli/{knowledge-validator-p0xcx7jx.js → knowledge-validator-fsdx14tk.js} +8 -8
  61. package/dist/cli/{model-preflight-w85ecyxh.js → model-preflight-yqqchzjn.js} +1 -1
  62. package/dist/cli/{pending-delegations-vad1z71d.js → pending-delegations-6ae7wy5q.js} +7 -3
  63. package/dist/cli/{pr-review-reentry-authorization-kn3nny7h.js → pr-review-reentry-authorization-986tk381.js} +35 -33
  64. package/dist/cli/{pr-subscriptions-482gzvt6.js → pr-subscriptions-asjevc5p.js} +5 -4
  65. package/dist/cli/{runner-sn7a6zd0.js → runner-wsdcy2d6.js} +6 -6
  66. package/dist/cli/{scan-cursor-2v7995nb.js → scan-cursor-shn926r6.js} +7 -7
  67. package/dist/cli/{schema-dy8fqycb.js → schema-98tdb9h0.js} +4 -2
  68. package/dist/cli/{scope-persistence-baty62vx.js → scope-persistence-cn34xnwr.js} +10 -9
  69. package/dist/cli/{skill-generator-nwrvtqbz.js → skill-generator-kck7087c.js} +16 -15
  70. package/dist/cli/{telemetry-3rh94wv3.js → telemetry-gpr9s3sm.js} +3 -1
  71. package/dist/cli/{worktree-collision-ownership-cy24p5mr.js → worktree-collision-ownership-6b3kshcv.js} +6 -5
  72. package/dist/cli/{worktree-isolation-8jbx0s8d.js → worktree-isolation-he01qhss.js} +33 -32
  73. package/dist/config/constants.d.ts +8 -0
  74. package/dist/config/context-window.d.ts +11 -4
  75. package/dist/config/evidence-schema.d.ts +9 -6
  76. package/dist/config/schema.d.ts +8 -0
  77. package/dist/context-map/telemetry.d.ts +1 -1
  78. package/dist/health/learning-health.d.ts +356 -0
  79. package/dist/hooks/context-budget.d.ts +10 -1
  80. package/dist/hooks/curator.d.ts +2 -0
  81. package/dist/hooks/final-context-accounting.d.ts +2 -0
  82. package/dist/hooks/model-limits.d.ts +56 -25
  83. package/dist/hooks/pr-workflow-gate.d.ts +25 -1
  84. package/dist/hooks/skill-usage-pending.d.ts +1 -1
  85. package/dist/index.js +623 -609
  86. package/dist/observability/catalog.d.ts +2 -2
  87. package/dist/observability/ids.d.ts +17 -0
  88. package/dist/prm/trajectory-store.d.ts +1 -1
  89. package/dist/services/diagnose-service.d.ts +7 -0
  90. package/dist/services/status-service.d.ts +18 -0
  91. package/dist/telemetry.d.ts +52 -1
  92. package/dist/tools/context-status.d.ts +15 -1
  93. package/dist/tools/dispatch-lanes.d.ts +27 -3
  94. package/dist/tools/index.d.ts +1 -0
  95. package/dist/tools/manifest.d.ts +1 -0
  96. package/dist/tools/repo-graph/ontology.d.ts +6 -0
  97. package/dist/tools/repo-graph/pack-query.d.ts +36 -0
  98. package/dist/tools/repo-graph/types.d.ts +198 -1
  99. package/dist/tools/repo-graph.d.ts +5 -3
  100. package/dist/tools/sast-baseline.d.ts +2 -0
  101. package/dist/tools/sast-scan.d.ts +2 -2
  102. package/dist/tools/submit-pr-review-result.d.ts +5 -0
  103. package/dist/tools/tool-metadata.d.ts +8 -0
  104. package/opencode-swarm.schema.json +4 -0
  105. package/package.json +1 -1
  106. package/dist/cli/curator-llm-factory-pyp5kmra.js +0 -66
  107. package/dist/cli/guardrail-explain-a13kbmrt.js +0 -67
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * The event catalog (issue #2029).
3
3
  *
4
- * Exactly 54 entries, matching the `TelemetryEvent` union at
4
+ * Exactly 55 entries, matching the `TelemetryEvent` union at
5
5
  * `src/telemetry.ts:15-131`. Thirty-eight predate the #2029 contract; the 39th is
6
6
  * `agent_conflict_detected` (previously emitted through a force-cast past the
7
7
  * type system), the 40th is `close_archive_result` (issue #2030 — the
@@ -80,7 +80,7 @@ export interface CatalogEntry {
80
80
  /**
81
81
  * Whether an event of this kind must carry `trace.parentSpanId`.
82
82
  *
83
- * `false` for all 54 entries today, and that is a truthful statement about
83
+ * `false` for all 55 entries today, and that is a truthful statement about
84
84
  * the current system rather than a placeholder: no producer supplies a
85
85
  * parent span, so `createObservation` never sets one. Setting this to `true`
86
86
  * for a kind whose producer cannot supply a parent would make every
@@ -95,3 +95,20 @@ export declare function resolveLineageSalt(): string;
95
95
  * @param salt - Salt from {@link resolveLineageSalt}.
96
96
  */
97
97
  export declare function pseudonymousRef(absolutePath: string, salt: string): string;
98
+ /**
99
+ * Produce a pseudonymous reference for a session id (#2044).
100
+ *
101
+ * Same construction and salt handling as {@link pseudonymousRef}, applied to the
102
+ * opaque session id string: `sha256(salt + NUL + sessionId)`, truncated to
103
+ * {@link PSEUDONYMOUS_REF_LENGTH} hex chars. Used by the learning-health alarm
104
+ * registry so persisted health state and telemetry payloads never carry raw
105
+ * session ids (issue #2044 item 10).
106
+ *
107
+ * Contract note: session ids are operator-known opaque strings, not secrets;
108
+ * the pseudonym prevents cross-install linkage exactly as `pseudonymousRef`
109
+ * does for paths. With the public default salt a holder of a payload can
110
+ * CONFIRM a guessed session id by re-hashing; a private
111
+ * {@link LINEAGE_SALT_ENV} restores guess-resistance. This module stays pure —
112
+ * no I/O; the salt is read at call time.
113
+ */
114
+ export declare function pseudonymousSessionRef(sessionId: string, salt?: string): string;
@@ -34,7 +34,7 @@
34
34
  * .swarm/evidence/{taskId}/trajectory.jsonl for audit/evidence (bounded by its
35
35
  * own write-side truncation; untouched by this contract).
36
36
  */
37
- import { telemetry } from '../telemetry';
37
+ import { telemetry } from '../telemetry.js';
38
38
  import type { TrajectoryEntry } from './types';
39
39
  /**
40
40
  * Hard budgets for the bounded session-trajectory contract (issue #2041).
@@ -31,6 +31,13 @@ export interface DiagnoseData {
31
31
  * - Main bundle (everything else): stay put → dist/lang/grammars
32
32
  */
33
33
  export declare function resolveGrammarDir(thisDir: string): string;
34
+ /**
35
+ * Check (#2044): Learning/operations health — bounded-window alarm families
36
+ * from the learning-health registry. Warns when any alarm is active; the
37
+ * detail lines carry the same redacted form as the telemetry payload (16-hex
38
+ * refs, counts, enums — never raw session ids, paths, or content).
39
+ */
40
+ export declare function checkLearningHealth(directory: string): Promise<HealthCheck>;
34
41
  /**
35
42
  * Get diagnose data from the swarm directory.
36
43
  * Returns structured health checks for GUI, background flows, or commands.
@@ -122,6 +122,24 @@ export interface StatusData {
122
122
  * report id.
123
123
  */
124
124
  consensusReports?: number;
125
+ /**
126
+ * Learning/operations health (issue #2044): the bounded-window alarm
127
+ * snapshot from the learning-health registry (active alarms + transition
128
+ * count). `undefined` when the read failed (fail-open) — never blocks
129
+ * status rendering.
130
+ */
131
+ learningHealth?: {
132
+ activeAlarms: readonly {
133
+ alarm: string;
134
+ severity: string;
135
+ scopeClass: string;
136
+ scopeRef: string;
137
+ ageMs: number;
138
+ coverageFacts: number;
139
+ transitionCount: number;
140
+ }[];
141
+ totalTransitions: number;
142
+ };
125
143
  /**
126
144
  * Cohort/link status (issue #1846). Makes the linked knowledge store and its
127
145
  * health obvious in `/swarm status`. `undefined` when link state is absent.
@@ -32,7 +32,7 @@ export type TelemetryEvent = 'session_started' | 'session_ended' | 'agent_activa
32
32
  * `prm_hard_stop` TRIGGER emitted by `src/prm/escalation.ts`. A trigger with
33
33
  * no matching delivery means the containment never reached the agent.
34
34
  */
35
- | 'prm_hard_stop_delivered' | 'agent_conflict_detected' | 'close_archive_result' | 'knowledge_receipt_transition' | 'knowledge_maintenance' | 'residue_health' | 'context_telemetry_health' | 'skill_usage_health' | 'core_events_health' | 'shell_audit_health' | 'trajectory_health' | 'pr_subscription_health';
35
+ | 'prm_hard_stop_delivered' | 'agent_conflict_detected' | 'close_archive_result' | 'knowledge_receipt_transition' | 'knowledge_maintenance' | 'residue_health' | 'context_telemetry_health' | 'skill_usage_health' | 'core_events_health' | 'shell_audit_health' | 'trajectory_health' | 'learning_health_alarm' | 'pr_subscription_health';
36
36
  /** Stable classification for how a reviewer-gate decision was established. */
37
37
  export type ReviewerGateEvidenceKind = 'genuine' | 'fallback' | 'data_quality' | 'block';
38
38
  /**
@@ -77,6 +77,16 @@ export declare function emit(event: TelemetryEvent, data: Record<string, unknown
77
77
  * @param callback - Function called with (event, data) on each emit
78
78
  */
79
79
  export declare function addTelemetryListener(callback: TelemetryListener): void;
80
+ /**
81
+ * Remove a previously registered telemetry listener (issue #2044).
82
+ * Currently unused in-tree: the learning-health registry no longer attaches a
83
+ * listener (its six store feeds call the observer directly), and the heartbeat
84
+ * teardown splices `_listeners` inline by design. Kept as the public disposer
85
+ * complement to `addTelemetryListener` — push-only registration with no
86
+ * removal path was an API gap. Removing a listener that was never registered
87
+ * is a no-op.
88
+ */
89
+ export declare function removeTelemetryListener(callback: TelemetryListener): void;
80
90
  /**
81
91
  * Rotate telemetry file if it exceeds maxBytes.
82
92
  * Renames `telemetry.jsonl` → `telemetry.jsonl.1` and reopens a fresh stream.
@@ -376,6 +386,47 @@ export declare const telemetry: {
376
386
  checkpoint_bytes: number;
377
387
  limit_bytes: number;
378
388
  }): void;
389
+ /**
390
+ * Learning/operations health alarm transition (issue #2044): emitted by the
391
+ * learning-health registry (`src/observability/learning-health.ts`) when an
392
+ * alarm family raises, re-emits past its cooldown (`sustained`), or
393
+ * recovers. Payload is counts, closed-vocabulary enums (`alarm` from the
394
+ * eight-family closed set, `transition`, `severity`, `scope_class`),
395
+ * millisecond timestamps, model/provider identity, and 16-hex salted
396
+ * `session_ref` values — no raw session IDs, paths, queries, prompts, or
397
+ * content — matching the observability contract's no-content rule. Live
398
+ * readers: the `/swarm status` Learning Health section and the
399
+ * `/swarm diagnose` learning-health check.
400
+ */
401
+ learningHealthAlarm(data: {
402
+ alarm: string;
403
+ transition: "raised" | "sustained" | "recovered";
404
+ severity: "warning" | "critical";
405
+ scope_class: "session" | "identity" | "project";
406
+ session_ref?: string;
407
+ model?: string;
408
+ provider?: string;
409
+ window_ms: number;
410
+ coverage_facts: number;
411
+ raise_facts: number;
412
+ age_ms: number;
413
+ limit_source?: string;
414
+ denominator_fallback?: boolean;
415
+ pressure_pct?: number;
416
+ band?: string;
417
+ share_pct?: number;
418
+ field_count?: number;
419
+ non_field_count?: number;
420
+ store?: string;
421
+ dropped?: number;
422
+ corrupt?: number;
423
+ retained?: number;
424
+ accepted?: number;
425
+ gap_type?: "membership_to_terminal" | "terminal_to_application";
426
+ role?: string;
427
+ phase?: number;
428
+ reason?: string;
429
+ }): void;
379
430
  /**
380
431
  * Issue #2063 C2 — the PRM hard-stop DENIAL was actually delivered to the
381
432
  * agent (thrown by the guardrails `toolBefore` consumer). `prm_hard_stop`
@@ -14,7 +14,9 @@
14
14
  * Works whether `context_budget.enabled` is true or false.
15
15
  */
16
16
  import { loadPluginConfig } from '../config';
17
+ import type { ContextWindowSource } from '../config/context-window';
17
18
  import { type ContextUsageSource } from '../hooks/context-usage';
19
+ import { type ModelLimitSource } from '../hooks/model-limits';
18
20
  import { createSwarmTool } from './create-tool';
19
21
  /**
20
22
  * Shape of a message's info block.
@@ -56,6 +58,16 @@ export interface ContextStatusResult {
56
58
  usageSource: ContextUsageSource;
57
59
  /** Resolved model context limit in tokens */
58
60
  modelLimit: number;
61
+ /** Coarse provenance class of the resolved limit (issue #2044): where the
62
+ * denominator came from — host live window, user override, one of the two
63
+ * static tables, or the flat 128k fallback. */
64
+ modelLimitSource: ModelLimitSource;
65
+ /** Fine-grained resolution rung that produced the limit (which key/table). */
66
+ modelLimitResolution: ContextWindowSource;
67
+ /** True when the limit came from a static table or the flat default — i.e.
68
+ * the denominator is NOT the host's live window and headroom figures carry
69
+ * that uncertainty (issue #2044: "fallback can hide dead-headroom loops"). */
70
+ fallbackActive: boolean;
59
71
  /** Ratio of tokens-used to model-limit (0.0 – 1.0+) */
60
72
  usagePercent: number;
61
73
  /** Threshold state: 'none' | 'warn' | 'critical' */
@@ -91,7 +103,9 @@ export declare const _internals: {
91
103
  declare function computeContextHeadroom(messages: ContextMessage[], warnThreshold?: number, criticalThreshold?: number, modelLimitsConfig?: Record<string, number>, liveContextLimit?: unknown, modelIdentity?: {
92
104
  modelID?: string;
93
105
  providerID?: string;
94
- }): ContextStatusResult;
106
+ },
107
+ /** Project directory (#2044): scopes the model-limit health observation. */
108
+ directory?: string): ContextStatusResult;
95
109
  /**
96
110
  * context_status tool — read-only context window headroom report.
97
111
  *
@@ -460,16 +460,31 @@ export declare const _test_exports: {
460
460
  resolvePrReviewReceiptFallbacks: typeof resolvePrReviewReceiptFallbacks;
461
461
  resolvePrReviewReceiptFallbacksFromState: typeof resolvePrReviewReceiptFallbacksFromState;
462
462
  consumePrReviewReceiptAppendFailureLog: typeof consumePrReviewReceiptAppendFailureLog;
463
+ startAsyncLanePrompt: typeof startAsyncLanePrompt;
463
464
  prReviewLaneResponseBudgetChars: typeof prReviewLaneResponseBudgetChars;
464
465
  };
465
- type ReadOnlyToolPermissions = Record<string, false> & {
466
+ type ReadOnlyToolPermissions = Record<string, boolean> & {
466
467
  write: false;
467
468
  edit: false;
468
469
  patch: false;
469
470
  };
470
- interface DispatchLanesExecutionContext {
471
+ export interface DispatchLanesExecutionContext {
471
472
  callerAgent?: string;
472
473
  sessionID?: string;
474
+ /** Optional host-verified structured transport. Absent on current hosts. */
475
+ prReviewStructuredPromptAdapter?: PrReviewStructuredPromptAdapter;
476
+ }
477
+ export interface PrReviewStructuredPromptAdapter {
478
+ promptJsonSchema(args: {
479
+ sessionId: string;
480
+ agent: string;
481
+ schema: unknown;
482
+ parts: unknown[];
483
+ }): Promise<unknown>;
484
+ }
485
+ /** Explicit pre-execution capability miss; the only adapter error that falls back. */
486
+ export declare class PrReviewStructuredPromptUnsupportedError extends Error {
487
+ constructor(message?: string);
473
488
  }
474
489
  export declare function executeDispatchLanes(args: unknown, directory: string, context?: DispatchLanesExecutionContext): Promise<DispatchLanesResult>;
475
490
  export declare function executeDispatchLanesAsync(args: unknown, directory: string, context?: DispatchLanesExecutionContext): Promise<DispatchLanesAsyncResult>;
@@ -499,6 +514,15 @@ type LaneDiagnostics = Map<string, Set<string>>;
499
514
  declare function assembleCollectionDiagnostics(hostTimeouts: ReadonlySet<string>, settleFailureLogs: LaneDiagnostics, collectionResourceFailures: LaneDiagnostics): string[];
500
515
  declare function addLaneDiagnostic(diagnostics: LaneDiagnostics, laneLabel: string, message: string): void;
501
516
  declare function consumePrReviewReceiptAppendFailureLog(loggedFailures: Set<string>, parentSessionId: string, correlationId: string): boolean;
517
+ declare function startAsyncLanePrompt(args: {
518
+ session: SessionOps;
519
+ directory: string;
520
+ sessionId: string;
521
+ lane: DispatchLaneSpec;
522
+ timeoutMs: number;
523
+ mode?: string;
524
+ structuredAdapter?: PrReviewStructuredPromptAdapter;
525
+ }): Promise<void>;
502
526
  /**
503
527
  * Issue #2349: a terminal error read off the last assistant message of a lane
504
528
  * session, classified for settlement.
@@ -593,7 +617,7 @@ declare function resolvePrReviewReceiptFallbacksFromState(records: readonly Back
593
617
  declare function appendPrReviewCollectionReceipt(record: BackgroundDelegationRecord, result: BackgroundDelegationResult, receipt: PrReviewVerdictCollectionReceipt): BackgroundDelegationResult | null;
594
618
  declare function parsePrReviewCollectionReceipt(record: BackgroundDelegationRecord): PrReviewVerdictCollectionReceipt | null;
595
619
  declare function recordToLaneResult(record: BackgroundDelegationRecord, batchId: string, deliveryContext?: LaneResultDeliveryContext): DispatchLaneResult;
596
- declare function buildReadOnlyTools(): ReadOnlyToolPermissions;
620
+ declare function buildReadOnlyTools(mode?: string): ReadOnlyToolPermissions;
597
621
  type ApplyCommonPromptResult = {
598
622
  ok: true;
599
623
  lanes: DispatchLaneSpec[];
@@ -81,6 +81,7 @@ export { skill_retire } from './skill-retire';
81
81
  export { spec_write } from './spec-write';
82
82
  export { run_stale_reconciliation } from './stale-reconciliation';
83
83
  export { submit_phase_council_verdicts } from './submit-phase-council-verdicts';
84
+ export { submit_pr_review_result } from './submit-pr-review-result';
84
85
  export { summarize_work } from './summarize-work';
85
86
  export { createSwarmCommandTool, swarm_command } from './swarm-command';
86
87
  export { swarm_memory_outcome } from './swarm-memory-outcome';
@@ -45,6 +45,7 @@ export declare const TOOL_MANIFEST: {
45
45
  complete_pr_workflow: () => ToolDefinition;
46
46
  abort_pr_workflow: () => ToolDefinition;
47
47
  authorize_pr_review_reentry: () => ToolDefinition;
48
+ submit_pr_review_result: () => ToolDefinition;
48
49
  approve_plan_critic: () => ToolDefinition;
49
50
  prepare_pr_workflow_checkout: () => ToolDefinition;
50
51
  record_implementation_review: () => ToolDefinition;
@@ -38,4 +38,10 @@ export interface ExtractFileOntologyInput {
38
38
  * re-exported from the package index; call `extractFileOntology` instead.
39
39
  */
40
40
  export declare function maskMultilineStringLiterals(text: string, language: string): string;
41
+ /**
42
+ * Normalize one segment of a user-supplied route path so `route_trace` inputs
43
+ * like `/api/users/[...slug]` match the normalized form RouteFacts store
44
+ * (`/api/users/:slug*`). Exported for the query layer (KG-15, issue #1536).
45
+ */
46
+ export declare function normalizeRoutePathInput(input: string): string;
41
47
  export declare function extractFileOntology(input: ExtractFileOntologyInput): FileOntology;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * KG-15 change-risk pack queries (issue #1536).
3
+ *
4
+ * Route, data, and test packs over the persisted repo graph: `route_trace`,
5
+ * `data_trace`, and `test_pack`. Every function is stateless and read-only:
6
+ * inputs are validated by the `repo_map` tool layer; this module assumes
7
+ * well-formed arguments and focuses on bounded, workspace-relative,
8
+ * evidence-bearing output (the same contract as `symbol-query.ts`).
9
+ *
10
+ * Schema note: route/data packs read persisted `ontology.links` (schema
11
+ * >= 1.7.0) and degrade with `linksSupported: false` + warnings on older
12
+ * graphs, where the edges/facts-derived sections still populate. Test packs
13
+ * derive TESTS / USES_FIXTURE associations at query time from persisted
14
+ * edges plus colocated-name heuristics, so they work on every schema.
15
+ */
16
+ import type { DataTraceResult, RepoGraph, RouteMethod, RouteTraceResult, TestPackResult } from './types';
17
+ export declare function traceRoute(graph: RepoGraph, options: {
18
+ routePath?: string;
19
+ method?: RouteMethod;
20
+ file?: string;
21
+ symbol?: string;
22
+ topN?: number;
23
+ }): RouteTraceResult;
24
+ export declare function traceData(graph: RepoGraph, options: {
25
+ entity?: string;
26
+ file?: string;
27
+ symbol?: string;
28
+ topN?: number;
29
+ }): DataTraceResult;
30
+ export declare function buildTestPack(graph: RepoGraph, options: {
31
+ file?: string;
32
+ files?: string[];
33
+ symbol?: string;
34
+ diff?: string;
35
+ topN?: number;
36
+ }): TestPackResult;
@@ -54,8 +54,17 @@ export declare const REPO_GRAPH_FILENAME = "repo-graph.json";
54
54
  * The field is optional, so 1.0.0–1.5.0 graphs still load; queries surface
55
55
  * `kind: null` hits and a `kindSupported: false` degradation note instead of
56
56
  * failing (issue #1535).
57
+ *
58
+ * 1.7.0 adds the optional per-node `ontology.links` array (KG-15):
59
+ * `HANDLES_ROUTE` handler-symbol binding, entity-keyed `READS`/`WRITES`/
60
+ * `DELETES` data access, `VALIDATES`/`AUTHORIZES` security binding, and
61
+ * `CONFIGURES` env/config-key facts. `TESTS` and `USES_FIXTURE` associations
62
+ * are derived at query time from persisted edges plus colocated-name
63
+ * heuristics and are never stored. The field is optional, so 1.0.0–1.6.0
64
+ * graphs still load; queries surface `linksSupported: false` degradation
65
+ * notes instead of failing (issue #1536).
57
66
  */
58
- export declare const GRAPH_SCHEMA_VERSION = "1.6.0";
67
+ export declare const GRAPH_SCHEMA_VERSION = "1.7.0";
59
68
  /**
60
69
  * Default per-file source-size ceiling shared by graph construction and
61
70
  * query-time source reads. The builder treats this as the default value of
@@ -117,6 +126,39 @@ export interface OntologyFinding {
117
126
  message: string;
118
127
  line?: number;
119
128
  }
129
+ export declare const ONTOLOGY_LINK_KIND_VALUES: readonly ["HANDLES_ROUTE", "READS", "WRITES", "DELETES", "VALIDATES", "AUTHORIZES", "TESTS", "USES_FIXTURE", "CONFIGURES"];
130
+ export type OntologyLinkKind = (typeof ONTOLOGY_LINK_KIND_VALUES)[number];
131
+ export declare const ONTOLOGY_LINK_CONFIDENCE_VALUES: readonly ["low", "medium", "high"];
132
+ export type OntologyLinkConfidence = (typeof ONTOLOGY_LINK_CONFIDENCE_VALUES)[number];
133
+ /**
134
+ * A change-risk link binding one ontology fact to its subject and — when the
135
+ * evidence ties it to a declaration — to a symbol (KG-15, issue #1536).
136
+ *
137
+ * Persisted links are file-local (they live on the node whose source produced
138
+ * them): `HANDLES_ROUTE` (subject `'<METHOD> <path>'`, symbol = the handler
139
+ * export or named router callback), `READS`/`WRITES`/`DELETES` (subject = the
140
+ * entity/table name, file-level), `VALIDATES`/`AUTHORIZES` (from security
141
+ * facts, file-level), and `CONFIGURES` (subject = an env/config key).
142
+ *
143
+ * `TESTS` and `USES_FIXTURE` are part of the kind union for output shaping
144
+ * but are derived at query time from persisted edges + colocated-name
145
+ * heuristics (`buildTestPack`), never persisted here.
146
+ *
147
+ * Advisory and evidence-backed: `confidence` records heuristic strength, and
148
+ * every field is bounded by `validateOntologyStrings`.
149
+ */
150
+ export interface OntologyLink {
151
+ kind: OntologyLinkKind;
152
+ /** Route (`'GET /api/users'`), entity/table name, or config/env key. */
153
+ subject?: string;
154
+ /** 1-based line of the producing evidence (absent for file-level-only facts). */
155
+ line?: number;
156
+ /** Raw comment-stripped source line slice (<=160 chars). */
157
+ evidence?: string;
158
+ confidence: OntologyLinkConfidence;
159
+ /** Declaration the link is bound to, when evidence ties it to one symbol. */
160
+ symbol?: string;
161
+ }
120
162
  export interface FileOntology {
121
163
  roles: FileRole[];
122
164
  packageBoundary: string;
@@ -125,6 +167,8 @@ export interface FileOntology {
125
167
  security: SecurityFact[];
126
168
  conventions: ConventionFact[];
127
169
  findings: OntologyFinding[];
170
+ /** Change-risk links (schema >= 1.7.0; optional so older graphs load unchanged). */
171
+ links?: OntologyLink[];
128
172
  }
129
173
  /**
130
174
  * A node in the dependency graph representing a source file.
@@ -677,6 +721,159 @@ export interface GraphExplainResult {
677
721
  };
678
722
  warnings: string[];
679
723
  }
724
+ /** One matched route with its full change-risk pack (route_trace). */
725
+ export interface RouteTraceRoute {
726
+ route: {
727
+ method: RouteMethod;
728
+ path: string;
729
+ line: number | null;
730
+ source: RouteSource;
731
+ };
732
+ /** Workspace-relative handler file. */
733
+ file: string;
734
+ /** Handler symbol from a HANDLES_ROUTE link; null on pre-1.7.0 graphs. */
735
+ handlerSymbol: string | null;
736
+ handlerConfidence: OntologyLinkConfidence | null;
737
+ /** The link's evidence line (handler declaration); null without a link. */
738
+ handlerEvidence: string | null;
739
+ /** Depth-1 non-test node dependencies of the handler file, deduped + sorted. */
740
+ services: string[];
741
+ /** Facts from the handler file and its services (each list <= 20). */
742
+ dataOperations: Array<{
743
+ file: string;
744
+ fact: DataOperationFact;
745
+ }>;
746
+ security: Array<{
747
+ file: string;
748
+ fact: SecurityFact;
749
+ }>;
750
+ /** Handler-file ontology findings (the unguarded-mutating-route surface). */
751
+ findings: Array<{
752
+ file: string;
753
+ finding: OntologyFinding;
754
+ }>;
755
+ /** test_file-role importers of the handler/services files. */
756
+ tests: string[];
757
+ }
758
+ export interface RouteTraceResult {
759
+ target: {
760
+ routePath: string | null;
761
+ method: RouteMethod | null;
762
+ file: string | null;
763
+ symbol: string | null;
764
+ };
765
+ routes: RouteTraceRoute[];
766
+ /**
767
+ * False on graphs predating schema 1.7.0: handler-symbol binding degrades
768
+ * to null while the facts/edges-derived sections still populate.
769
+ */
770
+ linksSupported: boolean;
771
+ budget: {
772
+ returned: number;
773
+ dropped: number;
774
+ };
775
+ truncated: boolean;
776
+ warnings: string[];
777
+ }
778
+ /** One reader/writer/deleter/configurer match for a traced subject (data_trace). */
779
+ export interface DataTraceAccess {
780
+ file: string;
781
+ kind: 'READS' | 'WRITES' | 'DELETES' | 'CONFIGURES';
782
+ symbol: string | null;
783
+ line: number | null;
784
+ evidence: string | null;
785
+ confidence: OntologyLinkConfidence | null;
786
+ /** 'link' = schema 1.7.0 ontology link; 'fact' = DataOperationFact fallback (works on all schemas). */
787
+ via: 'link' | 'fact';
788
+ }
789
+ export interface DataTraceResult {
790
+ target: {
791
+ entity: string | null;
792
+ file: string | null;
793
+ symbol: string | null;
794
+ };
795
+ /** Resolved subject when `entity` was given (matched link subject or fact entity). */
796
+ subject: string | null;
797
+ readers: DataTraceAccess[];
798
+ writers: DataTraceAccess[];
799
+ deleters: DataTraceAccess[];
800
+ configurers: DataTraceAccess[];
801
+ /** Routes declared in files that touch the subject (<= 20). */
802
+ routes: Array<{
803
+ file: string;
804
+ fact: RouteFact;
805
+ }>;
806
+ tests: string[];
807
+ /** Fixed-vocabulary advisory notes with counts. */
808
+ riskNotes: string[];
809
+ linksSupported: boolean;
810
+ budget: {
811
+ returned: number;
812
+ dropped: number;
813
+ };
814
+ truncated: boolean;
815
+ warnings: string[];
816
+ }
817
+ /** One test file associated with a target (test_pack). */
818
+ export interface TestPackTestEntry {
819
+ file: string;
820
+ confidence: OntologyLinkConfidence;
821
+ /** 'import' = explicit import edge (high); 'colocated' = sibling-name heuristic (medium). */
822
+ basis: 'import' | 'colocated';
823
+ /** Why this association exists: the import specifier, or the colocated-name rationale. */
824
+ evidence: string;
825
+ /** Target exports referenced by the test (edge imported/used symbols ∩ target exports). */
826
+ coveredSymbols: string[];
827
+ }
828
+ /** A fixture-pattern file imported by at least one discovered test. */
829
+ export interface TestPackFixture {
830
+ file: string;
831
+ usedBy: string[];
832
+ /** Derivation is a path-pattern heuristic — always medium. */
833
+ confidence: OntologyLinkConfidence;
834
+ /** The import specifier a test used to pull the fixture in. */
835
+ evidence: string;
836
+ }
837
+ /**
838
+ * A query-time-derived TESTS / USES_FIXTURE association, materialized with
839
+ * its evidence and confidence so the two derived link kinds are
840
+ * consumer-visible (they are never persisted on the graph).
841
+ */
842
+ export interface DerivedAssociation {
843
+ kind: 'TESTS' | 'USES_FIXTURE';
844
+ /** Workspace-relative test file. */
845
+ fromFile: string;
846
+ /** Workspace-relative implementation or fixture file. */
847
+ toFile: string;
848
+ evidence: string;
849
+ confidence: OntologyLinkConfidence;
850
+ }
851
+ export interface TestPackResult {
852
+ target: {
853
+ files: string[];
854
+ symbol: string | null;
855
+ };
856
+ tests: TestPackTestEntry[];
857
+ fixtures: TestPackFixture[];
858
+ /** Non-fixture node deps shared by >= 2 discovered tests or under test-support directories. */
859
+ helpers: string[];
860
+ /** Target exports with no detected test coverage (coverage hints). */
861
+ uncoveredExports: Array<{
862
+ file: string;
863
+ symbol: string;
864
+ }>;
865
+ /** Fixed-vocabulary advisory notes (missing tests, uncovered exports, heuristic-only association). */
866
+ riskNotes: string[];
867
+ /** Derived TESTS / USES_FIXTURE associations (bounded, evidence + confidence). */
868
+ associations: DerivedAssociation[];
869
+ /** Aggregate across every bounded section: tests + fixtures + helpers + associations. */
870
+ budget: {
871
+ returned: number;
872
+ dropped: number;
873
+ };
874
+ truncated: boolean;
875
+ warnings: string[];
876
+ }
680
877
  export interface GraphExtractionFailure {
681
878
  file: string;
682
879
  language: string;
@@ -12,6 +12,7 @@
12
12
  * builder.ts — workspace scanning and full-graph construction
13
13
  * incremental.ts — incremental updates for changed files
14
14
  * symbol-query.ts — KG-14 symbol/impact/diff/explain queries (issue #1535)
15
+ * pack-query.ts — KG-15 route/data/test change-risk packs (issue #1536)
15
16
  *
16
17
  * All existing imports of this module continue to work unchanged.
17
18
  */
@@ -23,11 +24,12 @@ export type { FreshnessOptions, FreshnessProbe, } from './repo-graph/freshness';
23
24
  export { EXTRACTOR_STAMP, FINGERPRINT_SCHEMA_VERSION, invalidateFreshnessCache, probeFreshness, REPO_GRAPH_FINGERPRINT_FILENAME, writeFingerprint, } from './repo-graph/freshness';
24
25
  export { updateGraphForFiles } from './repo-graph/incremental';
25
26
  export type { ExtractFileOntologyInput } from './repo-graph/ontology';
26
- export { extractFileOntology } from './repo-graph/ontology';
27
+ export { extractFileOntology, normalizeRoutePathInput, } from './repo-graph/ontology';
28
+ export { buildTestPack, traceData, traceRoute } from './repo-graph/pack-query';
27
29
  export type { DeadExportsOptions } from './repo-graph/query';
28
30
  export { buildOntologyPreflightPacket, getBlastRadius, getCallers, getContextPack, getDeadExports, getDependencies, getFileOntology, getGraphHealth, getGraphNode, getImporters, getKeyFiles, getLocalizationContext, getPackageBoundaries, getSymbolConsumers, isGraphFresh, resetQueryCache, } from './repo-graph/query';
29
31
  export { getGraphPath, loadGraph, loadGraphSync, loadOrCreateGraph, saveGraph, saveIfDirty, } from './repo-graph/storage';
30
32
  export { explainGraphEntry, getDiffContext, getImpactCone, getSymbolContext, searchSymbols, } from './repo-graph/symbol-query';
31
- export type { AskHit, AskOptions, AskResult, BlastRadiusResult, BuildWorkspaceGraphOptions, CallerReference, ConeEntry, ContextPackCoverage, ContextPackResult, ContextPackSnippet, ContextPackSourceMode, ContextPackSpan, ConventionFact, DataOperationFact, DeadExportCandidate, DeadExportsResult, DiffContextResult, DiffFileSummary, DiffSymbolChange, ExplainReason, FileOntology, FileReference, FileRole, FreshnessProbeState, GraphEdge, GraphExplainResult, GraphExtractionFailure, GraphExtractorInputWitness, GraphHealthResult, GraphNode, GraphSymbolKind, GraphSymbolVisibility, GraphUnresolvedImport, ImpactConeResult, LocalizationBlock, OntologyFinding, PackageBoundarySummary, RepoGraph, RepoGraphDiagnostics, RouteFact, RouteMethod, SecurityFact, SymbolContextResult, SymbolEdge, SymbolEdgeEvidence, SymbolEdgeKind, SymbolEdgeResolution, SymbolHit, SymbolIdentityKind, SymbolReference, SymbolSearchResult, } from './repo-graph/types';
32
- export { createEmptyGraph, DEFAULT_MAX_SOURCE_BYTES, GRAPH_SCHEMA_VERSION, inferPackageBoundary, isSchemaVersionAtLeast, normalizeGraphPath, REPO_GRAPH_FILENAME, updateGraphMetadata, } from './repo-graph/types';
33
+ export type { AskHit, AskOptions, AskResult, BlastRadiusResult, BuildWorkspaceGraphOptions, CallerReference, ConeEntry, ContextPackCoverage, ContextPackResult, ContextPackSnippet, ContextPackSourceMode, ContextPackSpan, ConventionFact, DataOperationFact, DataTraceAccess, DataTraceResult, DeadExportCandidate, DeadExportsResult, DerivedAssociation, DiffContextResult, DiffFileSummary, DiffSymbolChange, ExplainReason, FileOntology, FileReference, FileRole, FreshnessProbeState, GraphEdge, GraphExplainResult, GraphExtractionFailure, GraphExtractorInputWitness, GraphHealthResult, GraphNode, GraphSymbolKind, GraphSymbolVisibility, GraphUnresolvedImport, ImpactConeResult, LocalizationBlock, OntologyFinding, OntologyLink, OntologyLinkConfidence, OntologyLinkKind, PackageBoundarySummary, RepoGraph, RepoGraphDiagnostics, RouteFact, RouteMethod, RouteTraceResult, RouteTraceRoute, SecurityFact, SymbolContextResult, SymbolEdge, SymbolEdgeEvidence, SymbolEdgeKind, SymbolEdgeResolution, SymbolHit, SymbolIdentityKind, SymbolReference, SymbolSearchResult, TestPackFixture, TestPackResult, TestPackTestEntry, } from './repo-graph/types';
34
+ export { createEmptyGraph, DEFAULT_MAX_SOURCE_BYTES, GRAPH_SCHEMA_VERSION, inferPackageBoundary, isSchemaVersionAtLeast, normalizeGraphPath, ONTOLOGY_LINK_CONFIDENCE_VALUES, ONTOLOGY_LINK_KIND_VALUES, REPO_GRAPH_FILENAME, updateGraphMetadata, } from './repo-graph/types';
33
35
  export { validateGraphEdge, validateGraphNode, validateWorkspace, } from './repo-graph/validation';
@@ -138,6 +138,8 @@ export type CaptureResult = {
138
138
  fingerprint_count: number;
139
139
  /** Novel absorptions recorded in triage_log by this capture. */
140
140
  absorbed_finding_count: number;
141
+ /** Prior triage entries whose fingerprints no longer survive this merge. */
142
+ dropped_triage_count: number;
141
143
  } | {
142
144
  status: 'absorption_blocked';
143
145
  path: string;
@@ -98,8 +98,8 @@ export interface SastScanResult {
98
98
  truncated_pre_existing?: boolean;
99
99
  /**
100
100
  * True when moved_findings were truncated to fit result limits. Advisory
101
- * telemetry only (no in-tree consumer) kept for parity with
102
- * truncated_pre_existing and for future audit consumers.
101
+ * telemetry: emitted into the sast_scan evidence payload when set (as is
102
+ * truncated_pre_existing) and mirrored on the result for callers.
103
103
  */
104
104
  truncated_moved_findings?: boolean;
105
105
  }
@@ -0,0 +1,5 @@
1
+ import { createSwarmTool } from './create-tool.js';
2
+ export declare function executeSubmitPrReviewResult(args: unknown, directory: string, context?: {
3
+ sessionID?: string;
4
+ }): Promise<string>;
5
+ export declare const submit_pr_review_result: ReturnType<typeof createSwarmTool>;
@@ -160,6 +160,14 @@ export declare const TOOL_METADATA: {
160
160
  description: string;
161
161
  agents: "architect"[];
162
162
  };
163
+ submit_pr_review_result: {
164
+ description: string;
165
+ agents: never[];
166
+ prWorkflow: {
167
+ modes: "PR_REVIEW"[];
168
+ capability: "validate";
169
+ };
170
+ };
163
171
  approve_plan_critic: {
164
172
  description: string;
165
173
  agents: "architect"[];
@@ -351,6 +351,10 @@
351
351
  },
352
352
  "additionalProperties": false
353
353
  },
354
+ "pr_review_legacy_transcript_compatibility": {
355
+ "description": "Deprecated migration-only opt-in for transcript-row PR-review base and micro discovery lanes.",
356
+ "type": "boolean"
357
+ },
354
358
  "gates": {
355
359
  "description": "Quality gate configuration (v6.9 anti-slop features).",
356
360
  "type": "object",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.159.3",
3
+ "version": "7.160.1",
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",