opencode-swarm 7.10.0 → 7.11.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.
@@ -1,4 +1,5 @@
1
1
  import type { AgentConfig } from '@opencode-ai/sdk';
2
+ export type { AgentConfig };
2
3
  export interface AgentDefinition {
3
4
  name: string;
4
5
  description?: string;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * skill_improver agent — low-frequency, expensive-model improvement loop
3
+ * (issue #629).
4
+ *
5
+ * Default behaviour:
6
+ * - read-only access to knowledge / skills / spec / docs
7
+ * - quota-bounded LLM usage (skill_improve tool enforces .swarm/skill-improver-quota.json)
8
+ * - never mutates source code; default write_mode is "proposal"
9
+ * - architect must ask user before invoking, when require_user_approval=true
10
+ */
11
+ import type { AgentDefinition } from './architect.js';
12
+ export declare function createSkillImproverAgent(model: string, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * spec_writer agent — independent author/reviewer for `.swarm/spec.md`.
3
+ *
4
+ * Allows architect to remain on a cheap model while spec authoring runs on a
5
+ * higher-capability model. Architect delegates spec work explicitly.
6
+ */
7
+ import type { AgentDefinition } from './architect.js';
8
+ export declare function createSpecWriterAgent(model: string, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
package/dist/cli/index.js CHANGED
@@ -34,7 +34,7 @@ var package_default;
34
34
  var init_package = __esm(() => {
35
35
  package_default = {
36
36
  name: "opencode-swarm",
37
- version: "7.10.0",
37
+ version: "7.11.1",
38
38
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
39
39
  main: "dist/index.js",
40
40
  types: "dist/index.d.ts",
@@ -16054,7 +16054,14 @@ var init_tool_names = __esm(() => {
16054
16054
  "set_qa_gates",
16055
16055
  "web_search",
16056
16056
  "convene_general_council",
16057
- "write_final_council_evidence"
16057
+ "write_final_council_evidence",
16058
+ "skill_generate",
16059
+ "skill_list",
16060
+ "skill_apply",
16061
+ "skill_inspect",
16062
+ "skill_improve",
16063
+ "spec_write",
16064
+ "knowledge_ack"
16058
16065
  ];
16059
16066
  TOOL_NAME_SET = new Set(TOOL_NAMES);
16060
16067
  });
@@ -16110,6 +16117,8 @@ var init_constants = __esm(() => {
16110
16117
  "council_generalist",
16111
16118
  "council_skeptic",
16112
16119
  "council_domain_expert",
16120
+ "skill_improver",
16121
+ "spec_writer",
16113
16122
  ...QA_AGENTS,
16114
16123
  ...PIPELINE_AGENTS
16115
16124
  ];
@@ -16292,7 +16301,13 @@ var init_constants = __esm(() => {
16292
16301
  "set_qa_gates",
16293
16302
  "convene_general_council",
16294
16303
  "web_search",
16295
- "write_final_council_evidence"
16304
+ "write_final_council_evidence",
16305
+ "skill_generate",
16306
+ "skill_list",
16307
+ "skill_apply",
16308
+ "skill_inspect",
16309
+ "skill_improve",
16310
+ "knowledge_ack"
16296
16311
  ],
16297
16312
  explorer: [
16298
16313
  "complexity_hotspots",
@@ -16462,7 +16477,32 @@ var init_constants = __esm(() => {
16462
16477
  curator_phase: ["knowledge_recall"],
16463
16478
  council_generalist: [],
16464
16479
  council_skeptic: [],
16465
- council_domain_expert: []
16480
+ council_domain_expert: [],
16481
+ skill_improver: [
16482
+ "knowledge_recall",
16483
+ "knowledge_query",
16484
+ "skill_list",
16485
+ "skill_inspect",
16486
+ "skill_generate",
16487
+ "skill_improve",
16488
+ "search",
16489
+ "doc_scan",
16490
+ "doc_extract",
16491
+ "web_search"
16492
+ ],
16493
+ spec_writer: [
16494
+ "search",
16495
+ "knowledge_recall",
16496
+ "knowledge_query",
16497
+ "doc_scan",
16498
+ "doc_extract",
16499
+ "req_coverage",
16500
+ "lint_spec",
16501
+ "retrieve_summary",
16502
+ "symbols",
16503
+ "extract_code_blocks",
16504
+ "spec_write"
16505
+ ]
16466
16506
  };
16467
16507
  for (const [agentName, tools] of Object.entries(AGENT_TOOL_MAP)) {
16468
16508
  const invalidTools = tools.filter((tool) => !TOOL_NAME_SET.has(tool));
@@ -16526,6 +16566,14 @@ var init_constants = __esm(() => {
16526
16566
  curator_phase: {
16527
16567
  model: "opencode/gpt-5-nano",
16528
16568
  fallback_models: ["opencode/big-pickle"]
16569
+ },
16570
+ skill_improver: {
16571
+ model: "opencode/big-pickle",
16572
+ fallback_models: ["opencode/gpt-5-nano"]
16573
+ },
16574
+ spec_writer: {
16575
+ model: "opencode/big-pickle",
16576
+ fallback_models: ["opencode/gpt-5-nano"]
16529
16577
  }
16530
16578
  };
16531
16579
  });
@@ -16559,7 +16607,7 @@ function getCanonicalAgentRole(agentName, generatedAgentNames) {
16559
16607
  function stripKnownSwarmPrefix(agentName) {
16560
16608
  return getCanonicalAgentRole(agentName);
16561
16609
  }
16562
- var SEPARATORS, CANONICAL_ROLES_LONGEST_FIRST, CANONICAL_ROLES_SET, AgentOverrideConfigSchema, SwarmConfigSchema, HooksConfigSchema, ScoringWeightsSchema, DecisionDecaySchema, TokenRatiosSchema, ScoringConfigSchema, ContextBudgetConfigSchema, EvidenceConfigSchema, GateFeatureSchema, PlaceholderScanConfigSchema, QualityBudgetConfigSchema, GateConfigSchema, PipelineConfigSchema, PhaseCompleteConfigSchema, SummaryConfigSchema, ReviewPassesConfigSchema, AdversarialDetectionConfigSchema, AdversarialTestingConfigSchemaBase, AdversarialTestingConfigSchema, IntegrationAnalysisConfigSchema, DocsConfigSchema, UIReviewConfigSchema, CompactionAdvisoryConfigSchema, LintConfigSchema, SecretscanConfigSchema, GuardrailsProfileSchema, DEFAULT_AGENT_PROFILES, DEFAULT_ARCHITECT_PROFILE, GuardrailsConfigSchema, WatchdogConfigSchema, SelfReviewConfigSchema, ToolFilterConfigSchema, PlanCursorConfigSchema, CheckpointConfigSchema, AutomationModeSchema, AutomationCapabilitiesSchema, AutomationConfigSchemaBase, AutomationConfigSchema, KnowledgeConfigSchema, CuratorConfigSchema, SlopDetectorConfigSchema, IncrementalVerifyConfigSchema, CompactionConfigSchema, PrmConfigSchema, AgentAuthorityRuleSchema, AuthorityConfigSchema, GeneralCouncilMemberConfigSchema, GeneralCouncilConfigSchema, CouncilConfigSchema, ParallelizationConfigSchema, PluginConfigSchema;
16610
+ var SEPARATORS, CANONICAL_ROLES_LONGEST_FIRST, CANONICAL_ROLES_SET, AgentOverrideConfigSchema, SwarmConfigSchema, HooksConfigSchema, ScoringWeightsSchema, DecisionDecaySchema, TokenRatiosSchema, ScoringConfigSchema, ContextBudgetConfigSchema, EvidenceConfigSchema, GateFeatureSchema, PlaceholderScanConfigSchema, QualityBudgetConfigSchema, GateConfigSchema, PipelineConfigSchema, PhaseCompleteConfigSchema, SummaryConfigSchema, ReviewPassesConfigSchema, AdversarialDetectionConfigSchema, AdversarialTestingConfigSchemaBase, AdversarialTestingConfigSchema, IntegrationAnalysisConfigSchema, DocsConfigSchema, UIReviewConfigSchema, CompactionAdvisoryConfigSchema, LintConfigSchema, SecretscanConfigSchema, GuardrailsProfileSchema, DEFAULT_AGENT_PROFILES, DEFAULT_ARCHITECT_PROFILE, GuardrailsConfigSchema, WatchdogConfigSchema, SelfReviewConfigSchema, ToolFilterConfigSchema, PlanCursorConfigSchema, CheckpointConfigSchema, AutomationModeSchema, AutomationCapabilitiesSchema, AutomationConfigSchemaBase, AutomationConfigSchema, KnowledgeConfigSchema, CuratorConfigSchema, KnowledgeApplicationConfigSchema, SkillImproverConfigSchema, SpecWriterConfigSchema, SlopDetectorConfigSchema, IncrementalVerifyConfigSchema, CompactionConfigSchema, PrmConfigSchema, AgentAuthorityRuleSchema, AuthorityConfigSchema, GeneralCouncilMemberConfigSchema, GeneralCouncilConfigSchema, CouncilConfigSchema, ParallelizationConfigSchema, PluginConfigSchema;
16563
16611
  var init_schema = __esm(() => {
16564
16612
  init_zod();
16565
16613
  init_constants();
@@ -17000,6 +17048,7 @@ var init_schema = __esm(() => {
17000
17048
  low_utility_threshold: exports_external.number().min(0).max(1).default(0.3),
17001
17049
  min_retrievals_for_utility: exports_external.number().min(1).max(100).default(3),
17002
17050
  schema_version: exports_external.number().int().min(1).default(1),
17051
+ directive_min_confidence: exports_external.number().min(0).max(1).default(0.75),
17003
17052
  same_project_weight: exports_external.number().min(0).max(5).default(1),
17004
17053
  cross_project_weight: exports_external.number().min(0).max(5).default(0.5),
17005
17054
  min_encounter_score: exports_external.number().min(0).max(1).default(0.1),
@@ -17019,7 +17068,36 @@ var init_schema = __esm(() => {
17019
17068
  compliance_report: exports_external.boolean().default(true),
17020
17069
  suppress_warnings: exports_external.boolean().default(true),
17021
17070
  drift_inject_max_chars: exports_external.number().min(100).max(2000).default(500),
17022
- llm_timeout_ms: exports_external.number().int().min(5000).max(600000).default(300000)
17071
+ llm_timeout_ms: exports_external.number().int().min(5000).max(600000).default(300000),
17072
+ skill_generation_enabled: exports_external.boolean().default(true),
17073
+ skill_generation_mode: exports_external.enum(["draft", "active"]).default("draft"),
17074
+ min_skill_confidence: exports_external.number().min(0).max(1).default(0.85),
17075
+ min_skill_confirmations: exports_external.number().int().min(1).max(50).default(2)
17076
+ });
17077
+ KnowledgeApplicationConfigSchema = exports_external.object({
17078
+ enabled: exports_external.boolean().default(true),
17079
+ mode: exports_external.enum(["warn", "enforce"]).default("warn"),
17080
+ min_confidence: exports_external.number().min(0).max(1).default(0.85),
17081
+ critical_requires_ack: exports_external.boolean().default(true),
17082
+ require_skill_refs: exports_external.boolean().default(true)
17083
+ });
17084
+ SkillImproverConfigSchema = exports_external.object({
17085
+ enabled: exports_external.boolean().default(false),
17086
+ model: exports_external.string().nullable().default(null),
17087
+ fallback_models: exports_external.array(exports_external.string()).default([]),
17088
+ max_calls_per_day: exports_external.number().int().min(1).max(1000).default(10),
17089
+ trigger: exports_external.enum(["manual", "scheduled"]).default("manual"),
17090
+ targets: exports_external.array(exports_external.enum(["skills", "spec", "architect_prompt", "knowledge"])).default(["skills", "spec", "architect_prompt", "knowledge"]),
17091
+ write_mode: exports_external.enum(["proposal", "draft_skills"]).default("proposal"),
17092
+ require_user_approval: exports_external.boolean().default(true),
17093
+ quota_window: exports_external.enum(["utc", "local"]).default("utc"),
17094
+ allow_deterministic_fallback: exports_external.boolean().default(true)
17095
+ });
17096
+ SpecWriterConfigSchema = exports_external.object({
17097
+ enabled: exports_external.boolean().default(true),
17098
+ model: exports_external.string().nullable().default(null),
17099
+ fallback_models: exports_external.array(exports_external.string()).default([]),
17100
+ allow_spec_write: exports_external.boolean().default(true)
17023
17101
  });
17024
17102
  SlopDetectorConfigSchema = exports_external.object({
17025
17103
  enabled: exports_external.boolean().default(true),
@@ -17155,6 +17233,9 @@ var init_schema = __esm(() => {
17155
17233
  automation: AutomationConfigSchema.optional(),
17156
17234
  knowledge: KnowledgeConfigSchema.optional(),
17157
17235
  curator: CuratorConfigSchema.optional(),
17236
+ knowledge_application: KnowledgeApplicationConfigSchema.optional(),
17237
+ skill_improver: SkillImproverConfigSchema.optional(),
17238
+ spec_writer: SpecWriterConfigSchema.optional(),
17158
17239
  tool_output: exports_external.object({
17159
17240
  truncation_enabled: exports_external.boolean().default(true),
17160
17241
  max_lines: exports_external.number().min(10).max(500).default(150),
@@ -20705,6 +20786,10 @@ function resetSwarmState() {
20705
20786
  swarmState.opencodeClient = null;
20706
20787
  swarmState.curatorInitAgentNames = [];
20707
20788
  swarmState.curatorPhaseAgentNames = [];
20789
+ swarmState.skillImproverAgentNames = [];
20790
+ swarmState.specWriterAgentNames = [];
20791
+ swarmState.currentCriticalShownIds.clear();
20792
+ swarmState.knowledgeAckDedup.clear();
20708
20793
  swarmState.generatedAgentNames = [];
20709
20794
  _rehydrationCache = null;
20710
20795
  swarmState.fullAutoEnabledInConfig = false;
@@ -20750,6 +20835,10 @@ var init_state = __esm(() => {
20750
20835
  opencodeClient: null,
20751
20836
  curatorInitAgentNames: [],
20752
20837
  curatorPhaseAgentNames: [],
20838
+ skillImproverAgentNames: [],
20839
+ specWriterAgentNames: [],
20840
+ currentCriticalShownIds: new Map,
20841
+ knowledgeAckDedup: new Set,
20753
20842
  generatedAgentNames: [],
20754
20843
  lastBudgetPct: 0,
20755
20844
  agentSessions: defaultRunContext.agentSessions,
@@ -34810,13 +34899,59 @@ async function readKnowledge(filePath) {
34810
34899
  if (!trimmed)
34811
34900
  continue;
34812
34901
  try {
34813
- results.push(JSON.parse(trimmed));
34902
+ const raw = JSON.parse(trimmed);
34903
+ results.push(normalizeEntry(raw));
34814
34904
  } catch {
34815
34905
  console.warn(`[knowledge-store] Skipping corrupted JSONL line in ${filePath}: ${trimmed.slice(0, 80)}`);
34816
34906
  }
34817
34907
  }
34818
34908
  return results;
34819
34909
  }
34910
+ function normalizeEntry(raw) {
34911
+ if (!raw || typeof raw !== "object")
34912
+ return raw;
34913
+ const obj = raw;
34914
+ if (!("retrieval_outcomes" in obj))
34915
+ return raw;
34916
+ const ro = obj.retrieval_outcomes;
34917
+ if (ro && typeof ro === "object") {
34918
+ if (typeof ro.shown_count !== "number") {
34919
+ ro.shown_count = typeof ro.applied_count === "number" ? ro.applied_count : 0;
34920
+ }
34921
+ if (typeof ro.acknowledged_count !== "number")
34922
+ ro.acknowledged_count = 0;
34923
+ if (typeof ro.applied_explicit_count !== "number") {
34924
+ ro.applied_explicit_count = 0;
34925
+ }
34926
+ if (typeof ro.ignored_count !== "number")
34927
+ ro.ignored_count = 0;
34928
+ if (typeof ro.violated_count !== "number")
34929
+ ro.violated_count = 0;
34930
+ if (typeof ro.succeeded_after_shown_count !== "number") {
34931
+ ro.succeeded_after_shown_count = typeof ro.succeeded_after_count === "number" ? ro.succeeded_after_count : 0;
34932
+ }
34933
+ if (typeof ro.failed_after_shown_count !== "number") {
34934
+ ro.failed_after_shown_count = typeof ro.failed_after_count === "number" ? ro.failed_after_count : 0;
34935
+ }
34936
+ }
34937
+ const arrayFields = [
34938
+ "triggers",
34939
+ "required_actions",
34940
+ "forbidden_actions",
34941
+ "applies_to_agents",
34942
+ "applies_to_tools",
34943
+ "verification_checks",
34944
+ "source_refs",
34945
+ "source_knowledge_ids"
34946
+ ];
34947
+ for (const f of arrayFields) {
34948
+ const v = obj[f];
34949
+ if (v !== undefined && !Array.isArray(v)) {
34950
+ delete obj[f];
34951
+ }
34952
+ }
34953
+ return raw;
34954
+ }
34820
34955
  async function readRejectedLessons(directory) {
34821
34956
  return readKnowledge(resolveSwarmRejectedPath(directory));
34822
34957
  }
@@ -35189,7 +35324,7 @@ async function restoreEntry(directory, entryId) {
35189
35324
  }
35190
35325
  }
35191
35326
  }
35192
- var import_proper_lockfile4, DANGEROUS_COMMAND_PATTERNS, SECURITY_DEGRADING_PATTERNS, INVISIBLE_FORMAT_CHARS, INJECTION_PATTERNS, VALID_CATEGORIES, TECH_REFERENCE_WORDS, ACTION_VERB_WORDS, NEGATION_PAIRS;
35327
+ var import_proper_lockfile4, DANGEROUS_COMMAND_PATTERNS, SECURITY_DEGRADING_PATTERNS, INVISIBLE_FORMAT_CHARS, INJECTION_PATTERNS, VALID_CATEGORIES, TECH_REFERENCE_WORDS, ACTION_VERB_WORDS, NEGATION_PAIRS, VALID_DIRECTIVE_PRIORITIES;
35193
35328
  var init_knowledge_validator = __esm(() => {
35194
35329
  init_logger();
35195
35330
  init_knowledge_store();
@@ -35295,12 +35430,20 @@ var init_knowledge_validator = __esm(() => {
35295
35430
  ["use", "don't use"],
35296
35431
  ["recommended", "not recommended"]
35297
35432
  ];
35433
+ VALID_DIRECTIVE_PRIORITIES = new Set([
35434
+ "low",
35435
+ "medium",
35436
+ "high",
35437
+ "critical"
35438
+ ]);
35298
35439
  });
35299
35440
 
35300
35441
  // src/hooks/curator.ts
35301
35442
  var init_curator = __esm(() => {
35302
35443
  init_event_bus();
35444
+ init_schema();
35303
35445
  init_manager();
35446
+ init_state();
35304
35447
  init_bun_compat();
35305
35448
  init_logger();
35306
35449
  init_knowledge_store();
@@ -35565,11 +35708,11 @@ async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
35565
35708
  const foundInSwarm = new Set;
35566
35709
  for (const entry of entries) {
35567
35710
  if (shownIds.includes(entry.id)) {
35568
- entry.retrieval_outcomes.applied_count++;
35711
+ const ro = entry.retrieval_outcomes;
35569
35712
  if (phaseSucceeded) {
35570
- entry.retrieval_outcomes.succeeded_after_count++;
35713
+ ro.succeeded_after_shown_count = (ro.succeeded_after_shown_count ?? 0) + 1;
35571
35714
  } else {
35572
- entry.retrieval_outcomes.failed_after_count++;
35715
+ ro.failed_after_shown_count = (ro.failed_after_shown_count ?? 0) + 1;
35573
35716
  }
35574
35717
  updated = true;
35575
35718
  foundInSwarm.add(entry.id);
@@ -35589,11 +35732,11 @@ async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
35589
35732
  let hiveUpdated = false;
35590
35733
  for (const entry of hiveEntries) {
35591
35734
  if (remainingIds.includes(entry.id)) {
35592
- entry.retrieval_outcomes.applied_count++;
35735
+ const ro = entry.retrieval_outcomes;
35593
35736
  if (phaseSucceeded) {
35594
- entry.retrieval_outcomes.succeeded_after_count++;
35737
+ ro.succeeded_after_shown_count = (ro.succeeded_after_shown_count ?? 0) + 1;
35595
35738
  } else {
35596
- entry.retrieval_outcomes.failed_after_count++;
35739
+ ro.failed_after_shown_count = (ro.failed_after_shown_count ?? 0) + 1;
35597
35740
  }
35598
35741
  hiveUpdated = true;
35599
35742
  }
@@ -2,8 +2,8 @@ import type { ToolName } from '../tools/tool-names';
2
2
  export declare const QA_AGENTS: readonly ["reviewer", "critic", "critic_oversight"];
3
3
  export declare const PIPELINE_AGENTS: readonly ["explorer", "coder", "test_engineer"];
4
4
  export declare const ORCHESTRATOR_NAME: "architect";
5
- export declare const ALL_SUBAGENT_NAMES: readonly ["sme", "docs", "designer", "critic_sounding_board", "critic_drift_verifier", "critic_hallucination_verifier", "curator_init", "curator_phase", "council_generalist", "council_skeptic", "council_domain_expert", "reviewer", "critic", "critic_oversight", "explorer", "coder", "test_engineer"];
6
- export declare const ALL_AGENT_NAMES: readonly ["architect", "sme", "docs", "designer", "critic_sounding_board", "critic_drift_verifier", "critic_hallucination_verifier", "curator_init", "curator_phase", "council_generalist", "council_skeptic", "council_domain_expert", "reviewer", "critic", "critic_oversight", "explorer", "coder", "test_engineer"];
5
+ export declare const ALL_SUBAGENT_NAMES: readonly ["sme", "docs", "designer", "critic_sounding_board", "critic_drift_verifier", "critic_hallucination_verifier", "curator_init", "curator_phase", "council_generalist", "council_skeptic", "council_domain_expert", "skill_improver", "spec_writer", "reviewer", "critic", "critic_oversight", "explorer", "coder", "test_engineer"];
6
+ export declare const ALL_AGENT_NAMES: readonly ["architect", "sme", "docs", "designer", "critic_sounding_board", "critic_drift_verifier", "critic_hallucination_verifier", "curator_init", "curator_phase", "council_generalist", "council_skeptic", "council_domain_expert", "skill_improver", "spec_writer", "reviewer", "critic", "critic_oversight", "explorer", "coder", "test_engineer"];
7
7
  export declare const OPENCODE_NATIVE_AGENTS: Set<"compaction" | "title" | "build" | "general" | "plan" | "explore" | "summary">;
8
8
  export declare const CLAUDE_CODE_NATIVE_COMMANDS: ReadonlySet<string>;
9
9
  export type QAAgentName = (typeof QA_AGENTS)[number];
@@ -490,6 +490,7 @@ export declare const KnowledgeConfigSchema: z.ZodObject<{
490
490
  low_utility_threshold: z.ZodDefault<z.ZodNumber>;
491
491
  min_retrievals_for_utility: z.ZodDefault<z.ZodNumber>;
492
492
  schema_version: z.ZodDefault<z.ZodNumber>;
493
+ directive_min_confidence: z.ZodDefault<z.ZodNumber>;
493
494
  same_project_weight: z.ZodDefault<z.ZodNumber>;
494
495
  cross_project_weight: z.ZodDefault<z.ZodNumber>;
495
496
  min_encounter_score: z.ZodDefault<z.ZodNumber>;
@@ -511,8 +512,60 @@ export declare const CuratorConfigSchema: z.ZodObject<{
511
512
  suppress_warnings: z.ZodDefault<z.ZodBoolean>;
512
513
  drift_inject_max_chars: z.ZodDefault<z.ZodNumber>;
513
514
  llm_timeout_ms: z.ZodDefault<z.ZodNumber>;
515
+ skill_generation_enabled: z.ZodDefault<z.ZodBoolean>;
516
+ skill_generation_mode: z.ZodDefault<z.ZodEnum<{
517
+ draft: "draft";
518
+ active: "active";
519
+ }>>;
520
+ min_skill_confidence: z.ZodDefault<z.ZodNumber>;
521
+ min_skill_confirmations: z.ZodDefault<z.ZodNumber>;
514
522
  }, z.core.$strip>;
515
523
  export type CuratorConfig = z.infer<typeof CuratorConfigSchema>;
524
+ export declare const KnowledgeApplicationConfigSchema: z.ZodObject<{
525
+ enabled: z.ZodDefault<z.ZodBoolean>;
526
+ mode: z.ZodDefault<z.ZodEnum<{
527
+ enforce: "enforce";
528
+ warn: "warn";
529
+ }>>;
530
+ min_confidence: z.ZodDefault<z.ZodNumber>;
531
+ critical_requires_ack: z.ZodDefault<z.ZodBoolean>;
532
+ require_skill_refs: z.ZodDefault<z.ZodBoolean>;
533
+ }, z.core.$strip>;
534
+ export type KnowledgeApplicationConfig = z.infer<typeof KnowledgeApplicationConfigSchema>;
535
+ export declare const SkillImproverConfigSchema: z.ZodObject<{
536
+ enabled: z.ZodDefault<z.ZodBoolean>;
537
+ model: z.ZodDefault<z.ZodNullable<z.ZodString>>;
538
+ fallback_models: z.ZodDefault<z.ZodArray<z.ZodString>>;
539
+ max_calls_per_day: z.ZodDefault<z.ZodNumber>;
540
+ trigger: z.ZodDefault<z.ZodEnum<{
541
+ manual: "manual";
542
+ scheduled: "scheduled";
543
+ }>>;
544
+ targets: z.ZodDefault<z.ZodArray<z.ZodEnum<{
545
+ skills: "skills";
546
+ spec: "spec";
547
+ architect_prompt: "architect_prompt";
548
+ knowledge: "knowledge";
549
+ }>>>;
550
+ write_mode: z.ZodDefault<z.ZodEnum<{
551
+ proposal: "proposal";
552
+ draft_skills: "draft_skills";
553
+ }>>;
554
+ require_user_approval: z.ZodDefault<z.ZodBoolean>;
555
+ quota_window: z.ZodDefault<z.ZodEnum<{
556
+ utc: "utc";
557
+ local: "local";
558
+ }>>;
559
+ allow_deterministic_fallback: z.ZodDefault<z.ZodBoolean>;
560
+ }, z.core.$strip>;
561
+ export type SkillImproverConfig = z.infer<typeof SkillImproverConfigSchema>;
562
+ export declare const SpecWriterConfigSchema: z.ZodObject<{
563
+ enabled: z.ZodDefault<z.ZodBoolean>;
564
+ model: z.ZodDefault<z.ZodNullable<z.ZodString>>;
565
+ fallback_models: z.ZodDefault<z.ZodArray<z.ZodString>>;
566
+ allow_spec_write: z.ZodDefault<z.ZodBoolean>;
567
+ }, z.core.$strip>;
568
+ export type SpecWriterConfig = z.infer<typeof SpecWriterConfigSchema>;
516
569
  export declare const SlopDetectorConfigSchema: z.ZodObject<{
517
570
  enabled: z.ZodDefault<z.ZodBoolean>;
518
571
  classThreshold: z.ZodDefault<z.ZodNumber>;
@@ -985,6 +1038,7 @@ export declare const PluginConfigSchema: z.ZodObject<{
985
1038
  low_utility_threshold: z.ZodDefault<z.ZodNumber>;
986
1039
  min_retrievals_for_utility: z.ZodDefault<z.ZodNumber>;
987
1040
  schema_version: z.ZodDefault<z.ZodNumber>;
1041
+ directive_min_confidence: z.ZodDefault<z.ZodNumber>;
988
1042
  same_project_weight: z.ZodDefault<z.ZodNumber>;
989
1043
  cross_project_weight: z.ZodDefault<z.ZodNumber>;
990
1044
  min_encounter_score: z.ZodDefault<z.ZodNumber>;
@@ -1005,6 +1059,55 @@ export declare const PluginConfigSchema: z.ZodObject<{
1005
1059
  suppress_warnings: z.ZodDefault<z.ZodBoolean>;
1006
1060
  drift_inject_max_chars: z.ZodDefault<z.ZodNumber>;
1007
1061
  llm_timeout_ms: z.ZodDefault<z.ZodNumber>;
1062
+ skill_generation_enabled: z.ZodDefault<z.ZodBoolean>;
1063
+ skill_generation_mode: z.ZodDefault<z.ZodEnum<{
1064
+ draft: "draft";
1065
+ active: "active";
1066
+ }>>;
1067
+ min_skill_confidence: z.ZodDefault<z.ZodNumber>;
1068
+ min_skill_confirmations: z.ZodDefault<z.ZodNumber>;
1069
+ }, z.core.$strip>>;
1070
+ knowledge_application: z.ZodOptional<z.ZodObject<{
1071
+ enabled: z.ZodDefault<z.ZodBoolean>;
1072
+ mode: z.ZodDefault<z.ZodEnum<{
1073
+ enforce: "enforce";
1074
+ warn: "warn";
1075
+ }>>;
1076
+ min_confidence: z.ZodDefault<z.ZodNumber>;
1077
+ critical_requires_ack: z.ZodDefault<z.ZodBoolean>;
1078
+ require_skill_refs: z.ZodDefault<z.ZodBoolean>;
1079
+ }, z.core.$strip>>;
1080
+ skill_improver: z.ZodOptional<z.ZodObject<{
1081
+ enabled: z.ZodDefault<z.ZodBoolean>;
1082
+ model: z.ZodDefault<z.ZodNullable<z.ZodString>>;
1083
+ fallback_models: z.ZodDefault<z.ZodArray<z.ZodString>>;
1084
+ max_calls_per_day: z.ZodDefault<z.ZodNumber>;
1085
+ trigger: z.ZodDefault<z.ZodEnum<{
1086
+ manual: "manual";
1087
+ scheduled: "scheduled";
1088
+ }>>;
1089
+ targets: z.ZodDefault<z.ZodArray<z.ZodEnum<{
1090
+ skills: "skills";
1091
+ spec: "spec";
1092
+ architect_prompt: "architect_prompt";
1093
+ knowledge: "knowledge";
1094
+ }>>>;
1095
+ write_mode: z.ZodDefault<z.ZodEnum<{
1096
+ proposal: "proposal";
1097
+ draft_skills: "draft_skills";
1098
+ }>>;
1099
+ require_user_approval: z.ZodDefault<z.ZodBoolean>;
1100
+ quota_window: z.ZodDefault<z.ZodEnum<{
1101
+ utc: "utc";
1102
+ local: "local";
1103
+ }>>;
1104
+ allow_deterministic_fallback: z.ZodDefault<z.ZodBoolean>;
1105
+ }, z.core.$strip>>;
1106
+ spec_writer: z.ZodOptional<z.ZodObject<{
1107
+ enabled: z.ZodDefault<z.ZodBoolean>;
1108
+ model: z.ZodDefault<z.ZodNullable<z.ZodString>>;
1109
+ fallback_models: z.ZodDefault<z.ZodArray<z.ZodString>>;
1110
+ allow_spec_write: z.ZodDefault<z.ZodBoolean>;
1008
1111
  }, z.core.$strip>>;
1009
1112
  tool_output: z.ZodOptional<z.ZodObject<{
1010
1113
  truncation_enabled: z.ZodDefault<z.ZodBoolean>;
@@ -94,6 +94,31 @@ export interface CuratorPhaseResult {
94
94
  compliance: ComplianceObservation[];
95
95
  knowledge_recommendations: KnowledgeRecommendation[];
96
96
  summary_updated: boolean;
97
+ /** v2: per-knowledge-entry application audit (applied/ignored/violated/n/a). */
98
+ knowledge_application_findings?: KnowledgeApplicationFinding[];
99
+ /** v2: candidate clusters the curator suggests compiling into SKILL.md. */
100
+ skill_candidates?: SkillCandidate[];
101
+ }
102
+ /** v2: machine-typed audit produced by the curator after each phase. */
103
+ export interface KnowledgeApplicationFinding {
104
+ knowledge_id: string;
105
+ expected_behavior: string;
106
+ observed_behavior: string;
107
+ verdict: 'applied' | 'ignored' | 'violated' | 'not_applicable';
108
+ evidence_refs: string[];
109
+ }
110
+ /** v2: skill cluster proposal emitted by the curator. */
111
+ export interface SkillCandidate {
112
+ slug: string;
113
+ title: string;
114
+ source_knowledge_ids: string[];
115
+ trigger: string;
116
+ required_procedure: string[];
117
+ forbidden_shortcuts: string[];
118
+ target_agents: string[];
119
+ reviewer_checks: string[];
120
+ confidence: number;
121
+ reason: string;
97
122
  }
98
123
  export interface CriticDriftResult {
99
124
  phase: number;
@@ -48,6 +48,26 @@ export declare const _internals: {
48
48
  * Action hints are extracted from parenthetical directives like "(suggests boost confidence, mark hive_eligible)"
49
49
  */
50
50
  export declare function parseKnowledgeRecommendations(llmOutput: string): KnowledgeRecommendation[];
51
+ /**
52
+ * v2: Strict-JSON parser for the new curator output blocks.
53
+ *
54
+ * Curator prompts may now emit JSON-fenced blocks like:
55
+ *
56
+ * ```json knowledge_application_findings
57
+ * [{ "knowledge_id": "...", "expected_behavior": "...", ... }]
58
+ * ```
59
+ *
60
+ * ```json skill_candidates
61
+ * [{ "slug": "...", "title": "...", ... }]
62
+ * ```
63
+ *
64
+ * Malformed JSON or unexpected types are silently dropped: no knowledge or
65
+ * skill writes happen when curator output is malformed.
66
+ */
67
+ export declare function parseStructuredCuratorBlocks(llmOutput: string): {
68
+ findings: import('./curator-types.js').KnowledgeApplicationFinding[];
69
+ candidates: import('./curator-types.js').SkillCandidate[];
70
+ };
51
71
  /**
52
72
  * Read curator summary from .swarm/curator-summary.json
53
73
  * @param directory - The workspace directory
@@ -61,7 +81,19 @@ export declare function readCuratorSummary(directory: string): Promise<CuratorSu
61
81
  */
62
82
  export declare function writeCuratorSummary(directory: string, summary: CuratorSummary): Promise<void>;
63
83
  /**
64
- * Normalize agent name by stripping common swarm prefixes.
84
+ * Normalize an agent name to its canonical role.
85
+ *
86
+ * v2 (Phase F′ remediation): use the repository's canonical resolver
87
+ * `getCanonicalAgentRole`, registry-aware. When the generated-agent registry
88
+ * is populated (post plugin-init), an arbitrary swarm id like
89
+ * `banana_coder` resolves to `coder` IFF it appears in the registry.
90
+ * Pre-init (registry empty), the resolver falls back to a permissive
91
+ * suffix-match against ALL_AGENT_NAMES — preserving today's behaviour for
92
+ * arbitrary user prefixes without the hard-coded
93
+ * `(mega|paid|local|lowtier|modelrelay)_` whitelist.
94
+ *
95
+ * Lower-casing is preserved for backwards compatibility with the prior
96
+ * comparator code paths in this file.
65
97
  */
66
98
  declare function normalizeAgentName(name: string): string;
67
99
  /**
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Runtime wiring for the knowledge application contract.
3
+ *
4
+ * Two integration points:
5
+ *
6
+ * 1. `experimental.chat.messages.transform` — scans the latest
7
+ * architect-authored message for `KNOWLEDGE_APPLIED|IGNORED|VIOLATED`
8
+ * markers and records them via `recordAcknowledgmentDeduped`. This
9
+ * runs BEFORE the architect's next tool call so the toolBefore gate
10
+ * sees the ack.
11
+ *
12
+ * 2. `tool.execute.before` (FAIL-CLOSED chain at src/index.ts) — when a
13
+ * high-risk tool fires and the calling agent is the architect,
14
+ * consults `swarmState.currentCriticalShownIds` and the audit log to
15
+ * assemble the set of critical directives that have been shown but
16
+ * not acknowledged. In `mode: 'enforce'` it THROWS to block the
17
+ * action (per the FAIL-CLOSED contract — `output.error` is NOT a
18
+ * write API at toolBefore time). In `mode: 'warn'` it appends to
19
+ * `events.jsonl` and lets the action proceed.
20
+ *
21
+ * Tools considered high-risk:
22
+ * - save_plan
23
+ * - update_task_status
24
+ * - phase_complete
25
+ * - Task (delegations to coder/reviewer/test_engineer/sme/docs/designer)
26
+ *
27
+ * Non-architect agents are never gated.
28
+ */
29
+ import { type KnowledgeApplicationConfig } from './knowledge-application.js';
30
+ import type { MessageWithParts } from './knowledge-types.js';
31
+ /** Tools that require knowledge-directive acknowledgment before execution. */
32
+ export declare const HIGH_RISK_TOOLS: Set<string>;
33
+ export interface GateInput {
34
+ tool: unknown;
35
+ agent?: unknown;
36
+ sessionID?: unknown;
37
+ }
38
+ /**
39
+ * Pre-tool gate. Throws when the architect attempts a high-risk action with
40
+ * an unacknowledged critical directive in `enforce` mode. Always returns in
41
+ * `warn` mode (with a side-effect events.jsonl write).
42
+ */
43
+ export declare function knowledgeApplicationGateBefore(directory: string, input: GateInput, config: KnowledgeApplicationConfig): Promise<void>;
44
+ declare function writeWarnEvent(directory: string, record: Record<string, unknown>): Promise<void>;
45
+ /**
46
+ * Compose into `experimental.chat.messages.transform`. Scans the most recent
47
+ * `role: 'user'`-shaped architect message for ack markers (per
48
+ * `full-auto-intercept.ts` pattern: architect outputs appear as user role)
49
+ * and records each via `recordAcknowledgmentDeduped`. Best-effort: never
50
+ * throws; never mutates the messages array.
51
+ */
52
+ export declare function knowledgeApplicationTransformScan(directory: string, output: {
53
+ messages?: MessageWithParts[];
54
+ }, sessionID?: string): Promise<void>;
55
+ export declare const _internals: {
56
+ knowledgeApplicationGateBefore: typeof knowledgeApplicationGateBefore;
57
+ knowledgeApplicationTransformScan: typeof knowledgeApplicationTransformScan;
58
+ HIGH_RISK_TOOLS: Set<string>;
59
+ writeWarnEvent: typeof writeWarnEvent;
60
+ };
61
+ export {};