instar 0.28.102 → 0.28.103
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.
- package/.claude/hooks/instar/before-prompt-recall.js +90 -0
- package/dist/cli.js +28 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +14 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/jobMigrate.d.ts +46 -0
- package/dist/commands/jobMigrate.d.ts.map +1 -0
- package/dist/commands/jobMigrate.js +292 -0
- package/dist/commands/jobMigrate.js.map +1 -0
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +88 -42
- package/dist/commands/server.js.map +1 -1
- package/dist/core/BackupManager.d.ts +27 -1
- package/dist/core/BackupManager.d.ts.map +1 -1
- package/dist/core/BackupManager.js +56 -1
- package/dist/core/BackupManager.js.map +1 -1
- package/dist/core/GitStateManager.d.ts +8 -0
- package/dist/core/GitStateManager.d.ts.map +1 -1
- package/dist/core/GitStateManager.js +31 -1
- package/dist/core/GitStateManager.js.map +1 -1
- package/dist/core/MigratorStepEngine.d.ts +170 -0
- package/dist/core/MigratorStepEngine.d.ts.map +1 -0
- package/dist/core/MigratorStepEngine.js +352 -0
- package/dist/core/MigratorStepEngine.js.map +1 -0
- package/dist/core/PostUpdateMigrator.d.ts +76 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +252 -1
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/PreCompactionFlush.d.ts +101 -0
- package/dist/core/PreCompactionFlush.d.ts.map +1 -0
- package/dist/core/PreCompactionFlush.js +282 -0
- package/dist/core/PreCompactionFlush.js.map +1 -0
- package/dist/core/PromptBuildRecall.d.ts +97 -0
- package/dist/core/PromptBuildRecall.d.ts.map +1 -0
- package/dist/core/PromptBuildRecall.js +152 -0
- package/dist/core/PromptBuildRecall.js.map +1 -0
- package/dist/core/selectIntelligenceProvider.d.ts +41 -0
- package/dist/core/selectIntelligenceProvider.d.ts.map +1 -0
- package/dist/core/selectIntelligenceProvider.js +89 -0
- package/dist/core/selectIntelligenceProvider.js.map +1 -0
- package/dist/lifeline/ServerSupervisor.d.ts +183 -0
- package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
- package/dist/lifeline/ServerSupervisor.js +443 -0
- package/dist/lifeline/ServerSupervisor.js.map +1 -1
- package/dist/memory/NativeModuleHealer.d.ts +89 -0
- package/dist/memory/NativeModuleHealer.d.ts.map +1 -1
- package/dist/memory/NativeModuleHealer.js +371 -1
- package/dist/memory/NativeModuleHealer.js.map +1 -1
- package/dist/memory/SemanticMemory.d.ts +131 -0
- package/dist/memory/SemanticMemory.d.ts.map +1 -1
- package/dist/memory/SemanticMemory.js +315 -0
- package/dist/memory/SemanticMemory.js.map +1 -1
- package/dist/messaging/DeliveryRetryManager.d.ts +60 -0
- package/dist/messaging/DeliveryRetryManager.d.ts.map +1 -1
- package/dist/messaging/DeliveryRetryManager.js +104 -0
- package/dist/messaging/DeliveryRetryManager.js.map +1 -1
- package/dist/monitoring/DegradationReporter.d.ts +164 -0
- package/dist/monitoring/DegradationReporter.d.ts.map +1 -1
- package/dist/monitoring/DegradationReporter.js +309 -1
- package/dist/monitoring/DegradationReporter.js.map +1 -1
- package/dist/monitoring/ErrorCodeExtractor.d.ts +69 -0
- package/dist/monitoring/ErrorCodeExtractor.d.ts.map +1 -0
- package/dist/monitoring/ErrorCodeExtractor.js +131 -0
- package/dist/monitoring/ErrorCodeExtractor.js.map +1 -0
- package/dist/monitoring/PromptGate.d.ts +34 -0
- package/dist/monitoring/PromptGate.d.ts.map +1 -1
- package/dist/monitoring/PromptGate.js +81 -1
- package/dist/monitoring/PromptGate.js.map +1 -1
- package/dist/monitoring/Redactor.d.ts +58 -0
- package/dist/monitoring/Redactor.d.ts.map +1 -0
- package/dist/monitoring/Redactor.js +143 -0
- package/dist/monitoring/Redactor.js.map +1 -0
- package/dist/monitoring/probes/LifelineProbe.d.ts +7 -0
- package/dist/monitoring/probes/LifelineProbe.d.ts.map +1 -1
- package/dist/monitoring/probes/LifelineProbe.js +7 -0
- package/dist/monitoring/probes/LifelineProbe.js.map +1 -1
- package/dist/monitoring/probes/__shared.d.ts +50 -0
- package/dist/monitoring/probes/__shared.d.ts.map +1 -0
- package/dist/monitoring/probes/__shared.js +51 -0
- package/dist/monitoring/probes/__shared.js.map +1 -0
- package/dist/remediation/IntentJournal.d.ts +64 -0
- package/dist/remediation/IntentJournal.d.ts.map +1 -0
- package/dist/remediation/IntentJournal.js +118 -0
- package/dist/remediation/IntentJournal.js.map +1 -0
- package/dist/remediation/MachineLock.d.ts +137 -0
- package/dist/remediation/MachineLock.d.ts.map +1 -0
- package/dist/remediation/MachineLock.js +314 -0
- package/dist/remediation/MachineLock.js.map +1 -0
- package/dist/remediation/PrimaryAggregatorLease.d.ts +205 -0
- package/dist/remediation/PrimaryAggregatorLease.d.ts.map +1 -0
- package/dist/remediation/PrimaryAggregatorLease.js +450 -0
- package/dist/remediation/PrimaryAggregatorLease.js.map +1 -0
- package/dist/remediation/RemediationContext.d.ts +63 -0
- package/dist/remediation/RemediationContext.d.ts.map +1 -0
- package/dist/remediation/RemediationContext.js +109 -0
- package/dist/remediation/RemediationContext.js.map +1 -0
- package/dist/remediation/RemediationKeyVault.d.ts +123 -0
- package/dist/remediation/RemediationKeyVault.d.ts.map +1 -0
- package/dist/remediation/RemediationKeyVault.js +564 -0
- package/dist/remediation/RemediationKeyVault.js.map +1 -0
- package/dist/remediation/Remediator.d.ts +288 -0
- package/dist/remediation/Remediator.d.ts.map +1 -0
- package/dist/remediation/Remediator.js +520 -0
- package/dist/remediation/Remediator.js.map +1 -0
- package/dist/remediation/RemediatorBootstrap.d.ts +141 -0
- package/dist/remediation/RemediatorBootstrap.d.ts.map +1 -0
- package/dist/remediation/RemediatorBootstrap.js +255 -0
- package/dist/remediation/RemediatorBootstrap.js.map +1 -0
- package/dist/remediation/TrustElevationSource.d.ts +153 -0
- package/dist/remediation/TrustElevationSource.d.ts.map +1 -0
- package/dist/remediation/TrustElevationSource.js +208 -0
- package/dist/remediation/TrustElevationSource.js.map +1 -0
- package/dist/remediation/audit/AuditProjection.d.ts +37 -0
- package/dist/remediation/audit/AuditProjection.d.ts.map +1 -0
- package/dist/remediation/audit/AuditProjection.js +118 -0
- package/dist/remediation/audit/AuditProjection.js.map +1 -0
- package/dist/remediation/audit/AuditWriter.d.ts +79 -0
- package/dist/remediation/audit/AuditWriter.d.ts.map +1 -0
- package/dist/remediation/audit/AuditWriter.js +132 -0
- package/dist/remediation/audit/AuditWriter.js.map +1 -0
- package/dist/remediation/channels/CliApprovalChannel.d.ts +37 -0
- package/dist/remediation/channels/CliApprovalChannel.d.ts.map +1 -0
- package/dist/remediation/channels/CliApprovalChannel.js +45 -0
- package/dist/remediation/channels/CliApprovalChannel.js.map +1 -0
- package/dist/remediation/channels/TelegramApprovalChannel.d.ts +37 -0
- package/dist/remediation/channels/TelegramApprovalChannel.d.ts.map +1 -0
- package/dist/remediation/channels/TelegramApprovalChannel.js +45 -0
- package/dist/remediation/channels/TelegramApprovalChannel.js.map +1 -0
- package/dist/remediation/runbooks/db-corruption.d.ts +86 -0
- package/dist/remediation/runbooks/db-corruption.d.ts.map +1 -0
- package/dist/remediation/runbooks/db-corruption.js +190 -0
- package/dist/remediation/runbooks/db-corruption.js.map +1 -0
- package/dist/remediation/runbooks/messaging-delivery-failed.d.ts +108 -0
- package/dist/remediation/runbooks/messaging-delivery-failed.d.ts.map +1 -0
- package/dist/remediation/runbooks/messaging-delivery-failed.js +172 -0
- package/dist/remediation/runbooks/messaging-delivery-failed.js.map +1 -0
- package/dist/remediation/runbooks/node-abi-mismatch.d.ts +70 -0
- package/dist/remediation/runbooks/node-abi-mismatch.d.ts.map +1 -0
- package/dist/remediation/runbooks/node-abi-mismatch.js +216 -0
- package/dist/remediation/runbooks/node-abi-mismatch.js.map +1 -0
- package/dist/remediation/runbooks/supervisor-preflight.d.ts +114 -0
- package/dist/remediation/runbooks/supervisor-preflight.d.ts.map +1 -0
- package/dist/remediation/runbooks/supervisor-preflight.js +299 -0
- package/dist/remediation/runbooks/supervisor-preflight.js.map +1 -0
- package/dist/scheduler/AgentMdAtomicSave.d.ts +85 -0
- package/dist/scheduler/AgentMdAtomicSave.d.ts.map +1 -0
- package/dist/scheduler/AgentMdAtomicSave.js +169 -0
- package/dist/scheduler/AgentMdAtomicSave.js.map +1 -0
- package/dist/scheduler/AgentMdReconcile.d.ts +62 -0
- package/dist/scheduler/AgentMdReconcile.d.ts.map +1 -0
- package/dist/scheduler/AgentMdReconcile.js +212 -0
- package/dist/scheduler/AgentMdReconcile.js.map +1 -0
- package/dist/scheduler/DisabledBodyDrift.d.ts +70 -0
- package/dist/scheduler/DisabledBodyDrift.d.ts.map +1 -0
- package/dist/scheduler/DisabledBodyDrift.js +149 -0
- package/dist/scheduler/DisabledBodyDrift.js.map +1 -0
- package/dist/scheduler/InstallBuiltinJobs.d.ts +53 -0
- package/dist/scheduler/InstallBuiltinJobs.d.ts.map +1 -0
- package/dist/scheduler/InstallBuiltinJobs.js +212 -0
- package/dist/scheduler/InstallBuiltinJobs.js.map +1 -0
- package/dist/scheduler/JobLoader.d.ts.map +1 -1
- package/dist/scheduler/JobLoader.js +48 -0
- package/dist/scheduler/JobLoader.js.map +1 -1
- package/dist/scheduler/MigrationInvariants.d.ts +62 -0
- package/dist/scheduler/MigrationInvariants.d.ts.map +1 -0
- package/dist/scheduler/MigrationInvariants.js +215 -0
- package/dist/scheduler/MigrationInvariants.js.map +1 -0
- package/dist/scheduler/MigrationLedger.d.ts +84 -0
- package/dist/scheduler/MigrationLedger.d.ts.map +1 -0
- package/dist/scheduler/MigrationLedger.js +114 -0
- package/dist/scheduler/MigrationLedger.js.map +1 -0
- package/dist/server/fileRoutes.d.ts.map +1 -1
- package/dist/server/fileRoutes.js +7 -0
- package/dist/server/fileRoutes.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +141 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +3 -2
- package/scripts/classify-default-drift.mjs +238 -0
- package/scripts/eli16-overview-check.mjs +85 -0
- package/scripts/instar-dev-precommit.js +60 -1
- package/scripts/lint-degradation-emit-sites.js +116 -0
- package/scripts/lint-no-direct-destructive.js +12 -0
- package/scripts/protect-migration-guarantee.js +61 -0
- package/scripts/regen-default-job-templates.mjs +111 -0
- package/scripts/verify-runbook-pr-signature.js +366 -0
- package/src/data/builtin-manifest.json +93 -93
- package/src/scaffold/bootstrap.ts +138 -0
- package/src/scaffold/keys/instar-release-pub.pem +3 -0
- package/src/scaffold/templates/jobs/instar/.gitkeep +0 -0
- package/src/scaffold/templates/jobs/instar/commitment-detection.md +28 -0
- package/src/scaffold/templates/jobs/instar/evolution-overdue-check.md +28 -0
- package/src/scaffold/templates/jobs/instar/evolution-proposal-evaluate.md +30 -0
- package/src/scaffold/templates/jobs/instar/evolution-proposal-implement.md +25 -0
- package/src/scaffold/templates/jobs/instar/health-check.md +14 -0
- package/src/scaffold/templates/jobs/instar/identity-review.md +42 -0
- package/src/scaffold/templates/jobs/instar/insight-harvest.md +31 -0
- package/src/scaffold/templates/jobs/instar/overseer-development.md +23 -0
- package/src/scaffold/templates/jobs/instar/overseer-guardian.md +28 -0
- package/src/scaffold/templates/jobs/instar/overseer-infrastructure.md +26 -0
- package/src/scaffold/templates/jobs/instar/overseer-learning.md +28 -0
- package/src/scaffold/templates/jobs/instar/overseer-maintenance.md +27 -0
- package/src/scaffold/templates/jobs/instar/reflection-trigger.md +40 -0
- package/src/scaffold/templates/jobs/instar/relationship-maintenance.md +16 -0
- package/src/scaffold/templates.ts +1616 -0
- package/upgrades/0.28.102.md +6 -7
- package/upgrades/0.28.103.md +471 -0
- package/upgrades/side-effects/a47-primary-aggregator-lease.md +82 -0
- package/upgrades/side-effects/agentmd-atomic-save.md +66 -0
- package/upgrades/side-effects/agentmd-loader-200jobs-perf-benchmark.md +50 -0
- package/upgrades/side-effects/agentmd-reconcile-boot-lifecycle.md +66 -0
- package/upgrades/side-effects/api-safety-guard.md +80 -0
- package/upgrades/side-effects/c1-runbook-pr-gate.md +83 -0
- package/upgrades/side-effects/disabled-body-drift-detection.md +59 -0
- package/upgrades/side-effects/drift-classifier-release-time.md +71 -0
- package/upgrades/side-effects/eli16-overview-required-gate.md +77 -0
- package/upgrades/side-effects/f1-remediation-key-vault.md +195 -0
- package/upgrades/side-effects/f2-redactor-errorcode-extractor.md +130 -0
- package/upgrades/side-effects/f3-degradation-reporter-shim.md +105 -0
- package/upgrades/side-effects/f4-machine-locks-intent-journal-audit.md +117 -0
- package/upgrades/side-effects/f5-trust-elevation-source.md +258 -0
- package/upgrades/side-effects/f6-supervisor-handshake.md +234 -0
- package/upgrades/side-effects/f7-post-update-migrator-atomic-step.md +129 -0
- package/upgrades/side-effects/f8-remediator-skeleton.md +153 -0
- package/upgrades/side-effects/f8-rest-enforcement.md +72 -0
- package/upgrades/side-effects/file-viewer-jobs-instar-never-editable.md +41 -0
- package/upgrades/side-effects/frontmatter-interpolation-breakout-test.md +48 -0
- package/upgrades/side-effects/jobs-as-agentmd-phase-2.md +78 -0
- package/upgrades/side-effects/jobs-as-agentmd-phase-3.md +76 -0
- package/upgrades/side-effects/jobs-as-agentmd-phase-4-endpoints.md +62 -0
- package/upgrades/side-effects/jobs-as-agentmd-phase-5.md +67 -0
- package/upgrades/side-effects/jobs-as-agentmd-phase-6.md +53 -0
- package/upgrades/side-effects/jobs-endpoints-auth-verification.md +52 -0
- package/upgrades/side-effects/migration-guarantee-suite.md +61 -0
- package/upgrades/side-effects/migration-runtime-invariant-gate.md +59 -0
- package/upgrades/side-effects/migration-telemetry-invariant-8.md +68 -0
- package/upgrades/side-effects/npm-pack-templates-smoke.md +51 -0
- package/upgrades/side-effects/openclaw-import-before-prompt-build.md +84 -0
- package/upgrades/side-effects/openclaw-import-pre-compaction-flush.md +85 -0
- package/upgrades/side-effects/prompt-gate-no-prompt-cache.md +258 -0
- package/upgrades/side-effects/tier2-degradation-reporter-live-wire.md +146 -0
- package/upgrades/side-effects/w1-node-abi-mismatch-runbook.md +154 -0
- package/upgrades/side-effects/w2-supervisor-preflight-runbook.md +176 -0
- package/upgrades/side-effects/w3-messaging-delivery-failed-runbook.md +185 -0
- package/upgrades/side-effects/w4-db-corruption-runbook.md +114 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MigratorStepEngine — atomic-step primitive for post-update migrations.
|
|
3
|
+
*
|
|
4
|
+
* Implements F-7 of `docs/specs/SELF-HEALING-REMEDIATOR-V2-SPEC.md`
|
|
5
|
+
* (§R1 Upgrade invariants + §A35 + §A50 + §A57 Tier-2). Provides:
|
|
6
|
+
*
|
|
7
|
+
* 1. `MigratorStepEngine` — registers named, idempotent, run-once-per-
|
|
8
|
+
* version atomic steps that fire at release boundaries. Each step is
|
|
9
|
+
* self-contained; one step failing does NOT roll back prior steps or
|
|
10
|
+
* prevent subsequent steps from running. Persisted state lives at
|
|
11
|
+
* `<stateDir>/migrator-steps-completed.json` keyed by
|
|
12
|
+
* `<version>:<step-name>`.
|
|
13
|
+
*
|
|
14
|
+
* 2. `AnnouncementManager` — `announceOnce` primitive for "show this
|
|
15
|
+
* message to the user exactly once and then never again". Used for
|
|
16
|
+
* surfacing migration completions, structural changes, or any other
|
|
17
|
+
* one-shot user-facing notice. Persisted state lives at
|
|
18
|
+
* `<stateDir>/announcements-shown.json` keyed by announcementId.
|
|
19
|
+
*
|
|
20
|
+
* Design notes:
|
|
21
|
+
*
|
|
22
|
+
* - Atomic: each step records outcome (completed | skipped | failed)
|
|
23
|
+
* atomically (temp-file → fsync → rename). A crash mid-step leaves
|
|
24
|
+
* the ledger consistent — either the step is recorded or it isn't,
|
|
25
|
+
* never partial.
|
|
26
|
+
*
|
|
27
|
+
* - Version-gated: a step `version: "1.2.3"` runs only when the engine
|
|
28
|
+
* is invoked with `toVersion >= "1.2.3"` (semver compare). Steps for
|
|
29
|
+
* versions strictly newer than `toVersion` are skipped without being
|
|
30
|
+
* recorded — they will run on the next update boundary that catches
|
|
31
|
+
* up to them.
|
|
32
|
+
*
|
|
33
|
+
* - Once-per-version-step pair: a successful step is recorded with key
|
|
34
|
+
* `<version>:<step-name>`. Re-runs of `runPendingSteps()` short-circuit
|
|
35
|
+
* on that key. A FAILED step IS also recorded (with outcome `failed`)
|
|
36
|
+
* so the same broken step doesn't re-run unbounded on every update —
|
|
37
|
+
* operators see the failure in the report and decide whether to retry.
|
|
38
|
+
*
|
|
39
|
+
* - No rollback. Each step must be self-contained and atomic on its
|
|
40
|
+
* own. The spec deliberately rejects step ordering / dependency /
|
|
41
|
+
* rollback semantics — those couplings are what made v1's migrator
|
|
42
|
+
* unmaintainable.
|
|
43
|
+
*/
|
|
44
|
+
import fs from 'node:fs';
|
|
45
|
+
import path from 'node:path';
|
|
46
|
+
// ── Semver comparison (minimal, sufficient for this engine) ─────────
|
|
47
|
+
const VERSION_RE = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
48
|
+
function parseVersion(v) {
|
|
49
|
+
const m = VERSION_RE.exec(v.trim());
|
|
50
|
+
if (!m)
|
|
51
|
+
return null;
|
|
52
|
+
return [parseInt(m[1], 10), parseInt(m[2], 10), parseInt(m[3], 10), m[4] ?? ''];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Compare two semver strings. Returns -1 / 0 / 1. Pre-release strings are
|
|
56
|
+
* compared lexically when major.minor.patch match (good-enough for our
|
|
57
|
+
* "run on version >= X" usage). Unparseable inputs sort as -Infinity so
|
|
58
|
+
* a malformed `fromVersion` never blocks step execution.
|
|
59
|
+
*/
|
|
60
|
+
export function compareSemver(a, b) {
|
|
61
|
+
const pa = parseVersion(a);
|
|
62
|
+
const pb = parseVersion(b);
|
|
63
|
+
if (!pa && !pb)
|
|
64
|
+
return 0;
|
|
65
|
+
if (!pa)
|
|
66
|
+
return -1;
|
|
67
|
+
if (!pb)
|
|
68
|
+
return 1;
|
|
69
|
+
for (let i = 0; i < 3; i++) {
|
|
70
|
+
if (pa[i] < pb[i])
|
|
71
|
+
return -1;
|
|
72
|
+
if (pa[i] > pb[i])
|
|
73
|
+
return 1;
|
|
74
|
+
}
|
|
75
|
+
// major.minor.patch equal — compare pre-release. Absent pre-release
|
|
76
|
+
// outranks any pre-release (e.g. 1.0.0 > 1.0.0-rc1).
|
|
77
|
+
const preA = pa[3];
|
|
78
|
+
const preB = pb[3];
|
|
79
|
+
if (preA === '' && preB === '')
|
|
80
|
+
return 0;
|
|
81
|
+
if (preA === '')
|
|
82
|
+
return 1;
|
|
83
|
+
if (preB === '')
|
|
84
|
+
return -1;
|
|
85
|
+
if (preA < preB)
|
|
86
|
+
return -1;
|
|
87
|
+
if (preA > preB)
|
|
88
|
+
return 1;
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
// ── MigratorStepEngine ───────────────────────────────────────────────
|
|
92
|
+
export class MigratorStepEngine {
|
|
93
|
+
stateDir;
|
|
94
|
+
steps = [];
|
|
95
|
+
/** Path to the step-completion ledger. */
|
|
96
|
+
ledgerPath;
|
|
97
|
+
constructor(stateDir) {
|
|
98
|
+
this.stateDir = path.resolve(stateDir);
|
|
99
|
+
this.ledgerPath = path.join(this.stateDir, 'migrator-steps-completed.json');
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Register an atomic step. Steps run in registration order on each
|
|
103
|
+
* invocation of `runPendingSteps()`, subject to the version gate and
|
|
104
|
+
* the per-version-per-step idempotency guard.
|
|
105
|
+
*
|
|
106
|
+
* Duplicate `name` values are rejected at registration time — names
|
|
107
|
+
* are global identifiers in the ledger.
|
|
108
|
+
*/
|
|
109
|
+
registerStep(step) {
|
|
110
|
+
if (!step.name || typeof step.name !== 'string') {
|
|
111
|
+
throw new Error('MigratorStepEngine.registerStep: step.name is required');
|
|
112
|
+
}
|
|
113
|
+
if (!step.version || typeof step.version !== 'string') {
|
|
114
|
+
throw new Error(`MigratorStepEngine.registerStep: step.version is required (step=${step.name})`);
|
|
115
|
+
}
|
|
116
|
+
if (typeof step.run !== 'function') {
|
|
117
|
+
throw new Error(`MigratorStepEngine.registerStep: step.run must be a function (step=${step.name})`);
|
|
118
|
+
}
|
|
119
|
+
for (const existing of this.steps) {
|
|
120
|
+
if (existing.name === step.name) {
|
|
121
|
+
throw new Error(`MigratorStepEngine.registerStep: duplicate step name "${step.name}"`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
this.steps.push(step);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Run every pending step. A step is "pending" when:
|
|
128
|
+
* - its `version <= toVersion` (semver compare), AND
|
|
129
|
+
* - no ledger entry exists for `<version>:<name>`.
|
|
130
|
+
*
|
|
131
|
+
* Steps for versions strictly newer than `toVersion` are reported as
|
|
132
|
+
* `skipped` (with details: `future-version`) but NOT recorded — they
|
|
133
|
+
* will run on a later update boundary that crosses their threshold.
|
|
134
|
+
*
|
|
135
|
+
* Steps whose ledger entry already exists are reported as `skipped`
|
|
136
|
+
* (with details: `already-recorded:<previous-outcome>`).
|
|
137
|
+
*
|
|
138
|
+
* Each step is executed under a try/catch; thrown errors are converted
|
|
139
|
+
* to `outcome: 'failed'` and recorded. The engine never propagates
|
|
140
|
+
* step failures to the caller — one broken step cannot block subsequent
|
|
141
|
+
* steps.
|
|
142
|
+
*/
|
|
143
|
+
async runPendingSteps(fromVersion, toVersion) {
|
|
144
|
+
if (!fs.existsSync(this.stateDir)) {
|
|
145
|
+
fs.mkdirSync(this.stateDir, { recursive: true });
|
|
146
|
+
}
|
|
147
|
+
const ledger = this.readLedger();
|
|
148
|
+
const report = { steps: [] };
|
|
149
|
+
for (const step of this.steps) {
|
|
150
|
+
const key = `${step.version}:${step.name}`;
|
|
151
|
+
// Already recorded — skip.
|
|
152
|
+
if (ledger[key]) {
|
|
153
|
+
report.steps.push({
|
|
154
|
+
name: step.name,
|
|
155
|
+
outcome: 'skipped',
|
|
156
|
+
details: `already-recorded:${ledger[key].outcome}`,
|
|
157
|
+
});
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
// Future-version — skip without recording.
|
|
161
|
+
if (compareSemver(step.version, toVersion) > 0) {
|
|
162
|
+
report.steps.push({
|
|
163
|
+
name: step.name,
|
|
164
|
+
outcome: 'skipped',
|
|
165
|
+
details: `future-version:${step.version} > ${toVersion}`,
|
|
166
|
+
});
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
// Execute.
|
|
170
|
+
const ctx = {
|
|
171
|
+
stateDir: this.stateDir,
|
|
172
|
+
fromVersion,
|
|
173
|
+
toVersion,
|
|
174
|
+
logger: (_msg) => {
|
|
175
|
+
/* default no-op; callers wire a real logger via wrapping */
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
let result;
|
|
179
|
+
try {
|
|
180
|
+
result = await step.run(ctx);
|
|
181
|
+
if (!result || typeof result.outcome !== 'string') {
|
|
182
|
+
result = { outcome: 'failed', details: 'step returned malformed result' };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
187
|
+
result = { outcome: 'failed', details: `threw: ${msg}` };
|
|
188
|
+
}
|
|
189
|
+
// Record outcome (including failures — see class docstring).
|
|
190
|
+
ledger[key] = {
|
|
191
|
+
outcome: result.outcome,
|
|
192
|
+
details: result.details,
|
|
193
|
+
recordedAt: new Date().toISOString(),
|
|
194
|
+
};
|
|
195
|
+
this.writeLedger(ledger);
|
|
196
|
+
report.steps.push({
|
|
197
|
+
name: step.name,
|
|
198
|
+
outcome: result.outcome,
|
|
199
|
+
details: result.details,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
return report;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Look up whether `<version>:<name>` is recorded. Returns the ledger
|
|
206
|
+
* entry or `undefined`. Intended for callers that want to render a
|
|
207
|
+
* migration report.
|
|
208
|
+
*/
|
|
209
|
+
getRecorded(version, name) {
|
|
210
|
+
const ledger = this.readLedger();
|
|
211
|
+
return ledger[`${version}:${name}`];
|
|
212
|
+
}
|
|
213
|
+
// ── Ledger I/O ─────────────────────────────────────────────────────
|
|
214
|
+
readLedger() {
|
|
215
|
+
try {
|
|
216
|
+
if (!fs.existsSync(this.ledgerPath))
|
|
217
|
+
return {};
|
|
218
|
+
const raw = fs.readFileSync(this.ledgerPath, 'utf-8');
|
|
219
|
+
const parsed = JSON.parse(raw);
|
|
220
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
221
|
+
return parsed;
|
|
222
|
+
}
|
|
223
|
+
return {};
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
// Corrupt ledger — treat as empty rather than blocking. The crash
|
|
227
|
+
// recovery path is: subsequent run records its results into a
|
|
228
|
+
// fresh ledger. Lost history of past runs is acceptable; blocked
|
|
229
|
+
// upgrades are not.
|
|
230
|
+
return {};
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
writeLedger(ledger) {
|
|
234
|
+
const tmpPath = `${this.ledgerPath}.tmp-${process.pid}-${Date.now()}`;
|
|
235
|
+
const serialized = JSON.stringify(ledger, null, 2) + '\n';
|
|
236
|
+
const fd = fs.openSync(tmpPath, 'w', 0o600);
|
|
237
|
+
try {
|
|
238
|
+
fs.writeSync(fd, serialized);
|
|
239
|
+
fs.fsyncSync(fd);
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
fs.closeSync(fd);
|
|
243
|
+
}
|
|
244
|
+
fs.renameSync(tmpPath, this.ledgerPath);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* AnnouncementManager — "show this message to the user once, then never
|
|
249
|
+
* again" primitive. Used for one-shot migration completions, structural-
|
|
250
|
+
* change notices, etc.
|
|
251
|
+
*
|
|
252
|
+
* The default sink writes to stderr with an `[announcement]` prefix.
|
|
253
|
+
* Callers can pass a custom sink (e.g. routed to Telegram or the
|
|
254
|
+
* dashboard's attention queue) via the constructor.
|
|
255
|
+
*
|
|
256
|
+
* Persisted state at `<stateDir>/announcements-shown.json`. The ledger
|
|
257
|
+
* survives across instances and across agent restarts.
|
|
258
|
+
*/
|
|
259
|
+
export class AnnouncementManager {
|
|
260
|
+
stateDir;
|
|
261
|
+
ledgerPath;
|
|
262
|
+
sink;
|
|
263
|
+
constructor(stateDir, sink) {
|
|
264
|
+
this.stateDir = path.resolve(stateDir);
|
|
265
|
+
this.ledgerPath = path.join(this.stateDir, 'announcements-shown.json');
|
|
266
|
+
this.sink = sink ?? defaultSink;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Emit the announcement exactly once per `announcementId`.
|
|
270
|
+
*
|
|
271
|
+
* Returns `true` if the announcement was emitted this call; `false`
|
|
272
|
+
* if a prior call (in this process or a previous run) already
|
|
273
|
+
* emitted it.
|
|
274
|
+
*
|
|
275
|
+
* Caller-side idempotency: the ledger is consulted BEFORE the sink
|
|
276
|
+
* is invoked. Repeated calls with the same id are O(1) reads.
|
|
277
|
+
*/
|
|
278
|
+
async announceOnce(announcementId, message, channel) {
|
|
279
|
+
if (!announcementId || typeof announcementId !== 'string') {
|
|
280
|
+
throw new Error('AnnouncementManager.announceOnce: announcementId is required');
|
|
281
|
+
}
|
|
282
|
+
if (typeof message !== 'string') {
|
|
283
|
+
throw new Error('AnnouncementManager.announceOnce: message must be a string');
|
|
284
|
+
}
|
|
285
|
+
if (channel !== 'telegram' && channel !== 'dashboard' && channel !== 'log') {
|
|
286
|
+
throw new Error(`AnnouncementManager.announceOnce: invalid channel "${channel}"`);
|
|
287
|
+
}
|
|
288
|
+
if (!fs.existsSync(this.stateDir)) {
|
|
289
|
+
fs.mkdirSync(this.stateDir, { recursive: true });
|
|
290
|
+
}
|
|
291
|
+
const ledger = this.readLedger();
|
|
292
|
+
if (ledger[announcementId]) {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
// Record BEFORE emitting so a sink that throws cannot leave us
|
|
296
|
+
// emitting twice on the next call. Worst case: announcement was
|
|
297
|
+
// recorded but the sink failed — operator sees a missed notice
|
|
298
|
+
// once, never a duplicate.
|
|
299
|
+
ledger[announcementId] = {
|
|
300
|
+
channel,
|
|
301
|
+
shownAt: new Date().toISOString(),
|
|
302
|
+
};
|
|
303
|
+
this.writeLedger(ledger);
|
|
304
|
+
try {
|
|
305
|
+
await this.sink(announcementId, message, channel);
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
// Swallow — see comment above. The ledger entry stands.
|
|
309
|
+
}
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
/** Has this announcement been shown? Read-only check. */
|
|
313
|
+
hasBeenShown(announcementId) {
|
|
314
|
+
const ledger = this.readLedger();
|
|
315
|
+
return Boolean(ledger[announcementId]);
|
|
316
|
+
}
|
|
317
|
+
readLedger() {
|
|
318
|
+
try {
|
|
319
|
+
if (!fs.existsSync(this.ledgerPath))
|
|
320
|
+
return {};
|
|
321
|
+
const raw = fs.readFileSync(this.ledgerPath, 'utf-8');
|
|
322
|
+
const parsed = JSON.parse(raw);
|
|
323
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
324
|
+
return parsed;
|
|
325
|
+
}
|
|
326
|
+
return {};
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
return {};
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
writeLedger(ledger) {
|
|
333
|
+
const tmpPath = `${this.ledgerPath}.tmp-${process.pid}-${Date.now()}`;
|
|
334
|
+
const serialized = JSON.stringify(ledger, null, 2) + '\n';
|
|
335
|
+
const fd = fs.openSync(tmpPath, 'w', 0o600);
|
|
336
|
+
try {
|
|
337
|
+
fs.writeSync(fd, serialized);
|
|
338
|
+
fs.fsyncSync(fd);
|
|
339
|
+
}
|
|
340
|
+
finally {
|
|
341
|
+
fs.closeSync(fd);
|
|
342
|
+
}
|
|
343
|
+
fs.renameSync(tmpPath, this.ledgerPath);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
function defaultSink(announcementId, message, channel) {
|
|
347
|
+
// Default sink writes to stderr so it never interferes with stdout
|
|
348
|
+
// RPC responses or CLI output capture.
|
|
349
|
+
const line = `[announcement:${channel}] ${announcementId}: ${message}`;
|
|
350
|
+
process.stderr.write(line + '\n');
|
|
351
|
+
}
|
|
352
|
+
//# sourceMappingURL=MigratorStepEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MigratorStepEngine.js","sourceRoot":"","sources":["../../src/core/MigratorStepEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* - CLAUDE.md sections are appended only if missing (check by heading)
|
|
19
19
|
* - Scripts are installed only if missing (never overwrite user modifications)
|
|
20
20
|
*/
|
|
21
|
+
import { type MigratorStep, type RunPendingStepsResult } from './MigratorStepEngine.js';
|
|
21
22
|
export interface MigrationResult {
|
|
22
23
|
/** What was upgraded */
|
|
23
24
|
upgraded: string[];
|
|
@@ -35,7 +36,37 @@ export interface MigratorConfig {
|
|
|
35
36
|
}
|
|
36
37
|
export declare class PostUpdateMigrator {
|
|
37
38
|
private config;
|
|
39
|
+
/**
|
|
40
|
+
* F-7 atomic-step engine. Lazily constructed on first access via
|
|
41
|
+
* `getStepEngine()` so existing callers that never touch atomic steps
|
|
42
|
+
* pay zero cost. See `src/core/MigratorStepEngine.ts` for the primitive
|
|
43
|
+
* docs; see `docs/specs/SELF-HEALING-REMEDIATOR-V2-SPEC.md` §A35/§A50
|
|
44
|
+
* for the spec.
|
|
45
|
+
*/
|
|
46
|
+
private stepEngine;
|
|
38
47
|
constructor(config: MigratorConfig);
|
|
48
|
+
/**
|
|
49
|
+
* F-7 atomic-step primitive: register a step that will run once on
|
|
50
|
+
* the release boundary where `step.version <= toVersion`. Idempotent
|
|
51
|
+
* across runs — the engine records every step's outcome in
|
|
52
|
+
* `<stateDir>/migrator-steps-completed.json` keyed by
|
|
53
|
+
* `<version>:<step-name>`.
|
|
54
|
+
*
|
|
55
|
+
* Steps are atomic and self-contained: a failure in one step does not
|
|
56
|
+
* roll back prior steps and does not block subsequent steps.
|
|
57
|
+
*
|
|
58
|
+
* See `docs/specs/SELF-HEALING-REMEDIATOR-V2-SPEC.md` §A35 + §A50.
|
|
59
|
+
*/
|
|
60
|
+
registerStep(step: MigratorStep): void;
|
|
61
|
+
/**
|
|
62
|
+
* F-7 atomic-step primitive: execute every pending step. Pending =
|
|
63
|
+
* step.version <= toVersion AND no ledger entry recorded yet.
|
|
64
|
+
*
|
|
65
|
+
* Steps run in registration order. Failures are recorded (never
|
|
66
|
+
* thrown) and do not stop subsequent steps.
|
|
67
|
+
*/
|
|
68
|
+
runPendingSteps(fromVersion: string, toVersion: string): Promise<RunPendingStepsResult>;
|
|
69
|
+
private getStepEngine;
|
|
39
70
|
/**
|
|
40
71
|
* Run all post-update migrations. Safe to call multiple times —
|
|
41
72
|
* each migration is idempotent.
|
|
@@ -67,6 +98,51 @@ export declare class PostUpdateMigrator {
|
|
|
67
98
|
* Non-destructive — only writes SKILL.md files that don't already exist.
|
|
68
99
|
*/
|
|
69
100
|
private migrateBuiltinSkills;
|
|
101
|
+
/**
|
|
102
|
+
* Phase 2 — install/refresh built-in agentmd jobs. Copies the shipped
|
|
103
|
+
* markdown templates into `.instar/jobs/instar/` and writes their
|
|
104
|
+
* per-slug manifests. Honors operator-disabled state (preserves
|
|
105
|
+
* `enabled: false` + `disabledAtBodyHash` across updates). Retires
|
|
106
|
+
* jobs that are no longer shipped.
|
|
107
|
+
*
|
|
108
|
+
* The `.instar/jobs/user/` namespace is structurally untouched (Seamless
|
|
109
|
+
* Migration Guarantee invariant 4).
|
|
110
|
+
*/
|
|
111
|
+
private migrateBuiltinJobs;
|
|
112
|
+
/**
|
|
113
|
+
* Phase 5 — auto-run `instar jobs migrate` for pre-spec agents on update.
|
|
114
|
+
*
|
|
115
|
+
* Behavior:
|
|
116
|
+
* - SKIP entirely if `.instar/jobs/.migration-complete.json` exists
|
|
117
|
+
* (operator already confirmed completion via Dashboard).
|
|
118
|
+
* - SKIP entirely if `.instar/jobs/.migration-abandoned.json` exists
|
|
119
|
+
* (operator explicitly chose to roll back).
|
|
120
|
+
* - SKIP if `.instar/jobs.json` is absent (nothing to migrate).
|
|
121
|
+
* - Otherwise, invoke `jobsMigrate({ defaultAction: 'fork' })` —
|
|
122
|
+
* fork policy preserves the operator's customized body in user/
|
|
123
|
+
* namespace, never silently drops content. This is the
|
|
124
|
+
* spec-mandated default for the auto-run path.
|
|
125
|
+
* - Emit a Dashboard banner event via the migration result so the
|
|
126
|
+
* operator sees "migration ran on update — confirm in Dashboard."
|
|
127
|
+
*
|
|
128
|
+
* Seamless Migration Guarantee invariants enforced at this layer
|
|
129
|
+
* (PR #180 §Seamless Migration Guarantee):
|
|
130
|
+
* #6 in-flight protection — JobScheduler.activeRuns() check is
|
|
131
|
+
* currently a defensive no-op until Phase 4 wires the scheduler
|
|
132
|
+
* back-reference; the migration runs at update time, before the
|
|
133
|
+
* new scheduler instance comes up, so by construction nothing is
|
|
134
|
+
* in flight.
|
|
135
|
+
* #7 transactional safety on interrupt — `jobsMigrate` is structurally
|
|
136
|
+
* safe (backup-first, idempotent, rollback via --abandon).
|
|
137
|
+
* #8 telemetry — outcome is appended to result.upgraded/errors.
|
|
138
|
+
*/
|
|
139
|
+
private autoMigrateLegacyJobsJson;
|
|
140
|
+
/** Read the installed package's version, for the migration event's
|
|
141
|
+
* `instarVersion` field. Best-effort — returns undefined on failure. */
|
|
142
|
+
private readBundledInstarVersion;
|
|
143
|
+
/** Best-effort telemetry write. Missing telemetry is degradation, not a
|
|
144
|
+
* release-blocker, so failures are swallowed. */
|
|
145
|
+
private appendMigrationTelemetry;
|
|
70
146
|
/**
|
|
71
147
|
* Re-install hooks with the latest templates.
|
|
72
148
|
* Built-in hooks in instar/ are always overwritten.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostUpdateMigrator.d.ts","sourceRoot":"","sources":["../../src/core/PostUpdateMigrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;
|
|
1
|
+
{"version":3,"file":"PostUpdateMigrator.d.ts","sourceRoot":"","sources":["../../src/core/PostUpdateMigrator.ts"],"names":[],"mappings":"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"}
|