principles-disciple 1.8.1 → 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 +4 -4
- package/package.json +11 -13
- 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} +175 -62
- 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} +160 -80
- 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} +235 -79
- 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/{dist/service/subagent-workflow/empathy-observer-workflow-manager.js → src/service/subagent-workflow/empathy-observer-workflow-manager.ts} +240 -117
- 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/{dist/service/subagent-workflow/types.d.ts → src/service/subagent-workflow/types.ts} +137 -18
- 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 -129
- 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 -101
- 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 -13
- 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 -52
- package/dist/hooks/progressive-trust-gate.js +0 -134
- package/dist/hooks/prompt.d.ts +0 -49
- package/dist/hooks/prompt.js +0 -905
- 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 -681
- 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 -88
- package/dist/service/empathy-observer-manager.js +0 -414
- 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 -975
- package/dist/service/health-query-service.d.ts +0 -170
- package/dist/service/health-query-service.js +0 -662
- 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/subagent-workflow/empathy-observer-workflow-manager.d.ts +0 -48
- package/dist/service/subagent-workflow/index.d.ts +0 -4
- package/dist/service/subagent-workflow/index.js +0 -3
- package/dist/service/subagent-workflow/runtime-direct-driver.d.ts +0 -77
- package/dist/service/subagent-workflow/runtime-direct-driver.js +0 -75
- package/dist/service/subagent-workflow/types.js +0 -11
- package/dist/service/subagent-workflow/workflow-store.d.ts +0 -26
- package/dist/service/subagent-workflow/workflow-store.js +0 -165
- 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,534 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shadow Observation Registry — Runtime Shadow Evidence for Promotion Gate
|
|
3
|
+
* =======================================================================
|
|
4
|
+
*
|
|
5
|
+
* PURPOSE: Track real-world runtime evidence from shadow deployments to inform
|
|
6
|
+
* promotion gate decisions. Real evidence replaces eval verdict proxies.
|
|
7
|
+
*
|
|
8
|
+
* ARCHITECTURE:
|
|
9
|
+
* - Shadow observations are recorded by the routing system when a checkpoint
|
|
10
|
+
* is routed in shadow mode
|
|
11
|
+
* - Each observation captures whether the routing decision was accepted,
|
|
12
|
+
* rejected, or escalated by the runtime
|
|
13
|
+
* - The promotion gate queries this registry to get real arbiter/executability
|
|
14
|
+
* reject rates instead of using eval verdict as a proxy
|
|
15
|
+
*
|
|
16
|
+
* SHADOW OBSERVATION LIFECYCLE:
|
|
17
|
+
* 1. Routing system routes task to shadow checkpoint (shadow_ready state)
|
|
18
|
+
* 2. Observation recorded: { checkpointId, taskFingerprint, routedAt }
|
|
19
|
+
* 3. Task completes or times out
|
|
20
|
+
* 4. Observation updated: { completedAt, accepted/rejected/escalated, failureSignals }
|
|
21
|
+
* 5. After sufficient observations, promotion gate can query real reject rates
|
|
22
|
+
*
|
|
23
|
+
* DATA RETENTION:
|
|
24
|
+
* - Observations are kept for 7 days by default
|
|
25
|
+
* - Can be queried by checkpointId, time window, or outcome
|
|
26
|
+
*
|
|
27
|
+
* DESIGN CONSTRAINTS:
|
|
28
|
+
* - Fail-closed: if no shadow evidence exists, fall back to eval proxies
|
|
29
|
+
* - Shadow evidence must be statistically significant (min sample size)
|
|
30
|
+
* - Observations are retained until cleanup removes expired entries
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import * as fs from 'fs';
|
|
34
|
+
import * as path from 'path';
|
|
35
|
+
import * as crypto from 'crypto';
|
|
36
|
+
import { withLock } from '../utils/file-lock.js';
|
|
37
|
+
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// Constants
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Registry file for shadow observations.
|
|
44
|
+
*/
|
|
45
|
+
const SHADOW_REGISTRY_FILE = 'shadow-registry.json';
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Default observation retention period in milliseconds.
|
|
49
|
+
* 7 days
|
|
50
|
+
*/
|
|
51
|
+
export const DEFAULT_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Minimum number of shadow observations required before trusting the evidence.
|
|
55
|
+
* Below this, we fall back to eval proxies.
|
|
56
|
+
*/
|
|
57
|
+
export const MIN_OBSERVATIONS_FOR_TRUST = 5;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Time window for computing recent reject rates.
|
|
61
|
+
* Only observations within this window are considered.
|
|
62
|
+
* 24 hours
|
|
63
|
+
*/
|
|
64
|
+
export const RECENT_WINDOW_MS = 24 * 60 * 60 * 1000;
|
|
65
|
+
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// Types
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Outcome of a shadow routing observation.
|
|
72
|
+
*/
|
|
73
|
+
export type ShadowOutcome = 'accepted' | 'rejected' | 'escalated';
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Runtime failure signals captured during shadow routing.
|
|
77
|
+
*/
|
|
78
|
+
export interface RuntimeFailureSignals {
|
|
79
|
+
/** Whether the task timed out */
|
|
80
|
+
timedOut: boolean;
|
|
81
|
+
|
|
82
|
+
/** Whether an exception was thrown */
|
|
83
|
+
threwException: boolean;
|
|
84
|
+
|
|
85
|
+
/** Whether the output was empty or invalid */
|
|
86
|
+
invalidOutput: boolean;
|
|
87
|
+
|
|
88
|
+
/** Whether the worker profile rejected the routing */
|
|
89
|
+
profileRejected: boolean;
|
|
90
|
+
|
|
91
|
+
/** Additional failure signals (free-form for extensibility) */
|
|
92
|
+
extra: Record<string, boolean>;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* A shadow observation — records a single shadow routing event.
|
|
97
|
+
*/
|
|
98
|
+
export interface ShadowObservation {
|
|
99
|
+
/** Unique identifier for this observation */
|
|
100
|
+
observationId: string;
|
|
101
|
+
|
|
102
|
+
/** Checkpoint being routed to in shadow mode */
|
|
103
|
+
checkpointId: string;
|
|
104
|
+
|
|
105
|
+
/** Worker profile this observation is for */
|
|
106
|
+
workerProfile: string;
|
|
107
|
+
|
|
108
|
+
/** Task fingerprint (hash of task input for deduplication) */
|
|
109
|
+
taskFingerprint: string;
|
|
110
|
+
|
|
111
|
+
/** ISO-8601 timestamp when routing decision was made */
|
|
112
|
+
routedAt: string;
|
|
113
|
+
|
|
114
|
+
/** ISO-8601 timestamp when task completed (null if still pending) */
|
|
115
|
+
completedAt?: string;
|
|
116
|
+
|
|
117
|
+
/** Outcome of the shadow routing */
|
|
118
|
+
outcome?: ShadowOutcome;
|
|
119
|
+
|
|
120
|
+
/** Runtime failure signals (null if still pending) */
|
|
121
|
+
failureSignals?: RuntimeFailureSignals;
|
|
122
|
+
|
|
123
|
+
/** Whether this observation was used in a promotion gate evaluation */
|
|
124
|
+
usedInGate?: boolean;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Computed statistics from shadow observations.
|
|
129
|
+
*/
|
|
130
|
+
export interface ShadowStats {
|
|
131
|
+
/** Checkpoint ID these stats are for */
|
|
132
|
+
checkpointId: string;
|
|
133
|
+
|
|
134
|
+
/** Total observations in the time window */
|
|
135
|
+
totalCount: number;
|
|
136
|
+
|
|
137
|
+
/** Count by outcome */
|
|
138
|
+
acceptedCount: number;
|
|
139
|
+
rejectedCount: number;
|
|
140
|
+
escalatedCount: number;
|
|
141
|
+
|
|
142
|
+
/** Computed rates */
|
|
143
|
+
rejectRate: number; // rejected / totalCount
|
|
144
|
+
escalationRate: number; // escalated / totalCount
|
|
145
|
+
acceptanceRate: number; // accepted / totalCount
|
|
146
|
+
|
|
147
|
+
/** Failure signal frequencies */
|
|
148
|
+
timedOutRate: number;
|
|
149
|
+
threwExceptionRate: number;
|
|
150
|
+
invalidOutputRate: number;
|
|
151
|
+
profileRejectedRate: number;
|
|
152
|
+
|
|
153
|
+
/** Whether this has enough data to trust */
|
|
154
|
+
isStatisticallySignificant: boolean;
|
|
155
|
+
|
|
156
|
+
/** Time window used for computation */
|
|
157
|
+
windowStart: string;
|
|
158
|
+
windowEnd: string;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* The complete shadow registry.
|
|
163
|
+
*/
|
|
164
|
+
export interface ShadowRegistry {
|
|
165
|
+
observations: ShadowObservation[];
|
|
166
|
+
|
|
167
|
+
/** Schema version for migration support */
|
|
168
|
+
version: number;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
// Registry Path
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
|
|
175
|
+
function getRegistryPath(stateDir: string): string {
|
|
176
|
+
return path.join(stateDir, SHADOW_REGISTRY_FILE);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Ensure the registry directory exists.
|
|
181
|
+
*/
|
|
182
|
+
function ensureRegistryDir(stateDir: string): void {
|
|
183
|
+
const registryPath = getRegistryPath(stateDir);
|
|
184
|
+
const dir = path.dirname(registryPath);
|
|
185
|
+
if (!fs.existsSync(dir)) {
|
|
186
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
// File Operations
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Read the registry from disk. Returns empty registry if missing.
|
|
196
|
+
*/
|
|
197
|
+
function readRegistry(stateDir: string): ShadowRegistry {
|
|
198
|
+
const registryPath = getRegistryPath(stateDir);
|
|
199
|
+
if (!fs.existsSync(registryPath)) {
|
|
200
|
+
return { observations: [], version: 1 };
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
const content = fs.readFileSync(registryPath, 'utf-8');
|
|
204
|
+
return JSON.parse(content) as ShadowRegistry;
|
|
205
|
+
} catch (err) {
|
|
206
|
+
console.warn(`[shadow-observation-registry] Registry corrupted at ${registryPath}, recovering with empty state: ${String(err)}`);
|
|
207
|
+
return { observations: [], version: 1 };
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Write the registry to disk atomically.
|
|
213
|
+
*/
|
|
214
|
+
function writeRegistry(stateDir: string, registry: ShadowRegistry): void {
|
|
215
|
+
ensureRegistryDir(stateDir);
|
|
216
|
+
const registryPath = getRegistryPath(stateDir);
|
|
217
|
+
const tmpPath = `${registryPath}.tmp`;
|
|
218
|
+
fs.writeFileSync(tmpPath, JSON.stringify(registry, null, 2), 'utf-8');
|
|
219
|
+
fs.renameSync(tmpPath, registryPath);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Execute a read-modify-write under an exclusive file lock.
|
|
224
|
+
*/
|
|
225
|
+
function withShadowRegistryLock<T>(
|
|
226
|
+
stateDir: string,
|
|
227
|
+
fn: (registry: ShadowRegistry) => T
|
|
228
|
+
): T {
|
|
229
|
+
const registryPath = getRegistryPath(stateDir);
|
|
230
|
+
return withLock(registryPath, () => {
|
|
231
|
+
const registry = readRegistry(stateDir);
|
|
232
|
+
return fn(registry);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// ---------------------------------------------------------------------------
|
|
237
|
+
// Observation Recording
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Parameters for recording a shadow routing observation.
|
|
242
|
+
*/
|
|
243
|
+
export interface RecordObservationParams {
|
|
244
|
+
/** Checkpoint being routed to in shadow mode */
|
|
245
|
+
checkpointId: string;
|
|
246
|
+
|
|
247
|
+
/** Worker profile */
|
|
248
|
+
workerProfile: string;
|
|
249
|
+
|
|
250
|
+
/** Task fingerprint for deduplication */
|
|
251
|
+
taskFingerprint: string;
|
|
252
|
+
|
|
253
|
+
/** ISO-8601 timestamp when routing decision was made */
|
|
254
|
+
routedAt?: string;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Record a new shadow observation (when task is routed to shadow checkpoint).
|
|
259
|
+
*
|
|
260
|
+
* @param stateDir - Workspace state directory
|
|
261
|
+
* @param params - Observation parameters
|
|
262
|
+
* @returns The created ShadowObservation
|
|
263
|
+
*/
|
|
264
|
+
export function recordShadowRouting(
|
|
265
|
+
stateDir: string,
|
|
266
|
+
params: RecordObservationParams
|
|
267
|
+
): ShadowObservation {
|
|
268
|
+
const observation: ShadowObservation = {
|
|
269
|
+
observationId: crypto.randomUUID(),
|
|
270
|
+
checkpointId: params.checkpointId,
|
|
271
|
+
workerProfile: params.workerProfile,
|
|
272
|
+
taskFingerprint: params.taskFingerprint,
|
|
273
|
+
routedAt: params.routedAt ?? new Date().toISOString(),
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
return withShadowRegistryLock(stateDir, (registry) => {
|
|
277
|
+
registry.observations.push(observation);
|
|
278
|
+
writeRegistry(stateDir, registry);
|
|
279
|
+
return observation;
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Parameters for completing a shadow observation.
|
|
285
|
+
*/
|
|
286
|
+
export interface CompleteObservationParams {
|
|
287
|
+
/** Observation ID to complete */
|
|
288
|
+
observationId: string;
|
|
289
|
+
|
|
290
|
+
/** Outcome of the shadow routing */
|
|
291
|
+
outcome: ShadowOutcome;
|
|
292
|
+
|
|
293
|
+
/** Runtime failure signals */
|
|
294
|
+
failureSignals?: RuntimeFailureSignals;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Complete a pending shadow observation (when task finishes).
|
|
299
|
+
*
|
|
300
|
+
* @param stateDir - Workspace state directory
|
|
301
|
+
* @param params - Completion parameters
|
|
302
|
+
* @returns The updated ShadowObservation, or null if not found
|
|
303
|
+
*/
|
|
304
|
+
export function completeShadowObservation(
|
|
305
|
+
stateDir: string,
|
|
306
|
+
params: CompleteObservationParams
|
|
307
|
+
): ShadowObservation | null {
|
|
308
|
+
return withShadowRegistryLock(stateDir, (registry) => {
|
|
309
|
+
const idx = registry.observations.findIndex(
|
|
310
|
+
(o) => o.observationId === params.observationId
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
if (idx === -1) {
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const observation = registry.observations[idx];
|
|
318
|
+
observation.completedAt = new Date().toISOString();
|
|
319
|
+
observation.outcome = params.outcome;
|
|
320
|
+
observation.failureSignals = params.failureSignals ?? {
|
|
321
|
+
timedOut: false,
|
|
322
|
+
threwException: false,
|
|
323
|
+
invalidOutput: false,
|
|
324
|
+
profileRejected: false,
|
|
325
|
+
extra: {},
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
writeRegistry(stateDir, registry);
|
|
329
|
+
return observation;
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Complete a shadow observation by task fingerprint (alternative lookup).
|
|
335
|
+
*
|
|
336
|
+
* @param stateDir - Workspace state directory
|
|
337
|
+
* @param taskFingerprint - Task fingerprint to look up
|
|
338
|
+
* @param outcome - Outcome of the shadow routing
|
|
339
|
+
* @param failureSignals - Runtime failure signals
|
|
340
|
+
* @returns The updated ShadowObservation, or null if not found
|
|
341
|
+
*/
|
|
342
|
+
export function completeShadowObservationByTask(
|
|
343
|
+
stateDir: string,
|
|
344
|
+
taskFingerprint: string,
|
|
345
|
+
outcome: ShadowOutcome,
|
|
346
|
+
failureSignals?: RuntimeFailureSignals
|
|
347
|
+
): ShadowObservation | null {
|
|
348
|
+
return withShadowRegistryLock(stateDir, (registry) => {
|
|
349
|
+
// Find the oldest pending observation for this task
|
|
350
|
+
const pendingObs = registry.observations
|
|
351
|
+
.filter((o) => o.taskFingerprint === taskFingerprint && !o.completedAt)
|
|
352
|
+
.sort((a, b) => a.routedAt.localeCompare(b.routedAt));
|
|
353
|
+
|
|
354
|
+
if (pendingObs.length === 0) {
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const observation = pendingObs[0];
|
|
359
|
+
observation.completedAt = new Date().toISOString();
|
|
360
|
+
observation.outcome = outcome;
|
|
361
|
+
observation.failureSignals = failureSignals ?? {
|
|
362
|
+
timedOut: false,
|
|
363
|
+
threwException: false,
|
|
364
|
+
invalidOutput: false,
|
|
365
|
+
profileRejected: false,
|
|
366
|
+
extra: {},
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
writeRegistry(stateDir, registry);
|
|
370
|
+
return observation;
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// ---------------------------------------------------------------------------
|
|
375
|
+
// Statistics Computation
|
|
376
|
+
// ---------------------------------------------------------------------------
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Parameters for computing shadow statistics.
|
|
380
|
+
*/
|
|
381
|
+
export interface ComputeShadowStatsParams {
|
|
382
|
+
/** Checkpoint ID to compute stats for */
|
|
383
|
+
checkpointId: string;
|
|
384
|
+
|
|
385
|
+
/** Time window in milliseconds (default: RECENT_WINDOW_MS) */
|
|
386
|
+
windowMs?: number;
|
|
387
|
+
|
|
388
|
+
/** Retention period in milliseconds (default: DEFAULT_RETENTION_MS) */
|
|
389
|
+
retentionMs?: number;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Compute shadow routing statistics for a checkpoint.
|
|
394
|
+
*
|
|
395
|
+
* @param stateDir - Workspace state directory
|
|
396
|
+
* @param params - Computation parameters
|
|
397
|
+
* @returns ShadowStats with computed rates, or null if not enough data
|
|
398
|
+
*/
|
|
399
|
+
export function computeShadowStats(
|
|
400
|
+
stateDir: string,
|
|
401
|
+
params: ComputeShadowStatsParams
|
|
402
|
+
): ShadowStats | null {
|
|
403
|
+
const {
|
|
404
|
+
checkpointId,
|
|
405
|
+
windowMs = RECENT_WINDOW_MS,
|
|
406
|
+
retentionMs = DEFAULT_RETENTION_MS,
|
|
407
|
+
} = params;
|
|
408
|
+
|
|
409
|
+
const now = Date.now();
|
|
410
|
+
const windowStart = new Date(now - windowMs).toISOString();
|
|
411
|
+
const windowEnd = new Date(now).toISOString();
|
|
412
|
+
|
|
413
|
+
return withShadowRegistryLock(stateDir, (registry) => {
|
|
414
|
+
// Filter observations:
|
|
415
|
+
// 1. For this checkpoint
|
|
416
|
+
// 2. Within the time window
|
|
417
|
+
// 3. Not expired (within retention period)
|
|
418
|
+
const cutoff = new Date(now - retentionMs).toISOString();
|
|
419
|
+
|
|
420
|
+
const relevantObs = registry.observations.filter((o) => {
|
|
421
|
+
if (o.checkpointId !== checkpointId) return false;
|
|
422
|
+
if (o.routedAt < cutoff) return false; // expired
|
|
423
|
+
if (o.routedAt < windowStart) return false; // outside window
|
|
424
|
+
if (!o.completedAt) return false; // still pending
|
|
425
|
+
return true;
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
const totalCount = relevantObs.length;
|
|
429
|
+
|
|
430
|
+
// Not enough data - fail closed (return null to use eval proxies)
|
|
431
|
+
if (totalCount < MIN_OBSERVATIONS_FOR_TRUST) {
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
const acceptedCount = relevantObs.filter((o) => o.outcome === 'accepted').length;
|
|
436
|
+
const rejectedCount = relevantObs.filter((o) => o.outcome === 'rejected').length;
|
|
437
|
+
const escalatedCount = relevantObs.filter((o) => o.outcome === 'escalated').length;
|
|
438
|
+
|
|
439
|
+
// Failure signal counts
|
|
440
|
+
const withTimedOut = relevantObs.filter((o) => o.failureSignals?.timedOut).length;
|
|
441
|
+
const withThrewException = relevantObs.filter((o) => o.failureSignals?.threwException).length;
|
|
442
|
+
const withInvalidOutput = relevantObs.filter((o) => o.failureSignals?.invalidOutput).length;
|
|
443
|
+
const withProfileRejected = relevantObs.filter((o) => o.failureSignals?.profileRejected).length;
|
|
444
|
+
|
|
445
|
+
const rejectRate = totalCount > 0 ? rejectedCount / totalCount : 0;
|
|
446
|
+
const escalationRate = totalCount > 0 ? escalatedCount / totalCount : 0;
|
|
447
|
+
const acceptanceRate = totalCount > 0 ? acceptedCount / totalCount : 0;
|
|
448
|
+
|
|
449
|
+
return {
|
|
450
|
+
checkpointId,
|
|
451
|
+
totalCount,
|
|
452
|
+
acceptedCount,
|
|
453
|
+
rejectedCount,
|
|
454
|
+
escalatedCount,
|
|
455
|
+
rejectRate: Math.round(rejectRate * 1000) / 1000,
|
|
456
|
+
escalationRate: Math.round(escalationRate * 1000) / 1000,
|
|
457
|
+
acceptanceRate: Math.round(acceptanceRate * 1000) / 1000,
|
|
458
|
+
timedOutRate: Math.round((withTimedOut / totalCount) * 1000) / 1000,
|
|
459
|
+
threwExceptionRate: Math.round((withThrewException / totalCount) * 1000) / 1000,
|
|
460
|
+
invalidOutputRate: Math.round((withInvalidOutput / totalCount) * 1000) / 1000,
|
|
461
|
+
profileRejectedRate: Math.round((withProfileRejected / totalCount) * 1000) / 1000,
|
|
462
|
+
isStatisticallySignificant: totalCount >= MIN_OBSERVATIONS_FOR_TRUST,
|
|
463
|
+
windowStart,
|
|
464
|
+
windowEnd,
|
|
465
|
+
};
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Query shadow observations for a checkpoint.
|
|
471
|
+
*
|
|
472
|
+
* @param stateDir - Workspace state directory
|
|
473
|
+
* @param checkpointId - Checkpoint ID to query
|
|
474
|
+
* @param limit - Maximum observations to return (default: 100)
|
|
475
|
+
* @returns Array of shadow observations
|
|
476
|
+
*/
|
|
477
|
+
export function queryShadowObservations(
|
|
478
|
+
stateDir: string,
|
|
479
|
+
checkpointId: string,
|
|
480
|
+
limit: number = 100
|
|
481
|
+
): ShadowObservation[] {
|
|
482
|
+
return withShadowRegistryLock(stateDir, (registry) => {
|
|
483
|
+
return registry.observations
|
|
484
|
+
.filter((o) => o.checkpointId === checkpointId)
|
|
485
|
+
.sort((a, b) => b.routedAt.localeCompare(a.routedAt)) // newest first
|
|
486
|
+
.slice(0, limit);
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Mark observations as used in a promotion gate evaluation.
|
|
492
|
+
*
|
|
493
|
+
* @param stateDir - Workspace state directory
|
|
494
|
+
* @param observationIds - IDs of observations to mark
|
|
495
|
+
*/
|
|
496
|
+
export function markObservationsUsedInGate(
|
|
497
|
+
stateDir: string,
|
|
498
|
+
observationIds: string[]
|
|
499
|
+
): void {
|
|
500
|
+
withShadowRegistryLock(stateDir, (registry) => {
|
|
501
|
+
for (const obs of registry.observations) {
|
|
502
|
+
if (observationIds.includes(obs.observationId)) {
|
|
503
|
+
obs.usedInGate = true;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
writeRegistry(stateDir, registry);
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Clean up expired observations (older than retention period).
|
|
512
|
+
*
|
|
513
|
+
* @param stateDir - Workspace state directory
|
|
514
|
+
* @param retentionMs - Retention period in milliseconds (default: DEFAULT_RETENTION_MS)
|
|
515
|
+
* @returns Number of observations removed
|
|
516
|
+
*/
|
|
517
|
+
export function cleanupExpiredObservations(
|
|
518
|
+
stateDir: string,
|
|
519
|
+
retentionMs: number = DEFAULT_RETENTION_MS
|
|
520
|
+
): number {
|
|
521
|
+
const cutoff = new Date(Date.now() - retentionMs).toISOString();
|
|
522
|
+
let removed = 0;
|
|
523
|
+
|
|
524
|
+
withShadowRegistryLock(stateDir, (registry) => {
|
|
525
|
+
const before = registry.observations.length;
|
|
526
|
+
registry.observations = registry.observations.filter(
|
|
527
|
+
(o) => o.routedAt >= cutoff
|
|
528
|
+
);
|
|
529
|
+
removed = before - registry.observations.length;
|
|
530
|
+
writeRegistry(stateDir, registry);
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
return removed;
|
|
534
|
+
}
|
|
@@ -1,30 +1,34 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { resolvePdPath } from './paths.js';
|
|
4
|
+
|
|
4
5
|
/**
|
|
5
6
|
* System Logger for Principles Disciple
|
|
6
7
|
* Writes critical evolutionary events to the project's memory/logs/SYSTEM.log
|
|
7
8
|
* Uses asynchronous writing to avoid blocking the Node.js event loop.
|
|
8
9
|
*/
|
|
9
10
|
export const SystemLogger = {
|
|
10
|
-
log(workspaceDir, eventType, message) {
|
|
11
|
-
if (!workspaceDir)
|
|
12
|
-
|
|
11
|
+
log(workspaceDir: string | undefined, eventType: string, message: string): void {
|
|
12
|
+
if (!workspaceDir) return;
|
|
13
|
+
|
|
13
14
|
try {
|
|
14
15
|
const logFile = resolvePdPath(workspaceDir, 'SYSTEM_LOG');
|
|
15
16
|
const logDir = path.dirname(logFile);
|
|
17
|
+
|
|
16
18
|
if (!fs.existsSync(logDir)) {
|
|
17
19
|
fs.mkdirSync(logDir, { recursive: true });
|
|
18
20
|
}
|
|
21
|
+
|
|
19
22
|
const timestamp = new Date().toISOString();
|
|
23
|
+
|
|
20
24
|
// Format: [YYYY-MM-DDTHH:mm:ss.sssZ] [EVENT_TYPE] Message
|
|
21
25
|
const logEntry = `[${timestamp}] [${eventType.padEnd(15)}] ${message}\n`;
|
|
26
|
+
|
|
22
27
|
// Use fire-and-forget async append to prevent blocking
|
|
23
28
|
fs.appendFile(logFile, logEntry, 'utf8', (err) => {
|
|
24
29
|
// Silently drop errors (e.g. disk full) to not crash the gateway
|
|
25
30
|
});
|
|
26
|
-
}
|
|
27
|
-
catch (e) {
|
|
31
|
+
} catch (e) {
|
|
28
32
|
// Silently fail if we can't setup the log
|
|
29
33
|
}
|
|
30
34
|
}
|