progmune-runtime 2.1.6 → 3.2.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 (356) hide show
  1. package/README.md +108 -468
  2. package/dist/ablation-study.js +144 -0
  3. package/dist/ablation-study.test.js +18 -0
  4. package/dist/action-runtime.js +3 -1
  5. package/dist/active-learning.js +211 -0
  6. package/dist/analytics.js +139 -0
  7. package/dist/asset-factory.js +309 -0
  8. package/dist/asset-growth.js +244 -0
  9. package/dist/asset-promotion.js +382 -0
  10. package/dist/asset-quality.js +550 -0
  11. package/dist/audit/business-translator.js +285 -0
  12. package/dist/audit/cli.js +66 -0
  13. package/dist/audit/formatters/html.js +379 -0
  14. package/dist/audit/formatters/json.js +11 -0
  15. package/dist/audit/formatters/markdown.js +192 -0
  16. package/dist/audit/formatters/terminal.js +189 -0
  17. package/dist/audit/index.js +25 -0
  18. package/dist/audit/report-builder.js +318 -0
  19. package/dist/audit/types.js +8 -0
  20. package/dist/audit.js +3 -3
  21. package/dist/auto-benchmark-generator.js +137 -0
  22. package/dist/auto-benchmark-generator.test.js +45 -0
  23. package/dist/auto-protocol-synthesizer.js +362 -0
  24. package/dist/auto-protocol-synthesizer.test.js +82 -0
  25. package/dist/autonomous-patch.js +175 -0
  26. package/dist/autonomous-patch.test.js +128 -0
  27. package/dist/badge/badge-server.js +98 -0
  28. package/dist/behavior-miner.js +442 -0
  29. package/dist/belief-layer.js +475 -0
  30. package/dist/benchmark-count.js +5 -0
  31. package/dist/benchmark-generator.js +211 -0
  32. package/dist/benchmark-harness.js +201 -0
  33. package/dist/benchmark-pass-rate.js +7 -0
  34. package/dist/benchmark-report.js +8 -3
  35. package/dist/benchmark-save.js +14 -1
  36. package/dist/bootstrap-validation.js +197 -0
  37. package/dist/bootstrap-validation.test.js +51 -0
  38. package/dist/branch-ledger.js +1 -1
  39. package/dist/capability-gap.js +130 -0
  40. package/dist/certify-html.js +351 -0
  41. package/dist/certify.js +326 -0
  42. package/dist/check.js +4 -4
  43. package/dist/compliance-miner.js +447 -0
  44. package/dist/continuous-benchmark.js +194 -0
  45. package/dist/continuous-benchmark.test.js +116 -0
  46. package/dist/corpus-stats.js +173 -0
  47. package/dist/counterfactual-engine.js +288 -0
  48. package/dist/coverage-dashboard.js +109 -0
  49. package/dist/coverage-system.test.js +205 -0
  50. package/dist/cross-repo-precision.js +352 -0
  51. package/dist/cve-benchmark.js +180 -0
  52. package/dist/cve-benchmark.test.js +28 -0
  53. package/dist/cve-collector.js +73 -0
  54. package/dist/data-quality.js +141 -0
  55. package/dist/decision-engine.js +388 -0
  56. package/dist/derive-metadata.js +250 -0
  57. package/dist/difficulty-active.test.js +198 -0
  58. package/dist/difficulty-map.js +244 -0
  59. package/dist/discovery-analytics.js +125 -0
  60. package/dist/discovery-model.js +149 -0
  61. package/dist/discovery-optimize.test.js +199 -0
  62. package/dist/discovery-trace.js +276 -0
  63. package/dist/discovery-trace.test.js +97 -0
  64. package/dist/emitter.js +83 -1
  65. package/dist/enterprise-dashboard.js +405 -0
  66. package/dist/eval-hardening.js +297 -0
  67. package/dist/eval-hardening.test.js +85 -0
  68. package/dist/evaluation-campaign.js +359 -0
  69. package/dist/evaluation-campaign.test.js +181 -0
  70. package/dist/evidence-growth.js +143 -0
  71. package/dist/evidence-repository.js +209 -0
  72. package/dist/evidence-system.js +441 -0
  73. package/dist/execute.js +15 -7
  74. package/dist/experimental/software-physics.js +291 -0
  75. package/dist/experimental/state-inference.js +516 -0
  76. package/dist/experimental/unsupervised-physics.js +230 -0
  77. package/dist/extract-ir-python.js +54 -7
  78. package/dist/extract-ir.js +376 -12
  79. package/dist/failure-collector.js +2 -2
  80. package/dist/failure-corpus.js +322 -9
  81. package/dist/feedback.js +16 -5
  82. package/dist/feedback.test.js +49 -0
  83. package/dist/file-lock.js +1 -1
  84. package/dist/flywheel-batch.js +292 -0
  85. package/dist/frameworks/express-cli.js +237 -0
  86. package/dist/frameworks/express-detector.js +445 -0
  87. package/dist/frameworks/express-detector.test.js +206 -0
  88. package/dist/frameworks/index.js +30 -0
  89. package/dist/frameworks/nestjs-detector.js +302 -0
  90. package/dist/frameworks/trpc-detector.js +161 -0
  91. package/dist/frameworks/version-awareness.js +179 -0
  92. package/dist/function-synonyms.js +164 -0
  93. package/dist/function-synonyms.test.js +68 -0
  94. package/dist/generalization.test.js +352 -0
  95. package/dist/goal-annotator.js +113 -0
  96. package/dist/goal-planner.js +563 -0
  97. package/dist/gold-cve.js +164 -0
  98. package/dist/gold-cve.test.js +104 -0
  99. package/dist/gold-quality.js +206 -0
  100. package/dist/gold-tiers.js +241 -0
  101. package/dist/governance-dashboard.js +327 -0
  102. package/dist/graph-viz.js +240 -0
  103. package/dist/guided-frontier.js +195 -0
  104. package/dist/hierarchical-planner.js +148 -0
  105. package/dist/identifier-parser.js +260 -0
  106. package/dist/immune-metrics.js +93 -0
  107. package/dist/immune-receiver.js +158 -0
  108. package/dist/immune-reporter.js +1 -1
  109. package/dist/improvement-orchestrator.js +206 -0
  110. package/dist/inject-p0-vocabulary.js +300 -0
  111. package/dist/intent-parser.js +218 -0
  112. package/dist/invariant-algebra.js +476 -0
  113. package/dist/invariant-calculus.js +533 -0
  114. package/dist/ir-utils.js +70 -0
  115. package/dist/ir-utils.test.js +50 -0
  116. package/dist/knowledge-api.js +312 -0
  117. package/dist/knowledge-evolution.js +452 -0
  118. package/dist/knowledge-explorer.js +506 -0
  119. package/dist/knowledge-flywheel.js +274 -0
  120. package/dist/knowledge-governance.js +338 -0
  121. package/dist/knowledge-governance.test.js +150 -0
  122. package/dist/knowledge-graph.js +181 -0
  123. package/dist/knowledge-guided-synth.js +246 -0
  124. package/dist/knowledge-loop.test.js +77 -0
  125. package/dist/knowledge-object.js +316 -0
  126. package/dist/knowledge-package.js +98 -0
  127. package/dist/kpi-dashboard.js +561 -0
  128. package/dist/l3-cross-function.js +280 -0
  129. package/dist/learning-ranker.js +148 -0
  130. package/dist/learning-ranker.test.js +291 -0
  131. package/dist/ledger/accountability.js +322 -0
  132. package/dist/ledger/chain-builder.js +185 -0
  133. package/dist/ledger/cli.js +222 -0
  134. package/dist/ledger/index.js +13 -0
  135. package/dist/ledger/signatures.js +193 -0
  136. package/dist/ledger/types.js +9 -0
  137. package/dist/llm.js +74 -3
  138. package/dist/load-benchmarks.js +8 -3
  139. package/dist/logger.js +66 -0
  140. package/dist/logger.test.js +37 -0
  141. package/dist/logistic-reward.js +339 -0
  142. package/dist/logistic-reward.test.js +180 -0
  143. package/dist/macro-graph.js +193 -0
  144. package/dist/macro-repair.js +183 -0
  145. package/dist/mcp-server.mjs +1202 -483
  146. package/dist/memory-layer.js +42 -5
  147. package/dist/multi-repo-precision.js +422 -0
  148. package/dist/name-free-protocol.js +425 -0
  149. package/dist/name-free-protocol.test.js +170 -0
  150. package/dist/name-scrambling.js +138 -0
  151. package/dist/name-scrambling.test.js +16 -0
  152. package/dist/p3-observability.test.js +281 -0
  153. package/dist/p5-orchestrator.test.js +225 -0
  154. package/dist/pairwise-preference.js +294 -0
  155. package/dist/pairwise-preference.test.js +140 -0
  156. package/dist/planner-constraints.js +104 -0
  157. package/dist/planner-prompts.js +155 -0
  158. package/dist/planner-telemetry.js +415 -0
  159. package/dist/planner-trace.js +214 -0
  160. package/dist/planner.js +162 -167
  161. package/dist/plsb/artifact.js +116 -0
  162. package/dist/plsb/cli.js +71 -0
  163. package/dist/plsb/index.js +19 -0
  164. package/dist/plsb/leaderboard.js +249 -0
  165. package/dist/plsb/report-md.js +156 -0
  166. package/dist/plsb/schema.js +179 -0
  167. package/dist/plsb-benchmark.js +284 -0
  168. package/dist/plsb-benchmark.test.js +119 -0
  169. package/dist/policy/cli.js +134 -0
  170. package/dist/policy/engine.js +333 -0
  171. package/dist/policy/index.js +12 -0
  172. package/dist/policy/types.js +59 -0
  173. package/dist/policy-miner.js +505 -0
  174. package/dist/precision-analyze.js +229 -0
  175. package/dist/precision-benchmark.js +147 -0
  176. package/dist/precision-label-c.js +134 -0
  177. package/dist/precision-label.js +193 -0
  178. package/dist/precision-report-c.js +149 -0
  179. package/dist/precision-report.js +246 -0
  180. package/dist/progmune-status.js +108 -0
  181. package/dist/proof-engine.js +479 -0
  182. package/dist/proof-provenance.js +315 -0
  183. package/dist/protocol-coverage.js +294 -0
  184. package/dist/protocol-detector.js +1189 -0
  185. package/dist/protocol-embedding-expanded.js +297 -0
  186. package/dist/protocol-embedding-expanded.test.js +97 -0
  187. package/dist/protocol-embedding.js +195 -0
  188. package/dist/protocol-embedding.test.js +82 -0
  189. package/dist/protocol-extractor-v2.js +354 -0
  190. package/dist/protocol-extractor-v2.test.js +140 -0
  191. package/dist/protocol-extractor.js +310 -0
  192. package/dist/protocol-extractor.test.js +113 -0
  193. package/dist/protocol-foundation.js +322 -0
  194. package/dist/protocol-foundation.test.js +163 -0
  195. package/dist/protocol-frontier.js +243 -0
  196. package/dist/protocol-frontier.test.js +92 -0
  197. package/dist/protocol-gap-analyzer.js +228 -0
  198. package/dist/protocol-gap-analyzer.test.js +49 -0
  199. package/dist/protocol-invariants.js +276 -0
  200. package/dist/protocol-invariants.test.js +111 -0
  201. package/dist/protocol-knowledge.js +464 -0
  202. package/dist/protocol-miner.js +343 -0
  203. package/dist/protocol-mining.js +207 -0
  204. package/dist/protocol-mining.test.js +37 -0
  205. package/dist/protocol-registry.js +1 -1
  206. package/dist/protocol-security-benchmark.js +222 -0
  207. package/dist/protocol-vulnerability.js +257 -0
  208. package/dist/protocol-vulnerability.test.js +60 -0
  209. package/dist/python-benchmark.js +120 -0
  210. package/dist/python-emitter.js +163 -45
  211. package/dist/python-protocol-extractor.js +187 -0
  212. package/dist/python-protocol-extractor.test.js +116 -0
  213. package/dist/realworld-benchmark.js +646 -0
  214. package/dist/realworld-benchmark.test.js +36 -0
  215. package/dist/repair-arch.test.js +411 -0
  216. package/dist/repair-evolution.test.js +454 -0
  217. package/dist/repair-executor.js +719 -0
  218. package/dist/repair-proposal.js +4 -4
  219. package/dist/repair-ranker.js +141 -0
  220. package/dist/repair-strategies.js +419 -0
  221. package/dist/repair-taxonomy.js +234 -0
  222. package/dist/repair-types.js +12 -0
  223. package/dist/repo-evaluator.js +250 -0
  224. package/dist/repo-evaluator.test.js +128 -0
  225. package/dist/resource-abstraction.js +242 -0
  226. package/dist/resource-detector.js +211 -0
  227. package/dist/result.test.js +43 -0
  228. package/dist/reward-system.js +411 -0
  229. package/dist/reward-system.test.js +175 -0
  230. package/dist/risk-model.js +215 -0
  231. package/dist/rule-miner.js +234 -7
  232. package/dist/rule-specificity.js +254 -0
  233. package/dist/runtime-types.js +27 -0
  234. package/dist/scaffold.js +208 -0
  235. package/dist/scale-collector.test.js +101 -0
  236. package/dist/scale-trajectory-collector.js +128 -0
  237. package/dist/sdk.js +250 -0
  238. package/dist/search-planner.js +4 -41
  239. package/dist/semantic-snapshot.js +1 -1
  240. package/dist/semantic-topology.js +121 -0
  241. package/dist/semantic-trace.js +310 -317
  242. package/dist/sequence-extractor.js +343 -0
  243. package/dist/skill-library.js +245 -0
  244. package/dist/skill-planner.test.js +189 -0
  245. package/dist/software-physics.js +291 -0
  246. package/dist/software-physics.test.js +81 -0
  247. package/dist/ssg-precision.js +478 -0
  248. package/dist/ssg-validator.js +71 -21
  249. package/dist/state-inference-doubleblind.test.js +160 -0
  250. package/dist/state-inference.js +516 -0
  251. package/dist/state-inference.test.js +115 -0
  252. package/dist/state-machine-fingerprint.js +345 -0
  253. package/dist/state-machine-fingerprint.test.js +120 -0
  254. package/dist/state-miner.js +386 -0
  255. package/dist/state-name-inference.js +213 -0
  256. package/dist/state-name-inference.test.js +69 -0
  257. package/dist/strategy-planner.js +262 -96
  258. package/dist/strategy-planner.test.js +135 -0
  259. package/dist/telemetry-analytics.test.js +402 -0
  260. package/dist/terminal-format.js +68 -0
  261. package/dist/terminal-format.test.js +83 -0
  262. package/dist/topology-factory.js +196 -0
  263. package/dist/topology-representation.js +242 -0
  264. package/dist/topology-representation.test.js +27 -0
  265. package/dist/trajectory-augmentation.js +254 -0
  266. package/dist/trajectory-augmentation.test.js +63 -0
  267. package/dist/trajectory-corpus.js +440 -0
  268. package/dist/trajectory-corpus.test.js +32 -0
  269. package/dist/trajectory-feedback.test.js +116 -0
  270. package/dist/transition-synthesizer.js +286 -0
  271. package/dist/transition-synthesizer.test.js +123 -0
  272. package/dist/trust/api-semantic-mapper.js +809 -0
  273. package/dist/trust/call-graph-propagator.js +225 -0
  274. package/dist/trust/cli.js +122 -0
  275. package/dist/trust/compliance-scorer.js +283 -0
  276. package/dist/trust/confidence-calculator.js +261 -0
  277. package/dist/trust/engine.js +1145 -0
  278. package/dist/trust/explainability.js +85 -0
  279. package/dist/trust/formatters/ci.js +42 -0
  280. package/dist/trust/formatters/json.js +11 -0
  281. package/dist/trust/formatters/terminal.js +152 -0
  282. package/dist/trust/index.js +39 -0
  283. package/dist/trust/phase1-verify.js +171 -0
  284. package/dist/trust/protocol-domain-validator.js +697 -0
  285. package/dist/trust/score-calculator.js +282 -0
  286. package/dist/trust/ssg-bridge.js +641 -0
  287. package/dist/trust/ssg-bridge.test.js +269 -0
  288. package/dist/trust/types.js +67 -0
  289. package/dist/trust/violation-trace.js +335 -0
  290. package/dist/trust-api.js +179 -0
  291. package/dist/trust-calibration.js +279 -0
  292. package/dist/unknown-protocol-discovery.js +339 -0
  293. package/dist/unknown-protocol-discovery.test.js +102 -0
  294. package/dist/unsupervised-physics.js +230 -0
  295. package/dist/unsupervised-physics.test.js +95 -0
  296. package/dist/utils.test.js +37 -0
  297. package/dist/validator.js +187 -10
  298. package/dist/verification-intelligence.js +475 -0
  299. package/dist/verify-api.js +432 -0
  300. package/dist/vi-impact-report.js +293 -0
  301. package/dist/wl-fingerprint.js +162 -0
  302. package/dist/wl-fingerprint.test.js +130 -0
  303. package/dist/zeroshot-strategy.js +139 -0
  304. package/docs/Progmune_/346/212/225/350/265/204/344/272/272/347/231/275/347/232/256/344/271/246_v2.0.html +576 -0
  305. package/docs/Progmune_/351/241/271/347/233/256/345/205/250/350/247/243.html +710 -0
  306. package/package.json +74 -7
  307. package/protocols.json +1956 -50
  308. package/.dockerignore +0 -14
  309. package/.mcp.json +0 -11
  310. package/.progmune_allowlist +0 -50
  311. package/.test_report/test_report.md +0 -87
  312. package/Dockerfile +0 -9
  313. package/FAQ.md +0 -167
  314. package/WHITEPAPER.md +0 -540
  315. package/demo-project/auth.ts +0 -55
  316. package/demo-project/tsconfig.json +0 -8
  317. package/dist/acl-breakdown.js +0 -13
  318. package/dist/all-sessions.js +0 -11
  319. package/dist/antibody-stats.js +0 -11
  320. package/dist/branch-tree-count.js +0 -14
  321. package/dist/common-fixpath.js +0 -12
  322. package/dist/constraint-types.js +0 -12
  323. package/dist/exec-metrics.js +0 -11
  324. package/dist/failure-report.js +0 -11
  325. package/dist/fast-path-hits.js +0 -13
  326. package/dist/fingerprint-list.js +0 -15
  327. package/dist/gen-history-log.js +0 -13
  328. package/dist/heatmap-data.js +0 -11
  329. package/dist/recent-session.js +0 -12
  330. package/dist/svl-distribution.js +0 -11
  331. package/dist/terminal-status.js +0 -11
  332. package/dist/token-savings.js +0 -11
  333. package/dist/total-repairs.js +0 -12
  334. package/dist/unresolved-count.js +0 -12
  335. package/dist/valid-fingerprints.js +0 -13
  336. package/dist/verify-ledgers.js +0 -11
  337. package/docs/whitepaper-style.css +0 -77
  338. package/docs/whitepaper-v2.1.md +0 -609
  339. package/docs/whitepaper-v2.2.md +0 -1064
  340. package/docs/whitepaper-v2.2.pdf +0 -0
  341. package/fly.toml +0 -31
  342. package/public/dashboard.html +0 -119
  343. package/server/hub.js +0 -116
  344. package/test/replay-golden/sess_1780063202050_mgeld.json +0 -9
  345. package/test/replay-golden/sess_1780064032560_gocld.json +0 -354
  346. package/test/replay-golden/sess_1780064413331_s2709.json +0 -606
  347. package/test/replay-golden/sess_1780064792710_y3avo.json +0 -614
  348. package/test/replay-golden.ts +0 -84
  349. package/test_benchmark.js +0 -165
  350. package/test_comprehensive.mjs +0 -638
  351. package/test_concurrency.js +0 -129
  352. package/test_ir_robustness.js +0 -85
  353. package/test_semantic_contracts.js +0 -269
  354. package/test_ssg_stress.js +0 -156
  355. package/test_svl3.js +0 -58
  356. package/tsconfig.json +0 -17
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ /**
3
+ * P1: Goal Skeleton — Async Goal Annotator
4
+ *
5
+ * Converts natural language goals to structured GoalRecords via LLM.
6
+ * Non-blocking, best-effort, 500ms timeout. Falls back to keyword extraction
7
+ * on failure. This is a DATA FLYWHEEL, not a reasoning system.
8
+ *
9
+ * Principle: collect (goal, trajectory, outcome) pairs now,
10
+ * mine Goal Graphs from data later.
11
+ *
12
+ * @requires GOAL_TEXT @produces GOAL_RECORD
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.annotateGoal = annotateGoal;
16
+ exports.annotateGoalBackground = annotateGoalBackground;
17
+ const llm_1 = require("./llm");
18
+ const intent_parser_1 = require("./intent-parser");
19
+ const TIMEOUT_MS = 500;
20
+ // ═══════════════════════════════════════════════════════════════
21
+ // LLM extraction prompt
22
+ // ═══════════════════════════════════════════════════════════════
23
+ const ANNOTATION_PROMPT = `Extract structured goal info as JSON. Output ONLY the JSON object:
24
+
25
+ {
26
+ "protocol": "<FileProtocol|TransactionProtocol|DatabaseProtocol|AuthProtocol|default>",
27
+ "initial_state": "<starting state>",
28
+ "target_state": "<desired end state>",
29
+ "constraints": ["<constraint1>", "<constraint2>"]
30
+ }
31
+
32
+ Examples:
33
+ "safely write config file" → {"protocol":"FileProtocol","initial_state":"Closed","target_state":"Closed","constraints":["must persist data","must not violate protocol"]}
34
+ "transfer money with audit" → {"protocol":"TransactionProtocol","initial_state":"Pending","target_state":"Settled","constraints":["audit required","compliance"]}
35
+
36
+ Goal: `;
37
+ // ═══════════════════════════════════════════════════════════════
38
+ // Public API
39
+ // ═══════════════════════════════════════════════════════════════
40
+ /**
41
+ * Annotate a natural language goal asynchronously.
42
+ * Best-effort: LLM with 500ms timeout, falls back to keyword parser.
43
+ * Returns immediately with a GoalRecord (never throws).
44
+ */
45
+ async function annotateGoal(goalText) {
46
+ // Try LLM extraction with timeout
47
+ try {
48
+ const llmResult = await Promise.race([
49
+ (0, llm_1.generate)(ANNOTATION_PROMPT + `"${goalText}"`),
50
+ new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), TIMEOUT_MS)),
51
+ ]);
52
+ const jsonMatch = llmResult.match(/\{[\s\S]*\}/);
53
+ if (jsonMatch) {
54
+ const parsed = JSON.parse(jsonMatch[0]);
55
+ return {
56
+ text: goalText,
57
+ protocol: parsed.protocol || "default",
58
+ initial_state: parsed.initial_state || "INIT",
59
+ target_state: parsed.target_state || "COMPLETED",
60
+ constraints: parsed.constraints || [],
61
+ method: "llm_extracted",
62
+ confidence: 0.85,
63
+ };
64
+ }
65
+ }
66
+ catch {
67
+ // LLM timeout or parse error → fall through to keyword
68
+ }
69
+ // Fallback: keyword-based extraction
70
+ try {
71
+ const keywordResult = (0, intent_parser_1.parseGoalSync)(goalText);
72
+ return {
73
+ text: goalText,
74
+ protocol: keywordResult.protocol,
75
+ initial_state: keywordResult.initialState[0] || "INIT",
76
+ target_state: keywordResult.targetState[0] || "COMPLETED",
77
+ constraints: keywordResult.constraints.map(c => c.description),
78
+ method: "inferred",
79
+ confidence: 0.5,
80
+ };
81
+ }
82
+ catch {
83
+ // Complete failure
84
+ return {
85
+ text: goalText,
86
+ protocol: "default",
87
+ initial_state: "INIT",
88
+ target_state: "COMPLETED",
89
+ constraints: [],
90
+ method: "failed",
91
+ confidence: 0,
92
+ };
93
+ }
94
+ }
95
+ /**
96
+ * Fire-and-forget async annotation.
97
+ * Call this from the main flow — it runs in background and never blocks.
98
+ * The annotated goal is written to the trajectory record on next collection.
99
+ */
100
+ function annotateGoalBackground(goalText, onAnnotated) {
101
+ annotateGoal(goalText).then(onAnnotated).catch(() => {
102
+ // Silent — annotation failure must never surface to user
103
+ });
104
+ }
105
+ // ═══════════════════════════════════════════════════════════════
106
+ // CLI
107
+ // ═══════════════════════════════════════════════════════════════
108
+ if (require.main === module) {
109
+ const goal = process.argv[2] || "safely write config file";
110
+ annotateGoal(goal).then(result => {
111
+ console.log(JSON.stringify(result, null, 2));
112
+ });
113
+ }
@@ -0,0 +1,563 @@
1
+ "use strict";
2
+ /**
3
+ * P3.10: Goal-conditioned Protocol Planner
4
+ *
5
+ * Expands high-level goals into prerequisite subgoal chains,
6
+ * enabling ProtocolStrategy BFS to discover multi-step repair paths.
7
+ *
8
+ * Problem: ProtocolStrategy BFS can find single-hop cleanup (close_file)
9
+ * but can't plan "logout user" → [verify_password, generate_jwt,
10
+ * create_session, logout]. This causes 39% missing_candidate failures.
11
+ *
12
+ * Solution: Goal Templates map goal patterns to prerequisite chains.
13
+ * Lightweight (~20 templates), manually maintained, no GNN required.
14
+ *
15
+ * Target: reduce missing_candidate from 39% to <20%, Top-3 from 29% to >60%.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.GoalPlanner = void 0;
19
+ exports.expandGoalActions = expandGoalActions;
20
+ exports.getGoalPlanner = getGoalPlanner;
21
+ // ═══════════════════════════════════════════════════════════════
22
+ // Goal Templates (~20 patterns covering 4 protocol groups)
23
+ // ═══════════════════════════════════════════════════════════════
24
+ const GOAL_TEMPLATES = [
25
+ // ── Auth Protocol ──
26
+ {
27
+ pattern: /\b(missing.*(auth|authent)|no.*(auth|authent)|without.*(auth|authent)|unauthenticated|not.*authenticated)\b/i,
28
+ protocol: "AuthProtocol",
29
+ prerequisiteChains: [
30
+ ["verify_password", "generate_jwt", "create_session"],
31
+ ],
32
+ requiredStates: ["SESSION_ACTIVE"],
33
+ targetStates: ["SESSION_ACTIVE"],
34
+ },
35
+ {
36
+ pattern: /\b(logout|log\s*out|sign\s*out|terminate\s*session|end\s*session)\b/i,
37
+ protocol: "AuthProtocol",
38
+ prerequisiteChains: [
39
+ ["verify_password", "generate_jwt", "create_session"],
40
+ ],
41
+ requiredStates: ["SESSION_ACTIVE"],
42
+ targetStates: ["UNAUTHENTICATED"],
43
+ },
44
+ {
45
+ pattern: /\b(authenticate|auth|login|sign\s*in|verify\s*user|validate\s*user)\b/i,
46
+ protocol: "AuthProtocol",
47
+ prerequisiteChains: [
48
+ ["verify_password", "generate_jwt", "create_session"],
49
+ ],
50
+ requiredStates: ["SESSION_ACTIVE"],
51
+ targetStates: ["SESSION_ACTIVE"],
52
+ },
53
+ {
54
+ pattern: /\b(create\s*session|establish\s*session|start\s*session)\b/i,
55
+ protocol: "AuthProtocol",
56
+ prerequisiteChains: [
57
+ ["verify_password", "generate_jwt"],
58
+ ],
59
+ requiredStates: ["TOKEN_ISSUED"],
60
+ targetStates: ["SESSION_ACTIVE"],
61
+ },
62
+ {
63
+ pattern: /\b(generate\s*token|issue\s*token|create\s*token|jwt)\b/i,
64
+ protocol: "AuthProtocol",
65
+ prerequisiteChains: [
66
+ ["verify_password"],
67
+ ],
68
+ requiredStates: ["PASSWORD_VERIFIED"],
69
+ targetStates: ["TOKEN_ISSUED"],
70
+ },
71
+ {
72
+ pattern: /\b(full\s*auth|complete\s*auth|auth\s*lifecycle|auth\s*cycle)\b/i,
73
+ protocol: "AuthProtocol",
74
+ prerequisiteChains: [
75
+ ["verify_password", "generate_jwt", "create_session", "logout"],
76
+ ],
77
+ requiredStates: ["UNAUTHENTICATED"],
78
+ targetStates: ["UNAUTHENTICATED"],
79
+ },
80
+ {
81
+ pattern: /\brevok.*(?:token|auth)|re-?authenticate/i,
82
+ protocol: "AuthProtocol",
83
+ prerequisiteChains: [
84
+ ["verify_password", "generate_jwt"],
85
+ ],
86
+ requiredStates: ["TOKEN_ISSUED"],
87
+ targetStates: ["UNAUTHENTICATED"],
88
+ },
89
+ // ── File Protocol ──
90
+ {
91
+ pattern: /\b(safely\s*write|write.*file|write.*config|save.*file|persist.*file)\b/i,
92
+ protocol: "FileProtocol",
93
+ prerequisiteChains: [
94
+ ["open_file", "write_file"],
95
+ ],
96
+ requiredStates: ["FILE_OPEN"],
97
+ targetStates: [],
98
+ },
99
+ {
100
+ pattern: /\b(read.*file|open.*read|load.*file|parse.*file)\b/i,
101
+ protocol: "FileProtocol",
102
+ prerequisiteChains: [
103
+ ["open_file", "read_file"],
104
+ ],
105
+ requiredStates: ["FILE_OPEN"],
106
+ targetStates: [],
107
+ },
108
+ {
109
+ pattern: /\b(append.*file|add.*to.*file|update.*file)\b/i,
110
+ protocol: "FileProtocol",
111
+ prerequisiteChains: [
112
+ ["open_file", "write_file"],
113
+ ],
114
+ requiredStates: ["FILE_OPEN"],
115
+ targetStates: [],
116
+ },
117
+ {
118
+ pattern: /\b(double\s*open|re-?open.*file)\b/i,
119
+ protocol: "FileProtocol",
120
+ prerequisiteChains: [
121
+ ["open_file"],
122
+ ],
123
+ requiredStates: ["FILE_OPEN"],
124
+ targetStates: [],
125
+ },
126
+ // ── Database Protocol ──
127
+ {
128
+ pattern: /\b(query|select|fetch|read.*db|db.*read|database.*read)\b/i,
129
+ protocol: "DBProtocol",
130
+ prerequisiteChains: [
131
+ ["connect_db", "query_db"],
132
+ ],
133
+ requiredStates: ["DB_CONNECTED"],
134
+ targetStates: [],
135
+ },
136
+ {
137
+ pattern: /\b(insert|create.*record|add.*record|db.*write|write.*db)\b/i,
138
+ protocol: "DBProtocol",
139
+ prerequisiteChains: [
140
+ ["connect_db", "query_db"],
141
+ ],
142
+ requiredStates: ["DB_CONNECTED"],
143
+ targetStates: [],
144
+ },
145
+ {
146
+ pattern: /\b(connect.*db|db.*connect|open.*database|database.*open)\b/i,
147
+ protocol: "DBProtocol",
148
+ prerequisiteChains: [
149
+ ["connect_db"],
150
+ ],
151
+ requiredStates: ["DB_CONNECTED"],
152
+ targetStates: [],
153
+ },
154
+ {
155
+ pattern: /\b(reconnect|re-?connect)\b/i,
156
+ protocol: "DBProtocol",
157
+ prerequisiteChains: [
158
+ ["connect_db", "disconnect_db", "connect_db", "query_db"],
159
+ ],
160
+ requiredStates: ["DB_CONNECTED"],
161
+ targetStates: [],
162
+ },
163
+ {
164
+ pattern: /\b(bulk|batch|multi.*query|multi.*insert)\b/i,
165
+ protocol: "DBProtocol",
166
+ prerequisiteChains: [
167
+ ["connect_db", "query_db"],
168
+ ],
169
+ requiredStates: ["DB_CONNECTED"],
170
+ targetStates: [],
171
+ },
172
+ // ── IR Pipeline Protocol ──
173
+ {
174
+ pattern: /\b(extract.*ir|ir.*extract|scan.*code|code.*scan)\b/i,
175
+ protocol: "IRProtocol",
176
+ prerequisiteChains: [
177
+ ["extractIR", "validateAction", "validateActionSequence", "emitCode"],
178
+ ],
179
+ requiredStates: ["CODE_EMITTED"],
180
+ targetStates: ["CODE_EMITTED"],
181
+ },
182
+ {
183
+ pattern: /\b(validate.*action|action.*valid|check.*action)\b/i,
184
+ protocol: "IRProtocol",
185
+ prerequisiteChains: [
186
+ ["extractIR", "validateAction"],
187
+ ],
188
+ requiredStates: ["ACTION_VALIDATED"],
189
+ targetStates: ["ACTION_VALIDATED"],
190
+ },
191
+ {
192
+ pattern: /\b(emit.*code|generate.*code|code.*gen|output.*code)\b/i,
193
+ protocol: "IRProtocol",
194
+ prerequisiteChains: [
195
+ ["extractIR", "validateAction", "validateActionSequence", "emitCode"],
196
+ ],
197
+ requiredStates: ["CODE_EMITTED"],
198
+ targetStates: ["CODE_EMITTED"],
199
+ },
200
+ {
201
+ pattern: /\b(record.*session|save.*session|session.*record|store.*session)\b/i,
202
+ protocol: "IRProtocol",
203
+ prerequisiteChains: [
204
+ ["extractIR", "validateAction", "validateActionSequence", "emitCode", "recordSession"],
205
+ ],
206
+ requiredStates: ["SESSION_RECORDED"],
207
+ targetStates: ["SESSION_RECORDED"],
208
+ },
209
+ {
210
+ pattern: /\b(full.*pipeline|complete.*pipeline|end.*to.*end|ir.*pipeline|pipeline.*ir)\b/i,
211
+ protocol: "IRProtocol",
212
+ prerequisiteChains: [
213
+ ["extractIR", "validateAction", "validateActionSequence", "emitCode", "recordSession"],
214
+ ],
215
+ requiredStates: ["SESSION_RECORDED"],
216
+ targetStates: ["SESSION_RECORDED"],
217
+ },
218
+ {
219
+ pattern: /\b(re-?extract.*ir|stale.*ir|refresh.*ir)\b/i,
220
+ protocol: "IRProtocol",
221
+ prerequisiteChains: [
222
+ ["extractIR", "validateAction"],
223
+ ],
224
+ requiredStates: ["ACTION_VALIDATED"],
225
+ targetStates: ["ACTION_VALIDATED"],
226
+ },
227
+ // ── Cross-protocol ──
228
+ {
229
+ pattern: /\b(auth.*file|file.*auth|authenticate.*write|login.*save)\b/i,
230
+ protocol: "AuthProtocol",
231
+ prerequisiteChains: [
232
+ ["verify_password", "generate_jwt", "create_session"],
233
+ ],
234
+ requiredStates: ["SESSION_ACTIVE"],
235
+ targetStates: ["SESSION_ACTIVE"],
236
+ },
237
+ {
238
+ pattern: /\b(db.*file|file.*db|database.*file|file.*database)\b/i,
239
+ protocol: "DBProtocol",
240
+ prerequisiteChains: [
241
+ ["connect_db", "query_db", "disconnect_db"],
242
+ ],
243
+ requiredStates: [],
244
+ targetStates: [],
245
+ },
246
+ // ═══════════════════════════════════════════════════════════
247
+ // P7.3: New protocol type templates (12 templates)
248
+ // ═══════════════════════════════════════════════════════════
249
+ // ── Transaction Protocol ──
250
+ {
251
+ pattern: /\b(commit|finish\s*transaction|save\s*transaction|end\s*tx)\b/i,
252
+ protocol: "TransactionProtocol",
253
+ prerequisiteChains: [
254
+ ["begin_tx", "insert_record", "commit_tx"],
255
+ ["begin_tx", "update_record", "commit_tx"],
256
+ ],
257
+ requiredStates: ["TX_IDLE"],
258
+ targetStates: ["TX_IDLE"],
259
+ },
260
+ {
261
+ pattern: /\b(rollback|abort|undo|cancel\s*transaction|revert)\b/i,
262
+ protocol: "TransactionProtocol",
263
+ prerequisiteChains: [
264
+ ["begin_tx", "rollback_tx"],
265
+ ["begin_tx", "update_record", "rollback_tx"],
266
+ ],
267
+ requiredStates: ["TX_IDLE"],
268
+ targetStates: ["TX_IDLE"],
269
+ },
270
+ {
271
+ pattern: /\b(savepoint|checkpoint|partial\s*commit|nested\s*transaction)\b/i,
272
+ protocol: "TransactionProtocol",
273
+ prerequisiteChains: [
274
+ ["begin_tx", "savepoint_create", "update_record", "savepoint_release", "commit_tx"],
275
+ ["begin_tx", "savepoint_create", "delete_record", "rollback_to_savepoint", "rollback_tx"],
276
+ ],
277
+ requiredStates: ["TX_IDLE"],
278
+ targetStates: ["TX_IDLE"],
279
+ },
280
+ // ── Conditional Protocol ──
281
+ {
282
+ pattern: /\b(access\s*(check|eval\w*)|permission|authorize|policy\s*check|evaluat(e|ion)\s*access)\b/i,
283
+ protocol: "ConditionalProtocol",
284
+ prerequisiteChains: [
285
+ ["evaluate_access", "grant_access", "log_granted"],
286
+ ["evaluate_access", "deny_access", "log_denied"],
287
+ ],
288
+ requiredStates: ["COND_RESOLVED"],
289
+ targetStates: ["COND_RESOLVED"],
290
+ },
291
+ {
292
+ pattern: /\b(escalate|override|bypass.*policy|elevate)\b/i,
293
+ protocol: "ConditionalProtocol",
294
+ prerequisiteChains: [
295
+ ["evaluate_access", "deny_access", "escalate_access", "log_granted"],
296
+ ],
297
+ requiredStates: ["COND_RESOLVED"],
298
+ targetStates: ["COND_RESOLVED"],
299
+ },
300
+ {
301
+ pattern: /\b(audit.*access|log.*access|access.*log|compliance\s*check)\b/i,
302
+ protocol: "ConditionalProtocol",
303
+ prerequisiteChains: [
304
+ ["evaluate_access", "grant_access", "audit_condition"],
305
+ ["evaluate_access", "deny_access", "audit_condition"],
306
+ ],
307
+ requiredStates: ["COND_RESOLVED"],
308
+ targetStates: ["COND_RESOLVED"],
309
+ },
310
+ // ── Loop Protocol ──
311
+ {
312
+ pattern: /\b(fetch|paginate|iterate|process.*batch|batch.*process|loop.*data)\b/i,
313
+ protocol: "LoopProtocol",
314
+ prerequisiteChains: [
315
+ ["init_fetch_loop", "fetch_batch", "has_more_data", "process_item", "exit_loop"],
316
+ ],
317
+ requiredStates: ["LOOP_DONE"],
318
+ targetStates: ["LOOP_DONE"],
319
+ },
320
+ {
321
+ pattern: /\b(retry|re-?try|recover|re-?attempt|fallback)\b/i,
322
+ protocol: "LoopProtocol",
323
+ prerequisiteChains: [
324
+ ["init_fetch_loop", "fetch_batch", "retry_batch", "fetch_batch", "has_more_data", "process_item", "exit_loop"],
325
+ ],
326
+ requiredStates: ["LOOP_DONE"],
327
+ targetStates: ["LOOP_DONE"],
328
+ },
329
+ {
330
+ pattern: /\b(poll|wait.*for|monitor|watch|observe)\b/i,
331
+ protocol: "LoopProtocol",
332
+ prerequisiteChains: [
333
+ ["init_fetch_loop", "fetch_batch", "has_more_data", "process_item", "poll_status", "exit_loop"],
334
+ ],
335
+ requiredStates: ["LOOP_DONE"],
336
+ targetStates: ["LOOP_DONE"],
337
+ },
338
+ // ── Cross-Protocol (auth-gated resources) ──
339
+ {
340
+ pattern: /\b(auth.*db|secure.*db|gated.*db|database.*auth|login.*query)\b/i,
341
+ protocol: "CrossProtocol",
342
+ prerequisiteChains: [
343
+ ["verify_password", "create_session", "connect_db", "query_db", "disconnect_db", "logout"],
344
+ ],
345
+ requiredStates: [],
346
+ targetStates: ["UNAUTHENTICATED"],
347
+ },
348
+ {
349
+ pattern: /\b(auth.*file.*db|full.*secure|gated.*resource|end.*to.*end.*secure)\b/i,
350
+ protocol: "CrossProtocol",
351
+ prerequisiteChains: [
352
+ ["verify_password", "create_session", "open_file", "read_file", "connect_db", "query_db", "close_file", "disconnect_db", "logout"],
353
+ ],
354
+ requiredStates: [],
355
+ targetStates: ["UNAUTHENTICATED"],
356
+ },
357
+ // ── Stateless / Validation ──
358
+ {
359
+ pattern: /(sanitiz|clean.*input|validate.*input|input.*valid|schema.*valid)/i,
360
+ protocol: "StatelessProtocol",
361
+ prerequisiteChains: [
362
+ ["sanitize_input", "validate_schema"],
363
+ ],
364
+ requiredStates: [],
365
+ targetStates: [],
366
+ },
367
+ {
368
+ pattern: /\b(checksum|integrity|verify.*data|data.*integrity|hash.*verif|verif.*hash)\b/i,
369
+ protocol: "StatelessProtocol",
370
+ prerequisiteChains: [
371
+ ["compute_hash", "verify_checksum"],
372
+ ["decode_payload", "decompress_buffer", "verify_checksum"],
373
+ ],
374
+ requiredStates: [],
375
+ targetStates: [],
376
+ },
377
+ // ═══════════════════════════════════════════════════════════
378
+ // P7.3: Cross-protocol auth + resource chains (fix RW-005, RW-017)
379
+ // ═══════════════════════════════════════════════════════════
380
+ // ── Auth-gated database access ──
381
+ {
382
+ pattern: /\b(auth.*(db|database|query)|login.*(db|database|query)|authenticate.*(db|database|query)|missing.*auth.*(db|database))\b/i,
383
+ protocol: "CrossProtocol",
384
+ prerequisiteChains: [
385
+ ["verify_password", "generate_jwt", "create_session", "disconnect_db"],
386
+ ["verify_password", "generate_jwt", "create_session", "connect_db", "query_db", "disconnect_db"],
387
+ ],
388
+ requiredStates: ["UNAUTHENTICATED"],
389
+ targetStates: ["UNAUTHENTICATED"],
390
+ },
391
+ // ── Auth-gated file access ──
392
+ {
393
+ pattern: /\b(auth.*(file|write|read)|login.*(file|write|read)|gated.*(file|resource)|auth.*gate)\b/i,
394
+ protocol: "CrossProtocol",
395
+ prerequisiteChains: [
396
+ ["verify_password", "create_session", "open_file", "read_file", "close_file", "logout"],
397
+ ["verify_password", "create_session", "open_file", "write_file", "close_file", "logout"],
398
+ ],
399
+ requiredStates: ["UNAUTHENTICATED"],
400
+ targetStates: ["UNAUTHENTICATED"],
401
+ },
402
+ // ── Transaction error handling (RW-012) ──
403
+ {
404
+ pattern: /\b(transaction.*(error|fail)|tx.*(error|fail)|error.*(transaction|tx|rollback|savepoint)|savepoint.*(error|fail|rollback)|rollback.*(error|fail|savepoint))\b/i,
405
+ protocol: "TransactionProtocol",
406
+ prerequisiteChains: [
407
+ ["begin_tx", "savepoint_create", "update_record", "rollback_to_savepoint", "rollback_tx"],
408
+ ],
409
+ requiredStates: ["TX_IDLE"],
410
+ targetStates: ["TX_IDLE"],
411
+ },
412
+ ];
413
+ // ═══════════════════════════════════════════════════════════════
414
+ // Goal Planner
415
+ // ═══════════════════════════════════════════════════════════════
416
+ class GoalPlanner {
417
+ constructor(templates) {
418
+ this.templates = templates || GOAL_TEMPLATES;
419
+ }
420
+ /**
421
+ * Expand a natural language goal into an action sequence.
422
+ *
423
+ * Returns null if no template matches — caller falls back to
424
+ * existing ProtocolStrategy BFS.
425
+ */
426
+ expandGoal(goal) {
427
+ // Find matching templates (sorted by specificity: longer pattern match = better)
428
+ const matches = this.templates
429
+ .filter(t => t.pattern.test(goal))
430
+ .sort((a, b) => {
431
+ const aLen = (goal.match(a.pattern)?.[0]?.length ?? 0);
432
+ const bLen = (goal.match(b.pattern)?.[0]?.length ?? 0);
433
+ return bLen - aLen;
434
+ });
435
+ if (matches.length === 0)
436
+ return null;
437
+ const template = matches[0];
438
+ // Use the best chain (first = most specific for this template)
439
+ const chain = template.prerequisiteChains[0];
440
+ // Build subgoal descriptions from the chain
441
+ const subgoals = chain.map((fn, i) => {
442
+ const stepNames = {
443
+ verify_password: "verify user credentials",
444
+ generate_jwt: "issue authentication token",
445
+ create_session: "establish active session",
446
+ logout: "terminate session",
447
+ revoke_token: "revoke token",
448
+ open_file: "open file handle",
449
+ read_file: "read file contents",
450
+ write_file: "write file contents",
451
+ close_file: "close file handle",
452
+ connect_db: "connect to database",
453
+ query_db: "query database",
454
+ disconnect_db: "disconnect from database",
455
+ extractIR: "extract intermediate representation",
456
+ validateAction: "validate action semantics",
457
+ validateActionSequence: "validate action sequence",
458
+ emitCode: "emit target code",
459
+ recordSession: "record execution session",
460
+ // Transaction
461
+ begin_tx: "begin transaction",
462
+ commit_tx: "commit transaction",
463
+ rollback_tx: "rollback transaction",
464
+ insert_record: "insert record in transaction",
465
+ update_record: "update record in transaction",
466
+ delete_record: "delete record in transaction",
467
+ savepoint_create: "create savepoint",
468
+ savepoint_release: "release savepoint",
469
+ rollback_to_savepoint: "rollback to savepoint",
470
+ prep_two_phase: "prepare two-phase commit",
471
+ // Conditional
472
+ evaluate_access: "evaluate access policy",
473
+ grant_access: "grant access (true branch)",
474
+ deny_access: "deny access (false branch)",
475
+ log_granted: "log access granted",
476
+ log_denied: "log access denied",
477
+ escalate_access: "escalate denied access to grant",
478
+ bypass_condition: "bypass condition check",
479
+ retry_evaluation: "retry condition evaluation",
480
+ audit_condition: "audit condition outcome",
481
+ // Loop
482
+ init_fetch_loop: "initialize fetch loop",
483
+ fetch_batch: "fetch next data batch",
484
+ has_more_data: "check for more data",
485
+ process_item: "process data item",
486
+ next_iteration: "advance to next iteration",
487
+ exit_loop: "exit loop normally",
488
+ retry_batch: "retry failed batch fetch",
489
+ timeout_exit: "exit loop on timeout",
490
+ poll_status: "poll status in iteration",
491
+ // Stateless
492
+ compute_hash: "compute hash digest",
493
+ validate_schema: "validate data against schema",
494
+ sanitize_input: "sanitize user input",
495
+ verify_checksum: "verify data integrity checksum",
496
+ encode_payload: "encode data payload",
497
+ decode_payload: "decode data payload",
498
+ compress_buffer: "compress data buffer",
499
+ decompress_buffer: "decompress data buffer",
500
+ // Cross-protocol
501
+ auth_file_open: "open auth-gated file",
502
+ auth_file_read: "read through auth gate",
503
+ auth_file_close: "close auth-gated file session",
504
+ auth_db_connect: "connect through auth gate",
505
+ auth_db_query: "query through auth gate",
506
+ auth_db_disconnect: "disconnect auth-gated db",
507
+ };
508
+ return stepNames[fn] || `step ${i + 1}: ${fn}`;
509
+ });
510
+ return {
511
+ goal,
512
+ protocol: template.protocol,
513
+ template: goal.match(template.pattern)?.[0],
514
+ subgoals,
515
+ actions: chain,
516
+ confidence: 0.85,
517
+ };
518
+ }
519
+ /**
520
+ * Get all action sequences that could satisfy a goal.
521
+ * Used by ProtocolStrategy to generate candidates beyond single-hop BFS.
522
+ */
523
+ getCandidateActions(goal) {
524
+ const matches = this.templates
525
+ .filter(t => t.pattern.test(goal))
526
+ .sort((a, b) => {
527
+ const aLen = (goal.match(a.pattern)?.[0]?.length ?? 0);
528
+ const bLen = (goal.match(b.pattern)?.[0]?.length ?? 0);
529
+ return bLen - aLen;
530
+ });
531
+ return matches.flatMap(t => t.prerequisiteChains);
532
+ }
533
+ /** Check if a template exists for this goal. */
534
+ hasTemplate(goal) {
535
+ return this.templates.some(t => t.pattern.test(goal));
536
+ }
537
+ }
538
+ exports.GoalPlanner = GoalPlanner;
539
+ // ═══════════════════════════════════════════════════════════════
540
+ // Goal-aware Candidate Expansion
541
+ // ═══════════════════════════════════════════════════════════════
542
+ /**
543
+ * Expand a goal into additional repair actions.
544
+ *
545
+ * Given a goal like "safely write config file", this returns
546
+ * ["open_file", "write_file"] — the prerequisite chain that
547
+ * ProtocolStrategy BFS can then validate and extend.
548
+ *
549
+ * Used by ProtocolStrategy to discover multi-step candidates
550
+ * that single-hop BFS from currentState alone would miss.
551
+ */
552
+ function expandGoalActions(goal, planner) {
553
+ const gp = planner || new GoalPlanner();
554
+ const plan = gp.expandGoal(goal);
555
+ return plan?.actions ?? [];
556
+ }
557
+ /** Singleton for use across the codebase. */
558
+ let _defaultPlanner = null;
559
+ function getGoalPlanner() {
560
+ if (!_defaultPlanner)
561
+ _defaultPlanner = new GoalPlanner();
562
+ return _defaultPlanner;
563
+ }