principles-disciple 1.126.0 → 1.128.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 -93
- 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,891 +0,0 @@
|
|
|
1
|
-
import * as crypto from 'crypto';
|
|
2
|
-
import * as fs from 'fs';
|
|
3
|
-
import * as path from 'path';
|
|
4
|
-
import { withLock } from '../utils/file-lock.js';
|
|
5
|
-
import { atomicWriteFileSync } from '../utils/io.js';
|
|
6
|
-
import { PathResolver } from './path-resolver.js';
|
|
7
|
-
import { SystemLogger } from './system-logger.js';
|
|
8
|
-
import { shouldIgnorePainProtocolText } from './dictionary.js';
|
|
9
|
-
import { TrajectoryRegistry } from './trajectory.js';
|
|
10
|
-
import type {
|
|
11
|
-
CandidateCreatedData,
|
|
12
|
-
EvolutionLoopEvent,
|
|
13
|
-
PainDetectedData,
|
|
14
|
-
Principle,
|
|
15
|
-
PrincipleDeprecatedData,
|
|
16
|
-
PrincipleDetectorSpec,
|
|
17
|
-
PrincipleEvaluatorLevel,
|
|
18
|
-
PrinciplePromotedData,
|
|
19
|
-
PrincipleRolledBackData,
|
|
20
|
-
PrincipleStatus,
|
|
21
|
-
PrincipleSuggestedRule,
|
|
22
|
-
} from './evolution-types.js';
|
|
23
|
-
import { isCompleteDetectorMetadata } from './evolution-types.js';
|
|
24
|
-
import { updateTrainingStore, addPrincipleToLedger, updatePrinciple, type LedgerPrinciple } from './principle-tree-ledger.js';
|
|
25
|
-
import { PrincipleCompiler } from './principle-compiler/index.js';
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Wrapper for updatePrinciple calls in the compilation retry path.
|
|
29
|
-
* If updatePrinciple throws, logs the error instead of propagating —
|
|
30
|
-
* compilation retry state is best-effort and should not crash principle creation.
|
|
31
|
-
*/
|
|
32
|
-
function updateRetryCount(stateDir: string, workspaceDir: string, principleId: string, count: number): void {
|
|
33
|
-
try {
|
|
34
|
-
updatePrinciple(stateDir, principleId, { compilationRetryCount: count });
|
|
35
|
-
} catch (err) {
|
|
36
|
-
SystemLogger.log(workspaceDir, 'RETRY_COUNT_UPDATE_FAILED',
|
|
37
|
-
`Failed to update compilationRetryCount for ${principleId}: ${String(err)}`);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface EvolutionReducer {
|
|
42
|
-
|
|
43
|
-
emit(_event: EvolutionLoopEvent): void;
|
|
44
|
-
|
|
45
|
-
emitSync(_event: EvolutionLoopEvent): void;
|
|
46
|
-
getEventLog(): EvolutionLoopEvent[];
|
|
47
|
-
getCandidatePrinciples(): Principle[];
|
|
48
|
-
getProbationPrinciples(): Principle[];
|
|
49
|
-
getActivePrinciples(): Principle[];
|
|
50
|
-
|
|
51
|
-
getPrincipleById(_id: string): Principle | null;
|
|
52
|
-
|
|
53
|
-
promote(_principleId: string, _reason?: string): void;
|
|
54
|
-
|
|
55
|
-
deprecate(_principleId: string, _reason: string): void;
|
|
56
|
-
|
|
57
|
-
rollbackPrinciple(_principleId: string, _reason: string): void;
|
|
58
|
-
|
|
59
|
-
recordProbationFeedback(_principleId: string, _success: boolean): void;
|
|
60
|
-
/**
|
|
61
|
-
* Creates a new principle with generalized trigger/action from diagnostician.
|
|
62
|
-
* Called after diagnostician analysis to create principle directly.
|
|
63
|
-
*/
|
|
64
|
-
createPrincipleFromDiagnosis(params: {
|
|
65
|
-
painId: string;
|
|
66
|
-
painType: 'tool_failure' | 'subagent_error' | 'user_frustration';
|
|
67
|
-
triggerPattern: string;
|
|
68
|
-
action: string;
|
|
69
|
-
source: string;
|
|
70
|
-
evaluability?: PrincipleEvaluatorLevel;
|
|
71
|
-
detectorMetadata?: PrincipleDetectorSpec;
|
|
72
|
-
/** Highly abstracted principle text — if absent, falls back to action-based title */
|
|
73
|
-
abstractedPrinciple?: string;
|
|
74
|
-
/** Associated core axiom (e.g., "T-01") */
|
|
75
|
-
coreAxiomId?: string;
|
|
76
|
-
// ── Principle-Tree metadata (Phase 1, optional) ──
|
|
77
|
-
priority?: 'P0' | 'P1' | 'P2';
|
|
78
|
-
scope?: 'general' | 'domain';
|
|
79
|
-
domain?: string;
|
|
80
|
-
suggestedRules?: PrincipleSuggestedRule[];
|
|
81
|
-
}): string | null;
|
|
82
|
-
getStats(): {
|
|
83
|
-
candidateCount: number;
|
|
84
|
-
probationCount: number;
|
|
85
|
-
activeCount: number;
|
|
86
|
-
deprecatedCount: number;
|
|
87
|
-
lastPromotedAt: string | null;
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const PROBATION_SUCCESS_THRESHOLD = 3;
|
|
93
|
-
const CIRCUIT_BREAKER_THRESHOLD = 3;
|
|
94
|
-
const PROBATION_MAX_AGE_DAYS = 30;
|
|
95
|
-
|
|
96
|
-
export class EvolutionReducerImpl implements EvolutionReducer {
|
|
97
|
-
private readonly streamPath: string;
|
|
98
|
-
private readonly lockTargetPath: string;
|
|
99
|
-
private readonly blacklistPath: string;
|
|
100
|
-
private readonly principlesPath: string;
|
|
101
|
-
private readonly workspaceDir: string;
|
|
102
|
-
private readonly stateDir: string | undefined;
|
|
103
|
-
private readonly memoryEvents: EvolutionLoopEvent[] = [];
|
|
104
|
-
private readonly principles = new Map<string, Principle>();
|
|
105
|
-
private readonly failureStreak = new Map<string, number>();
|
|
106
|
-
private lastPromotedAt: string | null = null;
|
|
107
|
-
private isReplaying = false;
|
|
108
|
-
/** Registered pain_detected callbacks (e.g., PainSignalBridge). */
|
|
109
|
-
private readonly _painCallbacks: Array<(event: EvolutionLoopEvent) => void> = [];
|
|
110
|
-
|
|
111
|
-
constructor(opts: { workspaceDir: string; stateDir?: string }) {
|
|
112
|
-
this.workspaceDir = opts.workspaceDir;
|
|
113
|
-
this.stateDir = opts.stateDir;
|
|
114
|
-
const resolver = new PathResolver({ workspaceDir: opts.workspaceDir });
|
|
115
|
-
this.streamPath = resolver.resolve('EVOLUTION_STREAM');
|
|
116
|
-
this.lockTargetPath = resolver.resolve('EVOLUTION_LOCK');
|
|
117
|
-
this.blacklistPath = resolver.resolve('PRINCIPLE_BLACKLIST');
|
|
118
|
-
this.principlesPath = resolver.resolve('PRINCIPLES');
|
|
119
|
-
this.ensureDirs();
|
|
120
|
-
this.loadFromStream();
|
|
121
|
-
this.sweepExpiredProbation();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
emit(event: EvolutionLoopEvent): void {
|
|
125
|
-
this.emitSync(event);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
emitSync(event: EvolutionLoopEvent): void {
|
|
129
|
-
withLock(this.lockTargetPath, () => {
|
|
130
|
-
fs.appendFileSync(this.streamPath, `${JSON.stringify(event)}\n`, 'utf8');
|
|
131
|
-
}, { lockStaleMs: 15000 });
|
|
132
|
-
this.applyEvent(event);
|
|
133
|
-
if (event.type !== 'pain_detected') {
|
|
134
|
-
try {
|
|
135
|
-
TrajectoryRegistry.use(this.workspaceDir, (trajectory) => {
|
|
136
|
-
trajectory.recordPrincipleEvent({
|
|
137
|
-
principleId: 'principleId' in event.data && typeof event.data.principleId === 'string' ? event.data.principleId : null,
|
|
138
|
-
eventType: event.type,
|
|
139
|
-
payload: event.data,
|
|
140
|
-
createdAt: event.ts,
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
} catch {
|
|
144
|
-
// Keep evolution loop resilient if trajectory storage is unavailable.
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
// Performance: sweepExpiredProbation() moved to getProbationPrinciples() for lazy cleanup
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Register a callback for 'pain_detected' events.
|
|
152
|
-
* The callback is invoked synchronously within emitSync() after applyEvent completes.
|
|
153
|
-
* HG-4: Callbacks are fire-and-forget from the emitSync perspective.
|
|
154
|
-
*/
|
|
155
|
-
on(callback: (event: EvolutionLoopEvent) => void): void {
|
|
156
|
-
this._painCallbacks.push(callback);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
getEventLog(): EvolutionLoopEvent[] {
|
|
160
|
-
return [...this.memoryEvents];
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
getCandidatePrinciples(): Principle[] {
|
|
164
|
-
return this.getByStatus('candidate');
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
getProbationPrinciples(): Principle[] {
|
|
168
|
-
// Lazy cleanup: sweep expired probation principles on access
|
|
169
|
-
this.sweepExpiredProbation();
|
|
170
|
-
return this.getByStatus('probation');
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
getActivePrinciples(): Principle[] {
|
|
174
|
-
return this.getByStatus('active');
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
getPrincipleById(id: string): Principle | null {
|
|
178
|
-
return this.principles.get(id) ?? null;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
promote(principleId: string, reason = 'manual'): void {
|
|
182
|
-
const p = this.principles.get(principleId);
|
|
183
|
-
if (!p || p.status === 'active' || p.status === 'deprecated') return;
|
|
184
|
-
|
|
185
|
-
const toStatus = (p.status === 'candidate' ? 'probation' : p.status === 'probation' ? 'active' : p.status) as PrincipleStatus;
|
|
186
|
-
const event: EvolutionLoopEvent = {
|
|
187
|
-
ts: new Date().toISOString(),
|
|
188
|
-
type: 'principle_promoted',
|
|
189
|
-
data: {
|
|
190
|
-
principleId,
|
|
191
|
-
from: p.status,
|
|
192
|
-
to: toStatus,
|
|
193
|
-
reason,
|
|
194
|
-
successCount: p.validation.successCount,
|
|
195
|
-
},
|
|
196
|
-
};
|
|
197
|
-
this.emitSync(event);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
deprecate(principleId: string, reason: string): void {
|
|
201
|
-
const p = this.principles.get(principleId);
|
|
202
|
-
if (!p || p.status === 'deprecated') return;
|
|
203
|
-
|
|
204
|
-
this.emitSync({
|
|
205
|
-
ts: new Date().toISOString(),
|
|
206
|
-
type: 'principle_deprecated',
|
|
207
|
-
data: {
|
|
208
|
-
principleId,
|
|
209
|
-
reason,
|
|
210
|
-
triggeredBy: 'manual',
|
|
211
|
-
},
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
rollbackPrinciple(principleId: string, reason: string): void {
|
|
216
|
-
const p = this.principles.get(principleId);
|
|
217
|
-
if (!p) return;
|
|
218
|
-
|
|
219
|
-
this.emitSync({
|
|
220
|
-
ts: new Date().toISOString(),
|
|
221
|
-
type: 'principle_rolled_back',
|
|
222
|
-
data: {
|
|
223
|
-
principleId,
|
|
224
|
-
reason,
|
|
225
|
-
triggeredBy: 'user_command',
|
|
226
|
-
blacklistPattern: p.trigger,
|
|
227
|
-
relatedPainId: p.source.painId,
|
|
228
|
-
},
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
recordProbationFeedback(principleId: string, success: boolean): void {
|
|
233
|
-
const p = this.principles.get(principleId);
|
|
234
|
-
if (!p || p.status !== 'probation') return;
|
|
235
|
-
|
|
236
|
-
if (success) {
|
|
237
|
-
p.validation.successCount += 1;
|
|
238
|
-
p.feedbackScore += 10;
|
|
239
|
-
if (p.validation.successCount >= PROBATION_SUCCESS_THRESHOLD) {
|
|
240
|
-
this.promote(principleId, 'auto_threshold');
|
|
241
|
-
}
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
p.validation.conflictCount += 1;
|
|
246
|
-
if (p.validation.conflictCount >= 1) {
|
|
247
|
-
this.deprecate(principleId, 'conflict_detected');
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Creates a new principle with generalized trigger/action from diagnostician.
|
|
253
|
-
* Called after diagnostician analysis to create principle directly (no intermediate overfitted principle).
|
|
254
|
-
* @returns the new principle ID, or null if creation failed
|
|
255
|
-
*/
|
|
256
|
-
createPrincipleFromDiagnosis(params: {
|
|
257
|
-
painId: string;
|
|
258
|
-
painType: 'tool_failure' | 'subagent_error' | 'user_frustration';
|
|
259
|
-
triggerPattern: string;
|
|
260
|
-
action: string;
|
|
261
|
-
source: string;
|
|
262
|
-
evaluability?: PrincipleEvaluatorLevel;
|
|
263
|
-
detectorMetadata?: PrincipleDetectorSpec;
|
|
264
|
-
abstractedPrinciple?: string;
|
|
265
|
-
coreAxiomId?: string;
|
|
266
|
-
priority?: 'P0' | 'P1' | 'P2';
|
|
267
|
-
scope?: 'general' | 'domain';
|
|
268
|
-
domain?: string;
|
|
269
|
-
suggestedRules?: PrincipleSuggestedRule[];
|
|
270
|
-
}): string | null {
|
|
271
|
-
// Check blacklist first
|
|
272
|
-
if (this.isBlacklisted(params.painId, params.triggerPattern)) {
|
|
273
|
-
SystemLogger.log(
|
|
274
|
-
this.workspaceDir,
|
|
275
|
-
'PRINCIPLE_BLACKLISTED',
|
|
276
|
-
`Principle creation blocked by blacklist for trigger: "${params.triggerPattern.slice(0, 50)}..."`
|
|
277
|
-
);
|
|
278
|
-
return null;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// Evaluability defaults to 'weak_heuristic' — allows basic pattern-matching
|
|
282
|
-
// evaluation without requiring full detectorMetadata.
|
|
283
|
-
// #212: Only 'deterministic' requires complete detectorMetadata.
|
|
284
|
-
// 'weak_heuristic' can work with just the trigger pattern.
|
|
285
|
-
let evaluability: PrincipleEvaluatorLevel = params.evaluability ?? 'weak_heuristic';
|
|
286
|
-
if (evaluability === 'deterministic' && !isCompleteDetectorMetadata(params.detectorMetadata)) {
|
|
287
|
-
SystemLogger.log(
|
|
288
|
-
this.workspaceDir,
|
|
289
|
-
'EVALUABILITY_DOWNGRADED',
|
|
290
|
-
`Principle for painId "${params.painId}" requested evaluability="deterministic" without detectorMetadata — downgrading to "weak_heuristic". Provide valid detectorMetadata for deterministic evaluation.`
|
|
291
|
-
);
|
|
292
|
-
evaluability = 'weak_heuristic';
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// Check if a principle already exists for this painId
|
|
296
|
-
const existingPrinciple = [...this.principles.values()].find(
|
|
297
|
-
p => p.source.painId === params.painId
|
|
298
|
-
);
|
|
299
|
-
|
|
300
|
-
if (existingPrinciple) {
|
|
301
|
-
// Update existing principle instead of creating new one.
|
|
302
|
-
// Apply the same evaluability normalization as new creation:
|
|
303
|
-
// deterministic/weak_heuristic without detectorMetadata → downgraded to manual_only.
|
|
304
|
-
existingPrinciple.trigger = params.triggerPattern;
|
|
305
|
-
existingPrinciple.action = params.action;
|
|
306
|
-
existingPrinciple.text = `When ${params.triggerPattern}, then ${params.action}.`;
|
|
307
|
-
existingPrinciple.version += 1;
|
|
308
|
-
if (params.evaluability !== undefined) {
|
|
309
|
-
// Apply normalization (params.evaluability may be invalid without complete metadata)
|
|
310
|
-
// #212: Only 'deterministic' requires detectorMetadata; 'weak_heuristic' does not.
|
|
311
|
-
const normalizedEvaluability = (() => {
|
|
312
|
-
if (params.evaluability === 'deterministic' && !isCompleteDetectorMetadata(params.detectorMetadata)) {
|
|
313
|
-
SystemLogger.log(
|
|
314
|
-
this.workspaceDir,
|
|
315
|
-
'EVALUABILITY_DOWNGRADED',
|
|
316
|
-
`Principle update for painId "${params.painId}" requested evaluability="deterministic" without detectorMetadata — downgrading to "weak_heuristic".`
|
|
317
|
-
);
|
|
318
|
-
return 'weak_heuristic';
|
|
319
|
-
}
|
|
320
|
-
return params.evaluability;
|
|
321
|
-
})();
|
|
322
|
-
existingPrinciple.evaluability = normalizedEvaluability;
|
|
323
|
-
}
|
|
324
|
-
// Preserve detectorMetadata unless explicitly provided in this call.
|
|
325
|
-
// Accept only if complete (defense in depth — subagent should already filter).
|
|
326
|
-
if (isCompleteDetectorMetadata(params.detectorMetadata)) {
|
|
327
|
-
existingPrinciple.detectorMetadata = structuredClone(params.detectorMetadata);
|
|
328
|
-
} else if (params.detectorMetadata !== undefined) {
|
|
329
|
-
// Malformed metadata provided — clear any existing metadata
|
|
330
|
-
existingPrinciple.detectorMetadata = undefined;
|
|
331
|
-
}
|
|
332
|
-
// Refresh abstractedPrinciple if provided
|
|
333
|
-
if (params.abstractedPrinciple) {
|
|
334
|
-
existingPrinciple.abstractedPrinciple = params.abstractedPrinciple;
|
|
335
|
-
}
|
|
336
|
-
// Sync to file to ensure PRINCIPLES.md stays up to date
|
|
337
|
-
const synced = this.syncPrincipleToFile(existingPrinciple);
|
|
338
|
-
if (!synced) {
|
|
339
|
-
SystemLogger.log(this.workspaceDir, 'PRINCIPLE_SYNC_WARN', `Principle ${existingPrinciple.id} updated in memory but failed to sync to PRINCIPLES.md — manual file check required`);
|
|
340
|
-
}
|
|
341
|
-
SystemLogger.log(
|
|
342
|
-
this.workspaceDir,
|
|
343
|
-
'PRINCIPLE_UPDATED',
|
|
344
|
-
`Principle ${existingPrinciple.id} updated from diagnostician: "${params.triggerPattern.slice(0, 50)}..." [evaluability: ${existingPrinciple.evaluability}]`
|
|
345
|
-
);
|
|
346
|
-
return existingPrinciple.id;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// Create new principle with generalized content
|
|
350
|
-
const principleId = this.nextPrincipleId();
|
|
351
|
-
const now = new Date().toISOString();
|
|
352
|
-
const principle: Principle = {
|
|
353
|
-
id: principleId,
|
|
354
|
-
version: 1,
|
|
355
|
-
text: `When ${params.triggerPattern}, then ${params.action}.`,
|
|
356
|
-
source: {
|
|
357
|
-
painId: params.painId,
|
|
358
|
-
painType: params.painType,
|
|
359
|
-
timestamp: now,
|
|
360
|
-
},
|
|
361
|
-
trigger: params.triggerPattern,
|
|
362
|
-
action: params.action,
|
|
363
|
-
contextTags: [params.source],
|
|
364
|
-
validation: { successCount: 0, conflictCount: 0 },
|
|
365
|
-
status: 'candidate',
|
|
366
|
-
feedbackScore: 0,
|
|
367
|
-
usageCount: 0,
|
|
368
|
-
createdAt: now,
|
|
369
|
-
evaluability,
|
|
370
|
-
detectorMetadata: isCompleteDetectorMetadata(params.detectorMetadata)
|
|
371
|
-
? structuredClone(params.detectorMetadata)
|
|
372
|
-
: undefined,
|
|
373
|
-
abstractedPrinciple: params.abstractedPrinciple,
|
|
374
|
-
coreAxiomId: params.coreAxiomId,
|
|
375
|
-
|
|
376
|
-
// ── Principle-Tree metadata (Phase 1, optional) ──
|
|
377
|
-
priority: params.priority ?? 'P1',
|
|
378
|
-
scope: params.scope ?? 'general',
|
|
379
|
-
domain: params.domain,
|
|
380
|
-
suggestedRules: params.suggestedRules?.length ? params.suggestedRules : undefined,
|
|
381
|
-
};
|
|
382
|
-
|
|
383
|
-
this.principles.set(principleId, principle);
|
|
384
|
-
|
|
385
|
-
this.emitSync({
|
|
386
|
-
ts: now,
|
|
387
|
-
type: 'candidate_created',
|
|
388
|
-
data: {
|
|
389
|
-
painId: principle.source.painId,
|
|
390
|
-
painType: params.painType,
|
|
391
|
-
principleId,
|
|
392
|
-
trigger: params.triggerPattern,
|
|
393
|
-
action: params.action,
|
|
394
|
-
status: 'candidate',
|
|
395
|
-
evaluability,
|
|
396
|
-
detectorMetadata: isCompleteDetectorMetadata(params.detectorMetadata)
|
|
397
|
-
? structuredClone(params.detectorMetadata)
|
|
398
|
-
: undefined,
|
|
399
|
-
abstractedPrinciple: params.abstractedPrinciple,
|
|
400
|
-
},
|
|
401
|
-
});
|
|
402
|
-
|
|
403
|
-
this.promote(principleId, 'diagnostician_generalized');
|
|
404
|
-
const synced = this.syncPrincipleToFile(principle);
|
|
405
|
-
if (!synced) {
|
|
406
|
-
SystemLogger.log(this.workspaceDir, 'PRINCIPLE_SYNC_WARN', `Principle ${principleId} created in memory but failed to sync to PRINCIPLES.md — manual file check required`);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
// Add to ledger tree so the compiler can find this principle.
|
|
410
|
-
// Without this, newly diagnosed principles are invisible to the compiler
|
|
411
|
-
// (which reads tree.principles, not trainingStore or PRINCIPLES.md).
|
|
412
|
-
if (this.stateDir) {
|
|
413
|
-
try {
|
|
414
|
-
// Build a LedgerPrinciple (tree schema) from the evolution-types Principle.
|
|
415
|
-
// Tree schema Principle does NOT have: source, guardrails, contextTags, validation,
|
|
416
|
-
// feedbackScore, usageCount, activatedAt, abstractedPrinciple, valueMetrics.
|
|
417
|
-
// Pain source info is stored via derivedFromPainIds (which the compiler uses).
|
|
418
|
-
const ledgerPrinciple: LedgerPrinciple = {
|
|
419
|
-
id: principle.id,
|
|
420
|
-
version: principle.version,
|
|
421
|
-
text: principle.text,
|
|
422
|
-
triggerPattern: principle.trigger,
|
|
423
|
-
action: principle.action,
|
|
424
|
-
status: principle.status,
|
|
425
|
-
evaluability: principle.evaluability,
|
|
426
|
-
coreAxiomId: principle.coreAxiomId,
|
|
427
|
-
priority: principle.priority ?? 'P1',
|
|
428
|
-
scope: principle.scope ?? 'general',
|
|
429
|
-
domain: principle.domain,
|
|
430
|
-
suggestedRules: principle.suggestedRules?.map((r) => r.name),
|
|
431
|
-
detectorMetadata: principle.detectorMetadata,
|
|
432
|
-
deprecatedAt: principle.deprecatedAt,
|
|
433
|
-
deprecatedReason: undefined,
|
|
434
|
-
createdAt: principle.createdAt,
|
|
435
|
-
updatedAt: now,
|
|
436
|
-
// Ledger-only fields (derived from evolution-types Principle where applicable):
|
|
437
|
-
valueScore: 0,
|
|
438
|
-
adherenceRate: 0,
|
|
439
|
-
painPreventedCount: 0,
|
|
440
|
-
lastPainPreventedAt: undefined,
|
|
441
|
-
derivedFromPainIds: [params.painId],
|
|
442
|
-
ruleIds: [],
|
|
443
|
-
conflictsWithPrincipleIds: [],
|
|
444
|
-
supersedesPrincipleId: undefined,
|
|
445
|
-
};
|
|
446
|
-
addPrincipleToLedger(this.stateDir, ledgerPrinciple);
|
|
447
|
-
SystemLogger.log(this.workspaceDir, 'LEDGER_PRINCIPLE_ADDED', `Principle ${principleId} added to ledger tree`);
|
|
448
|
-
|
|
449
|
-
// Sync compile: attempt to compile immediately unless evaluability is manual_only.
|
|
450
|
-
// Failures are not fatal — heartbeat backfill will retry automatically.
|
|
451
|
-
if (evaluability !== 'manual_only' && this.stateDir) {
|
|
452
|
-
const trajectory = TrajectoryRegistry.get(this.workspaceDir);
|
|
453
|
-
const compiler = new PrincipleCompiler(this.stateDir, trajectory);
|
|
454
|
-
try {
|
|
455
|
-
const result = compiler.compileOne(principleId);
|
|
456
|
-
if (result.success) {
|
|
457
|
-
// Reset retry count on success
|
|
458
|
-
updatePrinciple(this.stateDir, principleId, { compilationRetryCount: undefined });
|
|
459
|
-
SystemLogger.log(this.workspaceDir, 'COMPILE_SUCCESS', `Principle ${principleId} compiled successfully`);
|
|
460
|
-
} else {
|
|
461
|
-
// Compile returned failure — queue for backfill retry (count=0 means "queued", Phase 2 will pick it up).
|
|
462
|
-
// This gives exactly 5 total attempts before exhaustion (backfill: 0-4, sync: 0-4).
|
|
463
|
-
updateRetryCount(this.stateDir, this.workspaceDir, principleId, 0);
|
|
464
|
-
SystemLogger.log(
|
|
465
|
-
this.workspaceDir, 'COMPILE_FAILED',
|
|
466
|
-
`Principle ${principleId} compile failed: ${result.reason ?? 'unknown'} (attempt 1/5)`
|
|
467
|
-
);
|
|
468
|
-
}
|
|
469
|
-
} catch (compileErr) {
|
|
470
|
-
// Unexpected error during compilation — queue for backfill retry
|
|
471
|
-
updateRetryCount(this.stateDir, this.workspaceDir, principleId, 0);
|
|
472
|
-
SystemLogger.log(
|
|
473
|
-
this.workspaceDir, 'COMPILE_FAILED',
|
|
474
|
-
`Principle ${principleId} compile threw: ${String(compileErr)} (attempt 1/5)`
|
|
475
|
-
);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
} catch (err) {
|
|
479
|
-
SystemLogger.log(this.workspaceDir, 'LEDGER_PRINCIPLE_ADD_FAILED', `Failed to add ${principleId} to ledger tree: ${String(err)}`);
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// #204: Write to training store so listEvaluablePrinciples() can find this principle
|
|
484
|
-
if (this.stateDir) {
|
|
485
|
-
try {
|
|
486
|
-
// Determine initial internalization status based on evaluability:
|
|
487
|
-
// - manual_only: prompt_only (can only be evaluated manually)
|
|
488
|
-
// - deterministic/weak_heuristic: needs_training (auto-evaluable, ready for training)
|
|
489
|
-
const initialStatus = evaluability === 'manual_only' ? 'prompt_only' : 'needs_training';
|
|
490
|
-
|
|
491
|
-
updateTrainingStore(this.stateDir, (trainingStore) => {
|
|
492
|
-
trainingStore[principleId] = {
|
|
493
|
-
principleId,
|
|
494
|
-
evaluability,
|
|
495
|
-
internalizationStatus: initialStatus,
|
|
496
|
-
applicableOpportunityCount: 0,
|
|
497
|
-
observedViolationCount: 0,
|
|
498
|
-
complianceRate: 0,
|
|
499
|
-
violationTrend: 0,
|
|
500
|
-
generatedSampleCount: 0,
|
|
501
|
-
approvedSampleCount: 0,
|
|
502
|
-
includedTrainRunIds: [],
|
|
503
|
-
deployedCheckpointIds: [],
|
|
504
|
-
};
|
|
505
|
-
});
|
|
506
|
-
SystemLogger.log(this.workspaceDir, 'TRAINING_STORE_UPDATED', `Principle ${principleId} added to training store with evaluability=${evaluability}, internalizationStatus=${initialStatus}`);
|
|
507
|
-
} catch (err) {
|
|
508
|
-
SystemLogger.log(this.workspaceDir, 'TRAINING_STORE_UPDATE_FAILED', `Failed to update training store for ${principleId}: ${String(err)}`);
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
SystemLogger.log(
|
|
513
|
-
this.workspaceDir,
|
|
514
|
-
'PRINCIPLE_CREATED',
|
|
515
|
-
`Principle ${principleId} created from diagnostician: "${params.triggerPattern.slice(0, 50)}..." [evaluability: ${evaluability}]`
|
|
516
|
-
);
|
|
517
|
-
|
|
518
|
-
return principleId;
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
private syncPrincipleToFile(principle: Principle): boolean {
|
|
522
|
-
try {
|
|
523
|
-
withLock(this.principlesPath + '.lock', () => {
|
|
524
|
-
let content = '';
|
|
525
|
-
if (fs.existsSync(this.principlesPath)) {
|
|
526
|
-
content = fs.readFileSync(this.principlesPath, 'utf8');
|
|
527
|
-
} else {
|
|
528
|
-
// Auto-create from template if missing
|
|
529
|
-
const extensionRoot = PathResolver.getExtensionRoot();
|
|
530
|
-
if (extensionRoot) {
|
|
531
|
-
const templatePath = path.join(extensionRoot, 'templates', 'workspace', '.principles', 'PRINCIPLES.md');
|
|
532
|
-
if (fs.existsSync(templatePath)) {
|
|
533
|
-
content = fs.readFileSync(templatePath, 'utf8');
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
if (!content) {
|
|
537
|
-
// Create a minimal PRINCIPLES.md with just the header
|
|
538
|
-
content = '# Principles\n\n<!-- 原则从这里开始记录 -->\n';
|
|
539
|
-
}
|
|
540
|
-
const parentDir = path.dirname(this.principlesPath);
|
|
541
|
-
if (!fs.existsSync(parentDir)) {
|
|
542
|
-
fs.mkdirSync(parentDir, { recursive: true });
|
|
543
|
-
}
|
|
544
|
-
atomicWriteFileSync(this.principlesPath, content);
|
|
545
|
-
SystemLogger.log(this.workspaceDir, 'PRINCIPLES_CREATED', `Created PRINCIPLES.md`);
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
const header = `### ${principle.id}:`;
|
|
549
|
-
const existingIdx = content.indexOf(header);
|
|
550
|
-
const formatted = EvolutionReducerImpl.formatPrincipleForFile(principle, content);
|
|
551
|
-
|
|
552
|
-
if (existingIdx >= 0) {
|
|
553
|
-
const nextPrincipleRe = /\n### [A-Za-z0-9_-]+:/g;
|
|
554
|
-
nextPrincipleRe.lastIndex = existingIdx + header.length;
|
|
555
|
-
const nextMatch = nextPrincipleRe.exec(content);
|
|
556
|
-
const endIdx = nextMatch ? nextMatch.index : content.length;
|
|
557
|
-
content = content.slice(0, existingIdx) + formatted + content.slice(endIdx);
|
|
558
|
-
} else {
|
|
559
|
-
const separator = content.trim().endsWith('<!-- 原则从这里开始记录 -->') ? '\n' : '\n\n';
|
|
560
|
-
content = content + separator + formatted;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
atomicWriteFileSync(this.principlesPath, content);
|
|
564
|
-
SystemLogger.log(this.workspaceDir, 'PRINCIPLE_SYNCED', `Principle ${principle.id} synced to PRINCIPLES.md`);
|
|
565
|
-
}, { lockStaleMs: 10000 });
|
|
566
|
-
return true;
|
|
567
|
-
} catch (e) {
|
|
568
|
-
SystemLogger.log(this.workspaceDir, 'PRINCIPLE_SYNC_ERROR', `Failed to sync ${principle.id} to PRINCIPLES.md: ${String(e)}`);
|
|
569
|
-
return false;
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
private static detectPrincipleLanguage(content: string): 'zh' | 'en' {
|
|
574
|
-
if (!content) return 'zh';
|
|
575
|
-
const zhMarkers = ['原则', '触发', '必须', '禁止', '验证', '例外', '来源'];
|
|
576
|
-
const enMarkers = ['Trigger', 'Constraint', 'Must', 'Forbidden', 'Verification', 'Exceptions', 'Source'];
|
|
577
|
-
let zhCount = 0;
|
|
578
|
-
let enCount = 0;
|
|
579
|
-
for (const m of zhMarkers) { if (content.includes(m)) zhCount++; }
|
|
580
|
-
for (const m of enMarkers) { if (content.includes(m)) enCount++; }
|
|
581
|
-
return zhCount >= enCount ? 'zh' : 'en';
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
private static formatPrincipleForFile(principle: Principle, existingContent: string): string {
|
|
585
|
-
const lang = EvolutionReducerImpl.detectPrincipleLanguage(existingContent);
|
|
586
|
-
const title = principle.abstractedPrinciple
|
|
587
|
-
? (principle.abstractedPrinciple.length > 60 ? principle.abstractedPrinciple.slice(0, 57) + '...' : principle.abstractedPrinciple)
|
|
588
|
-
: (principle.text.length > 60 ? principle.text.slice(0, 57) + '...' : principle.text);
|
|
589
|
-
const source = principle.source.painId ? `pain_id: ${principle.source.painId} / ${principle.source.timestamp?.slice(0, 10) ?? 'unknown'}` : 'unknown';
|
|
590
|
-
|
|
591
|
-
if (lang === 'zh') {
|
|
592
|
-
return [
|
|
593
|
-
`### ${principle.id}: ${title}`,
|
|
594
|
-
`- **Trigger**: ${principle.trigger}`,
|
|
595
|
-
`- **Constraint (Must)**: ${principle.action}`,
|
|
596
|
-
`- **Constraint (Forbidden)**: 禁止违反此原则的行为`,
|
|
597
|
-
`- **Verification**: 操作前检查是否遵循此原则`,
|
|
598
|
-
`- **Exceptions**: 无`,
|
|
599
|
-
`- **Source**: ${source}`,
|
|
600
|
-
'',
|
|
601
|
-
].join('\n');
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
return [
|
|
605
|
-
`### ${principle.id}: ${title}`,
|
|
606
|
-
`- **Trigger**: ${principle.trigger}`,
|
|
607
|
-
`- **Constraint (Must)**: ${principle.action}`,
|
|
608
|
-
`- **Constraint (Forbidden)**: Do not violate this principle`,
|
|
609
|
-
`- **Verification**: Check compliance before acting`,
|
|
610
|
-
`- **Exceptions**: None`,
|
|
611
|
-
`- **Source**: ${source}`,
|
|
612
|
-
'',
|
|
613
|
-
].join('\n');
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
getStats(): {
|
|
617
|
-
candidateCount: number;
|
|
618
|
-
probationCount: number;
|
|
619
|
-
activeCount: number;
|
|
620
|
-
deprecatedCount: number;
|
|
621
|
-
lastPromotedAt: string | null;
|
|
622
|
-
} {
|
|
623
|
-
return {
|
|
624
|
-
candidateCount: this.getCandidatePrinciples().length,
|
|
625
|
-
probationCount: this.getProbationPrinciples().length,
|
|
626
|
-
activeCount: this.getActivePrinciples().length,
|
|
627
|
-
deprecatedCount: this.getByStatus('deprecated').length,
|
|
628
|
-
lastPromotedAt: this.lastPromotedAt,
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
private ensureDirs(): void {
|
|
633
|
-
fs.mkdirSync(path.dirname(this.streamPath), { recursive: true });
|
|
634
|
-
fs.mkdirSync(path.dirname(this.lockTargetPath), { recursive: true });
|
|
635
|
-
fs.mkdirSync(path.dirname(this.blacklistPath), { recursive: true });
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
private loadFromStream(): void {
|
|
639
|
-
if (!fs.existsSync(this.streamPath)) return;
|
|
640
|
-
const raw = fs.readFileSync(this.streamPath, 'utf8').trim();
|
|
641
|
-
if (!raw) return;
|
|
642
|
-
|
|
643
|
-
this.isReplaying = true;
|
|
644
|
-
for (const line of raw.split('\n')) {
|
|
645
|
-
try {
|
|
646
|
-
const event = JSON.parse(line) as EvolutionLoopEvent;
|
|
647
|
-
this.applyEvent(event);
|
|
648
|
-
} catch (e) {
|
|
649
|
-
SystemLogger.log(this.workspaceDir, 'EVOLUTION_WARN', `skip malformed event line: ${String(e)}`);
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
this.isReplaying = false;
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
private applyEvent(event: EvolutionLoopEvent): void {
|
|
656
|
-
this.memoryEvents.push(event);
|
|
657
|
-
|
|
658
|
-
switch (event.type) {
|
|
659
|
-
case 'pain_detected':
|
|
660
|
-
this.updateFailureStreakFromPain(event.data);
|
|
661
|
-
if (!this.isReplaying) {
|
|
662
|
-
this.onPainDetected(event.data, event.ts);
|
|
663
|
-
}
|
|
664
|
-
// PainSignalBridge subscriptions: invoke registered callbacks (fire-and-forget)
|
|
665
|
-
for (const cb of this._painCallbacks) {
|
|
666
|
-
try {
|
|
667
|
-
cb(event);
|
|
668
|
-
} catch {
|
|
669
|
-
// Keep the evolution loop resilient — callback errors must not propagate
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
return;
|
|
673
|
-
case 'candidate_created':
|
|
674
|
-
this.onCandidateCreated(event.data, event.ts);
|
|
675
|
-
return;
|
|
676
|
-
case 'principle_promoted':
|
|
677
|
-
this.onPrinciplePromoted(event.data, event.ts);
|
|
678
|
-
return;
|
|
679
|
-
case 'principle_deprecated':
|
|
680
|
-
this.onPrincipleDeprecated(event.data, event.ts);
|
|
681
|
-
return;
|
|
682
|
-
case 'principle_rolled_back':
|
|
683
|
-
this.onPrincipleRolledBack(event.data, event.ts);
|
|
684
|
-
return;
|
|
685
|
-
case 'circuit_breaker_opened':
|
|
686
|
-
case 'legacy_import':
|
|
687
|
-
return;
|
|
688
|
-
default:
|
|
689
|
-
return;
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
private onCandidateCreated(data: CandidateCreatedData, ts: string): void {
|
|
694
|
-
const existing = this.principles.get(data.principleId);
|
|
695
|
-
if (existing) {
|
|
696
|
-
existing.status = 'candidate';
|
|
697
|
-
// Apply evaluability from event if present (supports event replay)
|
|
698
|
-
if (data.evaluability) {
|
|
699
|
-
existing.evaluability = data.evaluability;
|
|
700
|
-
}
|
|
701
|
-
if (data.detectorMetadata) {
|
|
702
|
-
existing.detectorMetadata = structuredClone(data.detectorMetadata);
|
|
703
|
-
}
|
|
704
|
-
// Restore abstractedPrinciple from event if present
|
|
705
|
-
if (data.abstractedPrinciple) {
|
|
706
|
-
existing.abstractedPrinciple = data.abstractedPrinciple;
|
|
707
|
-
}
|
|
708
|
-
if (data.coreAxiomId) {
|
|
709
|
-
existing.coreAxiomId = data.coreAxiomId;
|
|
710
|
-
}
|
|
711
|
-
return;
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
const principle: Principle = {
|
|
715
|
-
id: data.principleId,
|
|
716
|
-
version: 1,
|
|
717
|
-
text: `When ${data.trigger}, then ${data.action}.`,
|
|
718
|
-
source: {
|
|
719
|
-
painId: data.painId,
|
|
720
|
-
painType: data.painType ?? 'tool_failure',
|
|
721
|
-
timestamp: ts,
|
|
722
|
-
},
|
|
723
|
-
trigger: data.trigger,
|
|
724
|
-
action: data.action,
|
|
725
|
-
contextTags: [],
|
|
726
|
-
validation: { successCount: 0, conflictCount: 0 },
|
|
727
|
-
status: 'candidate',
|
|
728
|
-
feedbackScore: 0,
|
|
729
|
-
usageCount: 0,
|
|
730
|
-
createdAt: ts,
|
|
731
|
-
// Evaluability defaults to 'manual_only' for replayed events without the field
|
|
732
|
-
evaluability: data.evaluability ?? 'manual_only',
|
|
733
|
-
detectorMetadata: data.detectorMetadata
|
|
734
|
-
? structuredClone(data.detectorMetadata)
|
|
735
|
-
: undefined,
|
|
736
|
-
// Restore abstractedPrinciple from event if present
|
|
737
|
-
abstractedPrinciple: data.abstractedPrinciple,
|
|
738
|
-
coreAxiomId: data.coreAxiomId,
|
|
739
|
-
};
|
|
740
|
-
this.principles.set(principle.id, principle);
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
private onPrinciplePromoted(data: PrinciplePromotedData, ts: string): void {
|
|
744
|
-
const p = this.principles.get(data.principleId);
|
|
745
|
-
if (!p) return;
|
|
746
|
-
p.status = data.to;
|
|
747
|
-
if (data.to === 'active') {
|
|
748
|
-
p.activatedAt = ts;
|
|
749
|
-
}
|
|
750
|
-
this.lastPromotedAt = ts;
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
private onPrincipleDeprecated(data: PrincipleDeprecatedData, ts: string): void {
|
|
754
|
-
const p = this.principles.get(data.principleId);
|
|
755
|
-
if (!p) return;
|
|
756
|
-
p.status = 'deprecated';
|
|
757
|
-
p.deprecatedAt = ts;
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
private onPrincipleRolledBack(data: PrincipleRolledBackData, ts: string): void {
|
|
761
|
-
const p = this.principles.get(data.principleId);
|
|
762
|
-
if (p) {
|
|
763
|
-
p.status = 'deprecated';
|
|
764
|
-
p.deprecatedAt = ts;
|
|
765
|
-
}
|
|
766
|
-
this.persistBlacklist({
|
|
767
|
-
painId: data.relatedPainId,
|
|
768
|
-
pattern: data.blacklistPattern,
|
|
769
|
-
reason: data.reason,
|
|
770
|
-
rolledBackAt: ts,
|
|
771
|
-
});
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
private onPainDetected(data: PainDetectedData, _eventTs: string): void {
|
|
776
|
-
const trigger = String(data.reason ?? data.source ?? 'unknown trigger');
|
|
777
|
-
|
|
778
|
-
// Defense in depth: protocol/system tokens must never become principles,
|
|
779
|
-
// even if a pain_detected event is emitted from a new callsite in the future.
|
|
780
|
-
if (shouldIgnorePainProtocolText(trigger)) {
|
|
781
|
-
return;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
if (this.isBlacklisted(data.painId, trigger)) {
|
|
785
|
-
return;
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
// NOTE: Principle creation is now deferred to diagnostician analysis.
|
|
789
|
-
// The diagnostician will read conversation context, generalize the trigger pattern,
|
|
790
|
-
// and create a principle via createPrincipleFromDiagnosis() after analysis.
|
|
791
|
-
|
|
792
|
-
// Record pain for tracking purposes (but don't create principle yet)
|
|
793
|
-
this.emitSync({
|
|
794
|
-
ts: new Date().toISOString(),
|
|
795
|
-
type: 'pain_recorded',
|
|
796
|
-
data: {
|
|
797
|
-
painId: data.painId,
|
|
798
|
-
painType: data.painType,
|
|
799
|
-
source: data.source,
|
|
800
|
-
reason: data.reason,
|
|
801
|
-
sessionId: data.sessionId,
|
|
802
|
-
agentId: data.agentId,
|
|
803
|
-
},
|
|
804
|
-
});
|
|
805
|
-
|
|
806
|
-
// Circuit breaker logic remains for subagent errors
|
|
807
|
-
if (data.painType === 'subagent_error') {
|
|
808
|
-
const key = String(data.taskId ?? data.source ?? 'subagent');
|
|
809
|
-
const next = this.failureStreak.get(key) ?? 0;
|
|
810
|
-
if (next >= CIRCUIT_BREAKER_THRESHOLD) {
|
|
811
|
-
const nextRetryAt = new Date(Date.now() + 15 * 60 * 1000).toISOString();
|
|
812
|
-
this.emitSync({
|
|
813
|
-
ts: new Date().toISOString(),
|
|
814
|
-
type: 'circuit_breaker_opened',
|
|
815
|
-
data: {
|
|
816
|
-
taskId: key,
|
|
817
|
-
painId: data.painId,
|
|
818
|
-
failCount: next,
|
|
819
|
-
reason: 'Max retries exceeded',
|
|
820
|
-
requireHuman: true,
|
|
821
|
-
nextRetryAt,
|
|
822
|
-
},
|
|
823
|
-
});
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
private updateFailureStreakFromPain(data: PainDetectedData): void {
|
|
829
|
-
if (data.painType !== 'subagent_error') return;
|
|
830
|
-
|
|
831
|
-
const key = String(data.taskId ?? data.source ?? 'subagent');
|
|
832
|
-
const next = (this.failureStreak.get(key) ?? 0) + 1;
|
|
833
|
-
this.failureStreak.set(key, next);
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
private nextPrincipleId(): string {
|
|
837
|
-
const ids = [...this.principles.keys()]
|
|
838
|
-
.map((id) => Number(id.replace(/^P_/, '')))
|
|
839
|
-
.filter((n) => Number.isFinite(n));
|
|
840
|
-
const next = (ids.length ? Math.max(...ids) : 0) + 1;
|
|
841
|
-
return `P_${String(next).padStart(3, '0')}`;
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
private getByStatus(status: PrincipleStatus): Principle[] {
|
|
845
|
-
return [...this.principles.values()].filter((p) => p.status === status);
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
private sweepExpiredProbation(): void {
|
|
849
|
-
const now = Date.now();
|
|
850
|
-
const maxAgeMs = PROBATION_MAX_AGE_DAYS * 24 * 60 * 60 * 1000;
|
|
851
|
-
// Use getByStatus directly to avoid infinite recursion with getProbationPrinciples()
|
|
852
|
-
for (const p of this.getByStatus('probation')) {
|
|
853
|
-
const age = now - new Date(p.createdAt).getTime();
|
|
854
|
-
if (age > maxAgeMs) {
|
|
855
|
-
this.deprecate(p.id, 'probation_expired');
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
private persistBlacklist(entry: { painId?: string; pattern?: string; reason: string; rolledBackAt: string }): void {
|
|
861
|
-
const list = this.loadBlacklist();
|
|
862
|
-
list.push(entry);
|
|
863
|
-
atomicWriteFileSync(this.blacklistPath, JSON.stringify(list, null, 2));
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
private loadBlacklist(): { painId?: string; pattern?: string; reason: string; rolledBackAt: string }[] {
|
|
867
|
-
if (!fs.existsSync(this.blacklistPath)) return [];
|
|
868
|
-
try {
|
|
869
|
-
return JSON.parse(fs.readFileSync(this.blacklistPath, 'utf8')) as {
|
|
870
|
-
painId?: string;
|
|
871
|
-
pattern?: string;
|
|
872
|
-
reason: string;
|
|
873
|
-
rolledBackAt: string;
|
|
874
|
-
}[];
|
|
875
|
-
} catch (e) {
|
|
876
|
-
SystemLogger.log(this.workspaceDir, 'EVOLUTION_WARN', `failed to parse blacklist: ${String(e)}`);
|
|
877
|
-
return [];
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
private isBlacklisted(painId: string, trigger: string): boolean {
|
|
882
|
-
return this.loadBlacklist().some((entry) =>
|
|
883
|
-
(entry.painId && entry.painId === painId) ||
|
|
884
|
-
(entry.pattern && trigger.includes(entry.pattern))
|
|
885
|
-
);
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
export function stableContentHash(input: string): string {
|
|
890
|
-
return crypto.createHash('sha1').update(input).digest('hex');
|
|
891
|
-
}
|