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,390 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nocturnal ORPO Export — Approved Dataset to Decision-Point JSONL
|
|
3
|
+
* =================================================================
|
|
4
|
+
*
|
|
5
|
+
* PURPOSE: Export approved nocturnal samples as ORPO-formatted decision-point
|
|
6
|
+
* training JSONL, strictly separated from legacy correction export.
|
|
7
|
+
*
|
|
8
|
+
* ARCHITECTURE:
|
|
9
|
+
* - Export output: .state/exports/orpo/{exportId}.jsonl
|
|
10
|
+
* - Export manifest: .state/exports/orpo/{exportId}-manifest.json
|
|
11
|
+
* - Legacy corrections: untouched, separate path
|
|
12
|
+
*
|
|
13
|
+
* ORPO FORMAT (each line):
|
|
14
|
+
* {
|
|
15
|
+
* sampleFingerprint: string,
|
|
16
|
+
* artifactId: string,
|
|
17
|
+
* sessionId: string,
|
|
18
|
+
* principleId: string,
|
|
19
|
+
* targetModelFamily: string,
|
|
20
|
+
* prompt: string, // badDecision (the wrong choice)
|
|
21
|
+
* chosen: string, // betterDecision (the right choice)
|
|
22
|
+
* rejected: string, // badDecision (for ORPO)
|
|
23
|
+
* rationale: string,
|
|
24
|
+
* datasetMetadata: {
|
|
25
|
+
* sampleFingerprint: string,
|
|
26
|
+
* artifactPath: string,
|
|
27
|
+
* createdAt: string,
|
|
28
|
+
* exportedAt: string,
|
|
29
|
+
* exportId: string,
|
|
30
|
+
* datasetFingerprint: string
|
|
31
|
+
* }
|
|
32
|
+
* }
|
|
33
|
+
*
|
|
34
|
+
* EXPORT GATING (fail-closed):
|
|
35
|
+
* - reviewStatus === 'approved_for_training'
|
|
36
|
+
* - targetModelFamily matches requested target (or any if not specified)
|
|
37
|
+
* - Lineage fields complete (sampleFingerprint, artifactId, sessionId, principleId)
|
|
38
|
+
* - Source artifact file exists and is approved
|
|
39
|
+
*
|
|
40
|
+
* DESIGN CONSTRAINTS:
|
|
41
|
+
* - No trainer invocation
|
|
42
|
+
* - No automatic training
|
|
43
|
+
* - No checkpoint deploy
|
|
44
|
+
* - Export is read-only from dataset perspective
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
import * as fs from 'fs';
|
|
48
|
+
import * as path from 'path';
|
|
49
|
+
import * as crypto from 'crypto';
|
|
50
|
+
import {
|
|
51
|
+
listDatasetRecords,
|
|
52
|
+
readDatasetArtifact,
|
|
53
|
+
type NocturnalDatasetRecord,
|
|
54
|
+
} from './nocturnal-dataset.js';
|
|
55
|
+
import { NocturnalPathResolver } from './nocturnal-paths.js';
|
|
56
|
+
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
// Types
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* A single ORPO training sample in JSONL format.
|
|
63
|
+
*/
|
|
64
|
+
export interface ORPOSample {
|
|
65
|
+
sampleFingerprint: string;
|
|
66
|
+
artifactId: string;
|
|
67
|
+
sessionId: string;
|
|
68
|
+
principleId: string;
|
|
69
|
+
targetModelFamily: string;
|
|
70
|
+
/** The suboptimal decision (what the agent did wrong) */
|
|
71
|
+
prompt: string;
|
|
72
|
+
/** The correct decision (what should have been done) */
|
|
73
|
+
chosen: string;
|
|
74
|
+
/** The suboptimal decision (same as prompt, for ORPO structure) */
|
|
75
|
+
rejected: string;
|
|
76
|
+
rationale: string;
|
|
77
|
+
datasetMetadata: {
|
|
78
|
+
sampleFingerprint: string;
|
|
79
|
+
artifactPath: string;
|
|
80
|
+
createdAt: string;
|
|
81
|
+
exportedAt: string;
|
|
82
|
+
exportId: string;
|
|
83
|
+
datasetFingerprint: string;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Export manifest containing metadata about the entire export.
|
|
89
|
+
*/
|
|
90
|
+
export interface ORPOExportManifest {
|
|
91
|
+
exportId: string;
|
|
92
|
+
createdAt: string;
|
|
93
|
+
sampleCount: number;
|
|
94
|
+
targetModelFamily: string;
|
|
95
|
+
/** SHA-256 of all sample fingerprints, sorted — for reproducibility */
|
|
96
|
+
datasetFingerprint: string;
|
|
97
|
+
exportPath: string;
|
|
98
|
+
manifestPath: string;
|
|
99
|
+
samples: Array<{
|
|
100
|
+
sampleFingerprint: string;
|
|
101
|
+
artifactId: string;
|
|
102
|
+
sessionId: string;
|
|
103
|
+
principleId: string;
|
|
104
|
+
}>;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Result of an export operation.
|
|
109
|
+
*/
|
|
110
|
+
export interface ExportResult {
|
|
111
|
+
success: boolean;
|
|
112
|
+
manifest?: ORPOExportManifest;
|
|
113
|
+
error?: string;
|
|
114
|
+
emptyReason?: 'no_approved_samples' | 'family_mismatch' | 'all_samples_missing_artifacts';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
// Dataset Fingerprint (for reproducibility)
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Compute a deterministic dataset fingerprint from a sorted list of sample fingerprints.
|
|
123
|
+
* This allows reproducible exports — same dataset always produces same fingerprint.
|
|
124
|
+
*/
|
|
125
|
+
function computeDatasetFingerprint(sampleFingerprints: string[]): string {
|
|
126
|
+
const sorted = [...sampleFingerprints].sort();
|
|
127
|
+
const combined = sorted.join('|');
|
|
128
|
+
return crypto.createHash('sha256').update(combined, 'utf8').digest('hex');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
// Individual Sample Serialization
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Serialize a single dataset record + artifact to ORPO JSONL line.
|
|
137
|
+
* Caller guarantees record.targetModelFamily is non-null.
|
|
138
|
+
*/
|
|
139
|
+
function serializeORPOSample(
|
|
140
|
+
record: NocturnalDatasetRecord,
|
|
141
|
+
artifact: ReturnType<typeof readDatasetArtifact>,
|
|
142
|
+
exportId: string,
|
|
143
|
+
datasetFingerprint: string
|
|
144
|
+
): ORPOSample {
|
|
145
|
+
const now = new Date().toISOString();
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
sampleFingerprint: record.sampleFingerprint,
|
|
149
|
+
artifactId: record.artifactId,
|
|
150
|
+
sessionId: record.sessionId,
|
|
151
|
+
principleId: record.principleId,
|
|
152
|
+
targetModelFamily: record.targetModelFamily as string, // validated non-null by caller
|
|
153
|
+
// For ORPO: prompt = badDecision, chosen = betterDecision, rejected = badDecision
|
|
154
|
+
// This teaches the model to prefer betterDecision over badDecision
|
|
155
|
+
prompt: artifact.badDecision,
|
|
156
|
+
chosen: artifact.betterDecision,
|
|
157
|
+
rejected: artifact.badDecision,
|
|
158
|
+
rationale: artifact.rationale,
|
|
159
|
+
datasetMetadata: {
|
|
160
|
+
sampleFingerprint: record.sampleFingerprint,
|
|
161
|
+
artifactPath: record.artifactPath,
|
|
162
|
+
createdAt: record.createdAt,
|
|
163
|
+
exportedAt: now,
|
|
164
|
+
exportId,
|
|
165
|
+
datasetFingerprint,
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// ---------------------------------------------------------------------------
|
|
171
|
+
// Core Export Function
|
|
172
|
+
// ---------------------------------------------------------------------------
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Export approved nocturnal samples as ORPO decision-point JSONL.
|
|
176
|
+
*
|
|
177
|
+
* @param workspaceDir - Workspace directory
|
|
178
|
+
* @param targetModelFamily - Specific model family to export, or undefined for all
|
|
179
|
+
* @param options - Additional export options
|
|
180
|
+
* @returns ExportResult
|
|
181
|
+
*/
|
|
182
|
+
export function exportORPOSamples(
|
|
183
|
+
workspaceDir: string,
|
|
184
|
+
targetModelFamily?: string | null,
|
|
185
|
+
_options: Record<string, never> = {}
|
|
186
|
+
): ExportResult {
|
|
187
|
+
const exportId = crypto.randomUUID();
|
|
188
|
+
const now = new Date().toISOString();
|
|
189
|
+
|
|
190
|
+
// Step 1: Collect eligible records
|
|
191
|
+
// Use listDatasetRecords directly to have full control over the family filter
|
|
192
|
+
// (listExportReadyRecords uses ?? which maps null→undefined, losing the null distinction)
|
|
193
|
+
const allApprovedRecords = listDatasetRecords(workspaceDir, {
|
|
194
|
+
reviewStatus: 'approved_for_training',
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
let eligibleRecords: typeof allApprovedRecords;
|
|
198
|
+
|
|
199
|
+
if (targetModelFamily !== undefined && targetModelFamily !== null) {
|
|
200
|
+
// Specific family: check if ANY records (regardless of status) have this family
|
|
201
|
+
const allRecords = listDatasetRecords(workspaceDir);
|
|
202
|
+
const hasAnyWithFamily = allRecords.some((r) => r.targetModelFamily === targetModelFamily);
|
|
203
|
+
if (!hasAnyWithFamily) {
|
|
204
|
+
// Family doesn't exist in any record
|
|
205
|
+
return {
|
|
206
|
+
success: false,
|
|
207
|
+
error: 'No samples found for the requested target model family',
|
|
208
|
+
emptyReason: 'family_mismatch',
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
// Family exists but none are approved
|
|
212
|
+
eligibleRecords = allApprovedRecords.filter((r) => r.targetModelFamily === targetModelFamily);
|
|
213
|
+
} else {
|
|
214
|
+
// All families
|
|
215
|
+
eligibleRecords = allApprovedRecords;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Step 2: Validate we have records
|
|
219
|
+
if (eligibleRecords.length === 0) {
|
|
220
|
+
return {
|
|
221
|
+
success: false,
|
|
222
|
+
error: 'No approved samples found for export',
|
|
223
|
+
emptyReason: 'no_approved_samples',
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Step 3: Verify lineage completeness and read artifacts
|
|
228
|
+
const orpoSamples: ORPOSample[] = [];
|
|
229
|
+
const failedFingerprints: string[] = [];
|
|
230
|
+
|
|
231
|
+
for (const record of eligibleRecords) {
|
|
232
|
+
// Enforce targetModelFamily binding — samples without a family cannot enter training
|
|
233
|
+
if (record.targetModelFamily === null) {
|
|
234
|
+
failedFingerprints.push(record.sampleFingerprint);
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Verify lineage completeness
|
|
239
|
+
if (!record.sampleFingerprint || !record.artifactId || !record.sessionId || !record.principleId) {
|
|
240
|
+
failedFingerprints.push(record.sampleFingerprint);
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Read artifact (throws on error — distinguishes read failure from missing artifact)
|
|
245
|
+
let artifact;
|
|
246
|
+
try {
|
|
247
|
+
artifact = readDatasetArtifact(workspaceDir, record.sampleFingerprint);
|
|
248
|
+
} catch {
|
|
249
|
+
failedFingerprints.push(record.sampleFingerprint);
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Serialize
|
|
254
|
+
orpoSamples.push(serializeORPOSample(record, artifact, exportId, ''));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Step 4: Fail if all samples failed validation
|
|
258
|
+
if (orpoSamples.length === 0) {
|
|
259
|
+
return {
|
|
260
|
+
success: false,
|
|
261
|
+
error: `All ${eligibleRecords.length} eligible samples failed validation (missing artifacts or lineage)`,
|
|
262
|
+
emptyReason: 'all_samples_missing_artifacts',
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Step 5: Compute dataset fingerprint for manifest
|
|
267
|
+
const datasetFingerprint = computeDatasetFingerprint(
|
|
268
|
+
orpoSamples.map((s) => s.sampleFingerprint)
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
// Step 6: Fill in dataset fingerprint in all samples
|
|
272
|
+
for (const sample of orpoSamples) {
|
|
273
|
+
sample.datasetMetadata.datasetFingerprint = datasetFingerprint;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Step 7: Write JSONL file
|
|
277
|
+
const exportsDir = NocturnalPathResolver.exportsDir(workspaceDir);
|
|
278
|
+
const jsonlPath = path.join(exportsDir, `${exportId}.jsonl`);
|
|
279
|
+
const lines = orpoSamples.map((s) => JSON.stringify(s)).join('\n') + '\n';
|
|
280
|
+
fs.writeFileSync(jsonlPath, lines, 'utf-8');
|
|
281
|
+
|
|
282
|
+
// Step 8: Write manifest
|
|
283
|
+
const manifest: ORPOExportManifest = {
|
|
284
|
+
exportId,
|
|
285
|
+
createdAt: now,
|
|
286
|
+
sampleCount: orpoSamples.length,
|
|
287
|
+
targetModelFamily: targetModelFamily ?? 'all',
|
|
288
|
+
datasetFingerprint,
|
|
289
|
+
exportPath: jsonlPath,
|
|
290
|
+
manifestPath: path.join(exportsDir, `${exportId}-manifest.json`),
|
|
291
|
+
samples: orpoSamples.map((s) => ({
|
|
292
|
+
sampleFingerprint: s.sampleFingerprint,
|
|
293
|
+
artifactId: s.artifactId,
|
|
294
|
+
sessionId: s.sessionId,
|
|
295
|
+
principleId: s.principleId,
|
|
296
|
+
})),
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
fs.writeFileSync(manifest.manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');
|
|
300
|
+
|
|
301
|
+
return {
|
|
302
|
+
success: true,
|
|
303
|
+
manifest,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Verify an existing export by re-computing its dataset fingerprint.
|
|
309
|
+
* Returns true if the export is intact and reproducible.
|
|
310
|
+
*/
|
|
311
|
+
export function verifyExportIntegrity(
|
|
312
|
+
workspaceDir: string,
|
|
313
|
+
exportId: string
|
|
314
|
+
): { valid: boolean; computedFingerprint: string; manifestFingerprint: string } | null {
|
|
315
|
+
const exportsDir = NocturnalPathResolver.exportsDir(workspaceDir);
|
|
316
|
+
const manifestPath = path.join(exportsDir, `${exportId}-manifest.json`);
|
|
317
|
+
|
|
318
|
+
if (!fs.existsSync(manifestPath)) {
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
try {
|
|
323
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) as ORPOExportManifest;
|
|
324
|
+
const computedFingerprint = computeDatasetFingerprint(
|
|
325
|
+
manifest.samples.map((s) => s.sampleFingerprint)
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
return {
|
|
329
|
+
valid: computedFingerprint === manifest.datasetFingerprint,
|
|
330
|
+
computedFingerprint,
|
|
331
|
+
manifestFingerprint: manifest.datasetFingerprint,
|
|
332
|
+
};
|
|
333
|
+
} catch {
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* List all exports in the exports directory.
|
|
340
|
+
*/
|
|
341
|
+
export function listExports(workspaceDir: string): ORPOExportManifest[] {
|
|
342
|
+
const exportsDir = NocturnalPathResolver.exportsDir(workspaceDir);
|
|
343
|
+
if (!fs.existsSync(exportsDir)) {
|
|
344
|
+
return [];
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
try {
|
|
348
|
+
const files = fs.readdirSync(exportsDir);
|
|
349
|
+
const manifests: ORPOExportManifest[] = [];
|
|
350
|
+
|
|
351
|
+
for (const file of files) {
|
|
352
|
+
if (!file.endsWith('-manifest.json')) continue;
|
|
353
|
+
try {
|
|
354
|
+
const manifest = JSON.parse(
|
|
355
|
+
fs.readFileSync(path.join(exportsDir, file), 'utf-8')
|
|
356
|
+
) as ORPOExportManifest;
|
|
357
|
+
manifests.push(manifest);
|
|
358
|
+
} catch {
|
|
359
|
+
// Skip malformed manifest
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
return manifests.sort(
|
|
364
|
+
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
|
|
365
|
+
);
|
|
366
|
+
} catch {
|
|
367
|
+
return [];
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Read an export manifest by ID.
|
|
373
|
+
*/
|
|
374
|
+
export function getExportManifest(
|
|
375
|
+
workspaceDir: string,
|
|
376
|
+
exportId: string
|
|
377
|
+
): ORPOExportManifest | null {
|
|
378
|
+
const exportsDir = NocturnalPathResolver.exportsDir(workspaceDir);
|
|
379
|
+
const manifestPath = path.join(exportsDir, `${exportId}-manifest.json`);
|
|
380
|
+
|
|
381
|
+
if (!fs.existsSync(manifestPath)) {
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
try {
|
|
386
|
+
return JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) as ORPOExportManifest;
|
|
387
|
+
} catch {
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
@@ -24,14 +24,18 @@
|
|
|
24
24
|
* import { NocturnalPathResolver, NOCTURNAL_DIRS, NOCTURNAL_FILES } from './nocturnal-paths.js';
|
|
25
25
|
* const sampleDir = NocturnalPathResolver.samplesDir(workspaceDir);
|
|
26
26
|
*/
|
|
27
|
+
|
|
27
28
|
import * as path from 'path';
|
|
28
29
|
import * as fs from 'fs';
|
|
30
|
+
|
|
29
31
|
// ---------------------------------------------------------------------------
|
|
30
32
|
// Directory Constants
|
|
31
33
|
// ---------------------------------------------------------------------------
|
|
34
|
+
|
|
32
35
|
export const NOCTURNAL_DIRS = {
|
|
33
36
|
/** Root directory for all nocturnal reflection artifacts */
|
|
34
37
|
ROOT: '.state/nocturnal',
|
|
38
|
+
|
|
35
39
|
/**
|
|
36
40
|
* Structured decision-point samples from nocturnal reflection.
|
|
37
41
|
* Each file is a JSON artifact containing:
|
|
@@ -41,28 +45,33 @@ export const NOCTURNAL_DIRS = {
|
|
|
41
45
|
* - arbiter approval status
|
|
42
46
|
*/
|
|
43
47
|
SAMPLES: '.state/nocturnal/samples',
|
|
48
|
+
|
|
44
49
|
/**
|
|
45
50
|
* Short-term operator-facing reflection memory.
|
|
46
51
|
* Written by nocturnal service, NOT injected into prompts directly.
|
|
47
52
|
* Consumed by operator on next session start.
|
|
48
53
|
*/
|
|
49
54
|
MEMORY: '.state/nocturnal/memory',
|
|
55
|
+
|
|
50
56
|
/**
|
|
51
57
|
* Nocturnal runtime bookkeeping (cooldowns, quotas).
|
|
52
58
|
* NOTE: nocturnal-runtime.json is written to stateDir directly
|
|
53
59
|
* (not under NOCTURNAL_DIRS.ROOT) for simpler migration.
|
|
54
60
|
*/
|
|
55
61
|
// RUNTIME is in {stateDir}/nocturnal-runtime.json (not here)
|
|
62
|
+
|
|
56
63
|
/**
|
|
57
64
|
* Approved training pairs ready for export.
|
|
58
65
|
* Immutable once written — never modified in place.
|
|
59
66
|
* Consumed by external trainer (not the plugin).
|
|
60
67
|
*/
|
|
61
68
|
EXPORTS: '.state/exports/orpo',
|
|
62
|
-
};
|
|
69
|
+
} as const;
|
|
70
|
+
|
|
63
71
|
// ---------------------------------------------------------------------------
|
|
64
72
|
// File Path Constants (within their respective directories)
|
|
65
73
|
// ---------------------------------------------------------------------------
|
|
74
|
+
|
|
66
75
|
export const NOCTURNAL_FILES = {
|
|
67
76
|
/**
|
|
68
77
|
* Arbiter review queue for pending samples.
|
|
@@ -70,20 +79,23 @@ export const NOCTURNAL_FILES = {
|
|
|
70
79
|
* Format: JSON array of sample refs pending approval.
|
|
71
80
|
*/
|
|
72
81
|
REVIEW_QUEUE: '.state/nocturnal/review-queue.json',
|
|
82
|
+
|
|
73
83
|
/**
|
|
74
84
|
* Lineage metadata for all samples.
|
|
75
85
|
* Written alongside each sample file for traceability.
|
|
76
86
|
*/
|
|
77
87
|
LINEAGE_INDEX: '.state/nocturnal/samples/lineage-index.json',
|
|
78
|
-
};
|
|
88
|
+
} as const;
|
|
89
|
+
|
|
79
90
|
// ---------------------------------------------------------------------------
|
|
80
91
|
// Path Resolution
|
|
81
92
|
// ---------------------------------------------------------------------------
|
|
93
|
+
|
|
82
94
|
/**
|
|
83
95
|
* Cross-platform path join for workspace-relative paths.
|
|
84
96
|
* Handles Windows vs POSIX differences.
|
|
85
97
|
*/
|
|
86
|
-
function joinWorkspacePath(workspaceDir, relativePath) {
|
|
98
|
+
function joinWorkspacePath(workspaceDir: string, relativePath: string): string {
|
|
87
99
|
const normalized = relativePath.replace(/\\/g, '/');
|
|
88
100
|
if (/^[A-Za-z]:/.test(workspaceDir)) {
|
|
89
101
|
// Windows
|
|
@@ -91,77 +103,89 @@ function joinWorkspacePath(workspaceDir, relativePath) {
|
|
|
91
103
|
}
|
|
92
104
|
return path.posix.join(workspaceDir, ...normalized.split('/'));
|
|
93
105
|
}
|
|
106
|
+
|
|
94
107
|
/**
|
|
95
108
|
* Resolves a nocturnal directory path within a workspace.
|
|
96
109
|
*/
|
|
97
|
-
export function resolveNocturnalDir(workspaceDir, dirKey) {
|
|
110
|
+
export function resolveNocturnalDir(workspaceDir: string, dirKey: keyof typeof NOCTURNAL_DIRS): string {
|
|
98
111
|
return joinWorkspacePath(workspaceDir, NOCTURNAL_DIRS[dirKey]);
|
|
99
112
|
}
|
|
113
|
+
|
|
100
114
|
/**
|
|
101
115
|
* Resolves a nocturnal file path within a workspace.
|
|
102
116
|
*/
|
|
103
|
-
export function resolveNocturnalFile(workspaceDir, fileKey) {
|
|
117
|
+
export function resolveNocturnalFile(workspaceDir: string, fileKey: keyof typeof NOCTURNAL_FILES): string {
|
|
104
118
|
return joinWorkspacePath(workspaceDir, NOCTURNAL_FILES[fileKey]);
|
|
105
119
|
}
|
|
120
|
+
|
|
106
121
|
// ---------------------------------------------------------------------------
|
|
107
122
|
// NocturnalPathResolver — Fluent API for common resolutions
|
|
108
123
|
// ---------------------------------------------------------------------------
|
|
124
|
+
|
|
109
125
|
export const NocturnalPathResolver = {
|
|
110
126
|
/**
|
|
111
127
|
* Returns the samples directory path.
|
|
112
128
|
* Creates the directory if it does not exist.
|
|
113
129
|
*/
|
|
114
|
-
samplesDir(workspaceDir) {
|
|
130
|
+
samplesDir(workspaceDir: string): string {
|
|
115
131
|
const dir = resolveNocturnalDir(workspaceDir, 'SAMPLES');
|
|
116
132
|
if (!fs.existsSync(dir)) {
|
|
117
133
|
fs.mkdirSync(dir, { recursive: true });
|
|
118
134
|
}
|
|
119
135
|
return dir;
|
|
120
136
|
},
|
|
137
|
+
|
|
121
138
|
/**
|
|
122
139
|
* Returns the memory directory path.
|
|
123
140
|
* Creates the directory if it does not exist.
|
|
124
141
|
*/
|
|
125
|
-
memoryDir(workspaceDir) {
|
|
142
|
+
memoryDir(workspaceDir: string): string {
|
|
126
143
|
const dir = resolveNocturnalDir(workspaceDir, 'MEMORY');
|
|
127
144
|
if (!fs.existsSync(dir)) {
|
|
128
145
|
fs.mkdirSync(dir, { recursive: true });
|
|
129
146
|
}
|
|
130
147
|
return dir;
|
|
131
148
|
},
|
|
149
|
+
|
|
132
150
|
/**
|
|
133
151
|
* Returns the exports directory path.
|
|
134
152
|
* Creates the directory if it does not exist.
|
|
135
153
|
*/
|
|
136
|
-
exportsDir(workspaceDir) {
|
|
154
|
+
exportsDir(workspaceDir: string): string {
|
|
137
155
|
const dir = resolveNocturnalDir(workspaceDir, 'EXPORTS');
|
|
138
156
|
if (!fs.existsSync(dir)) {
|
|
139
157
|
fs.mkdirSync(dir, { recursive: true });
|
|
140
158
|
}
|
|
141
159
|
return dir;
|
|
142
160
|
},
|
|
161
|
+
|
|
143
162
|
/**
|
|
144
163
|
* Returns the path for a named sample file.
|
|
145
164
|
* File is NOT created — caller decides when to write.
|
|
146
165
|
*/
|
|
147
|
-
samplePath(workspaceDir, sampleId) {
|
|
166
|
+
samplePath(workspaceDir: string, sampleId: string): string {
|
|
148
167
|
const dir = resolveNocturnalDir(workspaceDir, 'SAMPLES');
|
|
149
168
|
// Sanitize sampleId for filesystem
|
|
150
169
|
const safeId = sampleId.replace(/[/\\:]/g, '_');
|
|
151
170
|
return path.join(dir, `${safeId}.json`);
|
|
152
171
|
},
|
|
172
|
+
|
|
153
173
|
/**
|
|
154
174
|
* Returns the path for nocturnal reflection memory.
|
|
155
175
|
* This is the operator-facing summary written after each nocturnal run.
|
|
156
176
|
*/
|
|
157
|
-
reflectionMemoryPath(workspaceDir) {
|
|
158
|
-
return path.join(
|
|
177
|
+
reflectionMemoryPath(workspaceDir: string): string {
|
|
178
|
+
return path.join(
|
|
179
|
+
resolveNocturnalDir(workspaceDir, 'MEMORY'),
|
|
180
|
+
'reflection-memory.md'
|
|
181
|
+
);
|
|
159
182
|
},
|
|
183
|
+
|
|
160
184
|
/**
|
|
161
185
|
* Lists all sample files in the samples directory.
|
|
162
186
|
* Returns absolute paths sorted by modification time (newest first).
|
|
163
187
|
*/
|
|
164
|
-
listSamples(workspaceDir) {
|
|
188
|
+
listSamples(workspaceDir: string): string[] {
|
|
165
189
|
const dir = resolveNocturnalDir(workspaceDir, 'SAMPLES');
|
|
166
190
|
if (!fs.existsSync(dir)) {
|
|
167
191
|
return [];
|
|
@@ -171,42 +195,44 @@ export const NocturnalPathResolver = {
|
|
|
171
195
|
.filter(f => f.endsWith('.json'))
|
|
172
196
|
.map(f => path.join(dir, f))
|
|
173
197
|
.sort((a, b) => fs.statSync(b).mtime.getTime() - fs.statSync(a).mtime.getTime());
|
|
174
|
-
}
|
|
175
|
-
catch {
|
|
198
|
+
} catch {
|
|
176
199
|
return [];
|
|
177
200
|
}
|
|
178
201
|
},
|
|
202
|
+
|
|
179
203
|
/**
|
|
180
204
|
* Lists all approved sample files ready for export.
|
|
181
205
|
* Filters to samples with status === 'approved'.
|
|
182
206
|
*/
|
|
183
|
-
listApprovedSamples(workspaceDir) {
|
|
207
|
+
listApprovedSamples(workspaceDir: string): string[] {
|
|
184
208
|
return this.listSamples(workspaceDir).filter(samplePath => {
|
|
185
209
|
try {
|
|
186
210
|
const content = fs.readFileSync(samplePath, 'utf-8');
|
|
187
211
|
const sample = JSON.parse(content);
|
|
188
212
|
return sample.status === 'approved';
|
|
189
|
-
}
|
|
190
|
-
catch {
|
|
213
|
+
} catch {
|
|
191
214
|
return false;
|
|
192
215
|
}
|
|
193
216
|
});
|
|
194
217
|
},
|
|
195
|
-
};
|
|
218
|
+
} as const;
|
|
219
|
+
|
|
196
220
|
// ---------------------------------------------------------------------------
|
|
197
221
|
// Constants for documentation / external reference
|
|
198
222
|
// ---------------------------------------------------------------------------
|
|
223
|
+
|
|
199
224
|
/**
|
|
200
225
|
* Complete path map for reference.
|
|
201
226
|
* These mirror the keys in NOCTURNAL_DIRS and NOCTURNAL_FILES.
|
|
202
227
|
*/
|
|
203
|
-
export const NOCTURNAL_PATH_DESCRIPTIONS = {
|
|
204
|
-
'.state/nocturnal/samples/':
|
|
205
|
-
'.state/nocturnal/memory/':
|
|
206
|
-
'.state/exports/orpo/':
|
|
228
|
+
export const NOCTURNAL_PATH_DESCRIPTIONS: Record<string, string> = {
|
|
229
|
+
'.state/nocturnal/samples/': 'Structured decision-point JSON artifacts (not injected into prompts)',
|
|
230
|
+
'.state/nocturnal/memory/': 'Short-term operator-facing reflection memory (not prompt-injected)',
|
|
231
|
+
'.state/exports/orpo/': 'Approved training pairs, immutable after export',
|
|
207
232
|
'.state/nocturnal/review-queue.json': 'Pending sample review queue',
|
|
208
|
-
'memory/reflection-log.md':
|
|
233
|
+
'memory/reflection-log.md': 'Operator-facing human-readable lessons (INJECTED into prompts)',
|
|
209
234
|
};
|
|
235
|
+
|
|
210
236
|
/**
|
|
211
237
|
* IMPORTANT: memory/reflection-log.md is NOT a nocturnal artifact.
|
|
212
238
|
* It is the pre-existing operator-facing reflection log, defined in paths.ts.
|