principles-disciple 1.127.0 → 1.129.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/archive-impl.d.ts +18 -0
- package/dist/commands/archive-impl.js +105 -0
- package/dist/commands/capabilities.d.ts +3 -0
- package/dist/commands/capabilities.js +76 -0
- package/dist/commands/context.d.ts +5 -0
- package/{src/commands/context.ts → dist/commands/context.js} +34 -83
- package/dist/commands/disable-impl.d.ts +22 -0
- package/dist/commands/disable-impl.js +118 -0
- package/dist/commands/evolution-status.d.ts +4 -0
- package/dist/commands/evolution-status.js +187 -0
- package/dist/commands/export.d.ts +2 -0
- package/dist/commands/export.js +53 -0
- package/dist/commands/focus.d.ts +14 -0
- package/dist/commands/focus.js +443 -0
- package/dist/commands/pain.d.ts +6 -0
- package/{src/commands/pain.ts → dist/commands/pain.js} +137 -188
- package/dist/commands/principle-rollback.d.ts +4 -0
- package/dist/commands/principle-rollback.js +26 -0
- package/dist/commands/promote-impl.d.ts +22 -0
- package/dist/commands/promote-impl.js +194 -0
- package/dist/commands/rollback-impl.d.ts +32 -0
- package/dist/commands/rollback-impl.js +180 -0
- package/dist/commands/rollback.d.ts +19 -0
- package/{src/commands/rollback.ts → dist/commands/rollback.js} +10 -53
- package/dist/commands/samples.d.ts +2 -0
- package/dist/commands/samples.js +58 -0
- package/dist/commands/strategy.d.ts +2 -0
- package/dist/commands/strategy.js +16 -0
- package/dist/commands/thinking-os.d.ts +2 -0
- package/{src/commands/thinking-os.ts → dist/commands/thinking-os.js} +35 -58
- package/dist/commands/workflow-debug.d.ts +6 -0
- package/{src/commands/workflow-debug.ts → dist/commands/workflow-debug.js} +13 -33
- package/dist/config/defaults/runtime.d.ts +58 -0
- package/{src/config/defaults/runtime.ts → dist/config/defaults/runtime.js} +4 -41
- package/dist/config/errors.d.ts +86 -0
- package/dist/config/errors.js +107 -0
- package/{src/config/index.ts → dist/config/index.d.ts} +1 -2
- package/dist/config/index.js +7 -0
- package/dist/constants/diagnostician.d.ts +12 -0
- package/{src/constants/diagnostician.ts → dist/constants/diagnostician.js} +0 -1
- package/dist/constants/tools.d.ts +17 -0
- package/dist/constants/tools.js +53 -0
- package/dist/core/__tests__/focus-history.test.d.ts +1 -0
- package/dist/core/__tests__/focus-history.test.js +160 -0
- package/dist/core/bootstrap-rules.d.ts +50 -0
- package/dist/core/bootstrap-rules.js +187 -0
- package/dist/core/code-implementation-storage.d.ts +71 -0
- package/dist/core/code-implementation-storage.js +139 -0
- package/dist/core/config-health.d.ts +27 -0
- package/dist/core/config-health.js +60 -0
- package/dist/core/config-service.d.ts +15 -0
- package/{src/core/config-service.ts → dist/core/config-service.js} +4 -7
- package/dist/core/config.d.ts +111 -0
- package/{src/core/config.ts → dist/core/config.js} +46 -146
- package/dist/core/control-ui-db.d.ts +106 -0
- package/dist/core/control-ui-db.js +309 -0
- package/dist/core/correction-cue-learner.d.ts +33 -0
- package/dist/core/correction-cue-learner.js +184 -0
- package/dist/core/correction-types.d.ts +3 -0
- package/dist/core/correction-types.js +1 -0
- package/dist/core/detection-funnel.d.ts +33 -0
- package/{src/core/detection-funnel.ts → dist/core/detection-funnel.js} +17 -37
- package/dist/core/detection-service.d.ts +15 -0
- package/{src/core/detection-service.ts → dist/core/detection-service.js} +4 -7
- package/dist/core/dictionary-service.d.ts +15 -0
- package/{src/core/dictionary-service.ts → dist/core/dictionary-service.js} +4 -7
- package/dist/core/dictionary.d.ts +38 -0
- package/{src/core/dictionary.ts → dist/core/dictionary.js} +33 -59
- package/dist/core/empathy-keyword-matcher.d.ts +5 -0
- package/dist/core/empathy-keyword-matcher.js +40 -0
- package/dist/core/empathy-types.d.ts +2 -0
- package/dist/core/empathy-types.js +1 -0
- package/dist/core/event-log.d.ts +90 -0
- package/dist/core/event-log.js +702 -0
- package/dist/core/evolution-engine.d.ts +119 -0
- package/dist/core/evolution-engine.js +460 -0
- package/dist/core/evolution-logger.d.ts +137 -0
- package/dist/core/evolution-logger.js +261 -0
- package/dist/core/evolution-migration.d.ts +5 -0
- package/dist/core/evolution-migration.js +65 -0
- package/dist/core/evolution-reducer.d.ts +124 -0
- package/dist/core/evolution-reducer.js +730 -0
- package/dist/core/evolution-types.d.ts +50 -0
- package/dist/core/evolution-types.js +11 -0
- package/dist/core/external-training-contract.d.ts +276 -0
- package/dist/core/external-training-contract.js +269 -0
- package/dist/core/file-store.d.ts +41 -0
- package/dist/core/file-store.js +46 -0
- package/dist/core/focus-history.d.ts +50 -0
- package/dist/core/focus-history.js +574 -0
- package/dist/core/hygiene/tracker.d.ts +22 -0
- package/dist/core/hygiene/tracker.js +110 -0
- package/dist/core/init.d.ts +30 -0
- package/{src/core/init.ts → dist/core/init.js} +87 -118
- package/dist/core/local-worker-routing.d.ts +124 -0
- package/dist/core/local-worker-routing.js +216 -0
- package/dist/core/migration.d.ts +6 -0
- package/{src/core/migration.ts → dist/core/migration.js} +10 -18
- package/dist/core/model-deployment-registry.d.ts +218 -0
- package/dist/core/model-deployment-registry.js +502 -0
- package/dist/core/model-training-registry.d.ts +295 -0
- package/dist/core/model-training-registry.js +474 -0
- package/dist/core/observability.d.ts +40 -0
- package/dist/core/observability.js +164 -0
- package/dist/core/pain-diagnostic-gate.d.ts +36 -0
- package/dist/core/pain-diagnostic-gate.js +105 -0
- package/dist/core/pain.d.ts +87 -0
- package/dist/core/pain.js +223 -0
- package/dist/core/path-resolver.d.ts +60 -0
- package/{src/core/path-resolver.ts → dist/core/path-resolver.js} +41 -131
- package/dist/core/paths.d.ts +60 -0
- package/{src/core/paths.ts → dist/core/paths.js} +4 -13
- package/dist/core/pd-config-loader.d.ts +96 -0
- package/dist/core/pd-config-loader.js +307 -0
- package/dist/core/pd-task-reconciler.d.ts +89 -0
- package/dist/core/pd-task-reconciler.js +262 -0
- package/dist/core/pd-task-service.d.ts +2 -0
- package/dist/core/pd-task-service.js +32 -0
- package/dist/core/pd-task-store.d.ts +5 -0
- package/dist/core/pd-task-store.js +62 -0
- package/dist/core/pd-task-types.d.ts +8 -0
- package/dist/core/pd-task-types.js +2 -0
- package/dist/core/principle-compiler/__tests__/compiler-replay-gate.test.d.ts +1 -0
- package/dist/core/principle-compiler/__tests__/compiler-replay-gate.test.js +132 -0
- package/dist/core/principle-compiler/code-validator.d.ts +14 -0
- package/dist/core/principle-compiler/code-validator.js +86 -0
- package/dist/core/principle-compiler/compiler.d.ts +45 -0
- package/dist/core/principle-compiler/compiler.js +287 -0
- package/{src/core/principle-compiler/index.ts → dist/core/principle-compiler/index.d.ts} +0 -1
- package/dist/core/principle-compiler/index.js +10 -0
- package/dist/core/principle-compiler/ledger-registrar.d.ts +28 -0
- package/dist/core/principle-compiler/ledger-registrar.js +95 -0
- package/{src/core/principle-compiler/template-generator.ts → dist/core/principle-compiler/template-generator.d.ts} +0 -1
- package/dist/core/principle-compiler/template-generator.js +7 -0
- package/{src/core/principle-injection.ts → dist/core/principle-injection.d.ts} +1 -7
- package/dist/core/principle-injection.js +10 -0
- package/dist/core/principle-internalization/filesystem-lifecycle-datasource.d.ts +15 -0
- package/dist/core/principle-internalization/filesystem-lifecycle-datasource.js +34 -0
- package/dist/core/principle-internalization/lifecycle-read-model.d.ts +17 -0
- package/{src/core/principle-internalization/lifecycle-read-model.ts → dist/core/principle-internalization/lifecycle-read-model.js} +2 -21
- package/dist/core/principle-internalization/lifecycle-refresh.d.ts +2 -0
- package/dist/core/principle-internalization/lifecycle-refresh.js +4 -0
- package/dist/core/principle-internalization/principle-lifecycle-service.d.ts +28 -0
- package/dist/core/principle-internalization/principle-lifecycle-service.js +89 -0
- package/dist/core/principle-training-state.d.ts +47 -0
- package/dist/core/principle-training-state.js +113 -0
- package/dist/core/principle-tree-ledger-adapter.d.ts +32 -0
- package/dist/core/principle-tree-ledger-adapter.js +125 -0
- package/dist/core/principle-tree-ledger.d.ts +82 -0
- package/dist/core/principle-tree-ledger.js +527 -0
- package/dist/core/profile.d.ts +62 -0
- package/dist/core/profile.js +211 -0
- package/dist/core/promotion-gate.d.ts +243 -0
- package/dist/core/promotion-gate.js +554 -0
- package/dist/core/reflection/reflection-context.d.ts +31 -0
- package/dist/core/reflection/reflection-context.js +91 -0
- package/dist/core/replay-engine.d.ts +12 -0
- package/dist/core/replay-engine.js +82 -0
- package/dist/core/risk-calculator.d.ts +22 -0
- package/{src/core/risk-calculator.ts → dist/core/risk-calculator.js} +19 -49
- package/{src/core/rule-host-helpers.ts → dist/core/rule-host-helpers.d.ts} +0 -1
- package/dist/core/rule-host-helpers.js +7 -0
- package/{src/core/rule-host-types.ts → dist/core/rule-host-types.d.ts} +1 -8
- package/dist/core/rule-host-types.js +7 -0
- package/dist/core/rule-host.d.ts +86 -0
- package/dist/core/rule-host.js +311 -0
- package/dist/core/rule-implementation-runtime.d.ts +18 -0
- package/dist/core/rule-implementation-runtime.js +112 -0
- package/dist/core/runtime-v2-prompt-activation-reader.d.ts +22 -0
- package/dist/core/runtime-v2-prompt-activation-reader.js +99 -0
- package/{src/core/schema/db-types.ts → dist/core/schema/db-types.d.ts} +4 -9
- package/dist/core/schema/db-types.js +5 -0
- package/{src/core/schema/index.ts → dist/core/schema/index.d.ts} +1 -10
- package/dist/core/schema/index.js +15 -0
- package/dist/core/schema/migration-runner.d.ts +53 -0
- package/dist/core/schema/migration-runner.js +170 -0
- package/dist/core/schema/migrations/001-init-trajectory.d.ts +6 -0
- package/{src/core/schema/migrations/001-init-trajectory.ts → dist/core/schema/migrations/001-init-trajectory.js} +38 -56
- package/dist/core/schema/migrations/002-init-central.d.ts +5 -0
- package/{src/core/schema/migrations/002-init-central.ts → dist/core/schema/migrations/002-init-central.js} +27 -41
- package/dist/core/schema/migrations/003-init-workflow.d.ts +5 -0
- package/{src/core/schema/migrations/003-init-workflow.ts → dist/core/schema/migrations/003-init-workflow.js} +16 -21
- package/dist/core/schema/migrations/004-add-thinking-and-gfi.d.ts +8 -0
- package/{src/core/schema/migrations/004-add-thinking-and-gfi.ts → dist/core/schema/migrations/004-add-thinking-and-gfi.js} +19 -27
- package/{src/core/schema/migrations/index.ts → dist/core/schema/migrations/index.d.ts} +1 -16
- package/dist/core/schema/migrations/index.js +27 -0
- package/dist/core/schema/schema-definitions.d.ts +46 -0
- package/{src/core/schema/schema-definitions.ts → dist/core/schema/schema-definitions.js} +242 -291
- package/dist/core/session-tracker.d.ts +119 -0
- package/{src/core/session-tracker.ts → dist/core/session-tracker.js} +96 -239
- package/dist/core/shadow-observation-registry.d.ts +217 -0
- package/dist/core/shadow-observation-registry.js +280 -0
- package/dist/core/surface-guard.d.ts +31 -0
- package/dist/core/surface-guard.js +131 -0
- package/dist/core/system-logger.d.ts +8 -0
- package/{src/core/system-logger.ts → dist/core/system-logger.js} +20 -34
- package/dist/core/thinking-models.d.ts +70 -0
- package/dist/core/thinking-models.js +300 -0
- package/dist/core/thinking-os-parser.d.ts +35 -0
- package/dist/core/thinking-os-parser.js +123 -0
- package/dist/core/trajectory-types.d.ts +220 -0
- package/dist/core/trajectory-types.js +8 -0
- package/dist/core/trajectory.d.ts +242 -0
- package/dist/core/trajectory.js +1500 -0
- package/dist/core/workflow-funnel-loader.d.ts +72 -0
- package/dist/core/workflow-funnel-loader.js +135 -0
- package/dist/core/workspace-context.d.ts +111 -0
- package/{src/core/workspace-context.ts → dist/core/workspace-context.js} +50 -105
- package/dist/core/workspace-dir-validation.d.ts +11 -0
- package/dist/core/workspace-dir-validation.js +37 -0
- package/dist/core/workspace-guidance-migrator.d.ts +12 -0
- package/{src/core/workspace-guidance-migrator.ts → dist/core/workspace-guidance-migrator.js} +21 -59
- package/dist/hooks/after-tool-call-helpers.d.ts +89 -0
- package/dist/hooks/after-tool-call-helpers.js +475 -0
- package/dist/hooks/after-tool-call-types.d.ts +86 -0
- package/dist/hooks/after-tool-call-types.js +13 -0
- package/dist/hooks/gate-block-helper.d.ts +44 -0
- package/dist/hooks/gate-block-helper.js +209 -0
- package/dist/hooks/gate.d.ts +16 -0
- package/dist/hooks/gate.js +381 -0
- package/dist/hooks/lifecycle.d.ts +5 -0
- package/dist/hooks/lifecycle.js +287 -0
- package/dist/hooks/llm.d.ts +13 -0
- package/{src/hooks/llm.ts → dist/hooks/llm.js} +63 -117
- package/dist/hooks/message-sanitize.d.ts +24 -0
- package/dist/hooks/message-sanitize.js +77 -0
- package/dist/hooks/pain.d.ts +33 -0
- package/dist/hooks/pain.js +294 -0
- package/dist/hooks/prompt.d.ts +52 -0
- package/dist/hooks/prompt.js +930 -0
- package/dist/hooks/raw-observation-adapter.d.ts +57 -0
- package/dist/hooks/raw-observation-adapter.js +170 -0
- package/dist/hooks/raw-observation-types.d.ts +62 -0
- package/dist/hooks/raw-observation-types.js +15 -0
- package/dist/hooks/subagent.d.ts +9 -0
- package/{src/hooks/subagent.ts → dist/hooks/subagent.js} +20 -60
- package/dist/hooks/trajectory-collector.d.ts +25 -0
- package/dist/hooks/trajectory-collector.js +225 -0
- package/dist/hooks/trajectory-evidence.d.ts +11 -0
- package/dist/hooks/trajectory-evidence.js +88 -0
- package/dist/hooks/triage-adapter.d.ts +58 -0
- package/{src/hooks/triage-adapter.ts → dist/hooks/triage-adapter.js} +36 -68
- package/dist/hooks/trigger-cooldown-tracker.d.ts +30 -0
- package/dist/hooks/trigger-cooldown-tracker.js +55 -0
- package/dist/i18n/commands.d.ts +26 -0
- package/dist/i18n/commands.js +96 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +829 -0
- package/dist/openclaw-sdk.d.ts +293 -0
- package/dist/openclaw-sdk.js +4 -0
- package/dist/service/central-database.d.ts +138 -0
- package/dist/service/central-database.js +731 -0
- package/dist/service/central-sync-service.d.ts +8 -0
- package/dist/service/central-sync-service.js +71 -0
- package/dist/service/correction-observer-service.d.ts +19 -0
- package/{src/service/correction-observer-service.ts → dist/service/correction-observer-service.js} +36 -76
- package/dist/service/evolution-dedup.d.ts +27 -0
- package/{src/service/evolution-dedup.ts → dist/service/evolution-dedup.js} +11 -31
- package/{src/service/evolution-queue-migration.ts → dist/service/evolution-queue-migration.d.ts} +15 -62
- package/dist/service/evolution-queue-migration.js +53 -0
- package/dist/service/evolution-worker.d.ts +103 -0
- package/{src/service/evolution-worker.ts → dist/service/evolution-worker.js} +169 -331
- package/dist/service/internalization-auto-consumer-service.d.ts +8 -0
- package/dist/service/internalization-auto-consumer-service.js +322 -0
- package/dist/service/keyword-optimization-service.d.ts +44 -0
- package/dist/service/keyword-optimization-service.js +137 -0
- package/dist/service/phase3-input-filter.d.ts +73 -0
- package/dist/service/phase3-input-filter.js +172 -0
- package/dist/service/queue-io.d.ts +30 -0
- package/dist/service/queue-io.js +79 -0
- package/{src/service/queue-migration.ts → dist/service/queue-migration.d.ts} +6 -45
- package/dist/service/queue-migration.js +56 -0
- package/dist/service/runtime-summary-service.d.ts +158 -0
- package/dist/service/runtime-summary-service.js +636 -0
- package/dist/service/subagent-workflow/subagent-error-utils.d.ts +8 -0
- package/{src/service/subagent-workflow/subagent-error-utils.ts → dist/service/subagent-workflow/subagent-error-utils.js} +3 -6
- package/{src/service/subagent-workflow/types.ts → dist/service/subagent-workflow/types.d.ts} +17 -80
- package/dist/service/subagent-workflow/types.js +11 -0
- package/dist/service/subagent-workflow/workflow-store.d.ts +30 -0
- package/{src/service/subagent-workflow/workflow-store.ts → dist/service/subagent-workflow/workflow-store.js} +43 -108
- package/dist/service/trajectory-service.d.ts +2 -0
- package/dist/service/trajectory-service.js +16 -0
- package/dist/service/workflow-watchdog.d.ts +23 -0
- package/dist/service/workflow-watchdog.js +103 -0
- package/dist/types/event-types.d.ts +2 -0
- package/dist/types/event-types.js +1 -0
- package/dist/types/hygiene-types.d.ts +2 -0
- package/dist/types/hygiene-types.js +1 -0
- package/{src/types/principle-tree-schema.ts → dist/types/principle-tree-schema.d.ts} +2 -25
- package/dist/types/principle-tree-schema.js +24 -0
- package/dist/types/queue.d.ts +2 -0
- package/dist/types/queue.js +1 -0
- package/dist/types/runtime-summary.d.ts +1 -0
- package/dist/types/runtime-summary.js +1 -0
- package/dist/types.d.ts +33 -0
- package/dist/types.js +16 -0
- package/dist/utils/file-lock.d.ts +68 -0
- package/dist/utils/file-lock.js +310 -0
- package/dist/utils/hashing.d.ts +9 -0
- package/{src/utils/hashing.ts → dist/utils/hashing.js} +4 -6
- package/dist/utils/io.d.ts +11 -0
- package/dist/utils/io.js +174 -0
- package/dist/utils/node-vm-polyfill.d.ts +9 -0
- package/{src/utils/node-vm-polyfill.ts → dist/utils/node-vm-polyfill.js} +0 -2
- package/dist/utils/retry.d.ts +210 -0
- package/dist/utils/retry.js +375 -0
- package/dist/utils/session-key.d.ts +10 -0
- package/{src/utils/session-key.ts → dist/utils/session-key.js} +5 -4
- package/dist/utils/shadow-fingerprint.d.ts +16 -0
- package/dist/utils/shadow-fingerprint.js +34 -0
- package/dist/utils/workspace-resolver.d.ts +82 -0
- package/dist/utils/workspace-resolver.js +288 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +8 -2
- package/templates/workspace/.principles/DECISION_POLICY.json +44 -0
- package/templates/workspace/.principles/PRINCIPLES.md +20 -0
- package/templates/workspace/.principles/PROFILE.json +54 -0
- package/templates/workspace/.principles/PROFILE.schema.json +56 -0
- package/templates/workspace/.principles/THINKING_OS.md +65 -0
- package/templates/workspace/.principles/THINKING_OS_ARCHIVE.md +7 -0
- package/templates/workspace/.principles/THINKING_OS_CANDIDATES.md +9 -0
- package/templates/workspace/.principles/models/_INDEX.md +27 -0
- package/templates/workspace/.principles/models/first_principles.md +62 -0
- package/templates/workspace/.principles/models/marketing_4p.md +52 -0
- package/templates/workspace/.principles/models/porter_five.md +63 -0
- package/templates/workspace/.principles/models/swot.md +60 -0
- package/templates/workspace/.principles/models/user_story_map.md +63 -0
- package/templates/workspace/.state/WORKBOARD.json +4 -0
- package/.dependency-cruiser.json +0 -19
- package/ADVANCED_CONFIG_ZH.md +0 -93
- package/AGENT_INSTALL.md +0 -173
- package/AGENT_INSTALL_EN.md +0 -173
- package/CHANGELOG.md +0 -26
- package/INSTALL.md +0 -254
- package/SKILL.md +0 -63
- package/esbuild.config.js +0 -104
- package/src/commands/archive-impl.ts +0 -147
- package/src/commands/capabilities.ts +0 -89
- package/src/commands/disable-impl.ts +0 -159
- package/src/commands/evolution-status.ts +0 -247
- package/src/commands/export.ts +0 -59
- package/src/commands/focus.ts +0 -523
- package/src/commands/principle-rollback.ts +0 -32
- package/src/commands/promote-impl.ts +0 -254
- package/src/commands/rollback-impl.ts +0 -246
- package/src/commands/samples.ts +0 -65
- package/src/commands/strategy.ts +0 -21
- package/src/config/errors.ts +0 -180
- package/src/constants/tools.ts +0 -62
- package/src/core/AGENTS.md +0 -34
- package/src/core/__tests__/focus-history.test.ts +0 -210
- package/src/core/bootstrap-rules.ts +0 -216
- package/src/core/code-implementation-storage.ts +0 -213
- package/src/core/config-health.ts +0 -72
- package/src/core/control-ui-db.ts +0 -454
- package/src/core/correction-cue-learner.ts +0 -239
- package/src/core/correction-types.ts +0 -16
- package/src/core/empathy-keyword-matcher.ts +0 -64
- package/src/core/empathy-types.ts +0 -18
- package/src/core/event-log.ts +0 -787
- package/src/core/evolution-engine.ts +0 -613
- package/src/core/evolution-logger.ts +0 -357
- package/src/core/evolution-migration.ts +0 -77
- package/src/core/evolution-reducer.ts +0 -891
- package/src/core/evolution-types.ts +0 -110
- package/src/core/external-training-contract.ts +0 -530
- package/src/core/file-store.ts +0 -80
- package/src/core/focus-history.ts +0 -763
- package/src/core/hygiene/tracker.ts +0 -122
- package/src/core/local-worker-routing.ts +0 -337
- package/src/core/model-deployment-registry.ts +0 -724
- package/src/core/model-training-registry.ts +0 -815
- package/src/core/observability.ts +0 -242
- package/src/core/pain-diagnostic-gate.ts +0 -169
- package/src/core/pain.ts +0 -309
- package/src/core/pd-config-loader.ts +0 -400
- package/src/core/pd-task-reconciler.ts +0 -380
- package/src/core/pd-task-service.ts +0 -43
- package/src/core/pd-task-store.ts +0 -78
- package/src/core/pd-task-types.ts +0 -24
- package/src/core/principle-compiler/__tests__/compiler-replay-gate.test.ts +0 -174
- package/src/core/principle-compiler/code-validator.ts +0 -96
- package/src/core/principle-compiler/compiler.ts +0 -327
- package/src/core/principle-compiler/ledger-registrar.ts +0 -116
- package/src/core/principle-internalization/filesystem-lifecycle-datasource.ts +0 -42
- package/src/core/principle-internalization/lifecycle-refresh.ts +0 -11
- package/src/core/principle-internalization/principle-lifecycle-service.ts +0 -170
- package/src/core/principle-training-state.ts +0 -177
- package/src/core/principle-tree-ledger-adapter.ts +0 -145
- package/src/core/principle-tree-ledger.ts +0 -725
- package/src/core/profile.ts +0 -228
- package/src/core/promotion-gate.ts +0 -854
- package/src/core/reflection/reflection-context.ts +0 -133
- package/src/core/replay-engine.ts +0 -106
- package/src/core/rule-host.ts +0 -386
- package/src/core/rule-implementation-runtime.ts +0 -145
- package/src/core/runtime-v2-prompt-activation-reader.ts +0 -114
- package/src/core/schema/migration-runner.ts +0 -207
- package/src/core/shadow-observation-registry.ts +0 -508
- package/src/core/surface-guard.ts +0 -188
- package/src/core/thinking-models.ts +0 -377
- package/src/core/thinking-os-parser.ts +0 -165
- package/src/core/trajectory-types.ts +0 -247
- package/src/core/trajectory.ts +0 -1831
- package/src/core/workflow-funnel-loader.ts +0 -195
- package/src/core/workspace-dir-validation.ts +0 -52
- package/src/hooks/AGENTS.md +0 -31
- package/src/hooks/after-tool-call-helpers.ts +0 -601
- package/src/hooks/after-tool-call-types.ts +0 -99
- package/src/hooks/gate-block-helper.ts +0 -265
- package/src/hooks/gate.ts +0 -394
- package/src/hooks/lifecycle.ts +0 -334
- package/src/hooks/message-sanitize.ts +0 -102
- package/src/hooks/pain.ts +0 -358
- package/src/hooks/prompt.ts +0 -1102
- package/src/hooks/raw-observation-adapter.ts +0 -215
- package/src/hooks/raw-observation-types.ts +0 -77
- package/src/hooks/trajectory-collector.ts +0 -253
- package/src/hooks/trajectory-evidence.ts +0 -97
- package/src/hooks/trigger-cooldown-tracker.ts +0 -82
- package/src/i18n/commands.ts +0 -101
- package/src/index.ts +0 -939
- package/src/openclaw-sdk.ts +0 -312
- package/src/service/central-database.ts +0 -936
- package/src/service/central-sync-service.ts +0 -85
- package/src/service/internalization-auto-consumer-service.ts +0 -397
- package/src/service/keyword-optimization-service.ts +0 -169
- package/src/service/phase3-input-filter.ts +0 -237
- package/src/service/queue-io.ts +0 -108
- package/src/service/runtime-summary-service.ts +0 -990
- package/src/service/trajectory-service.ts +0 -16
- package/src/service/workflow-watchdog.ts +0 -125
- package/src/types/event-types.ts +0 -39
- package/src/types/hygiene-types.ts +0 -8
- package/src/types/queue.ts +0 -15
- package/src/types/runtime-summary.ts +0 -5
- package/src/types.ts +0 -53
- package/src/utils/file-lock.ts +0 -394
- package/src/utils/io.ts +0 -176
- package/src/utils/retry.ts +0 -573
- package/src/utils/shadow-fingerprint.ts +0 -42
- package/src/utils/workspace-resolver.ts +0 -393
- package/tests/README.md +0 -120
- package/tests/build-artifacts.test.ts +0 -55
- package/tests/commands/evolution-status.test.ts +0 -511
- package/tests/commands/export.test.ts +0 -78
- package/tests/commands/pain.test.ts +0 -287
- package/tests/commands/samples.test.ts +0 -65
- package/tests/commands/strategy.test.ts +0 -19
- package/tests/commands/thinking-os.test.ts +0 -88
- package/tests/core/bootstrap-rules.test.ts +0 -596
- package/tests/core/code-implementation-storage.test.ts +0 -300
- package/tests/core/code-validator.test.ts +0 -197
- package/tests/core/config-service.test.ts +0 -89
- package/tests/core/config.test.ts +0 -90
- package/tests/core/control-ui-db.test.ts +0 -75
- package/tests/core/core-principle-registry-drift.test.ts +0 -39
- package/tests/core/core-template-guidance.test.ts +0 -21
- package/tests/core/correction-cue-learner.test.ts +0 -345
- package/tests/core/detection-service.test.ts +0 -50
- package/tests/core/dictionary-service.test.ts +0 -116
- package/tests/core/dictionary.test.ts +0 -171
- package/tests/core/empathy-keyword-matcher.test.ts +0 -209
- package/tests/core/event-log.test.ts +0 -484
- package/tests/core/evolution-engine.test.ts +0 -610
- package/tests/core/evolution-logger.test.ts +0 -148
- package/tests/core/evolution-migration.test.ts +0 -374
- package/tests/core/evolution-paths.test.ts +0 -21
- package/tests/core/evolution-reducer.compilation-retry.test.ts +0 -189
- package/tests/core/evolution-reducer.detector-metadata.test.ts +0 -602
- package/tests/core/evolution-types-loop.test.ts +0 -48
- package/tests/core/external-training-contract.test.ts +0 -463
- package/tests/core/file-store.test.ts +0 -102
- package/tests/core/focus-history.test.ts +0 -874
- package/tests/core/init-flatten.test.ts +0 -69
- package/tests/core/init-refactor.test.ts +0 -87
- package/tests/core/init-v1.3.test.ts +0 -46
- package/tests/core/init.test.ts +0 -190
- package/tests/core/ledger-registrar.test.ts +0 -235
- package/tests/core/migration.test.ts +0 -84
- package/tests/core/model-deployment-registry.test.ts +0 -858
- package/tests/core/model-training-registry.test.ts +0 -908
- package/tests/core/observability.test.ts +0 -382
- package/tests/core/pain-diagnostic-gate.test.ts +0 -614
- package/tests/core/pain-score.property.test.ts +0 -19
- package/tests/core/pain.test.ts +0 -132
- package/tests/core/path-resolver.test.ts +0 -57
- package/tests/core/paths-refactor.test.ts +0 -20
- package/tests/core/pd-config-loader.test.ts +0 -407
- package/tests/core/pd-task-store.test.ts +0 -126
- package/tests/core/phase7-rollout-integration.test.ts +0 -477
- package/tests/core/principle-compiler.test.ts +0 -350
- package/tests/core/principle-injection.test.ts +0 -223
- package/tests/core/principle-internalization/deprecated-readiness.test.ts +0 -193
- package/tests/core/principle-internalization/lifecycle-metrics.test.ts +0 -350
- package/tests/core/principle-internalization/lifecycle-routing-policy.test.ts +0 -212
- package/tests/core/principle-internalization/lineage-source-retired.test.ts +0 -56
- package/tests/core/principle-internalization/principle-lifecycle-service.test.ts +0 -189
- package/tests/core/principle-training-state.test.ts +0 -939
- package/tests/core/principle-tree-ledger-adapter.test.ts +0 -253
- package/tests/core/principle-tree-ledger.test.ts +0 -423
- package/tests/core/profile.test.ts +0 -56
- package/tests/core/promotion-gate.test.ts +0 -561
- package/tests/core/queue-purge.test.ts +0 -337
- package/tests/core/reflection-context.test.ts +0 -342
- package/tests/core/regression-v1-9-1.test.ts +0 -266
- package/tests/core/replay-engine.test.ts +0 -165
- package/tests/core/risk-calculator.test.ts +0 -168
- package/tests/core/rule-host-adversarial-output.test.ts +0 -242
- package/tests/core/rule-host-autocorrect-vm.test.ts +0 -163
- package/tests/core/rule-host-helpers.test.ts +0 -120
- package/tests/core/rule-host-resource-bounds.test.ts +0 -231
- package/tests/core/rule-host-sqlite-source.test.ts +0 -720
- package/tests/core/rule-host-unhealthy-visibility.test.ts +0 -261
- package/tests/core/rule-host-validation.test.ts +0 -315
- package/tests/core/rule-implementation-runtime.test.ts +0 -49
- package/tests/core/session-tracker.test.ts +0 -191
- package/tests/core/surface-guard.test.ts +0 -338
- package/tests/core/template-generator.test.ts +0 -101
- package/tests/core/trajectory.test.ts +0 -427
- package/tests/core/workflow-funnel-loader.test.ts +0 -1028
- package/tests/core/workspace-context-factory.test.ts +0 -18
- package/tests/core/workspace-context.test.ts +0 -187
- package/tests/core/workspace-guidance-migrator.test.ts +0 -248
- package/tests/core-anti-growth.test.ts +0 -182
- package/tests/evolution-worker-quarantine.test.ts +0 -400
- package/tests/evolution-worker-slimming.test.ts +0 -380
- package/tests/fixtures/legacy-queue-v1.json +0 -74
- package/tests/fixtures/production-compatibility.test.ts +0 -147
- package/tests/fixtures/production-mock-generator.ts +0 -282
- package/tests/globalSetup.ts +0 -38
- package/tests/hook-workspace-nextaction-contract.test.ts +0 -50
- package/tests/hooks/confirm-first-removal.test.ts +0 -188
- package/tests/hooks/gate-auto-correct-shadow.test.ts +0 -309
- package/tests/hooks/gate-auto-correct.test.ts +0 -664
- package/tests/hooks/gate-block-helper-profile.test.ts +0 -186
- package/tests/hooks/gate-no-path-write-tool.test.ts +0 -171
- package/tests/hooks/gate-rule-host-pipeline.test.ts +0 -230
- package/tests/hooks/gate-rule-host-real-pipeline.test.ts +0 -190
- package/tests/hooks/lifecycle.test.ts +0 -248
- package/tests/hooks/message-sanitize.test.ts +0 -244
- package/tests/hooks/pain-emission-characterization.test.ts +0 -420
- package/tests/hooks/pain.test.ts +0 -795
- package/tests/hooks/prompt-characterization.test.ts +0 -476
- package/tests/hooks/prompt-diet.test.ts +0 -335
- package/tests/hooks/prompt-size-guard.test.ts +0 -319
- package/tests/hooks/raw-observation-adapter.test.ts +0 -312
- package/tests/hooks/runtime-v2-prompt-activation.test.ts +0 -895
- package/tests/hooks/single-gate-pain-admission.test.ts +0 -258
- package/tests/hooks/subagent.test.ts +0 -469
- package/tests/hooks/trajectory-collector.test.ts +0 -269
- package/tests/hooks/trajectory-evidence.test.ts +0 -280
- package/tests/hooks/triage-adapter.test.ts +0 -331
- package/tests/hygiene-tracker.test.ts +0 -77
- package/tests/index.test.ts +0 -142
- package/tests/integration/auto-entry-gate.test.ts +0 -256
- package/tests/integration/gate-real-io.e2e.test.ts +0 -248
- package/tests/integration/m8-legacy-paths.test.ts +0 -63
- package/tests/integration/mvp-surface-registry-guard.test.ts +0 -536
- package/tests/integration/pain-id-chain-e2e.test.ts +0 -313
- package/tests/integration/principle-compiler-e2e.test.ts +0 -403
- package/tests/integration/principle-lifecycle.e2e.test.ts +0 -198
- package/tests/integration/runtime-v2-pain-guard.test.ts +0 -125
- package/tests/integration/trajectory-lifecycle.e2e.test.ts +0 -523
- package/tests/internalization-auto-consumer-gate.test.ts +0 -158
- package/tests/internalization-auto-consumer-service.test.ts +0 -219
- package/tests/plugin-config-resolution-cutover.test.ts +0 -359
- package/tests/queue/async-lock.test.ts +0 -200
- package/tests/runtime-v2-discovery-guard.test.ts +0 -153
- package/tests/scripts/validate-live-path.test.ts +0 -286
- package/tests/service/central-database.test.ts +0 -457
- package/tests/service/correction-observer-service.test.ts +0 -505
- package/tests/service/evolution-worker.compilation-backfill.test.ts +0 -203
- package/tests/service/evolution-worker.correction-observer.test.ts +0 -50
- package/tests/service/evolution-worker.queue.test.ts +0 -296
- package/tests/service/evolution-worker.timeout.test.ts +0 -233
- package/tests/service/keyword-optimization-service.test.ts +0 -121
- package/tests/service/phase3-input-filter.test.ts +0 -289
- package/tests/service/queue-io.test.ts +0 -168
- package/tests/service/queue-migration.test.ts +0 -147
- package/tests/service/runtime-summary-service.test.ts +0 -1100
- package/tests/service/workflow-watchdog.test.ts +0 -281
- package/tests/task-compliance.test.ts +0 -166
- package/tests/test-utils.ts +0 -48
- package/tests/utils/file-lock.test.ts +0 -409
- package/tests/utils/hashing.test.ts +0 -32
- package/tests/utils/hook-workspace-resolver.test.ts +0 -524
- package/tests/utils/io.test.ts +0 -39
- package/tests/utils/retry.test.ts +0 -327
- package/tests/utils/session-key.test.ts +0 -52
- package/tsconfig.json +0 -16
- package/vitest.config.ts +0 -61
- package/vitest.unit.config.ts +0 -12
|
@@ -1,37 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
/* global NodeJS */
|
|
4
|
-
|
|
5
2
|
import * as fs from 'fs';
|
|
6
3
|
import * as path from 'path';
|
|
7
|
-
import type { OpenClawPluginServiceContext, OpenClawPluginApi, PluginLogger } from '../openclaw-sdk.js';
|
|
8
4
|
import { DictionaryService } from '../core/dictionary-service.js';
|
|
9
5
|
import { DetectionService } from '../core/detection-service.js';
|
|
10
6
|
import { ensureStateTemplates, ensureCorePrinciples } from '../core/init.js';
|
|
11
7
|
import { SystemLogger } from '../core/system-logger.js';
|
|
12
8
|
import { WorkspaceContext } from '../core/workspace-context.js';
|
|
13
|
-
import type { EventLog } from '../core/event-log.js';
|
|
14
9
|
import { initPersistence, flushAllSessions } from '../core/session-tracker.js';
|
|
15
|
-
import type { TaskKind, TaskPriority } from '../core/trajectory-types.js';
|
|
16
|
-
import type { PrincipleEvaluability } from '../types/principle-tree-schema.js';
|
|
17
|
-
export type { TaskKind, TaskPriority } from '../core/trajectory-types.js';
|
|
18
10
|
import { atomicWriteFileSync } from '../utils/io.js';
|
|
19
|
-
|
|
20
11
|
// Re-export queue I/O (extracted to queue-io.ts)
|
|
21
12
|
export { loadEvolutionQueue, saveEvolutionQueue, withQueueLock, acquireQueueLock, requireQueueLock } from './queue-io.js';
|
|
22
13
|
export { EVOLUTION_QUEUE_LOCK_SUFFIX, LOCK_MAX_RETRIES, LOCK_RETRY_DELAY_MS, LOCK_STALE_MS } from './queue-io.js';
|
|
23
14
|
import { saveEvolutionQueue, requireQueueLock } from './queue-io.js';
|
|
24
15
|
import { WorkflowStore } from './subagent-workflow/workflow-store.js';
|
|
25
|
-
|
|
26
|
-
|
|
27
16
|
import { PrincipleCompiler } from '../core/principle-compiler/index.js';
|
|
28
17
|
import { loadLedger, updatePrinciple } from '../core/principle-tree-ledger.js';
|
|
29
18
|
import { findRecentDuplicateTask } from './evolution-dedup.js';
|
|
30
19
|
import { TrajectoryRegistry } from '../core/trajectory.js';
|
|
31
20
|
import { WORKFLOW_TTL_MS } from '../config/defaults/runtime.js';
|
|
32
|
-
|
|
33
21
|
// ── Queue Event Payload Validation ─────────────────────────────────────────
|
|
34
|
-
|
|
35
22
|
/**
|
|
36
23
|
* Validates a queue event payload string before JSON.parse.
|
|
37
24
|
* Checks:
|
|
@@ -41,8 +28,9 @@ import { WORKFLOW_TTL_MS } from '../config/defaults/runtime.js';
|
|
|
41
28
|
* Returns empty object {} if payload is falsy.
|
|
42
29
|
* Throws Error if payload is a non-empty string that fails validation.
|
|
43
30
|
*/
|
|
44
|
-
function validateQueueEventPayload(payload
|
|
45
|
-
if (!payload)
|
|
31
|
+
function validateQueueEventPayload(payload) {
|
|
32
|
+
if (!payload)
|
|
33
|
+
return {};
|
|
46
34
|
if (typeof payload !== 'string') {
|
|
47
35
|
throw new Error(`Queue event payload must be a string, got: ${typeof payload}`);
|
|
48
36
|
}
|
|
@@ -55,84 +43,30 @@ function validateQueueEventPayload(payload: string | null | undefined): Record<s
|
|
|
55
43
|
throw new Error('Queue event payload missing required fields: type, workspaceId');
|
|
56
44
|
}
|
|
57
45
|
return parsed;
|
|
58
|
-
}
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
59
48
|
if (err instanceof SyntaxError) {
|
|
60
49
|
throw new Error(`Invalid JSON in queue event payload: ${err.message}`);
|
|
61
50
|
}
|
|
62
51
|
throw err;
|
|
63
52
|
}
|
|
64
53
|
}
|
|
65
|
-
|
|
66
54
|
/* istanbul ignore next — test export for validateQueueEventPayload */
|
|
67
55
|
export { validateQueueEventPayload };
|
|
68
|
-
|
|
69
56
|
// Re-export workflow watchdog (extracted to workflow-watchdog.ts)
|
|
70
|
-
import { runWorkflowWatchdog
|
|
57
|
+
import { runWorkflowWatchdog } from './workflow-watchdog.js';
|
|
71
58
|
export { runWorkflowWatchdog };
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
let timeoutId: NodeJS.Timeout | null = null;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Queue V2 Schema - Supports background evolution task kinds.
|
|
78
|
-
*
|
|
79
|
-
* Pain diagnosis is Runtime v2 only: after_tool_call / pd pain record ->
|
|
80
|
-
* PainSignalBridge -> SplitDiagnosticianRunner. EvolutionWorker does not read
|
|
81
|
-
* .pain_flag or process pain_diagnosis queue items.
|
|
82
|
-
*/
|
|
83
|
-
/** @deprecated Use PDTaskStatus from '@principles/core/runtime-v2'. M2 migration will replace this. */
|
|
84
|
-
export type QueueStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'canceled';
|
|
85
|
-
export type TaskResolution = 'marker_detected' | 'auto_completed_timeout' | 'failed_max_retries' | 'runtime_unavailable' | 'canceled' | 'late_marker_principle_created' | 'late_marker_no_principle' | 'stub_fallback' | 'skipped_thin_violation' | 'noise_classified' | 'retired';
|
|
86
|
-
|
|
87
|
-
export interface EvolutionQueueItem {
|
|
88
|
-
// Core identity
|
|
89
|
-
id: string;
|
|
90
|
-
taskKind: TaskKind; // V2: distinguishes task types
|
|
91
|
-
priority: TaskPriority; // V2: scheduling priority
|
|
92
|
-
source: string;
|
|
93
|
-
traceId?: string; // Trace ID for linking events across the evolution lifecycle
|
|
94
|
-
|
|
95
|
-
// Legacy fields kept for existing queue records and background task metadata.
|
|
96
|
-
task?: string;
|
|
97
|
-
score: number;
|
|
98
|
-
reason: string;
|
|
99
|
-
timestamp: string;
|
|
100
|
-
enqueued_at?: string;
|
|
101
|
-
started_at?: string;
|
|
102
|
-
completed_at?: string;
|
|
103
|
-
assigned_session_key?: string;
|
|
104
|
-
trigger_text_preview?: string;
|
|
105
|
-
status: QueueStatus; // V2: includes 'failed' and 'canceled'
|
|
106
|
-
resolution?: TaskResolution;
|
|
107
|
-
session_id?: string;
|
|
108
|
-
agent_id?: string;
|
|
109
|
-
|
|
110
|
-
// V2 retry support
|
|
111
|
-
retryCount: number; // V2: number of retry attempts
|
|
112
|
-
maxRetries: number; // V2: maximum retry attempts allowed
|
|
113
|
-
lastError?: string; // V2: last error message if failed
|
|
114
|
-
|
|
115
|
-
// V2 result reference
|
|
116
|
-
resultRef?: string; // V2: reference to result artifact
|
|
117
|
-
|
|
118
|
-
painEventId?: number;
|
|
119
|
-
}
|
|
120
|
-
|
|
59
|
+
let timeoutId = null;
|
|
121
60
|
// ── Queue Migration (extracted to queue-migration.ts) ────────────────────────
|
|
122
|
-
import { migrateToV2, isLegacyQueueItem, migrateQueueToV2,
|
|
123
|
-
export { migrateToV2, isLegacyQueueItem, migrateQueueToV2,
|
|
124
|
-
export type { RawQueueItem };
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
61
|
+
import { migrateToV2, isLegacyQueueItem, migrateQueueToV2, DEFAULT_TASK_KIND, DEFAULT_PRIORITY, DEFAULT_MAX_RETRIES } from './queue-migration.js';
|
|
62
|
+
export { migrateToV2, isLegacyQueueItem, migrateQueueToV2, DEFAULT_TASK_KIND, DEFAULT_PRIORITY, DEFAULT_MAX_RETRIES };
|
|
128
63
|
// Queue lock constants and requireQueueLock are imported from queue-io.ts
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
64
|
+
export function extractEvolutionTaskId(task) {
|
|
65
|
+
if (!task)
|
|
66
|
+
return null;
|
|
132
67
|
const match = /\[ID:\s*([A-Za-z0-9_-]+)\]/.exec(task);
|
|
133
68
|
return match?.[1] || null;
|
|
134
69
|
}
|
|
135
|
-
|
|
136
70
|
/**
|
|
137
71
|
* Purge stale failed tasks from the queue.
|
|
138
72
|
* Failed tasks older than the threshold are noise — they won't auto-recover
|
|
@@ -141,49 +75,41 @@ export function extractEvolutionTaskId(task: string): string | null {
|
|
|
141
75
|
* Called at the start of each cycle to keep the queue lean.
|
|
142
76
|
*/
|
|
143
77
|
const STALE_FAILED_TASK_MAX_AGE_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
144
|
-
|
|
145
|
-
export function purgeStaleFailedTasks(
|
|
146
|
-
queue: EvolutionQueueItem[],
|
|
147
|
-
logger: PluginLogger,
|
|
148
|
-
): { purged: number; remaining: number; byReason: Record<string, number> } {
|
|
78
|
+
export function purgeStaleFailedTasks(queue, logger) {
|
|
149
79
|
const cutoff = Date.now() - STALE_FAILED_TASK_MAX_AGE_MS;
|
|
150
|
-
const byReason
|
|
151
|
-
|
|
80
|
+
const byReason = {};
|
|
152
81
|
const purged = queue.filter((t) => {
|
|
153
|
-
if (t.status !== 'failed')
|
|
82
|
+
if (t.status !== 'failed')
|
|
83
|
+
return false;
|
|
154
84
|
const taskTime = new Date(t.timestamp || t.enqueued_at || 0).getTime();
|
|
155
|
-
if (!Number.isFinite(taskTime) || taskTime > cutoff)
|
|
85
|
+
if (!Number.isFinite(taskTime) || taskTime > cutoff)
|
|
86
|
+
return false;
|
|
156
87
|
const reason = t.lastError || t.resolution || 'unknown';
|
|
157
88
|
byReason[reason] = (byReason[reason] || 0) + 1;
|
|
158
89
|
return true;
|
|
159
90
|
});
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
91
|
+
if (purged.length === 0)
|
|
92
|
+
return { purged: 0, remaining: queue.length, byReason };
|
|
163
93
|
// Remove purged items from the queue (mutates in place)
|
|
164
94
|
const purgedIds = new Set(purged.map((t) => t.id));
|
|
165
95
|
for (let i = queue.length - 1; i >= 0; i--) {
|
|
166
|
-
if (purgedIds.has(queue[i].id))
|
|
96
|
+
if (purgedIds.has(queue[i].id))
|
|
97
|
+
queue.splice(i, 1);
|
|
167
98
|
}
|
|
168
|
-
|
|
169
99
|
const summary = Object.entries(byReason)
|
|
170
100
|
.map(([r, c]) => `${c}x ${r}`)
|
|
171
101
|
.join('; ');
|
|
172
102
|
logger?.info?.(`[PD:EvolutionWorker] Purged ${purged.length} stale failed tasks (>24h): ${summary}`);
|
|
173
|
-
|
|
174
103
|
return { purged: purged.length, remaining: queue.length, byReason };
|
|
175
104
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
export function hasRecentDuplicateTask(queue: EvolutionQueueItem[], source: string, preview: string, now: number, reason?: string): boolean {
|
|
105
|
+
export function hasRecentDuplicateTask(queue, source, preview, now, reason) {
|
|
180
106
|
return !!findRecentDuplicateTask(queue, source, preview, now, reason);
|
|
181
107
|
}
|
|
182
|
-
|
|
183
|
-
export function hasEquivalentPromotedRule(dictionary: { getAllRules(): Record<string, { type: string; phrases?: string[]; pattern?: string; status: string; }> }, phrase: string): boolean {
|
|
108
|
+
export function hasEquivalentPromotedRule(dictionary, phrase) {
|
|
184
109
|
const normalizedPhrase = phrase.trim().toLowerCase();
|
|
185
110
|
return Object.values(dictionary.getAllRules()).some((rule) => {
|
|
186
|
-
if (rule.status !== 'active')
|
|
111
|
+
if (rule.status !== 'active')
|
|
112
|
+
return false;
|
|
187
113
|
if (rule.type === 'exact_match' && Array.isArray(rule.phrases)) {
|
|
188
114
|
return rule.phrases.some((candidate) => candidate.trim().toLowerCase() === normalizedPhrase);
|
|
189
115
|
}
|
|
@@ -193,7 +119,6 @@ export function hasEquivalentPromotedRule(dictionary: { getAllRules(): Record<st
|
|
|
193
119
|
return false;
|
|
194
120
|
});
|
|
195
121
|
}
|
|
196
|
-
|
|
197
122
|
/**
|
|
198
123
|
* Process compilation backfill and retry loop.
|
|
199
124
|
* Phase 1 — Backfill: on first call, scan for old principles (compilationRetryCount === undefined)
|
|
@@ -201,92 +126,83 @@ export function hasEquivalentPromotedRule(dictionary: { getAllRules(): Record<st
|
|
|
201
126
|
* Phase 2 — Retry: compile all principles with compilationRetryCount >= 0.
|
|
202
127
|
* After 5 consecutive failures, downgrades to manual_only and logs COMPILE_EXHAUSTED.
|
|
203
128
|
*/
|
|
204
|
-
export async function processCompilationBackfill(
|
|
205
|
-
wctx
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if (!wctx.stateDir) return;
|
|
209
|
-
|
|
210
|
-
let ledger: ReturnType<typeof loadLedger>;
|
|
129
|
+
export async function processCompilationBackfill(wctx, logger) {
|
|
130
|
+
if (!wctx.stateDir)
|
|
131
|
+
return;
|
|
132
|
+
let ledger;
|
|
211
133
|
try {
|
|
212
134
|
ledger = loadLedger(wctx.stateDir);
|
|
213
|
-
}
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
214
137
|
logger?.warn?.(`[PD:EvolutionWorker] CompilationBackfill: failed to load ledger: ${String(err)}`);
|
|
215
138
|
return;
|
|
216
139
|
}
|
|
217
|
-
|
|
218
140
|
// ── Phase 1: Backfill old principles (runs once per process) ─────────────────
|
|
219
141
|
const backfillMarkerPath = path.join(wctx.stateDir, 'COMPILATION_BACKFILL_DONE');
|
|
220
142
|
const hasBackfillRun = fs.existsSync(backfillMarkerPath);
|
|
221
143
|
if (!hasBackfillRun) {
|
|
222
144
|
let backfillQueued = 0;
|
|
223
145
|
for (const [principleId, principle] of Object.entries(ledger.tree.principles)) {
|
|
224
|
-
if (principle.compilationRetryCount !== undefined)
|
|
225
|
-
|
|
146
|
+
if (principle.compilationRetryCount !== undefined)
|
|
147
|
+
continue; // already processed
|
|
148
|
+
if (principle.evaluability === 'manual_only')
|
|
149
|
+
continue;
|
|
226
150
|
// Check if already has active implementation
|
|
227
|
-
const hasActiveImpl = Object.values(ledger.tree.implementations).some(
|
|
228
|
-
(impl) => impl.lifecycleState === 'active' && (
|
|
229
|
-
ledger.tree.rules[impl.ruleId]?.principleId === principleId
|
|
230
|
-
)
|
|
231
|
-
);
|
|
151
|
+
const hasActiveImpl = Object.values(ledger.tree.implementations).some((impl) => impl.lifecycleState === 'active' && (ledger.tree.rules[impl.ruleId]?.principleId === principleId));
|
|
232
152
|
if (hasActiveImpl) {
|
|
233
153
|
// Already compiled — mark as done
|
|
234
154
|
try {
|
|
235
155
|
updatePrinciple(wctx.stateDir, principleId, { compilationRetryCount: undefined });
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
SystemLogger.log(wctx.workspaceDir, 'BACKFILL_UPDATE_FAILED', `Failed to mark principle ${principleId} as done: ${String(err)}`);
|
|
239
159
|
continue;
|
|
240
160
|
}
|
|
241
|
-
}
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
242
163
|
// Needs compilation — queue it
|
|
243
164
|
try {
|
|
244
165
|
updatePrinciple(wctx.stateDir, principleId, { compilationRetryCount: 0 });
|
|
245
166
|
backfillQueued++;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
SystemLogger.log(wctx.workspaceDir, 'BACKFILL_UPDATE_FAILED', `Failed to queue principle ${principleId}: ${String(err)}`);
|
|
249
170
|
continue;
|
|
250
171
|
}
|
|
251
172
|
}
|
|
252
173
|
}
|
|
253
174
|
if (backfillQueued > 0) {
|
|
254
|
-
SystemLogger.log(wctx.workspaceDir, 'COMPILE_BACKFILL_QUEUED',
|
|
255
|
-
`Queued ${backfillQueued} old principles for compilation`);
|
|
175
|
+
SystemLogger.log(wctx.workspaceDir, 'COMPILE_BACKFILL_QUEUED', `Queued ${backfillQueued} old principles for compilation`);
|
|
256
176
|
}
|
|
257
177
|
// Write marker so we don't backfill again in this process
|
|
258
178
|
try {
|
|
259
179
|
atomicWriteFileSync(backfillMarkerPath, new Date().toISOString());
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
SystemLogger.log(wctx.workspaceDir, 'BACKFILL_MARKER_WRITE_FAILED', `Failed to write backfill marker: ${String(err)}`);
|
|
263
183
|
}
|
|
264
184
|
}
|
|
265
|
-
|
|
266
185
|
// ── Phase 2: Retry pending compilations ───────────────────────────────────
|
|
267
186
|
const trajectory = TrajectoryRegistry.get(wctx.workspaceDir);
|
|
268
187
|
const compiler = new PrincipleCompiler(wctx.stateDir, trajectory);
|
|
269
|
-
|
|
270
188
|
// Re-load ledger after potential backfill updates
|
|
271
189
|
ledger = loadLedger(wctx.stateDir);
|
|
272
|
-
|
|
273
190
|
for (const [principleId, principle] of Object.entries(ledger.tree.principles)) {
|
|
274
191
|
const count = principle.compilationRetryCount;
|
|
275
|
-
|
|
276
192
|
// Skip: not in retry queue (undefined = done/succeeded)
|
|
277
|
-
if (count === undefined)
|
|
278
|
-
|
|
193
|
+
if (count === undefined)
|
|
194
|
+
continue;
|
|
279
195
|
// Skip: already exhausted (count >= 5 means 5 attempts already made)
|
|
280
|
-
if (count >= 5)
|
|
281
|
-
|
|
196
|
+
if (count >= 5)
|
|
197
|
+
continue;
|
|
282
198
|
// Error-isolate each principle so one failure doesn't stop all other retries
|
|
283
199
|
try {
|
|
284
200
|
const result = compiler.compileOne(principleId);
|
|
285
201
|
if (result.success) {
|
|
286
202
|
tryUpdateRetryCount(wctx.stateDir, wctx.workspaceDir, principleId, undefined);
|
|
287
|
-
SystemLogger.log(wctx.workspaceDir, 'COMPILE_SUCCESS',
|
|
288
|
-
|
|
289
|
-
|
|
203
|
+
SystemLogger.log(wctx.workspaceDir, 'COMPILE_SUCCESS', `Principle ${principleId} compiled successfully (attempt ${count + 1})`);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
290
206
|
const nextCount = count + 1;
|
|
291
207
|
if (nextCount >= 5) {
|
|
292
208
|
// Exhausted: single write to set manual_only (no intermediate count write)
|
|
@@ -294,15 +210,15 @@ export async function processCompilationBackfill(
|
|
|
294
210
|
evaluability: 'manual_only',
|
|
295
211
|
compilationRetryCount: undefined,
|
|
296
212
|
});
|
|
297
|
-
SystemLogger.log(wctx.workspaceDir, 'COMPILE_EXHAUSTED',
|
|
298
|
-
|
|
299
|
-
|
|
213
|
+
SystemLogger.log(wctx.workspaceDir, 'COMPILE_EXHAUSTED', `Principle ${principleId} compilation exhausted after 5 attempts: ${result.reason ?? 'unknown'}`);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
300
216
|
tryUpdateRetryCount(wctx.stateDir, wctx.workspaceDir, principleId, nextCount);
|
|
301
|
-
SystemLogger.log(wctx.workspaceDir, 'COMPILE_FAILED',
|
|
302
|
-
`Principle ${principleId} compile failed: ${result.reason ?? 'unknown'} (attempt ${nextCount}/5)`);
|
|
217
|
+
SystemLogger.log(wctx.workspaceDir, 'COMPILE_FAILED', `Principle ${principleId} compile failed: ${result.reason ?? 'unknown'} (attempt ${nextCount}/5)`);
|
|
303
218
|
}
|
|
304
219
|
}
|
|
305
|
-
}
|
|
220
|
+
}
|
|
221
|
+
catch (compileErr) {
|
|
306
222
|
const nextCount = count + 1;
|
|
307
223
|
if (nextCount >= 5) {
|
|
308
224
|
// Exhausted: single write to set manual_only (no intermediate count write)
|
|
@@ -310,65 +226,55 @@ export async function processCompilationBackfill(
|
|
|
310
226
|
evaluability: 'manual_only',
|
|
311
227
|
compilationRetryCount: undefined,
|
|
312
228
|
});
|
|
313
|
-
SystemLogger.log(wctx.workspaceDir, 'COMPILE_EXHAUSTED',
|
|
314
|
-
|
|
315
|
-
|
|
229
|
+
SystemLogger.log(wctx.workspaceDir, 'COMPILE_EXHAUSTED', `Principle ${principleId} compilation exhausted after 5 attempts: threw ${String(compileErr)}`);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
316
232
|
tryUpdateRetryCount(wctx.stateDir, wctx.workspaceDir, principleId, nextCount);
|
|
317
|
-
SystemLogger.log(wctx.workspaceDir, 'COMPILE_FAILED',
|
|
318
|
-
`Principle ${principleId} compile threw: ${String(compileErr)} (attempt ${nextCount}/5)`);
|
|
233
|
+
SystemLogger.log(wctx.workspaceDir, 'COMPILE_FAILED', `Principle ${principleId} compile threw: ${String(compileErr)} (attempt ${nextCount}/5)`);
|
|
319
234
|
}
|
|
320
235
|
}
|
|
321
236
|
}
|
|
322
237
|
}
|
|
323
|
-
|
|
324
238
|
/**
|
|
325
239
|
* Wrapper for updateRetryCount — logs but does not propagate errors.
|
|
326
240
|
* Errors are silently swallowed: if update fails, the principle stays in its
|
|
327
241
|
* current retry state and will be picked up again on the next heartbeat.
|
|
328
242
|
*/
|
|
329
|
-
function tryUpdateRetryCount(stateDir
|
|
243
|
+
function tryUpdateRetryCount(stateDir, workspaceDir, principleId, count) {
|
|
330
244
|
try {
|
|
331
245
|
updatePrinciple(stateDir, principleId, { compilationRetryCount: count });
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
|
|
246
|
+
}
|
|
247
|
+
catch (err) {
|
|
248
|
+
SystemLogger.log(workspaceDir, 'RETRY_COUNT_UPDATE_FAILED', `Failed to update retry count for ${principleId}: ${String(err)}`);
|
|
335
249
|
}
|
|
336
250
|
}
|
|
337
|
-
|
|
338
251
|
/**
|
|
339
252
|
* Wrapper for updatePrinciple with multiple fields — logs but does not propagate errors.
|
|
340
253
|
* Errors are silently swallowed: if update fails, the principle stays in its
|
|
341
254
|
* current state and will be picked up again on the next heartbeat.
|
|
342
255
|
*/
|
|
343
|
-
function tryUpdatePrinciple(
|
|
344
|
-
stateDir: string,
|
|
345
|
-
workspaceDir: string,
|
|
346
|
-
principleId: string,
|
|
347
|
-
updates: { evaluability?: PrincipleEvaluability; compilationRetryCount?: number },
|
|
348
|
-
): void {
|
|
256
|
+
function tryUpdatePrinciple(stateDir, workspaceDir, principleId, updates) {
|
|
349
257
|
try {
|
|
350
258
|
updatePrinciple(stateDir, principleId, updates);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
SystemLogger.log(workspaceDir, 'RETRY_PRINCIPLE_UPDATE_FAILED', `Failed to update principle ${principleId}: ${String(err)}`);
|
|
354
262
|
}
|
|
355
263
|
}
|
|
356
|
-
|
|
357
|
-
async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogger, _eventLog?: EventLog, _api?: OpenClawPluginApi) {
|
|
264
|
+
async function processEvolutionQueue(wctx, logger, _eventLog, _api) {
|
|
358
265
|
const queuePath = wctx.resolve('EVOLUTION_QUEUE');
|
|
359
266
|
if (!fs.existsSync(queuePath)) {
|
|
360
267
|
logger?.debug?.('[PD:EvolutionWorker] No evolution queue file — nothing to process');
|
|
361
268
|
return;
|
|
362
269
|
}
|
|
363
|
-
|
|
364
270
|
const releaseLock = await requireQueueLock(queuePath, logger, 'processEvolutionQueue');
|
|
365
271
|
let lockReleased = false;
|
|
366
|
-
|
|
367
272
|
try {
|
|
368
|
-
let rawQueue
|
|
273
|
+
let rawQueue = [];
|
|
369
274
|
try {
|
|
370
275
|
rawQueue = JSON.parse(fs.readFileSync(queuePath, 'utf8'));
|
|
371
|
-
}
|
|
276
|
+
}
|
|
277
|
+
catch (e) {
|
|
372
278
|
// Backup corrupted file instead of silently discarding
|
|
373
279
|
const backupPath = `${queuePath}.corrupted.${Date.now()}`;
|
|
374
280
|
try {
|
|
@@ -377,17 +283,16 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
|
|
|
377
283
|
logger.error(`[PD:EvolutionWorker] Evolution queue corrupted and backed up to ${backupPath}. All pending tasks have been preserved in the backup file. Parse error: ${String(e)}`);
|
|
378
284
|
}
|
|
379
285
|
SystemLogger.log(wctx.workspaceDir, 'QUEUE_CORRUPTED', `Queue file backed up to ${backupPath}. Error: ${String(e)}`);
|
|
380
|
-
}
|
|
286
|
+
}
|
|
287
|
+
catch (backupErr) {
|
|
381
288
|
if (logger) {
|
|
382
289
|
logger.error(`[PD:EvolutionWorker] Failed to backup corrupted queue: ${String(backupErr)}`);
|
|
383
290
|
}
|
|
384
291
|
}
|
|
385
292
|
return;
|
|
386
293
|
}
|
|
387
|
-
|
|
388
294
|
// V2: Migrate queue to current schema if needed
|
|
389
|
-
let queue
|
|
390
|
-
|
|
295
|
+
let queue = migrateQueueToV2(rawQueue);
|
|
391
296
|
// Runtime v2 owns pain diagnosis. Drop legacy pain_diagnosis queue items so
|
|
392
297
|
// EvolutionWorker cannot revive the old .pain_flag -> prompt path.
|
|
393
298
|
const beforeLegacyPainDrop = queue.length;
|
|
@@ -395,25 +300,31 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
|
|
|
395
300
|
if (queue.length < beforeLegacyPainDrop) {
|
|
396
301
|
logger?.info?.(`[PD:EvolutionWorker] Dropped ${beforeLegacyPainDrop - queue.length} legacy pain_diagnosis queue item(s); use PainSignalBridge/pd pain record`);
|
|
397
302
|
}
|
|
398
|
-
|
|
399
303
|
// Validate queue items — filter out malformed entries before processing.
|
|
400
304
|
// Malformed items are logged + skipped; they never crash the evolution cycle.
|
|
401
305
|
const beforeValidation = queue.length;
|
|
402
306
|
queue = queue.filter((item) => {
|
|
403
|
-
const errors
|
|
404
|
-
if (!item.id || typeof item.id !== 'string')
|
|
405
|
-
|
|
406
|
-
if (typeof item.
|
|
407
|
-
|
|
408
|
-
if (
|
|
307
|
+
const errors = [];
|
|
308
|
+
if (!item.id || typeof item.id !== 'string')
|
|
309
|
+
errors.push('missing/invalid id');
|
|
310
|
+
if (!item.source || typeof item.source !== 'string')
|
|
311
|
+
errors.push('missing/invalid source');
|
|
312
|
+
if (typeof item.score !== 'number')
|
|
313
|
+
errors.push('missing/invalid score');
|
|
314
|
+
if (!item.status || typeof item.status !== 'string')
|
|
315
|
+
errors.push('missing/invalid status');
|
|
316
|
+
if (!item.taskKind || typeof item.taskKind !== 'string')
|
|
317
|
+
errors.push('missing/invalid taskKind');
|
|
409
318
|
else {
|
|
410
319
|
const validTaskKinds = ['model_eval'];
|
|
411
320
|
if (!validTaskKinds.includes(item.taskKind)) {
|
|
412
321
|
errors.push(`invalid taskKind value '${item.taskKind}' (expected one of: ${validTaskKinds.join(', ')})`);
|
|
413
322
|
}
|
|
414
323
|
}
|
|
415
|
-
if (typeof item.retryCount !== 'number')
|
|
416
|
-
|
|
324
|
+
if (typeof item.retryCount !== 'number')
|
|
325
|
+
errors.push('missing/invalid retryCount');
|
|
326
|
+
if (typeof item.maxRetries !== 'number')
|
|
327
|
+
errors.push('missing/invalid maxRetries');
|
|
417
328
|
if (errors.length > 0) {
|
|
418
329
|
logger?.warn?.(`[PD:EvolutionWorker] Skipping malformed queue item: ${errors.join(', ')} | ${JSON.stringify(item).slice(0, 200)}`);
|
|
419
330
|
SystemLogger.log(wctx.workspaceDir, 'QUEUE_ITEM_MALFORMED', `Skipped: ${errors.join(', ')} | id=${item.id || 'N/A'}`);
|
|
@@ -424,34 +335,31 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
|
|
|
424
335
|
if (queue.length < beforeValidation) {
|
|
425
336
|
logger?.info?.(`[PD:EvolutionWorker] Filtered ${beforeValidation - queue.length} malformed queue item(s)`);
|
|
426
337
|
}
|
|
427
|
-
|
|
428
338
|
let queueChanged = rawQueue.some(isLegacyQueueItem) || queue.length < beforeLegacyPainDrop || queue.length < beforeValidation;
|
|
429
|
-
|
|
430
339
|
if (queueChanged) {
|
|
431
340
|
saveEvolutionQueue(queuePath, queue);
|
|
432
341
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
if (logger)
|
|
436
|
-
|
|
342
|
+
}
|
|
343
|
+
catch (err) {
|
|
344
|
+
if (logger)
|
|
345
|
+
logger.warn(`[PD:EvolutionWorker] Error processing evolution queue: ${String(err)}`);
|
|
346
|
+
}
|
|
347
|
+
finally {
|
|
437
348
|
if (!lockReleased) {
|
|
438
349
|
releaseLock();
|
|
439
350
|
}
|
|
440
351
|
}
|
|
441
352
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
async function processDetectionQueue(wctx: WorkspaceContext, api: OpenClawPluginApi, eventLog: EventLog) {
|
|
445
|
-
const {logger} = api;
|
|
353
|
+
async function processDetectionQueue(wctx, api, eventLog) {
|
|
354
|
+
const { logger } = api;
|
|
446
355
|
try {
|
|
447
356
|
const funnel = DetectionService.get(wctx.stateDir);
|
|
448
357
|
const queue = funnel.flushQueue();
|
|
449
|
-
if (queue.length === 0)
|
|
450
|
-
|
|
451
|
-
if (logger)
|
|
452
|
-
|
|
358
|
+
if (queue.length === 0)
|
|
359
|
+
return;
|
|
360
|
+
if (logger)
|
|
361
|
+
logger.info(`[PD:EvolutionWorker] Processing ${queue.length} items from detection funnel.`);
|
|
453
362
|
const dictionary = DictionaryService.get(wctx.stateDir);
|
|
454
|
-
|
|
455
363
|
for (const text of queue) {
|
|
456
364
|
const match = dictionary.match(text);
|
|
457
365
|
if (match) {
|
|
@@ -463,7 +371,8 @@ async function processDetectionQueue(wctx: WorkspaceContext, api: OpenClawPlugin
|
|
|
463
371
|
textPreview: text.substring(0, 100)
|
|
464
372
|
});
|
|
465
373
|
}
|
|
466
|
-
}
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
467
376
|
// L3 semantic search via trajectory database FTS5 (MEM-04)
|
|
468
377
|
if (wctx.trajectory) {
|
|
469
378
|
const searchResults = wctx.trajectory.searchPainEvents(text, 5);
|
|
@@ -480,210 +389,139 @@ async function processDetectionQueue(wctx: WorkspaceContext, api: OpenClawPlugin
|
|
|
480
389
|
// Update detection funnel cache with L3 hit result
|
|
481
390
|
funnel.updateCache(text, { detected: true, severity: searchResults[0].score });
|
|
482
391
|
// Don't track as candidate - this is a confirmed L3 hit
|
|
483
|
-
if (logger)
|
|
392
|
+
if (logger)
|
|
393
|
+
logger.info(`[PD:EvolutionWorker] L3 semantic hit: found ${searchResults.length} similar pain events for "${text.substring(0, 50)}..."`);
|
|
484
394
|
continue;
|
|
485
395
|
}
|
|
486
396
|
}
|
|
487
397
|
// No L3 hit — pain candidate tracking removed (D-05)
|
|
488
398
|
}
|
|
489
399
|
}
|
|
490
|
-
}
|
|
491
|
-
|
|
400
|
+
}
|
|
401
|
+
catch (err) {
|
|
402
|
+
if (logger)
|
|
403
|
+
logger.warn(`[PD:EvolutionWorker] Detection queue failed: ${String(err)}`);
|
|
492
404
|
}
|
|
493
405
|
}
|
|
494
|
-
|
|
495
406
|
// PAIN_CANDIDATES system removed (D-05, D-06): trackPainCandidate and processPromotion deleted
|
|
496
407
|
// Evolution queue is now the single active pain→principle path
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
export async function registerEvolutionTaskSession(
|
|
501
|
-
workspaceResolve: (key: string) => string,
|
|
502
|
-
taskId: string,
|
|
503
|
-
sessionKey: string,
|
|
504
|
-
logger?: { warn?: (message: string) => void; info?: (message: string) => void }
|
|
505
|
-
): Promise<boolean> {
|
|
408
|
+
export async function registerEvolutionTaskSession(workspaceResolve, taskId, sessionKey, logger) {
|
|
506
409
|
const queuePath = workspaceResolve('EVOLUTION_QUEUE');
|
|
507
|
-
if (!fs.existsSync(queuePath))
|
|
508
|
-
|
|
410
|
+
if (!fs.existsSync(queuePath))
|
|
411
|
+
return false;
|
|
509
412
|
const releaseLock = await requireQueueLock(queuePath, logger, 'registerEvolutionTaskSession');
|
|
510
|
-
|
|
511
413
|
try {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
let rawQueue: RawQueueItem[];
|
|
414
|
+
let rawQueue;
|
|
515
415
|
try {
|
|
516
416
|
rawQueue = JSON.parse(fs.readFileSync(queuePath, 'utf8'));
|
|
517
|
-
}
|
|
417
|
+
}
|
|
418
|
+
catch (parseErr) {
|
|
518
419
|
logger?.warn?.(`[PD:EvolutionWorker] Failed to parse EVOLUTION_QUEUE for session registration: ${queuePath} - ${parseErr instanceof Error ? parseErr.message : String(parseErr)}`);
|
|
519
420
|
return false;
|
|
520
421
|
}
|
|
521
|
-
|
|
522
422
|
// V2: Migrate queue to current schema
|
|
523
|
-
const queue
|
|
524
|
-
|
|
423
|
+
const queue = migrateQueueToV2(rawQueue);
|
|
525
424
|
const task = queue.find((item) => item.id === taskId && item.status === 'in_progress');
|
|
526
425
|
if (!task) {
|
|
527
426
|
logger?.warn?.(`[PD:EvolutionWorker] Could not find in-progress evolution task ${taskId} for session assignment`);
|
|
528
427
|
return false;
|
|
529
428
|
}
|
|
530
|
-
|
|
531
429
|
task.assigned_session_key = sessionKey;
|
|
532
430
|
if (!task.started_at) {
|
|
533
431
|
task.started_at = new Date().toISOString();
|
|
534
432
|
}
|
|
535
433
|
saveEvolutionQueue(queuePath, queue);
|
|
536
434
|
return true;
|
|
537
|
-
}
|
|
435
|
+
}
|
|
436
|
+
finally {
|
|
538
437
|
releaseLock();
|
|
539
438
|
}
|
|
540
439
|
}
|
|
541
|
-
|
|
542
|
-
/**
|
|
543
|
-
* Evolution Worker - Background service for pain processing and evolution task management.
|
|
544
|
-
*
|
|
545
|
-
* IMPORTANT: evolution_directive.json is a COMPATIBILITY-ONLY DISPLAY ARTIFACT.
|
|
546
|
-
* This service does NOT read or use directive for Phase 3 eligibility or any decisions.
|
|
547
|
-
* Queue (EVOLUTION_QUEUE) is the only authoritative execution truth source.
|
|
548
|
-
*
|
|
549
|
-
* Directive exists solely for UI/backwards compatibility display purposes.
|
|
550
|
-
* Production evidence shows directive stopped updating on 2026-03-22 and is stale.
|
|
551
|
-
*/
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
export interface ExtendedEvolutionWorkerService {
|
|
555
|
-
id: string;
|
|
556
|
-
api: OpenClawPluginApi | null;
|
|
557
|
-
_startedWorkspaces: Set<string>;
|
|
558
|
-
start: (ctx: OpenClawPluginServiceContext) => void | Promise<void>;
|
|
559
|
-
stop?: (ctx: OpenClawPluginServiceContext) => void | Promise<void>;
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
interface WorkerStatusReport {
|
|
564
|
-
timestamp: string;
|
|
565
|
-
cycle_start_ms: number;
|
|
566
|
-
duration_ms: number;
|
|
567
|
-
pain_flag: { exists: boolean; score: number | null; source: string | null; enqueued: boolean; skipped_reason: string | null };
|
|
568
|
-
queue: { total: number; pending: number; in_progress: number; completed_this_cycle: number; failed_this_cycle: number };
|
|
569
|
-
errors: string[];
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
function writeWorkerStatus(stateDir: string, report: WorkerStatusReport): void {
|
|
440
|
+
function writeWorkerStatus(stateDir, report) {
|
|
573
441
|
try {
|
|
574
442
|
const statusPath = path.join(stateDir, 'worker-status.json');
|
|
575
443
|
atomicWriteFileSync(statusPath, JSON.stringify(report, null, 2));
|
|
576
|
-
}
|
|
444
|
+
}
|
|
445
|
+
catch (statusErr) {
|
|
577
446
|
// Non-critical: worker-status.json is for monitoring, failure is acceptable
|
|
578
447
|
// (no logger available in this standalone helper)
|
|
579
448
|
void statusErr;
|
|
580
449
|
}
|
|
581
450
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
async function processEvolutionQueueWithResult(
|
|
586
|
-
wctx: WorkspaceContext,
|
|
587
|
-
logger: PluginLogger,
|
|
588
|
-
eventLog: EventLog,
|
|
589
|
-
api?: OpenClawPluginApi | undefined
|
|
590
|
-
): Promise<{ queue: WorkerStatusReport['queue']; errors: string[] }> {
|
|
591
|
-
const queueResult: WorkerStatusReport['queue'] = { total: 0, pending: 0, in_progress: 0, completed_this_cycle: 0, failed_this_cycle: 0 };
|
|
592
|
-
const errors: string[] = [];
|
|
593
|
-
|
|
451
|
+
async function processEvolutionQueueWithResult(wctx, logger, eventLog, api) {
|
|
452
|
+
const queueResult = { total: 0, pending: 0, in_progress: 0, completed_this_cycle: 0, failed_this_cycle: 0 };
|
|
453
|
+
const errors = [];
|
|
594
454
|
try {
|
|
595
455
|
const queuePath = wctx.resolve('EVOLUTION_QUEUE');
|
|
596
456
|
if (!fs.existsSync(queuePath)) {
|
|
597
457
|
return { queue: queueResult, errors };
|
|
598
458
|
}
|
|
599
|
-
|
|
600
|
-
const queue: EvolutionQueueItem[] = JSON.parse(fs.readFileSync(queuePath, 'utf8')) as EvolutionQueueItem[];
|
|
601
|
-
|
|
459
|
+
const queue = JSON.parse(fs.readFileSync(queuePath, 'utf8'));
|
|
602
460
|
// Purge stale failed tasks before processing (keeps queue lean)
|
|
603
461
|
const purgeResult = purgeStaleFailedTasks(queue, logger);
|
|
604
462
|
if (purgeResult.purged > 0) {
|
|
605
463
|
// Write back the cleaned queue
|
|
606
464
|
saveEvolutionQueue(queuePath, queue);
|
|
607
465
|
}
|
|
608
|
-
|
|
609
466
|
queueResult.total = queue.length;
|
|
610
467
|
queueResult.pending = queue.filter((t) => t.status === 'pending').length;
|
|
611
468
|
queueResult.in_progress = queue.filter((t) => t.status === 'in_progress').length;
|
|
612
469
|
queueResult.failed_this_cycle = queue.filter((t) => t.status === 'failed').length;
|
|
613
470
|
queueResult.completed_this_cycle = queue.filter((t) => t.status === 'completed').length;
|
|
614
|
-
|
|
615
471
|
// Log queue health snapshot every cycle
|
|
616
472
|
logger.info(`[PD:EvolutionWorker] Queue snapshot: total=${queueResult.total} pending=${queueResult.pending} in_progress=${queueResult.in_progress} completed=${queueResult.completed_this_cycle} failed=${queueResult.failed_this_cycle} purged=${purgeResult.purged}`);
|
|
617
|
-
|
|
618
473
|
await processEvolutionQueue(wctx, logger, eventLog, api);
|
|
619
|
-
}
|
|
474
|
+
}
|
|
475
|
+
catch (err) {
|
|
620
476
|
const errMsg = `processEvolutionQueue failed: ${String(err)}`;
|
|
621
477
|
errors.push(errMsg);
|
|
622
478
|
logger.error(`[PD:EvolutionWorker] ${errMsg}`);
|
|
623
479
|
}
|
|
624
|
-
|
|
625
480
|
return { queue: queueResult, errors };
|
|
626
481
|
}
|
|
627
|
-
|
|
628
|
-
export const EvolutionWorkerService: ExtendedEvolutionWorkerService = {
|
|
482
|
+
export const EvolutionWorkerService = {
|
|
629
483
|
id: 'principles-evolution-worker',
|
|
630
484
|
api: null,
|
|
631
|
-
_startedWorkspaces: new Set
|
|
632
|
-
|
|
633
|
-
start(ctx: OpenClawPluginServiceContext): void {
|
|
485
|
+
_startedWorkspaces: new Set(),
|
|
486
|
+
start(ctx) {
|
|
634
487
|
const workspaceDir = ctx?.workspaceDir;
|
|
635
488
|
const logger = ctx?.logger || console;
|
|
636
|
-
const {api} = this;
|
|
637
|
-
|
|
489
|
+
const { api } = this;
|
|
638
490
|
if (!workspaceDir) {
|
|
639
|
-
if (logger)
|
|
491
|
+
if (logger)
|
|
492
|
+
logger.warn('[PD:EvolutionWorker] workspaceDir not found in service config. Evolution cycle disabled.');
|
|
640
493
|
return;
|
|
641
494
|
}
|
|
642
|
-
|
|
643
495
|
// Guard: prevent duplicate starts for the SAME workspace
|
|
644
496
|
const started = EvolutionWorkerService._startedWorkspaces;
|
|
645
497
|
if (started.has(workspaceDir)) {
|
|
646
498
|
ctx?.logger?.info?.(`[PD:EvolutionWorker] Already started for ${workspaceDir}, skipping`);
|
|
647
499
|
return;
|
|
648
500
|
}
|
|
649
|
-
|
|
650
501
|
started.add(workspaceDir);
|
|
651
|
-
|
|
652
502
|
const wctx = WorkspaceContext.fromHookContext({ workspaceDir, ...ctx.config });
|
|
653
|
-
if (logger)
|
|
654
|
-
|
|
503
|
+
if (logger)
|
|
504
|
+
logger.info(`[PD:EvolutionWorker] Starting with workspaceDir=${wctx.workspaceDir}, stateDir=${wctx.stateDir}`);
|
|
655
505
|
initPersistence(wctx.stateDir);
|
|
656
|
-
const {eventLog} = wctx;
|
|
657
|
-
|
|
658
|
-
const {config} = wctx;
|
|
506
|
+
const { eventLog } = wctx;
|
|
507
|
+
const { config } = wctx;
|
|
659
508
|
const language = config.get('language') || 'en';
|
|
660
509
|
ensureStateTemplates({ logger }, wctx.stateDir, language);
|
|
661
510
|
ensureCorePrinciples(wctx.stateDir, logger);
|
|
662
|
-
|
|
663
511
|
const initialDelay = 5000;
|
|
664
512
|
const interval = config.get('intervals.worker_poll_ms') || (15 * 60 * 1000);
|
|
665
|
-
|
|
666
513
|
// Periodic trigger tracking
|
|
667
514
|
let heartbeatCounter = 0;
|
|
668
|
-
|
|
669
|
-
async function runCycle(): Promise<void> {
|
|
515
|
+
async function runCycle() {
|
|
670
516
|
const cycleStart = Date.now();
|
|
671
517
|
heartbeatCounter++;
|
|
672
|
-
|
|
673
518
|
// ──── DEBUG: Verify subagent availability in heartbeat context ────
|
|
674
519
|
const hbSubagent = api?.runtime?.subagent;
|
|
675
520
|
logger?.info?.(`[PD:DEBUG:SubagentCheck:Heartbeat] api_exists=${!!api}, subagent_exists=${!!hbSubagent}, subagent.run_exists=${!!hbSubagent?.run}, heartbeatCounter=${heartbeatCounter}`);
|
|
676
521
|
if (hbSubagent?.run) {
|
|
677
522
|
logger?.info?.('[PD:DEBUG:SubagentCheck:Heartbeat] run entrypoint is callable');
|
|
678
523
|
}
|
|
679
|
-
const cycleResult
|
|
680
|
-
timestamp: string;
|
|
681
|
-
cycle_start_ms: number;
|
|
682
|
-
duration_ms: number;
|
|
683
|
-
pain_flag: { exists: boolean; score: number | null; source: string | null; enqueued: boolean; skipped_reason: string | null };
|
|
684
|
-
queue: { total: number; pending: number; in_progress: number; completed_this_cycle: number; failed_this_cycle: number };
|
|
685
|
-
errors: string[];
|
|
686
|
-
} = {
|
|
524
|
+
const cycleResult = {
|
|
687
525
|
timestamp: new Date().toISOString(),
|
|
688
526
|
cycle_start_ms: cycleStart,
|
|
689
527
|
duration_ms: 0,
|
|
@@ -691,26 +529,22 @@ export const EvolutionWorkerService: ExtendedEvolutionWorkerService = {
|
|
|
691
529
|
queue: { total: 0, pending: 0, in_progress: 0, completed_this_cycle: 0, failed_this_cycle: 0 },
|
|
692
530
|
errors: [],
|
|
693
531
|
};
|
|
694
|
-
|
|
695
532
|
try {
|
|
696
533
|
// Compilation backfill: runs on every heartbeat to retry failed compilations.
|
|
697
534
|
// Fire-and-forget — errors are logged within the function.
|
|
698
535
|
processCompilationBackfill(wctx, logger).catch((err) => {
|
|
699
536
|
logger?.error?.(`[PD:EvolutionWorker] CompilationBackfill threw: ${String(err)}`);
|
|
700
537
|
});
|
|
701
|
-
|
|
702
538
|
logger?.info?.(`[PD:EvolutionWorker] HEARTBEAT cycle=${new Date().toISOString()}`);
|
|
703
|
-
|
|
704
539
|
const queueResult = await processEvolutionQueueWithResult(wctx, logger, eventLog, api ?? undefined);
|
|
705
540
|
cycleResult.queue = queueResult.queue;
|
|
706
|
-
if (queueResult.errors)
|
|
707
|
-
|
|
541
|
+
if (queueResult.errors)
|
|
542
|
+
cycleResult.errors.push(...queueResult.errors);
|
|
708
543
|
if (api) {
|
|
709
544
|
await processDetectionQueue(wctx, api, eventLog);
|
|
710
545
|
}
|
|
711
546
|
// processPromotion removed (D-06) — promotion via PAIN_CANDIDATES no longer needed
|
|
712
547
|
// Correction Observer extracted to independent service (PRI-293) — no longer runs on EvolutionWorker heartbeat
|
|
713
|
-
|
|
714
548
|
try {
|
|
715
549
|
const subagentRuntime = api?.runtime?.subagent;
|
|
716
550
|
const workflowStore = new WorkflowStore({ workspaceDir: wctx.workspaceDir });
|
|
@@ -723,13 +557,15 @@ export const EvolutionWorkerService: ExtendedEvolutionWorkerService = {
|
|
|
723
557
|
await subagentRuntime.deleteSession({ sessionKey: wf.child_session_key, deleteTranscript: true });
|
|
724
558
|
workflowStore.updateCleanupState(wf.workflow_id, 'completed');
|
|
725
559
|
logger?.info?.(`[PD:EvolutionWorker] Cleaned up session ${wf.child_session_key} for expired workflow ${wf.workflow_id}`);
|
|
726
|
-
}
|
|
560
|
+
}
|
|
561
|
+
catch (cleanupErr) {
|
|
727
562
|
const errMsg = `Session cleanup failed for workflow ${wf.workflow_id} (child_session=${wf.child_session_key}): ${String(cleanupErr)}`;
|
|
728
563
|
workflowStore.updateCleanupState(wf.workflow_id, 'failed');
|
|
729
564
|
cycleResult.errors.push(errMsg);
|
|
730
565
|
logger?.warn?.(`[PD:EvolutionWorker] ${errMsg}`);
|
|
731
566
|
}
|
|
732
|
-
}
|
|
567
|
+
}
|
|
568
|
+
else if (wf.child_session_key) {
|
|
733
569
|
// Runtime unavailable but session exists — structured failure, not silent
|
|
734
570
|
const errMsg = `Session cleanup unavailable for workflow ${wf.workflow_id} (child_session=${wf.child_session_key}): subagentRuntime not in gateway context`;
|
|
735
571
|
workflowStore.updateCleanupState(wf.workflow_id, 'failed');
|
|
@@ -740,15 +576,16 @@ export const EvolutionWorkerService: ExtendedEvolutionWorkerService = {
|
|
|
740
576
|
workflowStore.recordEvent(wf.workflow_id, 'swept', wf.state, 'expired', 'TTL expired', {});
|
|
741
577
|
logger?.warn?.(`[PD:EvolutionWorker] Marked workflow ${wf.workflow_id} as expired`);
|
|
742
578
|
}
|
|
743
|
-
}
|
|
579
|
+
}
|
|
580
|
+
finally {
|
|
744
581
|
workflowStore.dispose();
|
|
745
582
|
}
|
|
746
|
-
}
|
|
583
|
+
}
|
|
584
|
+
catch (sweepErr) {
|
|
747
585
|
const errMsg = `Failed to sweep expired workflows: ${String(sweepErr)}`;
|
|
748
586
|
cycleResult.errors.push(errMsg);
|
|
749
587
|
logger?.warn?.(`[PD:EvolutionWorker] ${errMsg}`);
|
|
750
588
|
}
|
|
751
|
-
|
|
752
589
|
// ── Workflow Watchdog: detect stale active workflows ──
|
|
753
590
|
// This catches bugs like #185 (orphaned active), #181 (empty results),
|
|
754
591
|
// #180/#183 (expired without cleanup), #182 (unhandled rejection).
|
|
@@ -758,18 +595,19 @@ export const EvolutionWorkerService: ExtendedEvolutionWorkerService = {
|
|
|
758
595
|
logger?.warn?.(`[PD:Watchdog] ${watchdogResult.anomalies} anomalies: ${watchdogResult.details.join('; ')}`);
|
|
759
596
|
cycleResult.errors.push(...watchdogResult.details);
|
|
760
597
|
}
|
|
761
|
-
}
|
|
598
|
+
}
|
|
599
|
+
catch (watchdogErr) {
|
|
762
600
|
logger?.warn?.(`[PD:Watchdog] Watchdog failed: ${String(watchdogErr)}`);
|
|
763
601
|
}
|
|
764
|
-
|
|
765
602
|
wctx.dictionary.flush();
|
|
766
603
|
flushAllSessions();
|
|
767
|
-
|
|
768
604
|
cycleResult.duration_ms = Date.now() - cycleStart;
|
|
769
605
|
writeWorkerStatus(wctx.stateDir, cycleResult);
|
|
770
|
-
}
|
|
606
|
+
}
|
|
607
|
+
catch (err) {
|
|
771
608
|
const errMsg = `Error in worker interval: ${String(err)}`;
|
|
772
|
-
if (logger)
|
|
609
|
+
if (logger)
|
|
610
|
+
logger.error(`[PD:EvolutionWorker] ${errMsg}`);
|
|
773
611
|
writeWorkerStatus(wctx.stateDir, {
|
|
774
612
|
timestamp: new Date().toISOString(),
|
|
775
613
|
cycle_start_ms: cycleStart,
|
|
@@ -779,11 +617,9 @@ export const EvolutionWorkerService: ExtendedEvolutionWorkerService = {
|
|
|
779
617
|
errors: [errMsg],
|
|
780
618
|
});
|
|
781
619
|
}
|
|
782
|
-
|
|
783
620
|
timeoutId = setTimeout(runCycle, interval);
|
|
784
621
|
timeoutId.unref();
|
|
785
622
|
}
|
|
786
|
-
|
|
787
623
|
timeoutId = setTimeout(() => {
|
|
788
624
|
void (async () => {
|
|
789
625
|
const queueResult = await processEvolutionQueueWithResult(wctx, logger, eventLog, api ?? undefined);
|
|
@@ -797,17 +633,19 @@ export const EvolutionWorkerService: ExtendedEvolutionWorkerService = {
|
|
|
797
633
|
timeoutId = setTimeout(runCycle, interval);
|
|
798
634
|
timeoutId.unref();
|
|
799
635
|
})().catch((err) => {
|
|
800
|
-
if (logger)
|
|
636
|
+
if (logger)
|
|
637
|
+
logger.error(`[PD:EvolutionWorker] Startup worker cycle failed: ${String(err)}`);
|
|
801
638
|
timeoutId = setTimeout(runCycle, interval);
|
|
802
639
|
timeoutId.unref();
|
|
803
640
|
});
|
|
804
641
|
}, initialDelay);
|
|
805
642
|
timeoutId.unref();
|
|
806
643
|
},
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
if (timeoutId)
|
|
644
|
+
stop(ctx) {
|
|
645
|
+
if (ctx?.logger)
|
|
646
|
+
ctx.logger.info('[PD:EvolutionWorker] Stopping background service...');
|
|
647
|
+
if (timeoutId)
|
|
648
|
+
clearTimeout(timeoutId);
|
|
811
649
|
flushAllSessions();
|
|
812
650
|
}
|
|
813
651
|
};
|