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
|
@@ -27,15 +27,60 @@ import { TreeGenerator } from '../knowledge/TreeGenerator.js';
|
|
|
27
27
|
import { HTTP_HOOK_TEMPLATES, buildHttpHookSettings } from '../data/http-hook-templates.js';
|
|
28
28
|
import { getMigrationDefaults, applyDefaults } from '../config/ConfigDefaults.js';
|
|
29
29
|
import { installBuiltinSkills } from '../commands/init.js';
|
|
30
|
+
import { installBuiltinJobs } from '../scheduler/InstallBuiltinJobs.js';
|
|
31
|
+
import { jobsMigrate } from '../commands/jobMigrate.js';
|
|
32
|
+
import { snapshotUserNamespace, verifyMigrationInvariants } from '../scheduler/MigrationInvariants.js';
|
|
33
|
+
import { appendMigrationEvent, normalizePerEntryAction } from '../scheduler/MigrationLedger.js';
|
|
34
|
+
import { randomUUID } from 'node:crypto';
|
|
30
35
|
import { ELIGIBILITY_SCHEMA_SQL, ELIGIBILITY_SCHEMA_SQL_SHA256, PUSH_GATE_SH, PUSH_GATE_SH_SHA256, INSTAR_PR_GATE_WORKFLOW_YML, INSTAR_PR_GATE_WORKFLOW_YML_SHA256, PR_GATE_SETUP_MD, PR_GATE_SETUP_MD_SHA256, } from '../data/pr-gate-artifacts.js';
|
|
31
36
|
import { SafeFsExecutor } from './SafeFsExecutor.js';
|
|
32
37
|
import { DegradationReporter } from '../monitoring/DegradationReporter.js';
|
|
38
|
+
import { MigratorStepEngine, } from './MigratorStepEngine.js';
|
|
33
39
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
34
40
|
export class PostUpdateMigrator {
|
|
35
41
|
config;
|
|
42
|
+
/**
|
|
43
|
+
* F-7 atomic-step engine. Lazily constructed on first access via
|
|
44
|
+
* `getStepEngine()` so existing callers that never touch atomic steps
|
|
45
|
+
* pay zero cost. See `src/core/MigratorStepEngine.ts` for the primitive
|
|
46
|
+
* docs; see `docs/specs/SELF-HEALING-REMEDIATOR-V2-SPEC.md` §A35/§A50
|
|
47
|
+
* for the spec.
|
|
48
|
+
*/
|
|
49
|
+
stepEngine;
|
|
36
50
|
constructor(config) {
|
|
37
51
|
this.config = config;
|
|
38
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* F-7 atomic-step primitive: register a step that will run once on
|
|
55
|
+
* the release boundary where `step.version <= toVersion`. Idempotent
|
|
56
|
+
* across runs — the engine records every step's outcome in
|
|
57
|
+
* `<stateDir>/migrator-steps-completed.json` keyed by
|
|
58
|
+
* `<version>:<step-name>`.
|
|
59
|
+
*
|
|
60
|
+
* Steps are atomic and self-contained: a failure in one step does not
|
|
61
|
+
* roll back prior steps and does not block subsequent steps.
|
|
62
|
+
*
|
|
63
|
+
* See `docs/specs/SELF-HEALING-REMEDIATOR-V2-SPEC.md` §A35 + §A50.
|
|
64
|
+
*/
|
|
65
|
+
registerStep(step) {
|
|
66
|
+
this.getStepEngine().registerStep(step);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* F-7 atomic-step primitive: execute every pending step. Pending =
|
|
70
|
+
* step.version <= toVersion AND no ledger entry recorded yet.
|
|
71
|
+
*
|
|
72
|
+
* Steps run in registration order. Failures are recorded (never
|
|
73
|
+
* thrown) and do not stop subsequent steps.
|
|
74
|
+
*/
|
|
75
|
+
async runPendingSteps(fromVersion, toVersion) {
|
|
76
|
+
return this.getStepEngine().runPendingSteps(fromVersion, toVersion);
|
|
77
|
+
}
|
|
78
|
+
getStepEngine() {
|
|
79
|
+
if (!this.stepEngine) {
|
|
80
|
+
this.stepEngine = new MigratorStepEngine(this.config.stateDir);
|
|
81
|
+
}
|
|
82
|
+
return this.stepEngine;
|
|
83
|
+
}
|
|
39
84
|
/**
|
|
40
85
|
* Run all post-update migrations. Safe to call multiple times —
|
|
41
86
|
* each migration is idempotent.
|
|
@@ -55,6 +100,8 @@ export class PostUpdateMigrator {
|
|
|
55
100
|
this.migrateBackupManifest(result);
|
|
56
101
|
this.migrateGitignore(result);
|
|
57
102
|
this.migrateBuiltinSkills(result);
|
|
103
|
+
this.migrateBuiltinJobs(result);
|
|
104
|
+
this.autoMigrateLegacyJobsJson(result);
|
|
58
105
|
this.migrateSkillPortHardcoding(result);
|
|
59
106
|
this.migrateSelfKnowledgeTree(result);
|
|
60
107
|
this.migrateSoulMd(result);
|
|
@@ -235,6 +282,210 @@ export class PostUpdateMigrator {
|
|
|
235
282
|
result.errors.push(`built-in skills: ${err}`);
|
|
236
283
|
}
|
|
237
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Phase 2 — install/refresh built-in agentmd jobs. Copies the shipped
|
|
287
|
+
* markdown templates into `.instar/jobs/instar/` and writes their
|
|
288
|
+
* per-slug manifests. Honors operator-disabled state (preserves
|
|
289
|
+
* `enabled: false` + `disabledAtBodyHash` across updates). Retires
|
|
290
|
+
* jobs that are no longer shipped.
|
|
291
|
+
*
|
|
292
|
+
* The `.instar/jobs/user/` namespace is structurally untouched (Seamless
|
|
293
|
+
* Migration Guarantee invariant 4).
|
|
294
|
+
*/
|
|
295
|
+
migrateBuiltinJobs(result) {
|
|
296
|
+
try {
|
|
297
|
+
// The package root is two levels up from this compiled module (dist/core/),
|
|
298
|
+
// which puts us at the installed npm package root in production or the
|
|
299
|
+
// repo root in dev.
|
|
300
|
+
const packageRoot = path.resolve(__dirname, '..', '..');
|
|
301
|
+
const report = installBuiltinJobs({
|
|
302
|
+
agentStateDir: this.config.stateDir,
|
|
303
|
+
packageRoot,
|
|
304
|
+
port: this.config.port,
|
|
305
|
+
});
|
|
306
|
+
if (report.installed.length > 0) {
|
|
307
|
+
result.upgraded.push(`built-in agentmd jobs: ${report.installed.length} installed/refreshed`);
|
|
308
|
+
}
|
|
309
|
+
else if (report.errors.length === 0) {
|
|
310
|
+
result.skipped.push('built-in agentmd jobs: nothing to install');
|
|
311
|
+
}
|
|
312
|
+
for (const slug of report.retired) {
|
|
313
|
+
result.upgraded.push(`built-in agentmd jobs: retired "${slug}"`);
|
|
314
|
+
}
|
|
315
|
+
for (const e of report.errors) {
|
|
316
|
+
result.errors.push(`built-in agentmd jobs${e.slug ? ` [${e.slug}]` : ''}: ${e.reason}`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
catch (err) {
|
|
320
|
+
result.errors.push(`built-in agentmd jobs: ${err instanceof Error ? err.message : String(err)}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Phase 5 — auto-run `instar jobs migrate` for pre-spec agents on update.
|
|
325
|
+
*
|
|
326
|
+
* Behavior:
|
|
327
|
+
* - SKIP entirely if `.instar/jobs/.migration-complete.json` exists
|
|
328
|
+
* (operator already confirmed completion via Dashboard).
|
|
329
|
+
* - SKIP entirely if `.instar/jobs/.migration-abandoned.json` exists
|
|
330
|
+
* (operator explicitly chose to roll back).
|
|
331
|
+
* - SKIP if `.instar/jobs.json` is absent (nothing to migrate).
|
|
332
|
+
* - Otherwise, invoke `jobsMigrate({ defaultAction: 'fork' })` —
|
|
333
|
+
* fork policy preserves the operator's customized body in user/
|
|
334
|
+
* namespace, never silently drops content. This is the
|
|
335
|
+
* spec-mandated default for the auto-run path.
|
|
336
|
+
* - Emit a Dashboard banner event via the migration result so the
|
|
337
|
+
* operator sees "migration ran on update — confirm in Dashboard."
|
|
338
|
+
*
|
|
339
|
+
* Seamless Migration Guarantee invariants enforced at this layer
|
|
340
|
+
* (PR #180 §Seamless Migration Guarantee):
|
|
341
|
+
* #6 in-flight protection — JobScheduler.activeRuns() check is
|
|
342
|
+
* currently a defensive no-op until Phase 4 wires the scheduler
|
|
343
|
+
* back-reference; the migration runs at update time, before the
|
|
344
|
+
* new scheduler instance comes up, so by construction nothing is
|
|
345
|
+
* in flight.
|
|
346
|
+
* #7 transactional safety on interrupt — `jobsMigrate` is structurally
|
|
347
|
+
* safe (backup-first, idempotent, rollback via --abandon).
|
|
348
|
+
* #8 telemetry — outcome is appended to result.upgraded/errors.
|
|
349
|
+
*/
|
|
350
|
+
autoMigrateLegacyJobsJson(result) {
|
|
351
|
+
const runId = randomUUID();
|
|
352
|
+
const startedAt = new Date().toISOString();
|
|
353
|
+
try {
|
|
354
|
+
const stateDir = this.config.stateDir;
|
|
355
|
+
const jobsJsonPath = path.join(stateDir, 'jobs.json');
|
|
356
|
+
const jobsRoot = path.join(stateDir, 'jobs');
|
|
357
|
+
const completedMarker = path.join(jobsRoot, '.migration-complete.json');
|
|
358
|
+
const abandonedMarker = path.join(jobsRoot, '.migration-abandoned.json');
|
|
359
|
+
if (!fs.existsSync(jobsJsonPath)) {
|
|
360
|
+
return; // nothing to migrate
|
|
361
|
+
}
|
|
362
|
+
if (fs.existsSync(completedMarker)) {
|
|
363
|
+
result.skipped.push('legacy jobs.json migration: already complete (operator-confirmed)');
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
if (fs.existsSync(abandonedMarker)) {
|
|
367
|
+
result.skipped.push('legacy jobs.json migration: explicitly abandoned by operator');
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
// Snapshot pre-migration state so the runtime invariant gate has
|
|
371
|
+
// ground truth to compare against. Per spec §Gate wiring:
|
|
372
|
+
// "Before performing any destructive write, the migrator re-verifies
|
|
373
|
+
// invariants 1, 2, 4, and 6 against the staged state. Failure aborts
|
|
374
|
+
// to fail-closed (invariant 9)."
|
|
375
|
+
let preMigrationJobs = [];
|
|
376
|
+
try {
|
|
377
|
+
preMigrationJobs = JSON.parse(fs.readFileSync(jobsJsonPath, 'utf-8'));
|
|
378
|
+
if (!Array.isArray(preMigrationJobs))
|
|
379
|
+
preMigrationJobs = [];
|
|
380
|
+
}
|
|
381
|
+
catch {
|
|
382
|
+
preMigrationJobs = [];
|
|
383
|
+
}
|
|
384
|
+
const preMigrationUserSnapshot = snapshotUserNamespace(stateDir);
|
|
385
|
+
const packageRoot = path.resolve(__dirname, '..', '..');
|
|
386
|
+
const instarVersion = this.readBundledInstarVersion(packageRoot);
|
|
387
|
+
const outcome = jobsMigrate({
|
|
388
|
+
agentStateDir: stateDir,
|
|
389
|
+
packageRoot,
|
|
390
|
+
defaultAction: 'fork',
|
|
391
|
+
});
|
|
392
|
+
if (outcome.status === 'completed') {
|
|
393
|
+
// Runtime invariant gate. Spec §Seamless Migration Guarantee #1, #2, #4.
|
|
394
|
+
// Invariant 6 (in-flight) is structurally satisfied at update-apply
|
|
395
|
+
// time because no jobs run mid-update.
|
|
396
|
+
const verification = verifyMigrationInvariants({
|
|
397
|
+
agentStateDir: stateDir,
|
|
398
|
+
preMigrationJobs,
|
|
399
|
+
preMigrationUserSnapshot,
|
|
400
|
+
});
|
|
401
|
+
if (!verification.ok) {
|
|
402
|
+
// Fail-closed (invariant 9): roll back via abandon.
|
|
403
|
+
try {
|
|
404
|
+
jobsMigrate({ agentStateDir: stateDir, packageRoot, abandon: true });
|
|
405
|
+
}
|
|
406
|
+
catch (rollbackErr) {
|
|
407
|
+
result.errors.push(`legacy jobs.json migration: invariant verification failed AND rollback errored — ` +
|
|
408
|
+
`${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`);
|
|
409
|
+
}
|
|
410
|
+
result.errors.push(`legacy jobs.json migration: ${verification.summary} — rolled back to pre-migration state`);
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
const migratedCount = outcome.perEntry.filter((e) => e.action === 'migrated-instar').length;
|
|
414
|
+
const forkedCount = outcome.perEntry.filter((e) => e.action === 'forked-user' || e.action === 'kept-user').length;
|
|
415
|
+
const renamedCount = outcome.perEntry.filter((e) => e.action === 'renamed-user').length;
|
|
416
|
+
result.upgraded.push(`legacy jobs.json migration: auto-ran on update — ${migratedCount} migrated to instar, ${forkedCount} preserved in user namespace, ${renamedCount} renamed. Invariants verified. Confirm via Dashboard to allow jobs.json removal.`);
|
|
417
|
+
if (outcome.backupPath) {
|
|
418
|
+
result.upgraded.push(`legacy jobs.json migration: backup at ${path.basename(outcome.backupPath)}`);
|
|
419
|
+
}
|
|
420
|
+
// Spec invariant 8: telemetry write is the LAST action of a
|
|
421
|
+
// successful migration. Append the migration.completed event.
|
|
422
|
+
this.appendMigrationTelemetry({
|
|
423
|
+
kind: 'migration.completed',
|
|
424
|
+
runId,
|
|
425
|
+
startedAt,
|
|
426
|
+
completedAt: new Date().toISOString(),
|
|
427
|
+
trigger: 'post-update',
|
|
428
|
+
perEntry: outcome.perEntry.map((e) => ({
|
|
429
|
+
slug: e.slug,
|
|
430
|
+
action: normalizePerEntryAction(e.action),
|
|
431
|
+
reason: e.reason,
|
|
432
|
+
})),
|
|
433
|
+
backupPath: outcome.backupPath,
|
|
434
|
+
instarVersion,
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
else if (outcome.status === 'aborted') {
|
|
438
|
+
result.errors.push(`legacy jobs.json migration: aborted — ${outcome.errors.join('; ')}`);
|
|
439
|
+
this.appendMigrationTelemetry({
|
|
440
|
+
kind: 'migration.aborted',
|
|
441
|
+
runId,
|
|
442
|
+
startedAt,
|
|
443
|
+
completedAt: new Date().toISOString(),
|
|
444
|
+
trigger: 'post-update',
|
|
445
|
+
perEntry: outcome.perEntry.map((e) => ({
|
|
446
|
+
slug: e.slug,
|
|
447
|
+
action: normalizePerEntryAction(e.action),
|
|
448
|
+
reason: e.reason,
|
|
449
|
+
})),
|
|
450
|
+
abortReason: outcome.errors.join('; '),
|
|
451
|
+
instarVersion,
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
catch (err) {
|
|
456
|
+
result.errors.push(`legacy jobs.json migration: ${err instanceof Error ? err.message : String(err)}`);
|
|
457
|
+
this.appendMigrationTelemetry({
|
|
458
|
+
kind: 'migration.aborted',
|
|
459
|
+
runId,
|
|
460
|
+
startedAt,
|
|
461
|
+
completedAt: new Date().toISOString(),
|
|
462
|
+
trigger: 'post-update',
|
|
463
|
+
perEntry: [],
|
|
464
|
+
abortReason: err instanceof Error ? err.message : String(err),
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
/** Read the installed package's version, for the migration event's
|
|
469
|
+
* `instarVersion` field. Best-effort — returns undefined on failure. */
|
|
470
|
+
readBundledInstarVersion(packageRoot) {
|
|
471
|
+
try {
|
|
472
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf-8'));
|
|
473
|
+
return typeof pkg.version === 'string' ? pkg.version : undefined;
|
|
474
|
+
}
|
|
475
|
+
catch {
|
|
476
|
+
return undefined;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
/** Best-effort telemetry write. Missing telemetry is degradation, not a
|
|
480
|
+
* release-blocker, so failures are swallowed. */
|
|
481
|
+
appendMigrationTelemetry(event) {
|
|
482
|
+
try {
|
|
483
|
+
appendMigrationEvent(this.config.stateDir, event);
|
|
484
|
+
}
|
|
485
|
+
catch {
|
|
486
|
+
// @silent-fallback-ok — telemetry is non-load-bearing
|
|
487
|
+
}
|
|
488
|
+
}
|
|
238
489
|
/**
|
|
239
490
|
* Re-install hooks with the latest templates.
|
|
240
491
|
* Built-in hooks in instar/ are always overwritten.
|
|
@@ -1256,7 +1507,7 @@ The user has been talking to you (possibly for days). A generic greeting like "H
|
|
|
1256
1507
|
- **Generate a file link**: \`curl -H "Authorization: Bearer $AUTH" "http://localhost:${port}/api/files/link?path=.claude/CLAUDE.md"\`
|
|
1257
1508
|
- **Download a file**: \`curl -H "Authorization: Bearer $AUTH" "http://localhost:${port}/api/files/download?path=.claude/CLAUDE.md" -O\`
|
|
1258
1509
|
- **Default config**: Browsing and editing enabled for the entire project directory (\`./\`) by default.
|
|
1259
|
-
- **Never editable**: \`.claude/hooks/\`, \`.claude/scripts/\`, \`node_modules/\` are always read-only regardless of config.
|
|
1510
|
+
- **Never editable**: \`.claude/hooks/\`, \`.claude/scripts/\`, \`node_modules/\`, \`.instar/jobs/instar/\` are always read-only regardless of config.
|
|
1260
1511
|
`;
|
|
1261
1512
|
// Insert after Dashboard section
|
|
1262
1513
|
const dashboardIdx = content.indexOf('**Dashboard**');
|