opencode-swarm 7.62.1 → 7.64.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 (46) hide show
  1. package/.opencode/skills/swarm-pr-review/SKILL.md +124 -0
  2. package/README.md +57 -0
  3. package/dist/agents/architect.d.ts +1 -1
  4. package/dist/agents/explorer.d.ts +1 -1
  5. package/dist/agents/reviewer-directive-compliance.d.ts +43 -0
  6. package/dist/cli/index.js +3418 -1029
  7. package/dist/config/constants.d.ts +2 -0
  8. package/dist/config/evidence-schema.d.ts +44 -44
  9. package/dist/config/schema.d.ts +201 -0
  10. package/dist/hooks/delegate-ack-collector.d.ts +51 -0
  11. package/dist/hooks/delegate-directive-injection.d.ts +33 -0
  12. package/dist/hooks/knowledge-application.d.ts +4 -3
  13. package/dist/hooks/knowledge-curator.d.ts +73 -1
  14. package/dist/hooks/knowledge-escalator.d.ts +50 -0
  15. package/dist/hooks/knowledge-events.d.ts +63 -3
  16. package/dist/hooks/knowledge-injector.d.ts +69 -1
  17. package/dist/hooks/knowledge-types.d.ts +41 -1
  18. package/dist/hooks/knowledge-validator.d.ts +43 -0
  19. package/dist/hooks/micro-reflector.d.ts +91 -0
  20. package/dist/hooks/phase-complete-directive-gate.d.ts +44 -0
  21. package/dist/hooks/phase-directives.d.ts +29 -0
  22. package/dist/hooks/reviewer-verdict-parser.d.ts +64 -0
  23. package/dist/hooks/search-knowledge.d.ts +33 -0
  24. package/dist/index.js +8600 -3951
  25. package/dist/memory/schema.d.ts +2 -2
  26. package/dist/services/directive-predicate-runner.d.ts +72 -0
  27. package/dist/services/external-skill-store.d.ts +96 -0
  28. package/dist/services/external-skill-validator.d.ts +160 -0
  29. package/dist/services/knowledge-diagnostics.d.ts +19 -0
  30. package/dist/services/skill-improver.d.ts +11 -0
  31. package/dist/services/status-service.d.ts +3 -0
  32. package/dist/services/synonym-map.d.ts +136 -0
  33. package/dist/services/trajectory-cluster.d.ts +49 -0
  34. package/dist/services/unactionable-hardening.d.ts +47 -0
  35. package/dist/tools/external-skill-delete.d.ts +16 -0
  36. package/dist/tools/external-skill-discover.d.ts +21 -0
  37. package/dist/tools/external-skill-inspect.d.ts +15 -0
  38. package/dist/tools/external-skill-list.d.ts +15 -0
  39. package/dist/tools/external-skill-promote.d.ts +20 -0
  40. package/dist/tools/external-skill-reject.d.ts +15 -0
  41. package/dist/tools/external-skill-revoke.d.ts +17 -0
  42. package/dist/tools/index.d.ts +7 -0
  43. package/dist/tools/manifest.d.ts +7 -0
  44. package/dist/tools/phase-complete.d.ts +10 -0
  45. package/dist/tools/tool-metadata.d.ts +28 -0
  46. package/package.json +1 -1
@@ -7,8 +7,76 @@
7
7
  */
8
8
  import { recordKnowledgeShown } from './knowledge-application.js';
9
9
  import { recordKnowledgeEvent } from './knowledge-events.js';
10
- import type { KnowledgeConfig, MessageWithParts } from './knowledge-types.js';
10
+ import type { RankedEntry } from './knowledge-reader.js';
11
+ import type { DirectivePriority, KnowledgeConfig, MessageWithParts } from './knowledge-types.js';
11
12
  import { searchKnowledge } from './search-knowledge.js';
13
+ /** Marker that uniquely identifies the delegate directive block in a transcript. */
14
+ export declare const DELEGATE_DIRECTIVE_BLOCK_TAG = "<delegate_knowledge_directives>";
15
+ /**
16
+ * Render a sanitized, deterministic `<delegate_knowledge_directives>` block for
17
+ * a delegated subagent (Change 1, Task 1.3). Entries are sorted by priority
18
+ * (critical first) then ID so the block is stable across runs and prompt caches
19
+ * remain warm. Returns null when there are no entries (no empty wrapper).
20
+ */
21
+ export declare function buildDelegateDirectiveBlock(entries: RankedEntry[], cfg: KnowledgeConfig): string | null;
22
+ /** A directive that was rendered into a delegate block, recovered by parsing. */
23
+ export interface ShownDelegateDirective {
24
+ id: string;
25
+ priority: DirectivePriority;
26
+ }
27
+ /**
28
+ * Recover the directive IDs (and priorities) that were rendered into a
29
+ * `<delegate_knowledge_directives>` block. Used by the ack-collector
30
+ * (Task 1.5) to reconcile a delegate's ack markers against what was actually
31
+ * shown — only IDs present here are honored, so a delegate cannot fabricate an
32
+ * ack for a directive it never received. Returns [] when no block is present.
33
+ */
34
+ export declare function parseDelegateDirectiveBlock(text: string): ShownDelegateDirective[];
35
+ export interface InjectForDelegateParams {
36
+ directory: string;
37
+ agent: string;
38
+ expectedTools?: string[];
39
+ taskTitle?: string;
40
+ sessionId?: string;
41
+ config: KnowledgeConfig;
42
+ /**
43
+ * Phase label recorded on the emitted `delegate_inject` event. Threading the
44
+ * real plan phase (rather than the task title) lets the reviewer verdict loop
45
+ * and the phase-complete gate window directives by phase (Change 2).
46
+ */
47
+ phase?: string;
48
+ /** Test seam: override the search function. Defaults to the live one. */
49
+ searchFn?: typeof searchKnowledge;
50
+ }
51
+ export interface InjectForDelegateResult {
52
+ entries: RankedEntry[];
53
+ trace_id: string;
54
+ }
55
+ /**
56
+ * Retrieve the subset of active knowledge directives scoped to a delegated
57
+ * subagent's role + expected tools (Change 1, Task 1.2). Emits a single
58
+ * `retrieved` event tagged `mode:'delegate_inject'` with the capped, in-scope
59
+ * entry IDs. Fail-open: any error yields an empty result.
60
+ */
61
+ export declare function injectForDelegate(params: InjectForDelegateParams): Promise<InjectForDelegateResult>;
62
+ /** Returns true if this agent is the architect (the sole intended recipient of orchestrator-tier knowledge injection). */
63
+ export declare function isOrchestratorAgent(agentName: string): boolean;
64
+ /**
65
+ * Returns true if this agent is a delegated subagent that should receive the
66
+ * per-agent directive block. Swarm prefixes (e.g. `mega_coder`) are stripped so
67
+ * prefixed agent names still match their canonical role.
68
+ */
69
+ export declare function isDelegatedAgent(agentName: string): boolean;
70
+ /** Returns the default expected-tools list for a delegated agent role. */
71
+ export declare function defaultExpectedToolsForAgent(agentName: string): string[];
72
+ /**
73
+ * Per-delegate scope match implementing the Change-1 OR semantics: an entry is
74
+ * in scope for a delegate when it is untargeted (no agent and no tool scope),
75
+ * OR its `applies_to_agents` includes the delegate's role, OR its
76
+ * `applies_to_tools` intersects the delegate's expected tools. Swarm prefixes
77
+ * are stripped on both sides so `mega_coder` matches a bare `coder`.
78
+ */
79
+ export declare function matchesDelegateScope(entry: Pick<RankedEntry, 'applies_to_agents' | 'applies_to_tools'>, role: string, expectedTools: readonly string[]): boolean;
12
80
  /**
13
81
  * Creates a knowledge injection hook that injects relevant knowledge into the
14
82
  * architect's message context at phase start. Supports caching for re-injection
@@ -43,9 +43,19 @@ export interface RetrievalOutcome {
43
43
  succeeded_after_shown_count?: number;
44
44
  /** v2: phase-failure count after a "shown" (replaces failed_after_count). */
45
45
  failed_after_shown_count?: number;
46
+ /** v3: recent violation timestamps (newest-first, capped) folded from the
47
+ * event-derived rollup. Surfaced for the repeat-mistake escalator. */
48
+ violation_timestamps?: string[];
46
49
  }
47
50
  /** v2: priority used by retrieval ranking and enforcement. */
48
51
  export type DirectivePriority = 'low' | 'medium' | 'high' | 'critical';
52
+ /** One automatic escalation applied to a directive (Change 3). */
53
+ export interface DirectiveEscalationRecord {
54
+ from: DirectivePriority;
55
+ to: DirectivePriority;
56
+ reason: 'repeat_violation' | string;
57
+ at: string;
58
+ }
49
59
  /** v2: optional actionable-directive metadata attached to a knowledge entry. */
50
60
  export interface ActionableDirectiveFields {
51
61
  /** Trigger phrases that surface this entry (e.g. "coder delegation modifying source"). */
@@ -60,6 +70,15 @@ export interface ActionableDirectiveFields {
60
70
  applies_to_tools?: string[];
61
71
  /** Reviewer/test-engineer/runtime checks the directive expects. */
62
72
  verification_checks?: string[];
73
+ /**
74
+ * A single machine-checkable verification predicate (Change 2). DSL:
75
+ * grep:<regex>:<path-glob> pass when ripgrep finds zero matches
76
+ * tool:<argv> pass when the (allowlisted, shell-free) command exits 0
77
+ * file_not_modified:<path> pass when the path is unchanged in the working tree
78
+ * file_modified:<path> pass when the path is changed in the working tree
79
+ * Runs fail-closed (parse error → error) with a hard 15s timeout, no shell.
80
+ */
81
+ verification_predicate?: string;
63
82
  /** Source pointers (file:line, plan section, etc.). Sanitized. */
64
83
  source_refs?: string[];
65
84
  /** UUIDs of source knowledge entries (for derived/clustered entries). */
@@ -70,6 +89,14 @@ export interface ActionableDirectiveFields {
70
89
  generated_skill_path?: string;
71
90
  /** Directive priority for ranking/enforcement. */
72
91
  directive_priority?: DirectivePriority;
92
+ /**
93
+ * Enforcement posture (Change 3). `'enforce'` makes the directive block at the
94
+ * point of violation; `'warn'` only records. Auto-set to `'enforce'` by the
95
+ * repeat-mistake escalator.
96
+ */
97
+ enforcement_mode?: 'warn' | 'enforce';
98
+ /** Audit trail of automatic escalations applied to this directive (Change 3). */
99
+ escalation_history?: DirectiveEscalationRecord[];
73
100
  /** ISO 8601 timestamp of last explicit application. */
74
101
  last_applied_at?: string;
75
102
  /** ISO 8601 timestamp of last explicit acknowledgment. */
@@ -83,7 +110,10 @@ export interface KnowledgeEntryBase extends ActionableDirectiveFields {
83
110
  tags: string[];
84
111
  scope: string;
85
112
  confidence: number;
86
- status: 'candidate' | 'established' | 'promoted' | 'archived' | 'quarantined';
113
+ status: 'candidate' | 'established' | 'promoted' | 'archived' | 'quarantined'
114
+ /** Change 4: failed the actionability layer (no predicate or no scope tag).
115
+ * Held out of the active store pending hardening by the skill-improver. */
116
+ | 'quarantined_unactionable';
87
117
  confirmed_by: PhaseConfirmationRecord[] | ProjectConfirmationRecord[];
88
118
  retrieval_outcomes: RetrievalOutcome;
89
119
  schema_version: number;
@@ -128,6 +158,8 @@ export interface KnowledgeConfig {
128
158
  auto_promote_days: number;
129
159
  /** Maximum knowledge entries to inject per architect message. Default: 5 */
130
160
  max_inject_count: number;
161
+ /** Maximum knowledge directives injected into a delegated subagent's prompt. Default: 8 */
162
+ delegate_max_inject_count?: number;
131
163
  /** Maximum total chars for the entire injection block. Default: 2000 */
132
164
  inject_char_budget?: number;
133
165
  /** Minimum headroom chars required before knowledge injection activates. Default: 300 */
@@ -172,6 +204,14 @@ export interface KnowledgeConfig {
172
204
  todo_max_phases: number;
173
205
  /** Enable age-based sweep of knowledge entries. Default: true */
174
206
  sweep_enabled: boolean;
207
+ /** Change 5: retrieval-upgrade tuning (MMR / cold-start / synonyms). */
208
+ retrieval?: {
209
+ mmr_lambda?: number;
210
+ cold_start_bonus?: number;
211
+ cold_start_max_age_phases?: number;
212
+ synonym_min_cooccurrence?: number;
213
+ synonym_map_max_pairs?: number;
214
+ };
175
215
  }
176
216
  export interface MessageInfo {
177
217
  role: string;
@@ -27,9 +27,52 @@ export interface ActionableValidationResult {
27
27
  }
28
28
  /** Validate a generated_skill_path: must be repo-local and under an allowed prefix. */
29
29
  export declare function validateSkillPath(p: unknown): boolean;
30
+ /**
31
+ * Validate that a path is a valid candidate storage path under `.swarm/skills/candidates/`.
32
+ * The filename must be a UUID v4 (canonical, no braces) with `.json` extension.
33
+ */
34
+ export declare function validateSkillCandidatePath(p: unknown): boolean;
30
35
  /** Validate the optional ActionableDirectiveFields block on a knowledge entry. */
31
36
  export declare function validateActionableFields(fields: ActionableDirectiveFields | undefined): ActionableValidationResult;
32
37
  export type { ActionableDirectiveFields, DirectivePriority };
38
+ export interface ActionabilityResult {
39
+ actionable: boolean;
40
+ /** Present only when not actionable. */
41
+ reason?: 'missing_predicate' | 'missing_scope' | 'missing_predicate_and_scope';
42
+ }
43
+ /**
44
+ * Layer 5: an entry is actionable only when it carries at least one
45
+ * machine-checkable predicate AND at least one scope tag.
46
+ *
47
+ * predicate := forbidden_actions | required_actions | verification_checks
48
+ * | verification_predicate
49
+ * scope := applies_to_tools | applies_to_agents
50
+ *
51
+ * Plain-prose lessons (no predicate, no scope) are NOT actionable and must be
52
+ * quarantined rather than activated.
53
+ */
54
+ export declare function validateActionability(entry: Pick<KnowledgeEntryBase, 'forbidden_actions' | 'required_actions' | 'verification_checks' | 'verification_predicate' | 'applies_to_tools' | 'applies_to_agents'>): ActionabilityResult;
55
+ /** Returns `.swarm/knowledge-unactionable.jsonl` for the given directory. */
56
+ export declare function resolveUnactionablePath(directory: string): string;
57
+ /** One quarantined-unactionable record. */
58
+ export interface UnactionableRecord extends KnowledgeEntryBase {
59
+ status: 'quarantined_unactionable';
60
+ unactionable_reason: string;
61
+ quarantined_at: string;
62
+ }
63
+ /**
64
+ * Persist an entry that failed the actionability layer to the unactionable
65
+ * queue (held out of the active store, pending hardening by the skill-improver).
66
+ * FIFO-capped at 200. Best-effort: throws only on lock failure for tests.
67
+ *
68
+ * Flooding tradeoff (Phase 4 review): duplicate prose lessons are NOT deduped
69
+ * at queue time, so a looping producer can fill the queue with duplicates and
70
+ * FIFO-evict older legitimate records. Accepted because (a) the cap bounds the
71
+ * damage at 200 records of plain text, (b) the hardening loop's promotion path
72
+ * dedups at commit time against the active store, and (c) queue producers are
73
+ * themselves quota- or phase-bounded. Revisit if telemetry shows real evictions.
74
+ */
75
+ export declare function appendUnactionable(directory: string, entry: KnowledgeEntryBase, reason: string): Promise<void>;
33
76
  export interface QuarantinedEntry extends KnowledgeEntryBase {
34
77
  original_status: string;
35
78
  quarantine_reason: string;
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Micro-reflector (Swarm Learning System, Change 6 / Task 5.1).
3
+ *
4
+ * The innermost reflection loop: runs when a delegated subagent returns (a
5
+ * `tool.execute.after` hook on the `Task` tool). It reads the delegate's
6
+ * transcript and the per-task trajectory slice
7
+ * (`.swarm/evidence/<taskId>/trajectory.jsonl`), classifies the outcome, and —
8
+ * ONLY on failure/partial outcomes — calls a cheap, quota-gated LLM to emit
9
+ * 0–2 candidate insights conforming to the v3 actionability schema. Candidates
10
+ * are appended to `.swarm/insight-candidates.jsonl`; they are NEVER written
11
+ * directly to the knowledge store (the meso reflector consumes them at phase
12
+ * boundary, Task 5.2).
13
+ *
14
+ * Budget: the prompt is capped well under ~2k input chars and the model is
15
+ * asked for ≤512 output. Exactly one LLM call per qualifying return, gated by
16
+ * the shared skill-improver quota. Fail-open: never throws, never blocks.
17
+ */
18
+ import type { CuratorLLMDelegate } from './curator.js';
19
+ import type { EnrichmentQuotaOptions } from './knowledge-curator.js';
20
+ import type { ActionableDirectiveFields } from './knowledge-types.js';
21
+ import type { TrajectoryEntry } from './trajectory-logger.js';
22
+ export type MicroOutcome = 'success' | 'failure_test' | 'failure_lint' | 'failure_revert' | 'partial';
23
+ export declare const MICRO_PROMPT_INPUT_CAP = 1800;
24
+ /** One v3-schema candidate insight written to the queue. */
25
+ export interface InsightCandidate extends ActionableDirectiveFields {
26
+ lesson: string;
27
+ category: string;
28
+ tags: string[];
29
+ source: {
30
+ kind: 'micro_reflection';
31
+ task_id?: string;
32
+ agent: string;
33
+ outcome: MicroOutcome;
34
+ trajectory_steps: number;
35
+ };
36
+ created_at: string;
37
+ }
38
+ /** Returns `.swarm/insight-candidates.jsonl` for a project directory. */
39
+ export declare function resolveInsightCandidatesPath(directory: string): string;
40
+ /**
41
+ * Classify the delegate outcome from its transcript + trajectory. Trajectory
42
+ * tool results are authoritative when present; the transcript provides the
43
+ * fallback signal. Defaults to 'success' (no reflection) when nothing matches.
44
+ */
45
+ export declare function classifyOutcome(transcript: string, trajectory: TrajectoryEntry[]): MicroOutcome;
46
+ /** Read a task's trajectory slice. Fail-open: [] when absent/corrupt. */
47
+ export declare function readTaskTrajectory(directory: string, taskId: string): Promise<TrajectoryEntry[]>;
48
+ /** Build the bounded micro-reflection prompt (≤ MICRO_PROMPT_INPUT_CAP chars). */
49
+ export declare function buildMicroPrompt(params: {
50
+ agent: string;
51
+ outcome: MicroOutcome;
52
+ transcript: string;
53
+ trajectory: TrajectoryEntry[];
54
+ }): string;
55
+ /** Parse the LLM response into validated v3 candidates (allowlist + actionable). */
56
+ export declare function parseMicroCandidates(response: string, meta: {
57
+ agent: string;
58
+ outcome: MicroOutcome;
59
+ taskId?: string;
60
+ steps: number;
61
+ }): InsightCandidate[];
62
+ export interface MicroReflectionResult {
63
+ outcome: MicroOutcome;
64
+ reflected: boolean;
65
+ candidates: number;
66
+ }
67
+ /** Core micro-reflection. Never throws. */
68
+ export declare function runMicroReflection(params: {
69
+ directory: string;
70
+ taskId?: string;
71
+ agent: string;
72
+ transcript: string;
73
+ trajectory: TrajectoryEntry[];
74
+ llmDelegate?: CuratorLLMDelegate;
75
+ quota?: EnrichmentQuotaOptions;
76
+ }): Promise<MicroReflectionResult>;
77
+ export interface MicroReflectorInput {
78
+ tool: unknown;
79
+ args?: unknown;
80
+ sessionID?: unknown;
81
+ }
82
+ export interface MicroReflectorOutput {
83
+ output?: unknown;
84
+ }
85
+ /**
86
+ * `tool.execute.after` adapter for the `Task` tool. Resolves the delegate, the
87
+ * transcript, the task id, and the trajectory slice, then runs micro-reflection.
88
+ * The LLM delegate is provided by the caller (so tests can inject one); when
89
+ * absent, classification still runs but no LLM call is made.
90
+ */
91
+ export declare function microReflectorAfter(directory: string, input: MicroReflectorInput, output: MicroReflectorOutput, llmDelegate?: CuratorLLMDelegate, quota?: EnrichmentQuotaOptions): Promise<void>;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Phase-complete critical-directive gate (Swarm Learning System, Change 2 /
3
+ * Task 2.4).
4
+ *
5
+ * A phase may not complete while a CRITICAL knowledge directive shown during the
6
+ * phase lacks a terminal outcome, or carries an unremediated violation. A
7
+ * critical directive is RESOLVED when, within the phase window, it has either:
8
+ * - an `applied` outcome dated at/after its latest `violated` (remediation /
9
+ * reviewer VERIFIED), OR
10
+ * - an `ignored` or `n_a` outcome WITH a reason and no later `violated`.
11
+ * Otherwise it BLOCKS with one of:
12
+ * - 'no_verdict' — no terminal outcome at all, or
13
+ * - 'unremediated_violation' — a violation with no later applied/verified.
14
+ *
15
+ * The architect may override specific IDs via `acceptViolations` (logged as an
16
+ * `override` event with a written justification). Fail-CLOSED: any read error
17
+ * surfaces as a block, never a silent pass.
18
+ */
19
+ export type DirectiveBlockReason = 'no_verdict' | 'unremediated_violation';
20
+ export interface DirectiveGateResult {
21
+ blocked: boolean;
22
+ unresolved: Array<{
23
+ id: string;
24
+ reason: DirectiveBlockReason;
25
+ }>;
26
+ overridden: string[];
27
+ /** True when the gate could not read its inputs (fail-closed → blocked). */
28
+ failedClosed: boolean;
29
+ }
30
+ /**
31
+ * Evaluate all critical directives shown during the phase. Fail-closed.
32
+ */
33
+ export declare function evaluatePhaseCriticalDirectives(params: {
34
+ directory: string;
35
+ phaseLabel?: string;
36
+ acceptViolations?: string[];
37
+ }): Promise<DirectiveGateResult>;
38
+ /**
39
+ * Record an architect override for accepted critical violations. Each accepted
40
+ * id is logged as an `override` event with the written justification.
41
+ */
42
+ export declare function recordDirectiveOverrides(directory: string, ids: string[], justification: string, sessionId: string | undefined): Promise<void>;
43
+ /** Build a structured, human-readable block message for unresolved criticals. */
44
+ export declare function formatDirectiveBlockMessage(unresolved: DirectiveGateResult['unresolved']): string;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Phase-windowed directive sourcing (Swarm Learning System, Change 2).
3
+ *
4
+ * Single source of truth for "which knowledge directives were shown during this
5
+ * phase". Used by both the reviewer verdict loop (Task 2.1/2.3 — which IDs the
6
+ * reviewer must verify) and the phase-complete gate (Task 2.4 — which CRITICAL
7
+ * IDs must reach a terminal outcome before the phase advances).
8
+ *
9
+ * The window is defined by the retrieval event's `phase` label: every
10
+ * `retrieved` event (auto_injection AND delegate_inject) carries the plan phase
11
+ * label, so a single equality filter gives a consistent set across consumers.
12
+ * Passing an empty/undefined phase collects directives across all phases (used
13
+ * only as a permissive fallback).
14
+ */
15
+ import type { DirectiveToVerify } from '../agents/reviewer-directive-compliance.js';
16
+ import type { KnowledgeEntryBase } from './knowledge-types.js';
17
+ /** Collect the directive IDs surfaced by `retrieved` events in the phase window. */
18
+ export declare function collectPhaseDirectiveIds(directory: string, phaseLabel?: string): Promise<string[]>;
19
+ /** Load all knowledge entries (swarm + hive) indexed by id. */
20
+ export declare function readEntriesById(directory: string): Promise<Map<string, KnowledgeEntryBase>>;
21
+ /**
22
+ * Resolve the directives the reviewer must verify for a phase: the entries
23
+ * behind the phase's retrieved IDs, with priority + lesson + verification
24
+ * predicate. Archived/quarantined entries are excluded. Fail-open: returns [] on
25
+ * any error.
26
+ */
27
+ export declare function readPhaseDirectivesToVerify(directory: string, phaseLabel?: string): Promise<DirectiveToVerify[]>;
28
+ /** The CRITICAL directive IDs retrieved during the phase. */
29
+ export declare function readPhaseCriticalDirectiveIds(directory: string, phaseLabel?: string): Promise<string[]>;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Reviewer DIRECTIVE_COMPLIANCE parsing + reconciliation (Swarm Learning System,
3
+ * Change 2 / Task 2.3).
4
+ *
5
+ * Parses a reviewer's `DIRECTIVE_COMPLIANCE` block (VERIFIED / VIOLATED / N/A
6
+ * lines) and reconciles it against the set of directives the reviewer was asked
7
+ * to verify, emitting one receipt event per directive (tagged source:'reviewer'):
8
+ *
9
+ * VERIFIED:<id> → type:'applied' (verified === honored)
10
+ * VIOLATED:<id> → type:'violated' (+ run any verification_predicate)
11
+ * N/A:<id> → type:'n_a' (neutral)
12
+ *
13
+ * Anti-spoofing: verdicts for IDs that were not in the verify-set are dropped.
14
+ * A CRITICAL directive the reviewer never addressed gets a synthetic
15
+ * `violated` / `reviewer_omitted` event. Fail-open: never throws.
16
+ */
17
+ import { type DirectiveToVerify } from '../agents/reviewer-directive-compliance.js';
18
+ export type ReviewerVerdict = 'verified' | 'violated' | 'n_a';
19
+ export interface ParsedReviewerVerdict {
20
+ id: string;
21
+ verdict: ReviewerVerdict;
22
+ /** evidence=... (VERIFIED/VIOLATED) or reason=... (N/A). */
23
+ evidence?: string;
24
+ }
25
+ /** Parse a reviewer transcript's DIRECTIVE_COMPLIANCE verdict lines. */
26
+ export declare function parseReviewerDirectiveCompliance(text: string): ParsedReviewerVerdict[];
27
+ export interface ReconcileReviewerVerdictsParams {
28
+ directory: string;
29
+ transcript: string;
30
+ directivesToVerify: DirectiveToVerify[];
31
+ sessionId?: string;
32
+ taskId?: string;
33
+ phase?: string;
34
+ agent?: string;
35
+ }
36
+ export interface ReconcileReviewerVerdictsResult {
37
+ emitted: Array<{
38
+ id: string;
39
+ type: string;
40
+ source: 'reviewer';
41
+ }>;
42
+ omittedCriticals: string[];
43
+ }
44
+ /**
45
+ * Reconcile reviewer verdicts against the verify-set and emit receipt events.
46
+ * Runs a directive's verification_predicate when the reviewer reports VIOLATED
47
+ * and the directive carries one. Never throws.
48
+ */
49
+ export declare function reconcileReviewerVerdicts(params: ReconcileReviewerVerdictsParams): Promise<ReconcileReviewerVerdictsResult>;
50
+ export interface ReviewerVerdictInput {
51
+ tool: unknown;
52
+ args?: unknown;
53
+ sessionID?: unknown;
54
+ }
55
+ export interface ReviewerVerdictOutput {
56
+ output?: unknown;
57
+ }
58
+ /**
59
+ * `tool.execute.after` adapter (Task 2.3). When a reviewer Task returns,
60
+ * recover the verify-set from the `<directives_to_verify>` block in its prompt
61
+ * (anti-spoofing), then reconcile the reviewer's DIRECTIVE_COMPLIANCE verdicts
62
+ * into knowledge events. No-op for non-reviewer delegations. Never throws.
63
+ */
64
+ export declare function collectReviewerVerdictsAfter(directory: string, input: ReviewerVerdictInput, output: ReviewerVerdictOutput): Promise<void>;
@@ -63,6 +63,35 @@ export interface SearchKnowledgeResult {
63
63
  trace_id: string;
64
64
  results: RankedEntry[];
65
65
  }
66
+ /**
67
+ * Age of an entry measured in distinct confirming phases (Change 5 / Task 6.2).
68
+ * A brand-new candidate (no confirmations) is age 0; an entry confirmed across
69
+ * many phases is "established" and no longer eligible for the cold-start
70
+ * exploration bonus. Falls back to the raw confirmation count when phase numbers
71
+ * are absent.
72
+ */
73
+ declare function entryAgePhases(e: {
74
+ confirmed_by?: Array<{
75
+ phase_number?: number;
76
+ }>;
77
+ }): number;
78
+ /** Clamp the MMR lambda to [0,1], default 0.5. */
79
+ declare function clampLambda(v: number | undefined): number;
80
+ /**
81
+ * Maximal Marginal Relevance rerank (Change 5, Task 6.1). Greedily selects from
82
+ * `pool` to fill up to `max` total (counting the already-selected `pinned`),
83
+ * trading relevance against diversity:
84
+ * mmr(c) = λ·relevance(c) − (1−λ)·max_{s∈selected} bigram_jaccard(lesson_c, lesson_s)
85
+ * Reuses `jaccardBigram` (no second similarity function). Deterministic: ties
86
+ * break by finalScore, then recency, then id, so a query with uniform paraphrase
87
+ * distance yields a stable order.
88
+ */
89
+ declare function mmrRerank<T extends {
90
+ id: string;
91
+ finalScore: number;
92
+ lesson: string;
93
+ created_at: string;
94
+ }>(pool: T[], pinned: T[], max: number, lambda: number): T[];
66
95
  /**
67
96
  * Run unified knowledge retrieval. Returns a trace_id (always minted, even when
68
97
  * no entries match) and the ranked results. Reading/scoring failures degrade to
@@ -71,4 +100,8 @@ export interface SearchKnowledgeResult {
71
100
  export declare function searchKnowledge(params: SearchKnowledgeParams): Promise<SearchKnowledgeResult>;
72
101
  export declare const _internals: {
73
102
  searchKnowledge: typeof searchKnowledge;
103
+ mmrRerank: typeof mmrRerank;
104
+ clampLambda: typeof clampLambda;
105
+ entryAgePhases: typeof entryAgePhases;
74
106
  };
107
+ export {};