instar 0.28.102 → 0.28.104

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 (255) hide show
  1. package/.claude/hooks/instar/before-prompt-recall.js +90 -0
  2. package/dist/cli.js +28 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/init.d.ts +1 -0
  5. package/dist/commands/init.d.ts.map +1 -1
  6. package/dist/commands/init.js +14 -1
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/jobMigrate.d.ts +46 -0
  9. package/dist/commands/jobMigrate.d.ts.map +1 -0
  10. package/dist/commands/jobMigrate.js +292 -0
  11. package/dist/commands/jobMigrate.js.map +1 -0
  12. package/dist/commands/server.d.ts.map +1 -1
  13. package/dist/commands/server.js +88 -42
  14. package/dist/commands/server.js.map +1 -1
  15. package/dist/core/BackupManager.d.ts +27 -1
  16. package/dist/core/BackupManager.d.ts.map +1 -1
  17. package/dist/core/BackupManager.js +56 -1
  18. package/dist/core/BackupManager.js.map +1 -1
  19. package/dist/core/GitStateManager.d.ts +8 -0
  20. package/dist/core/GitStateManager.d.ts.map +1 -1
  21. package/dist/core/GitStateManager.js +31 -1
  22. package/dist/core/GitStateManager.js.map +1 -1
  23. package/dist/core/MigratorStepEngine.d.ts +170 -0
  24. package/dist/core/MigratorStepEngine.d.ts.map +1 -0
  25. package/dist/core/MigratorStepEngine.js +352 -0
  26. package/dist/core/MigratorStepEngine.js.map +1 -0
  27. package/dist/core/PostUpdateMigrator.d.ts +76 -0
  28. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  29. package/dist/core/PostUpdateMigrator.js +252 -1
  30. package/dist/core/PostUpdateMigrator.js.map +1 -1
  31. package/dist/core/PreCompactionFlush.d.ts +101 -0
  32. package/dist/core/PreCompactionFlush.d.ts.map +1 -0
  33. package/dist/core/PreCompactionFlush.js +282 -0
  34. package/dist/core/PreCompactionFlush.js.map +1 -0
  35. package/dist/core/PromptBuildRecall.d.ts +97 -0
  36. package/dist/core/PromptBuildRecall.d.ts.map +1 -0
  37. package/dist/core/PromptBuildRecall.js +152 -0
  38. package/dist/core/PromptBuildRecall.js.map +1 -0
  39. package/dist/core/selectIntelligenceProvider.d.ts +41 -0
  40. package/dist/core/selectIntelligenceProvider.d.ts.map +1 -0
  41. package/dist/core/selectIntelligenceProvider.js +89 -0
  42. package/dist/core/selectIntelligenceProvider.js.map +1 -0
  43. package/dist/lifeline/ServerSupervisor.d.ts +183 -0
  44. package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
  45. package/dist/lifeline/ServerSupervisor.js +443 -0
  46. package/dist/lifeline/ServerSupervisor.js.map +1 -1
  47. package/dist/memory/NativeModuleHealer.d.ts +109 -1
  48. package/dist/memory/NativeModuleHealer.d.ts.map +1 -1
  49. package/dist/memory/NativeModuleHealer.js +418 -2
  50. package/dist/memory/NativeModuleHealer.js.map +1 -1
  51. package/dist/memory/SemanticMemory.d.ts +131 -0
  52. package/dist/memory/SemanticMemory.d.ts.map +1 -1
  53. package/dist/memory/SemanticMemory.js +315 -0
  54. package/dist/memory/SemanticMemory.js.map +1 -1
  55. package/dist/messaging/DeliveryRetryManager.d.ts +60 -0
  56. package/dist/messaging/DeliveryRetryManager.d.ts.map +1 -1
  57. package/dist/messaging/DeliveryRetryManager.js +104 -0
  58. package/dist/messaging/DeliveryRetryManager.js.map +1 -1
  59. package/dist/monitoring/DegradationReporter.d.ts +164 -0
  60. package/dist/monitoring/DegradationReporter.d.ts.map +1 -1
  61. package/dist/monitoring/DegradationReporter.js +309 -1
  62. package/dist/monitoring/DegradationReporter.js.map +1 -1
  63. package/dist/monitoring/ErrorCodeExtractor.d.ts +69 -0
  64. package/dist/monitoring/ErrorCodeExtractor.d.ts.map +1 -0
  65. package/dist/monitoring/ErrorCodeExtractor.js +131 -0
  66. package/dist/monitoring/ErrorCodeExtractor.js.map +1 -0
  67. package/dist/monitoring/PromptGate.d.ts +34 -0
  68. package/dist/monitoring/PromptGate.d.ts.map +1 -1
  69. package/dist/monitoring/PromptGate.js +81 -1
  70. package/dist/monitoring/PromptGate.js.map +1 -1
  71. package/dist/monitoring/Redactor.d.ts +58 -0
  72. package/dist/monitoring/Redactor.d.ts.map +1 -0
  73. package/dist/monitoring/Redactor.js +143 -0
  74. package/dist/monitoring/Redactor.js.map +1 -0
  75. package/dist/monitoring/TokenLedger.d.ts.map +1 -1
  76. package/dist/monitoring/TokenLedger.js +11 -1
  77. package/dist/monitoring/TokenLedger.js.map +1 -1
  78. package/dist/monitoring/probes/LifelineProbe.d.ts +7 -0
  79. package/dist/monitoring/probes/LifelineProbe.d.ts.map +1 -1
  80. package/dist/monitoring/probes/LifelineProbe.js +7 -0
  81. package/dist/monitoring/probes/LifelineProbe.js.map +1 -1
  82. package/dist/monitoring/probes/__shared.d.ts +50 -0
  83. package/dist/monitoring/probes/__shared.d.ts.map +1 -0
  84. package/dist/monitoring/probes/__shared.js +51 -0
  85. package/dist/monitoring/probes/__shared.js.map +1 -0
  86. package/dist/remediation/IntentJournal.d.ts +64 -0
  87. package/dist/remediation/IntentJournal.d.ts.map +1 -0
  88. package/dist/remediation/IntentJournal.js +118 -0
  89. package/dist/remediation/IntentJournal.js.map +1 -0
  90. package/dist/remediation/MachineLock.d.ts +137 -0
  91. package/dist/remediation/MachineLock.d.ts.map +1 -0
  92. package/dist/remediation/MachineLock.js +314 -0
  93. package/dist/remediation/MachineLock.js.map +1 -0
  94. package/dist/remediation/PrimaryAggregatorLease.d.ts +205 -0
  95. package/dist/remediation/PrimaryAggregatorLease.d.ts.map +1 -0
  96. package/dist/remediation/PrimaryAggregatorLease.js +450 -0
  97. package/dist/remediation/PrimaryAggregatorLease.js.map +1 -0
  98. package/dist/remediation/RemediationContext.d.ts +63 -0
  99. package/dist/remediation/RemediationContext.d.ts.map +1 -0
  100. package/dist/remediation/RemediationContext.js +109 -0
  101. package/dist/remediation/RemediationContext.js.map +1 -0
  102. package/dist/remediation/RemediationKeyVault.d.ts +123 -0
  103. package/dist/remediation/RemediationKeyVault.d.ts.map +1 -0
  104. package/dist/remediation/RemediationKeyVault.js +564 -0
  105. package/dist/remediation/RemediationKeyVault.js.map +1 -0
  106. package/dist/remediation/Remediator.d.ts +288 -0
  107. package/dist/remediation/Remediator.d.ts.map +1 -0
  108. package/dist/remediation/Remediator.js +520 -0
  109. package/dist/remediation/Remediator.js.map +1 -0
  110. package/dist/remediation/RemediatorBootstrap.d.ts +141 -0
  111. package/dist/remediation/RemediatorBootstrap.d.ts.map +1 -0
  112. package/dist/remediation/RemediatorBootstrap.js +255 -0
  113. package/dist/remediation/RemediatorBootstrap.js.map +1 -0
  114. package/dist/remediation/TrustElevationSource.d.ts +153 -0
  115. package/dist/remediation/TrustElevationSource.d.ts.map +1 -0
  116. package/dist/remediation/TrustElevationSource.js +208 -0
  117. package/dist/remediation/TrustElevationSource.js.map +1 -0
  118. package/dist/remediation/audit/AuditProjection.d.ts +37 -0
  119. package/dist/remediation/audit/AuditProjection.d.ts.map +1 -0
  120. package/dist/remediation/audit/AuditProjection.js +118 -0
  121. package/dist/remediation/audit/AuditProjection.js.map +1 -0
  122. package/dist/remediation/audit/AuditWriter.d.ts +79 -0
  123. package/dist/remediation/audit/AuditWriter.d.ts.map +1 -0
  124. package/dist/remediation/audit/AuditWriter.js +132 -0
  125. package/dist/remediation/audit/AuditWriter.js.map +1 -0
  126. package/dist/remediation/channels/CliApprovalChannel.d.ts +37 -0
  127. package/dist/remediation/channels/CliApprovalChannel.d.ts.map +1 -0
  128. package/dist/remediation/channels/CliApprovalChannel.js +45 -0
  129. package/dist/remediation/channels/CliApprovalChannel.js.map +1 -0
  130. package/dist/remediation/channels/TelegramApprovalChannel.d.ts +37 -0
  131. package/dist/remediation/channels/TelegramApprovalChannel.d.ts.map +1 -0
  132. package/dist/remediation/channels/TelegramApprovalChannel.js +45 -0
  133. package/dist/remediation/channels/TelegramApprovalChannel.js.map +1 -0
  134. package/dist/remediation/runbooks/db-corruption.d.ts +86 -0
  135. package/dist/remediation/runbooks/db-corruption.d.ts.map +1 -0
  136. package/dist/remediation/runbooks/db-corruption.js +190 -0
  137. package/dist/remediation/runbooks/db-corruption.js.map +1 -0
  138. package/dist/remediation/runbooks/messaging-delivery-failed.d.ts +108 -0
  139. package/dist/remediation/runbooks/messaging-delivery-failed.d.ts.map +1 -0
  140. package/dist/remediation/runbooks/messaging-delivery-failed.js +172 -0
  141. package/dist/remediation/runbooks/messaging-delivery-failed.js.map +1 -0
  142. package/dist/remediation/runbooks/node-abi-mismatch.d.ts +70 -0
  143. package/dist/remediation/runbooks/node-abi-mismatch.d.ts.map +1 -0
  144. package/dist/remediation/runbooks/node-abi-mismatch.js +216 -0
  145. package/dist/remediation/runbooks/node-abi-mismatch.js.map +1 -0
  146. package/dist/remediation/runbooks/supervisor-preflight.d.ts +114 -0
  147. package/dist/remediation/runbooks/supervisor-preflight.d.ts.map +1 -0
  148. package/dist/remediation/runbooks/supervisor-preflight.js +299 -0
  149. package/dist/remediation/runbooks/supervisor-preflight.js.map +1 -0
  150. package/dist/scheduler/AgentMdAtomicSave.d.ts +85 -0
  151. package/dist/scheduler/AgentMdAtomicSave.d.ts.map +1 -0
  152. package/dist/scheduler/AgentMdAtomicSave.js +169 -0
  153. package/dist/scheduler/AgentMdAtomicSave.js.map +1 -0
  154. package/dist/scheduler/AgentMdReconcile.d.ts +62 -0
  155. package/dist/scheduler/AgentMdReconcile.d.ts.map +1 -0
  156. package/dist/scheduler/AgentMdReconcile.js +212 -0
  157. package/dist/scheduler/AgentMdReconcile.js.map +1 -0
  158. package/dist/scheduler/DisabledBodyDrift.d.ts +70 -0
  159. package/dist/scheduler/DisabledBodyDrift.d.ts.map +1 -0
  160. package/dist/scheduler/DisabledBodyDrift.js +149 -0
  161. package/dist/scheduler/DisabledBodyDrift.js.map +1 -0
  162. package/dist/scheduler/InstallBuiltinJobs.d.ts +53 -0
  163. package/dist/scheduler/InstallBuiltinJobs.d.ts.map +1 -0
  164. package/dist/scheduler/InstallBuiltinJobs.js +212 -0
  165. package/dist/scheduler/InstallBuiltinJobs.js.map +1 -0
  166. package/dist/scheduler/JobLoader.d.ts.map +1 -1
  167. package/dist/scheduler/JobLoader.js +48 -0
  168. package/dist/scheduler/JobLoader.js.map +1 -1
  169. package/dist/scheduler/MigrationInvariants.d.ts +62 -0
  170. package/dist/scheduler/MigrationInvariants.d.ts.map +1 -0
  171. package/dist/scheduler/MigrationInvariants.js +215 -0
  172. package/dist/scheduler/MigrationInvariants.js.map +1 -0
  173. package/dist/scheduler/MigrationLedger.d.ts +84 -0
  174. package/dist/scheduler/MigrationLedger.d.ts.map +1 -0
  175. package/dist/scheduler/MigrationLedger.js +114 -0
  176. package/dist/scheduler/MigrationLedger.js.map +1 -0
  177. package/dist/server/AgentServer.d.ts.map +1 -1
  178. package/dist/server/AgentServer.js +8 -0
  179. package/dist/server/AgentServer.js.map +1 -1
  180. package/dist/server/fileRoutes.d.ts.map +1 -1
  181. package/dist/server/fileRoutes.js +7 -0
  182. package/dist/server/fileRoutes.js.map +1 -1
  183. package/dist/server/routes.d.ts.map +1 -1
  184. package/dist/server/routes.js +141 -0
  185. package/dist/server/routes.js.map +1 -1
  186. package/package.json +3 -2
  187. package/scripts/classify-default-drift.mjs +238 -0
  188. package/scripts/eli16-overview-check.mjs +85 -0
  189. package/scripts/instar-dev-precommit.js +60 -1
  190. package/scripts/lint-degradation-emit-sites.js +116 -0
  191. package/scripts/lint-no-direct-destructive.js +12 -0
  192. package/scripts/protect-migration-guarantee.js +61 -0
  193. package/scripts/regen-default-job-templates.mjs +111 -0
  194. package/scripts/verify-runbook-pr-signature.js +366 -0
  195. package/src/data/builtin-manifest.json +94 -94
  196. package/src/scaffold/bootstrap.ts +138 -0
  197. package/src/scaffold/keys/instar-release-pub.pem +3 -0
  198. package/src/scaffold/templates/jobs/instar/.gitkeep +0 -0
  199. package/src/scaffold/templates/jobs/instar/commitment-detection.md +28 -0
  200. package/src/scaffold/templates/jobs/instar/evolution-overdue-check.md +28 -0
  201. package/src/scaffold/templates/jobs/instar/evolution-proposal-evaluate.md +30 -0
  202. package/src/scaffold/templates/jobs/instar/evolution-proposal-implement.md +25 -0
  203. package/src/scaffold/templates/jobs/instar/health-check.md +14 -0
  204. package/src/scaffold/templates/jobs/instar/identity-review.md +42 -0
  205. package/src/scaffold/templates/jobs/instar/insight-harvest.md +31 -0
  206. package/src/scaffold/templates/jobs/instar/overseer-development.md +23 -0
  207. package/src/scaffold/templates/jobs/instar/overseer-guardian.md +28 -0
  208. package/src/scaffold/templates/jobs/instar/overseer-infrastructure.md +26 -0
  209. package/src/scaffold/templates/jobs/instar/overseer-learning.md +28 -0
  210. package/src/scaffold/templates/jobs/instar/overseer-maintenance.md +27 -0
  211. package/src/scaffold/templates/jobs/instar/reflection-trigger.md +40 -0
  212. package/src/scaffold/templates/jobs/instar/relationship-maintenance.md +16 -0
  213. package/src/scaffold/templates.ts +1616 -0
  214. package/upgrades/0.28.102.md +6 -7
  215. package/upgrades/0.28.103.md +471 -0
  216. package/upgrades/0.28.104.md +77 -0
  217. package/upgrades/side-effects/a47-primary-aggregator-lease.md +82 -0
  218. package/upgrades/side-effects/agentmd-atomic-save.md +66 -0
  219. package/upgrades/side-effects/agentmd-loader-200jobs-perf-benchmark.md +50 -0
  220. package/upgrades/side-effects/agentmd-reconcile-boot-lifecycle.md +66 -0
  221. package/upgrades/side-effects/api-safety-guard.md +80 -0
  222. package/upgrades/side-effects/c1-runbook-pr-gate.md +83 -0
  223. package/upgrades/side-effects/disabled-body-drift-detection.md +59 -0
  224. package/upgrades/side-effects/drift-classifier-release-time.md +71 -0
  225. package/upgrades/side-effects/eli16-overview-required-gate.md +77 -0
  226. package/upgrades/side-effects/f1-remediation-key-vault.md +195 -0
  227. package/upgrades/side-effects/f2-redactor-errorcode-extractor.md +130 -0
  228. package/upgrades/side-effects/f3-degradation-reporter-shim.md +105 -0
  229. package/upgrades/side-effects/f4-machine-locks-intent-journal-audit.md +117 -0
  230. package/upgrades/side-effects/f5-trust-elevation-source.md +258 -0
  231. package/upgrades/side-effects/f6-supervisor-handshake.md +234 -0
  232. package/upgrades/side-effects/f7-post-update-migrator-atomic-step.md +129 -0
  233. package/upgrades/side-effects/f8-remediator-skeleton.md +153 -0
  234. package/upgrades/side-effects/f8-rest-enforcement.md +72 -0
  235. package/upgrades/side-effects/file-viewer-jobs-instar-never-editable.md +41 -0
  236. package/upgrades/side-effects/frontmatter-interpolation-breakout-test.md +48 -0
  237. package/upgrades/side-effects/jobs-as-agentmd-phase-2.md +78 -0
  238. package/upgrades/side-effects/jobs-as-agentmd-phase-3.md +76 -0
  239. package/upgrades/side-effects/jobs-as-agentmd-phase-4-endpoints.md +62 -0
  240. package/upgrades/side-effects/jobs-as-agentmd-phase-5.md +67 -0
  241. package/upgrades/side-effects/jobs-as-agentmd-phase-6.md +53 -0
  242. package/upgrades/side-effects/jobs-endpoints-auth-verification.md +52 -0
  243. package/upgrades/side-effects/migration-guarantee-suite.md +61 -0
  244. package/upgrades/side-effects/migration-runtime-invariant-gate.md +59 -0
  245. package/upgrades/side-effects/migration-telemetry-invariant-8.md +68 -0
  246. package/upgrades/side-effects/npm-pack-templates-smoke.md +51 -0
  247. package/upgrades/side-effects/openclaw-import-before-prompt-build.md +84 -0
  248. package/upgrades/side-effects/openclaw-import-pre-compaction-flush.md +85 -0
  249. package/upgrades/side-effects/prompt-gate-no-prompt-cache.md +258 -0
  250. package/upgrades/side-effects/tier2-degradation-reporter-live-wire.md +146 -0
  251. package/upgrades/side-effects/token-ledger-native-heal.md +136 -0
  252. package/upgrades/side-effects/w1-node-abi-mismatch-runbook.md +154 -0
  253. package/upgrades/side-effects/w2-supervisor-preflight-runbook.md +176 -0
  254. package/upgrades/side-effects/w3-messaging-delivery-failed-runbook.md +185 -0
  255. package/upgrades/side-effects/w4-db-corruption-runbook.md +114 -0
@@ -0,0 +1,292 @@
1
+ /**
2
+ * jobMigrate — Phase 3 migration script for INSTAR-JOBS-AS-AGENTMD spec.
3
+ *
4
+ * Reads `.instar/jobs.json` and produces:
5
+ * - `.instar/jobs/instar/<slug>.md` for default jobs whose body matched
6
+ * the shipped template via normalized SHA-256
7
+ * - `.instar/jobs/user/<slug>.md` for user-authored jobs and forked
8
+ * defaults (body did not match the template, or slug not in the lock-file)
9
+ * - `.instar/jobs/schedule/<slug>.json` per-slug manifests
10
+ * - `.instar/jobs.json.pre-migrate-<ts>` rollback anchor
11
+ *
12
+ * Body match algorithm: normalize then sha256 (CRLF→LF, ZWSP/ZWNJ/ZWJ/BOM
13
+ * strip, trimEnd + single trailing newline, sha256). Near-miss is
14
+ * Levenshtein distance > 75% of max length — the operator gets a three-
15
+ * choice prompt (interactive) or `--default-action` value (non-interactive).
16
+ *
17
+ * `--abandon` writes `.instar/jobs/.migration-abandoned.json` and deletes
18
+ * `.instar/jobs/schedule/`, leaving `jobs.json` intact for full rollback.
19
+ *
20
+ * Idempotent. Safe to run multiple times. The release-cut gate refuses to
21
+ * delete `jobs.json` until `.instar/jobs/.migration-complete.json` exists.
22
+ *
23
+ * Spec: docs/specs/INSTAR-JOBS-AS-AGENTMD-SPEC.md §Migration script.
24
+ */
25
+ import fs from 'node:fs';
26
+ import path from 'node:path';
27
+ import crypto from 'node:crypto';
28
+ import yaml from 'js-yaml';
29
+ import { SafeFsExecutor } from '../core/SafeFsExecutor.js';
30
+ const ZERO_WIDTH_RE = /[​-‍]/g;
31
+ function normalize(s) {
32
+ return s.replace(/\r\n/g, '\n').replace(ZERO_WIDTH_RE, '').trimEnd() + '\n';
33
+ }
34
+ function sha256(s) {
35
+ return 'sha256:' + crypto.createHash('sha256').update(s).digest('hex');
36
+ }
37
+ function levenshtein(a, b) {
38
+ if (a === b)
39
+ return 0;
40
+ if (!a.length)
41
+ return b.length;
42
+ if (!b.length)
43
+ return a.length;
44
+ const matrix = Array.from({ length: a.length + 1 }, () => new Array(b.length + 1));
45
+ for (let i = 0; i <= a.length; i++)
46
+ matrix[i][0] = i;
47
+ for (let j = 0; j <= b.length; j++)
48
+ matrix[0][j] = j;
49
+ for (let i = 1; i <= a.length; i++) {
50
+ for (let j = 1; j <= b.length; j++) {
51
+ if (a[i - 1] === b[j - 1])
52
+ matrix[i][j] = matrix[i - 1][j - 1];
53
+ else
54
+ matrix[i][j] = 1 + Math.min(matrix[i - 1][j], matrix[i][j - 1], matrix[i - 1][j - 1]);
55
+ }
56
+ }
57
+ return matrix[a.length][b.length];
58
+ }
59
+ function nearMiss(a, b) {
60
+ const max = Math.max(a.length, b.length);
61
+ if (max === 0)
62
+ return false;
63
+ return levenshtein(normalize(a), normalize(b)) <= 0.25 * max;
64
+ }
65
+ function loadShippedDefaults(packageRoot) {
66
+ const map = new Map();
67
+ const candidates = [
68
+ path.join(packageRoot, 'dist', 'scaffold', 'templates', 'jobs', 'instar'),
69
+ path.join(packageRoot, 'src', 'scaffold', 'templates', 'jobs', 'instar'),
70
+ ];
71
+ for (const dir of candidates) {
72
+ if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory())
73
+ continue;
74
+ for (const f of fs.readdirSync(dir)) {
75
+ if (!f.endsWith('.md') || f === '.gitkeep')
76
+ continue;
77
+ const slug = path.basename(f, '.md');
78
+ if (map.has(slug))
79
+ continue;
80
+ const raw = fs.readFileSync(path.join(dir, f), 'utf-8');
81
+ const m = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
82
+ if (!m)
83
+ continue;
84
+ let fm;
85
+ try {
86
+ fm = yaml.load(m[1], { schema: yaml.FAILSAFE_SCHEMA });
87
+ }
88
+ catch {
89
+ continue;
90
+ }
91
+ map.set(slug, { slug, body: m[2], frontmatter: fm ?? {} });
92
+ }
93
+ if (map.size > 0)
94
+ break;
95
+ }
96
+ return map;
97
+ }
98
+ function writeUserTemplate(userDir, slug, entry) {
99
+ fs.mkdirSync(userDir, { recursive: true });
100
+ const fm = {
101
+ name: entry.name,
102
+ description: entry.description,
103
+ schedule: entry.schedule,
104
+ priority: entry.priority,
105
+ expectedDurationMinutes: entry.expectedDurationMinutes,
106
+ model: entry.model,
107
+ enabled: entry.enabled !== false,
108
+ };
109
+ if (Array.isArray(entry.tags))
110
+ fm.tags = entry.tags;
111
+ if (entry.gate)
112
+ fm.gate = entry.gate;
113
+ if (typeof entry.telegramNotify === 'boolean')
114
+ fm.telegramNotify = entry.telegramNotify;
115
+ // User jobs default to minimal Read allowlist per spec §Trust Model.
116
+ fm.toolAllowlist = ['Read'];
117
+ const fmYaml = yaml.dump(fm, { lineWidth: -1, noRefs: true, quotingType: '"' }).trimEnd();
118
+ const body = (entry.execute && typeof entry.execute.value === 'string') ? entry.execute.value : '';
119
+ const content = `---\n${fmYaml}\n---\n${body.endsWith('\n') ? body : body + '\n'}`;
120
+ const target = path.join(userDir, `${slug}.md`);
121
+ fs.writeFileSync(target, content, 'utf-8');
122
+ return target;
123
+ }
124
+ function writeManifest(scheduleDir, slug, origin, entry) {
125
+ fs.mkdirSync(scheduleDir, { recursive: true });
126
+ const manifest = {
127
+ slug,
128
+ origin,
129
+ schedule: entry.schedule,
130
+ enabled: entry.enabled !== false,
131
+ execute: entry.execute && entry.execute.type === 'prompt' ? { type: 'agentmd' } : entry.execute,
132
+ manifestVersion: 1,
133
+ };
134
+ const target = path.join(scheduleDir, `${slug}.json`);
135
+ fs.writeFileSync(target, JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
136
+ return target;
137
+ }
138
+ export function jobsMigrate(opts) {
139
+ const { agentStateDir, packageRoot } = opts;
140
+ const defaultAction = opts.defaultAction ?? 'fail';
141
+ const jobsJsonPath = path.join(agentStateDir, 'jobs.json');
142
+ const jobsRoot = path.join(agentStateDir, 'jobs');
143
+ const userDir = path.join(jobsRoot, 'user');
144
+ const scheduleDir = path.join(jobsRoot, 'schedule');
145
+ const instarDir = path.join(jobsRoot, 'instar');
146
+ const completedMarker = path.join(jobsRoot, '.migration-complete.json');
147
+ const abandonedMarker = path.join(jobsRoot, '.migration-abandoned.json');
148
+ const outcome = { status: 'completed', perEntry: [], errors: [] };
149
+ // ── Abandon path ────────────────────────────────────────────────────
150
+ if (opts.abandon) {
151
+ fs.mkdirSync(jobsRoot, { recursive: true });
152
+ if (fs.existsSync(scheduleDir)) {
153
+ SafeFsExecutor.safeRmSync(scheduleDir, { recursive: true, force: true, operation: 'jobsMigrate abandon: remove schedule/' });
154
+ }
155
+ if (fs.existsSync(instarDir)) {
156
+ SafeFsExecutor.safeRmSync(instarDir, { recursive: true, force: true, operation: 'jobsMigrate abandon: remove instar/' });
157
+ }
158
+ fs.writeFileSync(abandonedMarker, JSON.stringify({ abandonedAt: new Date().toISOString(), reason: 'operator-initiated abandon' }, null, 2), 'utf-8');
159
+ outcome.status = 'abandoned';
160
+ return outcome;
161
+ }
162
+ if (!fs.existsSync(jobsJsonPath)) {
163
+ outcome.errors.push(`No jobs.json at ${jobsJsonPath}; nothing to migrate.`);
164
+ outcome.status = 'aborted';
165
+ return outcome;
166
+ }
167
+ let rawJobs;
168
+ try {
169
+ rawJobs = JSON.parse(fs.readFileSync(jobsJsonPath, 'utf-8'));
170
+ if (!Array.isArray(rawJobs))
171
+ throw new Error('jobs.json root must be an array');
172
+ }
173
+ catch (err) {
174
+ outcome.errors.push(`Failed to parse jobs.json: ${err instanceof Error ? err.message : String(err)}`);
175
+ outcome.status = 'aborted';
176
+ return outcome;
177
+ }
178
+ const shipped = loadShippedDefaults(packageRoot);
179
+ // ── Dry-run / report path ───────────────────────────────────────────
180
+ if (opts.report) {
181
+ for (const entry of rawJobs) {
182
+ const slug = entry.slug;
183
+ const action = classifyEntry(entry, shipped);
184
+ const reason = action.kind === 'migrated-instar' ? undefined : action.reason;
185
+ outcome.perEntry.push({ slug, action: action.kind, reason });
186
+ }
187
+ outcome.status = 'reported';
188
+ return outcome;
189
+ }
190
+ // ── Write backup BEFORE any destructive write ───────────────────────
191
+ fs.mkdirSync(jobsRoot, { recursive: true });
192
+ const ts = new Date().toISOString().replace(/[:.]/g, '-');
193
+ const backupPath = path.join(agentStateDir, `jobs.json.pre-migrate-${ts}`);
194
+ fs.copyFileSync(jobsJsonPath, backupPath);
195
+ outcome.backupPath = backupPath;
196
+ // ── Per-entry migration ─────────────────────────────────────────────
197
+ for (const entry of rawJobs) {
198
+ const slug = entry.slug;
199
+ if (!slug || typeof slug !== 'string') {
200
+ outcome.errors.push(`Skipping entry without slug: ${JSON.stringify(entry).slice(0, 100)}`);
201
+ continue;
202
+ }
203
+ const classification = classifyEntry(entry, shipped);
204
+ try {
205
+ if (classification.kind === 'migrated-instar') {
206
+ // Body matched. Write per-slug manifest pointing at the instar template.
207
+ writeManifest(scheduleDir, slug, 'instar', entry);
208
+ outcome.perEntry.push({ slug, action: 'migrated-instar' });
209
+ continue;
210
+ }
211
+ if (classification.kind === 'near-miss-default') {
212
+ // Body did NOT match a shipped default. Apply --default-action.
213
+ if (defaultAction === 'fail') {
214
+ outcome.errors.push(`Near-miss on default "${slug}": body does not match shipped template. ` +
215
+ `Re-run with --default-action=fork|rename|skip.`);
216
+ outcome.status = 'aborted';
217
+ return outcome;
218
+ }
219
+ if (defaultAction === 'skip') {
220
+ outcome.perEntry.push({ slug, action: 'skipped', reason: 'near-miss, --default-action=skip' });
221
+ continue;
222
+ }
223
+ const targetSlug = defaultAction === 'rename' ? `${slug}-user` : slug;
224
+ const tgt = writeUserTemplate(userDir, targetSlug, entry);
225
+ writeManifest(scheduleDir, targetSlug, 'user', entry);
226
+ outcome.perEntry.push({
227
+ slug: targetSlug,
228
+ action: defaultAction === 'rename' ? 'renamed-user' : 'forked-user',
229
+ reason: classification.reason,
230
+ targetPath: tgt,
231
+ });
232
+ continue;
233
+ }
234
+ if (classification.kind === 'kept-user' || classification.kind === 'forked-user') {
235
+ const tgt = writeUserTemplate(userDir, slug, entry);
236
+ writeManifest(scheduleDir, slug, 'user', entry);
237
+ outcome.perEntry.push({
238
+ slug,
239
+ action: classification.kind === 'kept-user' ? 'kept-user' : 'forked-user',
240
+ reason: classification.reason,
241
+ targetPath: tgt,
242
+ });
243
+ continue;
244
+ }
245
+ // Non-prompt entries (skill, script) — leave them in jobs.json.
246
+ outcome.perEntry.push({ slug, action: 'skipped', reason: classification.reason });
247
+ }
248
+ catch (err) {
249
+ outcome.errors.push(`${slug}: ${err instanceof Error ? err.message : String(err)}`);
250
+ outcome.perEntry.push({ slug, action: 'failed' });
251
+ }
252
+ }
253
+ // ── Completion marker (operator confirms via dashboard before jobs.json delete) ──
254
+ // We do NOT write .migration-complete.json automatically — that's the
255
+ // operator's job via the Dashboard "Confirm migration complete" button.
256
+ // The release-cut gate refuses to delete jobs.json until this marker exists.
257
+ // Remove abandonment marker if present (a new migrate run is a re-attempt).
258
+ if (fs.existsSync(abandonedMarker)) {
259
+ SafeFsExecutor.safeUnlinkSync(abandonedMarker, { operation: 'jobsMigrate clear abandonment marker on re-run' });
260
+ }
261
+ if (fs.existsSync(completedMarker)) {
262
+ // operator may run migrate multiple times; the completion marker should
263
+ // be recreated by the Dashboard, not by the script.
264
+ }
265
+ return outcome;
266
+ }
267
+ function classifyEntry(entry, shipped) {
268
+ if (!entry.execute || entry.execute.type !== 'prompt') {
269
+ return { kind: 'skipped', reason: `execute.type=${entry.execute?.type ?? 'absent'} — only prompt-type entries migrate to agentmd` };
270
+ }
271
+ const shippedDefault = shipped.get(entry.slug);
272
+ if (!shippedDefault) {
273
+ // Slug not in the shipped defaults → user job.
274
+ return { kind: 'kept-user', reason: 'slug not in shipped defaults' };
275
+ }
276
+ const entryBody = entry.execute.value ?? '';
277
+ if (sha256(normalize(entryBody)) === sha256(normalize(shippedDefault.body))) {
278
+ return { kind: 'migrated-instar' };
279
+ }
280
+ // Slug matches a shipped default but body differs. The --default-action
281
+ // flag drives the resolution (fork | rename | skip | fail). The
282
+ // Levenshtein distance is informational only for the operator-facing
283
+ // report — it doesn't change the routing.
284
+ const dist = levenshtein(normalize(entryBody), normalize(shippedDefault.body));
285
+ const maxLen = Math.max(entryBody.length, shippedDefault.body.length);
286
+ const pct = maxLen ? Math.round((dist / maxLen) * 100) : 100;
287
+ return {
288
+ kind: 'near-miss-default',
289
+ reason: `body differs from shipped default (~${pct}% changed by Levenshtein)`,
290
+ };
291
+ }
292
+ //# sourceMappingURL=jobMigrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jobMigrate.js","sourceRoot":"","sources":["../../src/commands/jobMigrate.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAkQH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAw4CD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA8nKtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmQH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAw4CD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAusKtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
@@ -26,6 +26,7 @@ import { TelegramAdapter, TOPIC_STYLE, selectTopicEmoji } from '../messaging/Tel
26
26
  import { RelationshipManager } from '../core/RelationshipManager.js';
27
27
  import { ClaudeCliIntelligenceProvider } from '../core/ClaudeCliIntelligenceProvider.js';
28
28
  import { AnthropicIntelligenceProvider } from '../core/AnthropicIntelligenceProvider.js';
29
+ import { selectIntelligenceProvider } from '../core/selectIntelligenceProvider.js';
29
30
  import { FeedbackManager } from '../core/FeedbackManager.js';
30
31
  import { FeedbackAnomalyDetector } from '../monitoring/FeedbackAnomalyDetector.js';
31
32
  import { DispatchManager } from '../core/DispatchManager.js';
@@ -1815,48 +1816,33 @@ export async function startServer(options) {
1815
1816
  _topicResumeMap = new TopicResumeMap(config.stateDir, config.sessions.projectDir, config.sessions.tmuxPath);
1816
1817
  _projectDir = config.sessions.projectDir;
1817
1818
  // Shared intelligence provider — lightweight LLM for internal classification tasks.
1818
- // Priority: Claude CLI subscription (zero extra cost, default) → Anthropic API (explicit opt-in)
1819
- // Components that need LLM intelligence (Sentinel, TelegramAdapter, etc.) share this.
1820
- //
1821
- // Rationale: Instar must not depend on an API key. The subscription path is the default so
1822
- // every agent gets LLM-gated features out of the box. Users who prefer direct API access can
1823
- // set `intelligenceProvider: "anthropic-api"` in config.json.
1824
- let sharedIntelligence;
1825
- const explicitIntelligenceProvider = config.intelligenceProvider;
1826
- let intelligenceSource = 'none';
1827
- if (explicitIntelligenceProvider === 'anthropic-api') {
1828
- try {
1829
- const apiProvider = AnthropicIntelligenceProvider.fromEnv();
1830
- if (apiProvider) {
1831
- sharedIntelligence = apiProvider;
1832
- intelligenceSource = 'Anthropic API (explicit opt-in)';
1833
- }
1834
- else {
1835
- console.log(pc.yellow(' intelligenceProvider: "anthropic-api" set but ANTHROPIC_API_KEY not found — falling back to Claude CLI'));
1836
- }
1837
- }
1838
- catch { /* no API key available */ }
1839
- }
1840
- if (!sharedIntelligence) {
1841
- try {
1842
- sharedIntelligence = new ClaudeCliIntelligenceProvider(config.sessions.claudePath);
1843
- intelligenceSource = 'Claude CLI subscription';
1844
- }
1845
- catch { /* CLI not available */ }
1846
- }
1847
- if (!sharedIntelligence && explicitIntelligenceProvider !== 'anthropic-api') {
1848
- // Last resort: if user has API key but didn't explicitly opt in, use it rather than
1849
- // leaving the agent flying blind. We prefer subscription, but degrading to heuristics
1850
- // is worse than using whatever LLM is available.
1851
- try {
1852
- const apiProvider = AnthropicIntelligenceProvider.fromEnv();
1853
- if (apiProvider) {
1854
- sharedIntelligence = apiProvider;
1855
- intelligenceSource = 'Anthropic API (CLI unavailable — last resort)';
1856
- }
1857
- }
1858
- catch { /* no API key available */ }
1859
- }
1819
+ // Subscription-by-default: API mode requires BOTH `intelligenceProvider: "anthropic-api"`
1820
+ // AND `intelligenceProviderConfirmed: true`. The selection logic lives in a separate
1821
+ // pure function so the safety rules are unit-testable.
1822
+ const apiOpts = config;
1823
+ const selection = selectIntelligenceProvider({
1824
+ intelligenceProvider: apiOpts.intelligenceProvider,
1825
+ intelligenceProviderConfirmed: apiOpts.intelligenceProviderConfirmed,
1826
+ anthropicApiKey: process.env['ANTHROPIC_API_KEY'],
1827
+ claudePath: config.sessions.claudePath,
1828
+ buildClaude: (claudePath) => new ClaudeCliIntelligenceProvider(claudePath),
1829
+ buildAnthropic: (apiKey) => new AnthropicIntelligenceProvider(apiKey),
1830
+ });
1831
+ const sharedIntelligence = selection.provider ?? undefined;
1832
+ for (const w of selection.warnings)
1833
+ console.log(pc.yellow(` ${w}`));
1834
+ if (selection.apiModeActive) {
1835
+ console.log(pc.yellow(' ┌─────────────────────────────────────────────────────────────────────┐'));
1836
+ console.log(pc.yellow(' │ BILLING: Anthropic API mode is ACTIVE — per-call charges apply │'));
1837
+ console.log(pc.yellow(' │ To switch back to subscription, unset intelligenceProvider in config│'));
1838
+ console.log(pc.yellow(' └─────────────────────────────────────────────────────────────────────┘'));
1839
+ }
1840
+ const intelligenceSourceLabel = {
1841
+ 'anthropic-api-confirmed': 'Anthropic API (explicit opt-in, confirmed)',
1842
+ 'claude-cli': 'Claude CLI subscription',
1843
+ 'none': 'none',
1844
+ };
1845
+ const intelligenceSource = intelligenceSourceLabel[selection.source];
1860
1846
  _sharedIntelligence = sharedIntelligence ?? null;
1861
1847
  if (sharedIntelligence) {
1862
1848
  console.log(pc.gray(` Intelligence: ${intelligenceSource}`));
@@ -3048,6 +3034,16 @@ export async function startServer(options) {
3048
3034
  impact: 'Knowledge graph unavailable. Migration, semantic search, and entity-relationship queries disabled.',
3049
3035
  });
3050
3036
  }
3037
+ // Pre-prompt memory recall (OpenClaw import T2.2). Bounded synchronous
3038
+ // recall pass that runs before UserPromptSubmit injects context. Default
3039
+ // off; opt in via config.promptBuildRecall.enabled.
3040
+ const promptRecallCfg = config.promptBuildRecall;
3041
+ if (promptRecallCfg?.enabled && semanticMemory) {
3042
+ const { PromptBuildRecall, DEFAULT_PROMPT_BUILD_RECALL_CONFIG } = await import('../core/PromptBuildRecall.js');
3043
+ const recall = new PromptBuildRecall({ semanticMemory }, { ...DEFAULT_PROMPT_BUILD_RECALL_CONFIG, ...promptRecallCfg });
3044
+ globalThis.__instarPromptBuildRecall = recall;
3045
+ console.log(pc.green(' Pre-prompt memory recall enabled'));
3046
+ }
3051
3047
  // WorkingMemoryAssembler is initialized after activitySentinel (see below)
3052
3048
  // so it can wire episodicMemory from the sentinel.
3053
3049
  let workingMemory;
@@ -4096,6 +4092,23 @@ export async function startServer(options) {
4096
4092
  }, 10_000);
4097
4093
  });
4098
4094
  console.log(pc.green(' Compaction auto-resume wired (PreCompact hook event)'));
4095
+ // Pre-compaction memory flush — write durable facts before compaction
4096
+ // collapses working memory. Off by default; enable via config.preCompactionFlush.
4097
+ // See docs/specs/OPENCLAW-IMPORT-PRE-COMPACTION-FLUSH-SPEC.md.
4098
+ const preCompactFlushCfg = config.preCompactionFlush;
4099
+ if (preCompactFlushCfg?.enabled) {
4100
+ const { PreCompactionFlush, DEFAULT_PRE_COMPACTION_FLUSH_CONFIG } = await import('../core/PreCompactionFlush.js');
4101
+ const flush = new PreCompactionFlush({
4102
+ intelligence: sharedIntelligence ?? null,
4103
+ projectDir: config.projectDir,
4104
+ }, { ...DEFAULT_PRE_COMPACTION_FLUSH_CONFIG, ...preCompactFlushCfg });
4105
+ hookEventReceiver.on('PreCompact', (payload) => {
4106
+ flush.handle(payload).catch(() => {
4107
+ /* handle() owns its audit; never throws. */
4108
+ });
4109
+ });
4110
+ console.log(pc.green(' Pre-compaction memory flush enabled'));
4111
+ }
4099
4112
  // Trigger 2: Watchdog 'compaction-idle' polling — report to sentinel.
4100
4113
  if (watchdog) {
4101
4114
  watchdog.on('compaction-idle', (sessionName) => {
@@ -6090,6 +6103,39 @@ export async function startServer(options) {
6090
6103
  toneGate: messagingToneGate ?? null,
6091
6104
  });
6092
6105
  }
6106
+ // Tier-2 live-mode wire-up (SELF-HEALING-REMEDIATOR-V2-SPEC §A57).
6107
+ //
6108
+ // When `config.remediator.enabled === true`, construct the full F-1..F-8
6109
+ // dispatch graph and register it with the DegradationReporter via the
6110
+ // F-3 `setRemediator()` hook. Default is OFF — the legacy alert path
6111
+ // + in-line healers (NativeModuleHealer.openWithHeal, supervisor
6112
+ // preflightSelfHeal) remain the safety net regardless of Remediator
6113
+ // state. See upgrades/side-effects/tier2-degradation-reporter-live-wire.md.
6114
+ {
6115
+ const remediatorEnabled = config
6116
+ .remediator?.enabled === true;
6117
+ if (remediatorEnabled) {
6118
+ try {
6119
+ const { bootstrapRemediator } = await import('../remediation/RemediatorBootstrap.js');
6120
+ const machineIdForRemediator = coordinator.identity?.machineId ?? os.hostname();
6121
+ const bootstrapResult = await bootstrapRemediator({
6122
+ stateDir: config.stateDir,
6123
+ machineId: machineIdForRemediator,
6124
+ autonomyProfile: config.autonomyProfile,
6125
+ });
6126
+ if (bootstrapResult.disabled) {
6127
+ console.log(pc.yellow(` Remediator live-mode requested but disabled: ${bootstrapResult.reason} — legacy alert path active.`));
6128
+ }
6129
+ else {
6130
+ degradationReporter.setRemediator(bootstrapResult.remediator);
6131
+ console.log(pc.green(` Remediator live-mode active (runbooks: ${bootstrapResult.registeredRunbookIds.join(', ') || 'none'}).`));
6132
+ }
6133
+ }
6134
+ catch (err) {
6135
+ console.error(pc.red(` Remediator bootstrap failed: ${err instanceof Error ? err.message : String(err)}. Legacy alert path active.`));
6136
+ }
6137
+ }
6138
+ }
6093
6139
  // Periodic housekeeping — calls orphaned cleanup methods every 6 hours.
6094
6140
  // These methods exist on their respective classes but were never scheduled.
6095
6141
  const HOUSEKEEPING_INTERVAL_MS = 6 * 60 * 60 * 1000;