principles-disciple 1.8.0 → 1.8.2
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/ADVANCED_CONFIG_ZH.md +97 -0
- package/AGENT_INSTALL.md +173 -0
- package/AGENT_INSTALL_EN.md +173 -0
- package/INSTALL.md +256 -0
- package/SKILL.md +63 -0
- package/docs/COMMAND_REFERENCE.md +76 -0
- package/docs/COMMAND_REFERENCE_EN.md +79 -0
- package/esbuild.config.js +75 -0
- package/openclaw.plugin.json +6 -1
- package/package.json +13 -15
- package/scripts/build-web.mjs +46 -0
- package/scripts/install-dependencies.cjs +47 -0
- package/scripts/sync-plugin.mjs +802 -0
- package/scripts/verify-build.mjs +109 -0
- package/src/agents/nocturnal-dreamer.md +152 -0
- package/src/agents/nocturnal-philosopher.md +138 -0
- package/src/agents/nocturnal-reflector.md +126 -0
- package/src/agents/nocturnal-scribe.md +164 -0
- package/src/commands/capabilities.ts +85 -0
- package/{dist/commands/context.js → src/commands/context.ts} +78 -38
- package/src/commands/evolution-status.ts +146 -0
- package/src/commands/export.ts +111 -0
- package/src/commands/focus.ts +533 -0
- package/src/commands/nocturnal-review.ts +311 -0
- package/src/commands/nocturnal-rollout.ts +763 -0
- package/src/commands/nocturnal-train.ts +1002 -0
- package/{dist/commands/pain.js → src/commands/pain.ts} +68 -49
- package/src/commands/principle-rollback.ts +27 -0
- package/{dist/commands/rollback.js → src/commands/rollback.ts} +44 -12
- package/src/commands/samples.ts +60 -0
- package/src/commands/strategy.ts +38 -0
- package/{dist/commands/thinking-os.js → src/commands/thinking-os.ts} +59 -36
- package/src/commands/workflow-debug.ts +128 -0
- package/{dist/config/defaults/runtime.js → src/config/defaults/runtime.ts} +12 -5
- package/src/config/errors.ts +163 -0
- package/{dist/config/index.d.ts → src/config/index.ts} +2 -1
- package/src/constants/diagnostician.ts +66 -0
- package/src/constants/tools.ts +62 -0
- package/src/core/adaptive-thresholds.ts +476 -0
- package/{dist/core/config-service.js → src/core/config-service.ts} +7 -4
- package/{dist/core/config.js → src/core/config.ts} +158 -46
- package/src/core/control-ui-db.ts +435 -0
- package/{dist/core/detection-funnel.js → src/core/detection-funnel.ts} +36 -21
- package/{dist/core/detection-service.js → src/core/detection-service.ts} +7 -4
- package/{dist/core/dictionary-service.js → src/core/dictionary-service.ts} +7 -4
- package/{dist/core/dictionary.js → src/core/dictionary.ts} +57 -34
- package/src/core/empathy-keyword-matcher.ts +327 -0
- package/src/core/empathy-types.ts +218 -0
- package/src/core/event-log.ts +544 -0
- package/src/core/evolution-engine.ts +612 -0
- package/src/core/evolution-logger.ts +353 -0
- package/src/core/evolution-migration.ts +77 -0
- package/src/core/evolution-reducer.ts +731 -0
- package/src/core/evolution-types.ts +456 -0
- package/src/core/external-training-contract.ts +527 -0
- package/src/core/focus-history.ts +1458 -0
- package/src/core/hygiene/tracker.ts +117 -0
- package/{dist/core/init.js → src/core/init.ts} +39 -26
- package/src/core/local-worker-routing.ts +617 -0
- package/{dist/core/migration.js → src/core/migration.ts} +18 -11
- package/src/core/model-deployment-registry.ts +722 -0
- package/src/core/model-training-registry.ts +813 -0
- package/src/core/nocturnal-arbiter.ts +706 -0
- package/src/core/nocturnal-candidate-scoring.ts +392 -0
- package/src/core/nocturnal-compliance.ts +1075 -0
- package/src/core/nocturnal-dataset.ts +668 -0
- package/src/core/nocturnal-executability.ts +428 -0
- package/src/core/nocturnal-export.ts +390 -0
- package/{dist/core/nocturnal-paths.js → src/core/nocturnal-paths.ts} +49 -23
- package/src/core/nocturnal-trajectory-extractor.ts +484 -0
- package/src/core/nocturnal-trinity.ts +1384 -0
- package/src/core/pain.ts +122 -0
- package/{dist/core/path-resolver.js → src/core/path-resolver.ts} +157 -36
- package/{dist/core/paths.js → src/core/paths.ts} +13 -4
- package/src/core/principle-training-state.ts +450 -0
- package/src/core/profile.ts +226 -0
- package/src/core/promotion-gate.ts +822 -0
- package/{dist/core/risk-calculator.js → src/core/risk-calculator.ts} +42 -16
- package/{dist/core/session-tracker.js → src/core/session-tracker.ts} +185 -63
- package/src/core/shadow-observation-registry.ts +534 -0
- package/{dist/core/system-logger.js → src/core/system-logger.ts} +9 -5
- package/src/core/thinking-models.ts +217 -0
- package/src/core/training-program.ts +630 -0
- package/src/core/trajectory-types.ts +243 -0
- package/src/core/trajectory.ts +1673 -0
- package/{dist/core/workspace-context.js → src/core/workspace-context.ts} +57 -32
- package/src/hooks/bash-risk.ts +171 -0
- package/src/hooks/edit-verification.ts +295 -0
- package/src/hooks/gate-block-helper.ts +160 -0
- package/src/hooks/gate.ts +210 -0
- package/src/hooks/gfi-gate.ts +177 -0
- package/src/hooks/lifecycle.ts +326 -0
- package/{dist/hooks/llm.js → src/hooks/llm.ts} +166 -139
- package/src/hooks/message-sanitize.ts +45 -0
- package/src/hooks/pain.ts +384 -0
- package/src/hooks/progressive-trust-gate.ts +174 -0
- package/src/hooks/prompt.ts +920 -0
- package/src/hooks/subagent.ts +207 -0
- package/src/hooks/thinking-checkpoint.ts +73 -0
- package/src/hooks/trajectory-collector.ts +290 -0
- package/src/http/principles-console-route.ts +716 -0
- package/src/i18n/commands.ts +117 -0
- package/src/index.ts +694 -0
- package/src/service/central-database.ts +831 -0
- package/src/service/control-ui-query-service.ts +888 -0
- package/src/service/evolution-query-service.ts +405 -0
- package/src/service/evolution-worker.ts +1646 -0
- package/src/service/health-query-service.ts +836 -0
- package/{dist/service/nocturnal-runtime.js → src/service/nocturnal-runtime.ts} +263 -36
- package/src/service/nocturnal-service.ts +1015 -0
- package/src/service/nocturnal-target-selector.ts +532 -0
- package/src/service/phase3-input-filter.ts +237 -0
- package/src/service/runtime-summary-service.ts +757 -0
- package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +513 -0
- package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +603 -0
- package/src/service/subagent-workflow/index.ts +51 -0
- package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +856 -0
- package/src/service/subagent-workflow/runtime-direct-driver.ts +166 -0
- package/src/service/subagent-workflow/types.ts +378 -0
- package/src/service/subagent-workflow/workflow-store.ts +328 -0
- package/src/service/trajectory-service.ts +15 -0
- package/{dist/tools/critique-prompt.js → src/tools/critique-prompt.ts} +25 -8
- package/src/tools/deep-reflect.ts +349 -0
- package/{dist/tools/model-index.js → src/tools/model-index.ts} +33 -17
- package/src/types/event-types.ts +453 -0
- package/src/types/hygiene-types.ts +31 -0
- package/src/types/principle-tree-schema.ts +244 -0
- package/src/types/runtime-summary.ts +49 -0
- package/src/types.ts +74 -0
- package/src/utils/file-lock.ts +391 -0
- package/{dist/utils/glob-match.js → src/utils/glob-match.ts} +21 -20
- package/{dist/utils/hashing.js → src/utils/hashing.ts} +6 -4
- package/src/utils/io.ts +110 -0
- package/{dist/utils/nlp.js → src/utils/nlp.ts} +19 -12
- package/{dist/utils/plugin-logger.js → src/utils/plugin-logger.ts} +33 -8
- package/src/utils/subagent-probe.ts +94 -0
- package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +70 -1
- package/templates/pain_settings.json +2 -1
- package/tests/README.md +120 -0
- package/tests/build-artifacts.test.ts +111 -0
- package/tests/commands/evolution-status.test.ts +222 -0
- package/tests/commands/evolver.test.ts +22 -0
- package/tests/commands/export.test.ts +78 -0
- package/tests/commands/nocturnal-review.test.ts +448 -0
- package/tests/commands/nocturnal-train.test.ts +97 -0
- package/tests/commands/pain.test.ts +108 -0
- package/tests/commands/samples.test.ts +65 -0
- package/tests/commands/strategy.test.ts +34 -0
- package/tests/commands/thinking-os.test.ts +88 -0
- package/tests/core/adaptive-thresholds.test.ts +261 -0
- package/tests/core/config-service.test.ts +89 -0
- package/tests/core/config.test.ts +90 -0
- package/tests/core/control-ui-db.test.ts +75 -0
- package/tests/core/core-template-guidance.test.ts +21 -0
- package/tests/core/detection-funnel.test.ts +63 -0
- package/tests/core/detection-service.test.ts +50 -0
- package/tests/core/dictionary-service.test.ts +116 -0
- package/tests/core/dictionary.test.ts +168 -0
- package/tests/core/empathy-keyword-matcher.test.ts +209 -0
- package/tests/core/event-log.test.ts +181 -0
- package/tests/core/evolution-e2e.test.ts +58 -0
- package/tests/core/evolution-engine-gate-integration.test.ts +543 -0
- package/tests/core/evolution-engine.test.ts +562 -0
- package/tests/core/evolution-logger.test.ts +148 -0
- package/tests/core/evolution-migration.test.ts +50 -0
- package/tests/core/evolution-paths.test.ts +21 -0
- package/tests/core/evolution-reducer.detector-metadata.test.ts +602 -0
- package/tests/core/evolution-reducer.test.ts +180 -0
- package/tests/core/evolution-types-loop.test.ts +48 -0
- package/tests/core/evolution-user-stories.e2e.test.ts +249 -0
- package/tests/core/external-training-contract.test.ts +463 -0
- package/tests/core/focus-history.test.ts +682 -0
- package/tests/core/init-flatten.test.ts +69 -0
- package/tests/core/init-refactor.test.ts +87 -0
- package/tests/core/init-v1.3.test.ts +46 -0
- package/tests/core/init.test.ts +190 -0
- package/tests/core/local-worker-routing.test.ts +757 -0
- package/tests/core/migration.test.ts +84 -0
- package/tests/core/model-deployment-registry.test.ts +845 -0
- package/tests/core/model-training-registry.test.ts +889 -0
- package/tests/core/nocturnal-arbiter.test.ts +494 -0
- package/tests/core/nocturnal-candidate-scoring.test.ts +400 -0
- package/tests/core/nocturnal-compliance.test.ts +646 -0
- package/tests/core/nocturnal-dataset.test.ts +892 -0
- package/tests/core/nocturnal-executability.test.ts +357 -0
- package/tests/core/nocturnal-export.test.ts +462 -0
- package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +428 -0
- package/tests/core/nocturnal-trajectory-extractor.test.ts +634 -0
- package/tests/core/nocturnal-trinity.test.ts +953 -0
- package/tests/core/pain.test.ts +33 -0
- package/tests/core/path-resolver.test.ts +57 -0
- package/tests/core/paths-refactor.test.ts +42 -0
- package/tests/core/phase7-rollout-integration.test.ts +477 -0
- package/tests/core/principle-training-state.test.ts +712 -0
- package/tests/core/profile.test.ts +56 -0
- package/tests/core/promotion-gate.test.ts +556 -0
- package/tests/core/risk-calculator.test.ts +168 -0
- package/tests/core/session-tracker.test.ts +191 -0
- package/tests/core/training-program.test.ts +472 -0
- package/tests/core/trajectory.test.ts +265 -0
- package/tests/core/workspace-context-factory.test.ts +18 -0
- package/tests/core/workspace-context.test.ts +134 -0
- package/tests/fixtures/nocturnal-reviewed-subset.json +183 -0
- package/tests/fixtures/production-compatibility.test.ts +147 -0
- package/tests/fixtures/production-mock-generator.ts +282 -0
- package/tests/hooks/bash-risk-integration.test.ts +137 -0
- package/tests/hooks/bash-risk.test.ts +81 -0
- package/tests/hooks/edit-verification.test.ts +678 -0
- package/tests/hooks/gate-edit-verification-p1.test.ts +632 -0
- package/tests/hooks/gate-edit-verification.test.ts +435 -0
- package/tests/hooks/gate-pipeline-integration.test.ts +404 -0
- package/tests/hooks/gate.test.ts +271 -0
- package/tests/hooks/gfi-gate-unit.test.ts +422 -0
- package/tests/hooks/gfi-gate.test.ts +669 -0
- package/tests/hooks/lifecycle.test.ts +248 -0
- package/tests/hooks/llm.test.ts +308 -0
- package/tests/hooks/message-sanitize.test.ts +36 -0
- package/tests/hooks/pain.test.ts +141 -0
- package/tests/hooks/progressive-trust-gate.test.ts +277 -0
- package/tests/hooks/prompt.test.ts +1411 -0
- package/tests/hooks/subagent.test.ts +467 -0
- package/tests/hooks/thinking-gate.test.ts +313 -0
- package/tests/http/principles-console-route.test.ts +140 -0
- package/tests/hygiene-tracker.test.ts +77 -0
- package/tests/index.integration.test.ts +179 -0
- package/tests/index.shadow-routing.integration.test.ts +140 -0
- package/tests/index.test.ts +9 -0
- package/tests/integration/empathy-workflow-integration.test.ts +627 -0
- package/tests/service/control-ui-query-service.test.ts +121 -0
- package/tests/service/empathy-observer-workflow-manager.test.ts +176 -0
- package/tests/service/evolution-worker.test.ts +585 -0
- package/tests/service/nocturnal-runtime.test.ts +470 -0
- package/tests/service/nocturnal-service.test.ts +577 -0
- package/tests/service/nocturnal-target-selector.test.ts +615 -0
- package/tests/service/nocturnal-workflow-manager.test.ts +439 -0
- package/tests/service/phase3-input-filter.test.ts +289 -0
- package/tests/service/runtime-summary-service.test.ts +919 -0
- package/tests/task-compliance.test.ts +166 -0
- package/tests/test-utils.ts +48 -0
- package/tests/tools/critique-prompt.test.ts +260 -0
- package/tests/tools/deep-reflect.test.ts +232 -0
- package/tests/tools/model-index.test.ts +246 -0
- package/tests/ui/app.test.tsx +114 -0
- package/tests/utils/file-lock.test.ts +407 -0
- package/tests/utils/hashing.test.ts +32 -0
- package/tests/utils/io.test.ts +39 -0
- package/tests/utils/nlp.test.ts +53 -0
- package/tests/utils/plugin-logger.test.ts +156 -0
- package/tsconfig.json +16 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/ui/src/App.tsx +45 -0
- package/ui/src/api.ts +216 -0
- package/ui/src/charts.tsx +586 -0
- package/ui/src/components/ErrorState.tsx +6 -0
- package/ui/src/components/Loading.tsx +13 -0
- package/ui/src/components/ProtectedRoute.tsx +12 -0
- package/ui/src/components/Shell.tsx +91 -0
- package/ui/src/components/WorkspaceConfig.tsx +146 -0
- package/ui/src/components/index.ts +5 -0
- package/ui/src/context/auth.tsx +80 -0
- package/ui/src/context/theme.tsx +66 -0
- package/ui/src/hooks/useAutoRefresh.ts +39 -0
- package/ui/src/i18n/ui.ts +363 -0
- package/ui/src/main.tsx +16 -0
- package/ui/src/pages/EvolutionPage.tsx +352 -0
- package/ui/src/pages/FeedbackPage.tsx +140 -0
- package/ui/src/pages/GateMonitorPage.tsx +136 -0
- package/ui/src/pages/LoginPage.tsx +88 -0
- package/ui/src/pages/OverviewPage.tsx +238 -0
- package/ui/src/pages/SamplesPage.tsx +174 -0
- package/ui/src/pages/ThinkingModelsPage.tsx +127 -0
- package/ui/src/styles.css +1661 -0
- package/ui/src/types.ts +368 -0
- package/ui/src/utils/format.ts +15 -0
- package/vitest.config.ts +23 -0
- package/dist/commands/capabilities.d.ts +0 -3
- package/dist/commands/capabilities.js +0 -73
- package/dist/commands/context.d.ts +0 -5
- package/dist/commands/evolution-status.d.ts +0 -4
- package/dist/commands/evolution-status.js +0 -117
- package/dist/commands/evolver.d.ts +0 -9
- package/dist/commands/evolver.js +0 -26
- package/dist/commands/export.d.ts +0 -2
- package/dist/commands/export.js +0 -98
- package/dist/commands/focus.d.ts +0 -14
- package/dist/commands/focus.js +0 -457
- package/dist/commands/nocturnal-review.d.ts +0 -24
- package/dist/commands/nocturnal-review.js +0 -265
- package/dist/commands/nocturnal-rollout.d.ts +0 -27
- package/dist/commands/nocturnal-rollout.js +0 -671
- package/dist/commands/nocturnal-train.d.ts +0 -25
- package/dist/commands/nocturnal-train.js +0 -919
- package/dist/commands/pain.d.ts +0 -5
- package/dist/commands/principle-rollback.d.ts +0 -4
- package/dist/commands/principle-rollback.js +0 -22
- package/dist/commands/rollback.d.ts +0 -19
- package/dist/commands/samples.d.ts +0 -2
- package/dist/commands/samples.js +0 -55
- package/dist/commands/strategy.d.ts +0 -3
- package/dist/commands/strategy.js +0 -29
- package/dist/commands/thinking-os.d.ts +0 -2
- package/dist/config/defaults/runtime.d.ts +0 -40
- package/dist/config/errors.d.ts +0 -84
- package/dist/config/errors.js +0 -94
- package/dist/config/index.js +0 -7
- package/dist/constants/diagnostician.d.ts +0 -12
- package/dist/constants/diagnostician.js +0 -56
- package/dist/constants/tools.d.ts +0 -17
- package/dist/constants/tools.js +0 -54
- package/dist/core/adaptive-thresholds.d.ts +0 -186
- package/dist/core/adaptive-thresholds.js +0 -300
- package/dist/core/config-service.d.ts +0 -15
- package/dist/core/config.d.ts +0 -127
- package/dist/core/control-ui-db.d.ts +0 -95
- package/dist/core/control-ui-db.js +0 -292
- package/dist/core/detection-funnel.d.ts +0 -33
- package/dist/core/detection-service.d.ts +0 -15
- package/dist/core/dictionary-service.d.ts +0 -15
- package/dist/core/dictionary.d.ts +0 -38
- package/dist/core/event-log.d.ts +0 -82
- package/dist/core/event-log.js +0 -463
- package/dist/core/evolution-engine.d.ts +0 -118
- package/dist/core/evolution-engine.js +0 -464
- package/dist/core/evolution-logger.d.ts +0 -137
- package/dist/core/evolution-logger.js +0 -256
- package/dist/core/evolution-migration.d.ts +0 -5
- package/dist/core/evolution-migration.js +0 -65
- package/dist/core/evolution-reducer.d.ts +0 -98
- package/dist/core/evolution-reducer.js +0 -465
- package/dist/core/evolution-types.d.ts +0 -287
- package/dist/core/evolution-types.js +0 -78
- package/dist/core/external-training-contract.d.ts +0 -276
- package/dist/core/external-training-contract.js +0 -269
- package/dist/core/focus-history.d.ts +0 -210
- package/dist/core/focus-history.js +0 -1185
- package/dist/core/hygiene/tracker.d.ts +0 -22
- package/dist/core/hygiene/tracker.js +0 -106
- package/dist/core/init.d.ts +0 -12
- package/dist/core/local-worker-routing.d.ts +0 -175
- package/dist/core/local-worker-routing.js +0 -525
- package/dist/core/migration.d.ts +0 -6
- package/dist/core/model-deployment-registry.d.ts +0 -218
- package/dist/core/model-deployment-registry.js +0 -503
- package/dist/core/model-training-registry.d.ts +0 -295
- package/dist/core/model-training-registry.js +0 -475
- package/dist/core/nocturnal-arbiter.d.ts +0 -159
- package/dist/core/nocturnal-arbiter.js +0 -534
- package/dist/core/nocturnal-candidate-scoring.d.ts +0 -137
- package/dist/core/nocturnal-candidate-scoring.js +0 -266
- package/dist/core/nocturnal-compliance.d.ts +0 -175
- package/dist/core/nocturnal-compliance.js +0 -824
- package/dist/core/nocturnal-dataset.d.ts +0 -224
- package/dist/core/nocturnal-dataset.js +0 -443
- package/dist/core/nocturnal-executability.d.ts +0 -85
- package/dist/core/nocturnal-executability.js +0 -331
- package/dist/core/nocturnal-export.d.ts +0 -124
- package/dist/core/nocturnal-export.js +0 -275
- package/dist/core/nocturnal-paths.d.ts +0 -124
- package/dist/core/nocturnal-trajectory-extractor.d.ts +0 -242
- package/dist/core/nocturnal-trajectory-extractor.js +0 -307
- package/dist/core/nocturnal-trinity.d.ts +0 -311
- package/dist/core/nocturnal-trinity.js +0 -880
- package/dist/core/pain.d.ts +0 -4
- package/dist/core/pain.js +0 -70
- package/dist/core/path-resolver.d.ts +0 -46
- package/dist/core/paths.d.ts +0 -65
- package/dist/core/principle-training-state.d.ts +0 -121
- package/dist/core/principle-training-state.js +0 -321
- package/dist/core/profile.d.ts +0 -62
- package/dist/core/profile.js +0 -210
- package/dist/core/promotion-gate.d.ts +0 -238
- package/dist/core/promotion-gate.js +0 -529
- package/dist/core/risk-calculator.d.ts +0 -22
- package/dist/core/session-tracker.d.ts +0 -99
- package/dist/core/shadow-observation-registry.d.ts +0 -217
- package/dist/core/shadow-observation-registry.js +0 -308
- package/dist/core/system-logger.d.ts +0 -8
- package/dist/core/thinking-models.d.ts +0 -38
- package/dist/core/thinking-models.js +0 -170
- package/dist/core/training-program.d.ts +0 -233
- package/dist/core/training-program.js +0 -433
- package/dist/core/trajectory.d.ts +0 -411
- package/dist/core/trajectory.js +0 -1307
- package/dist/core/workspace-context.d.ts +0 -71
- package/dist/hooks/bash-risk.d.ts +0 -57
- package/dist/hooks/bash-risk.js +0 -137
- package/dist/hooks/edit-verification.d.ts +0 -62
- package/dist/hooks/edit-verification.js +0 -256
- package/dist/hooks/gate-block-helper.d.ts +0 -44
- package/dist/hooks/gate-block-helper.js +0 -119
- package/dist/hooks/gate.d.ts +0 -24
- package/dist/hooks/gate.js +0 -173
- package/dist/hooks/gfi-gate.d.ts +0 -40
- package/dist/hooks/gfi-gate.js +0 -113
- package/dist/hooks/lifecycle.d.ts +0 -5
- package/dist/hooks/lifecycle.js +0 -284
- package/dist/hooks/llm.d.ts +0 -12
- package/dist/hooks/message-sanitize.d.ts +0 -3
- package/dist/hooks/message-sanitize.js +0 -37
- package/dist/hooks/pain.d.ts +0 -5
- package/dist/hooks/pain.js +0 -301
- package/dist/hooks/progressive-trust-gate.d.ts +0 -51
- package/dist/hooks/progressive-trust-gate.js +0 -89
- package/dist/hooks/prompt.d.ts +0 -47
- package/dist/hooks/prompt.js +0 -884
- package/dist/hooks/subagent.d.ts +0 -10
- package/dist/hooks/subagent.js +0 -387
- package/dist/hooks/thinking-checkpoint.d.ts +0 -37
- package/dist/hooks/thinking-checkpoint.js +0 -51
- package/dist/hooks/trajectory-collector.d.ts +0 -32
- package/dist/hooks/trajectory-collector.js +0 -256
- package/dist/http/principles-console-route.d.ts +0 -9
- package/dist/http/principles-console-route.js +0 -567
- package/dist/i18n/commands.d.ts +0 -26
- package/dist/i18n/commands.js +0 -116
- package/dist/index.d.ts +0 -7
- package/dist/index.js +0 -581
- package/dist/service/central-database.d.ts +0 -104
- package/dist/service/central-database.js +0 -649
- package/dist/service/control-ui-query-service.d.ts +0 -221
- package/dist/service/control-ui-query-service.js +0 -543
- package/dist/service/empathy-observer-manager.d.ts +0 -52
- package/dist/service/empathy-observer-manager.js +0 -229
- package/dist/service/evolution-query-service.d.ts +0 -155
- package/dist/service/evolution-query-service.js +0 -258
- package/dist/service/evolution-worker.d.ts +0 -101
- package/dist/service/evolution-worker.js +0 -974
- package/dist/service/nocturnal-runtime.d.ts +0 -183
- package/dist/service/nocturnal-service.d.ts +0 -163
- package/dist/service/nocturnal-service.js +0 -787
- package/dist/service/nocturnal-target-selector.d.ts +0 -145
- package/dist/service/nocturnal-target-selector.js +0 -315
- package/dist/service/phase3-input-filter.d.ts +0 -73
- package/dist/service/phase3-input-filter.js +0 -172
- package/dist/service/runtime-summary-service.d.ts +0 -122
- package/dist/service/runtime-summary-service.js +0 -485
- package/dist/service/trajectory-service.d.ts +0 -2
- package/dist/service/trajectory-service.js +0 -15
- package/dist/tools/critique-prompt.d.ts +0 -14
- package/dist/tools/deep-reflect.d.ts +0 -39
- package/dist/tools/deep-reflect.js +0 -350
- package/dist/tools/model-index.d.ts +0 -9
- package/dist/types/event-types.d.ts +0 -306
- package/dist/types/event-types.js +0 -106
- package/dist/types/hygiene-types.d.ts +0 -20
- package/dist/types/hygiene-types.js +0 -12
- package/dist/types/runtime-summary.d.ts +0 -47
- package/dist/types/runtime-summary.js +0 -1
- package/dist/types.d.ts +0 -50
- package/dist/types.js +0 -22
- package/dist/utils/file-lock.d.ts +0 -71
- package/dist/utils/file-lock.js +0 -309
- package/dist/utils/glob-match.d.ts +0 -28
- package/dist/utils/hashing.d.ts +0 -9
- package/dist/utils/io.d.ts +0 -6
- package/dist/utils/io.js +0 -106
- package/dist/utils/nlp.d.ts +0 -9
- package/dist/utils/plugin-logger.d.ts +0 -39
- package/dist/utils/subagent-probe.d.ts +0 -34
- package/dist/utils/subagent-probe.js +0 -81
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nocturnal Target Selector — Principle + Session Selection for Sleep-Mode Reflection
|
|
3
|
+
* ================================================================================
|
|
4
|
+
*
|
|
5
|
+
* PURPOSE: Select one target principle and one violating session for nocturnal
|
|
6
|
+
* reflection processing. This module is a PURE SELECTOR — it does NOT execute
|
|
7
|
+
* reflection or write any artifacts.
|
|
8
|
+
*
|
|
9
|
+
* SELECTION LOGIC:
|
|
10
|
+
* 1. Filter principles to evaluable candidates (not manual_only, not cooldown)
|
|
11
|
+
* 2. Score candidates by: compliance health, violation trend, sample scarcity
|
|
12
|
+
* 3. Select top principle
|
|
13
|
+
* 4. Find violating sessions for that principle
|
|
14
|
+
* 5. Select best violating session by violation density
|
|
15
|
+
*
|
|
16
|
+
* SKIP CONDITIONS (return no-op cleanly):
|
|
17
|
+
* - no_evaluable_principles: No principles with auto-trainable evaluability
|
|
18
|
+
* - all_targets_in_cooldown: All candidates are in cooldown
|
|
19
|
+
* - no_violating_sessions: No sessions show violation signals for selected principle
|
|
20
|
+
* - workspace_not_idle: Workspace is active, nocturnal run not allowed
|
|
21
|
+
* - quota_exhausted: Max runs per window reached
|
|
22
|
+
* - insufficient_snapshot_data: Sessions exist but lack tool calls
|
|
23
|
+
*
|
|
24
|
+
* DESIGN CONSTRAINTS:
|
|
25
|
+
* - This is a PURE SELECTOR — no reflection execution
|
|
26
|
+
* - No raw text exposure
|
|
27
|
+
* - No artifact writing
|
|
28
|
+
* - No真实 subagent 调用
|
|
29
|
+
* - Deterministic based on inputs (no random selection)
|
|
30
|
+
*
|
|
31
|
+
* OUTPUT: NocturnalSelectionResult with:
|
|
32
|
+
* - decision: 'selected' | 'skip'
|
|
33
|
+
* - selectedPrincipleId?: string
|
|
34
|
+
* - selectedSessionId?: string
|
|
35
|
+
* - skipReason?: SkipReason
|
|
36
|
+
* - diagnostics: scoring and filtering details
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
import {
|
|
40
|
+
NocturnalTrajectoryExtractor,
|
|
41
|
+
NocturnalSessionSummary,
|
|
42
|
+
} from '../core/nocturnal-trajectory-extractor.js';
|
|
43
|
+
import {
|
|
44
|
+
listEvaluablePrinciples,
|
|
45
|
+
loadStore,
|
|
46
|
+
type PrincipleTrainingState,
|
|
47
|
+
} from '../core/principle-training-state.js';
|
|
48
|
+
import {
|
|
49
|
+
checkWorkspaceIdle,
|
|
50
|
+
checkCooldown,
|
|
51
|
+
checkPreflight,
|
|
52
|
+
DEFAULT_IDLE_THRESHOLD_MS,
|
|
53
|
+
DEFAULT_PRINCIPLE_COOLDOWN_MS,
|
|
54
|
+
DEFAULT_GLOBAL_COOLDOWN_MS,
|
|
55
|
+
type IdleCheckResult,
|
|
56
|
+
} from './nocturnal-runtime.js';
|
|
57
|
+
import { detectViolation } from '../core/nocturnal-compliance.js';
|
|
58
|
+
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Types
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
export type SkipReason =
|
|
64
|
+
| 'no_evaluable_principles' // No principles with evaluability !== manual_only
|
|
65
|
+
| 'all_targets_in_cooldown' // All candidates are in per-principle cooldown
|
|
66
|
+
| 'no_violating_sessions' // No sessions show violation signals for selected principle
|
|
67
|
+
| 'workspace_not_idle' // Workspace is active, nocturnal not allowed
|
|
68
|
+
| 'quota_exhausted' // Max runs per quota window reached
|
|
69
|
+
| 'insufficient_snapshot_data' // Sessions exist but lack tool calls / events
|
|
70
|
+
| 'global_cooldown_active'; // Global cooldown is in effect
|
|
71
|
+
|
|
72
|
+
export interface SelectionDiagnostics {
|
|
73
|
+
/** Total evaluable principles found */
|
|
74
|
+
totalEvaluablePrinciples: number;
|
|
75
|
+
/** Principles filtered out by cooldown */
|
|
76
|
+
filteredByCooldown: number;
|
|
77
|
+
/** Principles that passed all filters */
|
|
78
|
+
passedPrinciples: string[];
|
|
79
|
+
/** Violating sessions found for selected principle */
|
|
80
|
+
violatingSessionCount: number;
|
|
81
|
+
/** Violation density of selected session (failures / total tool calls) */
|
|
82
|
+
selectedSessionViolationDensity: number | null;
|
|
83
|
+
/** Score of selected principle */
|
|
84
|
+
selectedPrincipleScore: number | null;
|
|
85
|
+
/** Score breakdown */
|
|
86
|
+
scoringBreakdown: Record<string, number>;
|
|
87
|
+
/** Whether workspace idle check passed */
|
|
88
|
+
idleCheckPassed: boolean;
|
|
89
|
+
/** Whether cooldown check passed */
|
|
90
|
+
cooldownCheckPassed: boolean;
|
|
91
|
+
/** Whether quota check passed */
|
|
92
|
+
quotaCheckPassed: boolean;
|
|
93
|
+
/** Recent pain context used for ranking bias (if available) */
|
|
94
|
+
painContext?: {
|
|
95
|
+
recentPainCount: number;
|
|
96
|
+
recentMaxPainScore: number;
|
|
97
|
+
hasRecentPain: boolean;
|
|
98
|
+
painSource?: string;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface NocturnalSelectionResult {
|
|
103
|
+
/** Whether a target was selected */
|
|
104
|
+
decision: 'selected' | 'skip';
|
|
105
|
+
/** Selected principle ID (if decision === 'selected') */
|
|
106
|
+
selectedPrincipleId?: string;
|
|
107
|
+
/** Selected violating session ID (if decision === 'selected') */
|
|
108
|
+
selectedSessionId?: string;
|
|
109
|
+
/** Reason for skip (if decision === 'skip') */
|
|
110
|
+
skipReason?: SkipReason;
|
|
111
|
+
/** Detailed diagnostics for observability */
|
|
112
|
+
diagnostics: SelectionDiagnostics;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
// Scoring
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
|
|
119
|
+
interface ScoredPrinciple {
|
|
120
|
+
principleId: string;
|
|
121
|
+
state: PrincipleTrainingState;
|
|
122
|
+
score: number;
|
|
123
|
+
violationDensity: number; // violations / applicable opportunities
|
|
124
|
+
cooldownActive: boolean;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
interface ViolationSignal {
|
|
128
|
+
sessionId: string;
|
|
129
|
+
hasViolation: boolean;
|
|
130
|
+
violationSeverity: number; // 0-1
|
|
131
|
+
failureCount: number;
|
|
132
|
+
painEventCount: number;
|
|
133
|
+
gateBlockCount: number;
|
|
134
|
+
toolCallCount: number;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Score a principle for nocturnal targeting.
|
|
139
|
+
* Higher score = better candidate for reflection.
|
|
140
|
+
*
|
|
141
|
+
* Scoring dimensions:
|
|
142
|
+
* 1. Compliance health (higher compliance = more worth teaching)
|
|
143
|
+
* 2. Violation trend (worsening trend = higher priority)
|
|
144
|
+
* 3. Sample scarcity (fewer samples = more valuable)
|
|
145
|
+
* 4. Cooldown penalty (in cooldown = lower priority)
|
|
146
|
+
* 5. Pain context bias (recent pain = higher priority for related principles)
|
|
147
|
+
*
|
|
148
|
+
* Score range: 0-100 (normalized)
|
|
149
|
+
*/
|
|
150
|
+
function scorePrinciple(
|
|
151
|
+
state: PrincipleTrainingState,
|
|
152
|
+
cooldownActive: boolean,
|
|
153
|
+
recentPainContext?: {
|
|
154
|
+
mostRecent: { score: number; source: string; reason: string; timestamp: string } | null;
|
|
155
|
+
recentPainCount: number;
|
|
156
|
+
recentMaxPainScore: number;
|
|
157
|
+
}
|
|
158
|
+
): number {
|
|
159
|
+
let score = 50; // Base score
|
|
160
|
+
|
|
161
|
+
// Compliance contribution: 0-25 points
|
|
162
|
+
// High compliance = well-understood principle = good teaching target
|
|
163
|
+
// But very low compliance = confused principle = also needs work
|
|
164
|
+
const complianceContribution = Math.round(state.complianceRate * 25);
|
|
165
|
+
score += complianceContribution;
|
|
166
|
+
|
|
167
|
+
// Trend contribution: -10 to +10 points
|
|
168
|
+
// worsening trend (+1) = higher priority = +10
|
|
169
|
+
// improving trend (-1) = lower priority = -10
|
|
170
|
+
// stable (0) = neutral = 0
|
|
171
|
+
score += state.violationTrend * 10;
|
|
172
|
+
|
|
173
|
+
// Sample scarcity contribution: 0-15 points
|
|
174
|
+
// Fewer samples generated = more valuable new data
|
|
175
|
+
// Max at 0 samples, decreases as samples accumulate
|
|
176
|
+
const scarcityPenalty = Math.min(state.generatedSampleCount / 10, 1) * 15;
|
|
177
|
+
score += Math.round(15 - scarcityPenalty);
|
|
178
|
+
|
|
179
|
+
// Cooldown penalty: -30 points
|
|
180
|
+
if (cooldownActive) {
|
|
181
|
+
score -= 30;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Pain context bias: up to +25 points
|
|
185
|
+
// Bias toward principles related to recent pain signals
|
|
186
|
+
if (recentPainContext && recentPainContext.recentPainCount > 0) {
|
|
187
|
+
// Most recent pain score contributes up to 15 points (pain scores are 1-10)
|
|
188
|
+
const mostRecentPainScore = recentPainContext.mostRecent?.score ?? 0;
|
|
189
|
+
const painScoreContribution = Math.round((mostRecentPainScore / 10) * 15);
|
|
190
|
+
score += painScoreContribution;
|
|
191
|
+
|
|
192
|
+
// Additional pain count adds up to 5 more points
|
|
193
|
+
const additionalPainContribution = Math.min(recentPainContext.recentPainCount - 1, 5) * 1;
|
|
194
|
+
score += additionalPainContribution;
|
|
195
|
+
|
|
196
|
+
// High pain scores (> 7) get extra 5-point boost
|
|
197
|
+
if (recentPainContext.recentMaxPainScore > 7) {
|
|
198
|
+
score += 5;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return Math.max(0, Math.min(100, score));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Compute violation signal density for a session.
|
|
207
|
+
* Returns 0-1 score (higher = more violation evidence).
|
|
208
|
+
*/
|
|
209
|
+
function computeViolationDensity(session: NocturnalSessionSummary): number {
|
|
210
|
+
const total = session.toolCallCount;
|
|
211
|
+
if (total === 0) return 0;
|
|
212
|
+
|
|
213
|
+
// Violation signals: failures, pain events, gate blocks
|
|
214
|
+
const violationSignals =
|
|
215
|
+
session.failureCount + session.painEventCount * 0.5 + session.gateBlockCount * 0.3;
|
|
216
|
+
|
|
217
|
+
return Math.min(violationSignals / total, 1);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// ---------------------------------------------------------------------------
|
|
221
|
+
// Core Selector
|
|
222
|
+
// ---------------------------------------------------------------------------
|
|
223
|
+
|
|
224
|
+
export interface NocturnalTargetSelectorOptions {
|
|
225
|
+
/**
|
|
226
|
+
* Minimum violation density threshold for a session to be considered "violating".
|
|
227
|
+
* Default: 0.1 (at least 10% of tool calls are violation signals)
|
|
228
|
+
*/
|
|
229
|
+
minViolationDensity?: number;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Maximum number of recent sessions to consider for violation matching.
|
|
233
|
+
* Default: 50
|
|
234
|
+
*/
|
|
235
|
+
maxSessionCandidates?: number;
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Idle threshold override (ms).
|
|
239
|
+
* Default: from nocturnal-runtime DEFAULT_IDLE_THRESHOLD_MS
|
|
240
|
+
*/
|
|
241
|
+
idleThresholdMs?: number;
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Override idle check result (for testing).
|
|
245
|
+
* If provided, this result is used instead of calling checkWorkspaceIdle.
|
|
246
|
+
*/
|
|
247
|
+
idleCheckOverride?: IdleCheckResult;
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Recent pain context from evolution worker.
|
|
251
|
+
* When provided, principles related to recent pain signals get ranking bias.
|
|
252
|
+
* This threads recent pain into sleep_reflection targeting without merging task kinds.
|
|
253
|
+
*/
|
|
254
|
+
recentPainContext?: {
|
|
255
|
+
mostRecent: {
|
|
256
|
+
score: number;
|
|
257
|
+
source: string;
|
|
258
|
+
reason: string;
|
|
259
|
+
timestamp: string;
|
|
260
|
+
} | null;
|
|
261
|
+
recentPainCount: number;
|
|
262
|
+
recentMaxPainScore: number;
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Nocturnal Target Selector.
|
|
268
|
+
*
|
|
269
|
+
* Selects one target principle and one violating session for nocturnal reflection.
|
|
270
|
+
* This is a PURE FUNCTION — no side effects, no artifact writing.
|
|
271
|
+
*/
|
|
272
|
+
export class NocturnalTargetSelector {
|
|
273
|
+
private readonly extractor: NocturnalTrajectoryExtractor;
|
|
274
|
+
private readonly stateDir: string;
|
|
275
|
+
private readonly workspaceDir: string;
|
|
276
|
+
private readonly opts: {
|
|
277
|
+
minViolationDensity: number;
|
|
278
|
+
maxSessionCandidates: number;
|
|
279
|
+
idleThresholdMs: number;
|
|
280
|
+
};
|
|
281
|
+
private readonly idleCheckOverride?: IdleCheckResult;
|
|
282
|
+
private readonly recentPainContext?: {
|
|
283
|
+
mostRecent: {
|
|
284
|
+
score: number;
|
|
285
|
+
source: string;
|
|
286
|
+
reason: string;
|
|
287
|
+
timestamp: string;
|
|
288
|
+
} | null;
|
|
289
|
+
recentPainCount: number;
|
|
290
|
+
recentMaxPainScore: number;
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
constructor(
|
|
294
|
+
workspaceDir: string,
|
|
295
|
+
stateDir: string,
|
|
296
|
+
extractor: NocturnalTrajectoryExtractor,
|
|
297
|
+
options: NocturnalTargetSelectorOptions = {}
|
|
298
|
+
) {
|
|
299
|
+
this.workspaceDir = workspaceDir;
|
|
300
|
+
this.stateDir = stateDir;
|
|
301
|
+
this.extractor = extractor;
|
|
302
|
+
// Destructure so they are NOT included in opts (stored separately)
|
|
303
|
+
const { idleCheckOverride, recentPainContext, ...restOptions } = options;
|
|
304
|
+
this.idleCheckOverride = idleCheckOverride;
|
|
305
|
+
this.recentPainContext = recentPainContext;
|
|
306
|
+
this.opts = {
|
|
307
|
+
minViolationDensity: restOptions.minViolationDensity ?? 0.1,
|
|
308
|
+
maxSessionCandidates: restOptions.maxSessionCandidates ?? 50,
|
|
309
|
+
idleThresholdMs: restOptions.idleThresholdMs ?? DEFAULT_IDLE_THRESHOLD_MS,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Select a target principle and violating session.
|
|
315
|
+
*
|
|
316
|
+
* @returns NocturnalSelectionResult with either selected targets or skip reason
|
|
317
|
+
*/
|
|
318
|
+
select(): NocturnalSelectionResult {
|
|
319
|
+
const diagnostics: SelectionDiagnostics = {
|
|
320
|
+
totalEvaluablePrinciples: 0,
|
|
321
|
+
filteredByCooldown: 0,
|
|
322
|
+
passedPrinciples: [],
|
|
323
|
+
violatingSessionCount: 0,
|
|
324
|
+
selectedSessionViolationDensity: null,
|
|
325
|
+
selectedPrincipleScore: null,
|
|
326
|
+
scoringBreakdown: {},
|
|
327
|
+
idleCheckPassed: false,
|
|
328
|
+
cooldownCheckPassed: false,
|
|
329
|
+
quotaCheckPassed: false,
|
|
330
|
+
painContext: this.recentPainContext ? {
|
|
331
|
+
recentPainCount: this.recentPainContext.recentPainCount,
|
|
332
|
+
recentMaxPainScore: this.recentPainContext.recentMaxPainScore,
|
|
333
|
+
hasRecentPain: this.recentPainContext.recentPainCount > 0,
|
|
334
|
+
painSource: this.recentPainContext.mostRecent?.source,
|
|
335
|
+
} : undefined,
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
// Step 1: Idle check — if workspace is not idle, skip
|
|
339
|
+
const idleResult = this.idleCheckOverride ?? checkWorkspaceIdle(this.workspaceDir, {
|
|
340
|
+
idleThresholdMs: this.opts.idleThresholdMs,
|
|
341
|
+
});
|
|
342
|
+
diagnostics.idleCheckPassed = idleResult.isIdle;
|
|
343
|
+
|
|
344
|
+
if (!idleResult.isIdle) {
|
|
345
|
+
return {
|
|
346
|
+
decision: 'skip',
|
|
347
|
+
skipReason: 'workspace_not_idle',
|
|
348
|
+
diagnostics,
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Step 2: Cooldown and quota check
|
|
353
|
+
const cooldownResult = checkCooldown(this.stateDir);
|
|
354
|
+
diagnostics.cooldownCheckPassed = !cooldownResult.globalCooldownActive;
|
|
355
|
+
diagnostics.quotaCheckPassed = !cooldownResult.quotaExhausted;
|
|
356
|
+
|
|
357
|
+
if (cooldownResult.globalCooldownActive) {
|
|
358
|
+
return {
|
|
359
|
+
decision: 'skip',
|
|
360
|
+
skipReason: 'global_cooldown_active',
|
|
361
|
+
diagnostics,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (cooldownResult.quotaExhausted) {
|
|
366
|
+
return {
|
|
367
|
+
decision: 'skip',
|
|
368
|
+
skipReason: 'quota_exhausted',
|
|
369
|
+
diagnostics,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Step 3: Get evaluable principles
|
|
374
|
+
const evaluablePrinciples = listEvaluablePrinciples(this.stateDir);
|
|
375
|
+
diagnostics.totalEvaluablePrinciples = evaluablePrinciples.length;
|
|
376
|
+
|
|
377
|
+
if (evaluablePrinciples.length === 0) {
|
|
378
|
+
return {
|
|
379
|
+
decision: 'skip',
|
|
380
|
+
skipReason: 'no_evaluable_principles',
|
|
381
|
+
diagnostics,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Step 4: Score and filter candidates
|
|
386
|
+
const scoredPrinciples: ScoredPrinciple[] = [];
|
|
387
|
+
|
|
388
|
+
for (const state of evaluablePrinciples) {
|
|
389
|
+
const cooldownCheck = checkCooldown(this.stateDir, state.principleId);
|
|
390
|
+
const cooldownActive = cooldownCheck.principleCooldownActive;
|
|
391
|
+
const score = scorePrinciple(state, cooldownActive, this.recentPainContext);
|
|
392
|
+
|
|
393
|
+
if (cooldownActive) {
|
|
394
|
+
diagnostics.filteredByCooldown++;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
scoredPrinciples.push({
|
|
398
|
+
principleId: state.principleId,
|
|
399
|
+
state,
|
|
400
|
+
score,
|
|
401
|
+
violationDensity:
|
|
402
|
+
state.applicableOpportunityCount > 0
|
|
403
|
+
? state.observedViolationCount / state.applicableOpportunityCount
|
|
404
|
+
: 0,
|
|
405
|
+
cooldownActive,
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
diagnostics.scoringBreakdown[state.principleId] = score;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// Filter out principles in cooldown (score already penalized but keep them in diagnostics)
|
|
412
|
+
const activeCandidates = scoredPrinciples.filter((p) => !p.cooldownActive);
|
|
413
|
+
|
|
414
|
+
if (activeCandidates.length === 0) {
|
|
415
|
+
diagnostics.passedPrinciples = [];
|
|
416
|
+
return {
|
|
417
|
+
decision: 'skip',
|
|
418
|
+
skipReason: 'all_targets_in_cooldown',
|
|
419
|
+
diagnostics,
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Sort by score descending
|
|
424
|
+
activeCandidates.sort((a, b) => b.score - a.score);
|
|
425
|
+
diagnostics.passedPrinciples = activeCandidates.map((p) => p.principleId);
|
|
426
|
+
|
|
427
|
+
// Select the top candidate
|
|
428
|
+
const selected = activeCandidates[0];
|
|
429
|
+
diagnostics.selectedPrincipleScore = selected.score;
|
|
430
|
+
|
|
431
|
+
// Step 5: Find violating sessions for the selected principle
|
|
432
|
+
const recentSessions = this.extractor.listRecentNocturnalCandidateSessions({
|
|
433
|
+
limit: this.opts.maxSessionCandidates,
|
|
434
|
+
minToolCalls: 1,
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
if (recentSessions.length === 0) {
|
|
438
|
+
return {
|
|
439
|
+
decision: 'skip',
|
|
440
|
+
skipReason: 'insufficient_snapshot_data',
|
|
441
|
+
diagnostics,
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Compute violation signals for each session
|
|
446
|
+
const violatingSessions: ViolationSignal[] = recentSessions.map((session) => {
|
|
447
|
+
const violationDensity = computeViolationDensity(session);
|
|
448
|
+
const snapshot = this.extractor.getNocturnalSessionSnapshot(session.sessionId);
|
|
449
|
+
|
|
450
|
+
// Use nocturnal-compliance to detect violations for the selected principle
|
|
451
|
+
let hasViolation = false;
|
|
452
|
+
if (snapshot) {
|
|
453
|
+
const violationResult = detectViolation(selected.principleId, {
|
|
454
|
+
sessionId: session.sessionId,
|
|
455
|
+
toolCalls: snapshot.toolCalls.map((tc) => ({
|
|
456
|
+
toolName: tc.toolName,
|
|
457
|
+
filePath: tc.filePath ?? undefined,
|
|
458
|
+
outcome: tc.outcome,
|
|
459
|
+
errorMessage: tc.errorMessage ?? undefined,
|
|
460
|
+
})),
|
|
461
|
+
painSignals: snapshot.painEvents.map((pe) => ({
|
|
462
|
+
source: pe.source,
|
|
463
|
+
score: pe.score,
|
|
464
|
+
reason: pe.reason ?? undefined,
|
|
465
|
+
})),
|
|
466
|
+
gateBlocks: snapshot.gateBlocks.map((gb) => ({
|
|
467
|
+
toolName: gb.toolName,
|
|
468
|
+
reason: gb.reason,
|
|
469
|
+
})),
|
|
470
|
+
userCorrections: [],
|
|
471
|
+
planApprovals: [],
|
|
472
|
+
});
|
|
473
|
+
hasViolation = violationResult.violated;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
return {
|
|
477
|
+
sessionId: session.sessionId,
|
|
478
|
+
hasViolation,
|
|
479
|
+
violationSeverity: violationDensity,
|
|
480
|
+
failureCount: session.failureCount,
|
|
481
|
+
painEventCount: session.painEventCount,
|
|
482
|
+
gateBlockCount: session.gateBlockCount,
|
|
483
|
+
toolCallCount: session.toolCallCount,
|
|
484
|
+
};
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
// Filter to sessions with violations above threshold
|
|
488
|
+
const violating = violatingSessions.filter(
|
|
489
|
+
(s) => s.hasViolation && s.violationSeverity >= this.opts.minViolationDensity
|
|
490
|
+
);
|
|
491
|
+
diagnostics.violatingSessionCount = violating.length;
|
|
492
|
+
|
|
493
|
+
if (violating.length === 0) {
|
|
494
|
+
return {
|
|
495
|
+
decision: 'skip',
|
|
496
|
+
skipReason: 'no_violating_sessions',
|
|
497
|
+
diagnostics,
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// Sort by violation severity descending (most violating first)
|
|
502
|
+
violating.sort((a, b) => b.violationSeverity - a.violationSeverity);
|
|
503
|
+
const selectedSession = violating[0];
|
|
504
|
+
diagnostics.selectedSessionViolationDensity = selectedSession.violationSeverity;
|
|
505
|
+
|
|
506
|
+
return {
|
|
507
|
+
decision: 'selected',
|
|
508
|
+
selectedPrincipleId: selected.principleId,
|
|
509
|
+
selectedSessionId: selectedSession.sessionId,
|
|
510
|
+
diagnostics,
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// ---------------------------------------------------------------------------
|
|
516
|
+
// Convenience function
|
|
517
|
+
// ---------------------------------------------------------------------------
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Select a nocturnal target (principle + session) with default options.
|
|
521
|
+
*
|
|
522
|
+
* This is a convenience wrapper for the common case.
|
|
523
|
+
*/
|
|
524
|
+
export function selectNocturnalTarget(
|
|
525
|
+
workspaceDir: string,
|
|
526
|
+
stateDir: string,
|
|
527
|
+
extractor: NocturnalTrajectoryExtractor,
|
|
528
|
+
options: NocturnalTargetSelectorOptions = {}
|
|
529
|
+
): NocturnalSelectionResult {
|
|
530
|
+
const selector = new NocturnalTargetSelector(workspaceDir, stateDir, extractor, options);
|
|
531
|
+
return selector.select();
|
|
532
|
+
}
|