principles-disciple 1.72.0 → 1.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALL.md +1 -3
- package/openclaw.plugin.json +10 -5
- package/package.json +17 -19
- package/scripts/acceptance-test.mjs +16 -73
- package/scripts/sync-plugin.mjs +382 -77
- package/src/commands/archive-impl.ts +2 -1
- package/src/commands/capabilities.ts +2 -2
- package/src/commands/context.ts +2 -2
- package/src/commands/disable-impl.ts +2 -1
- package/src/commands/evolution-status.ts +16 -16
- package/src/commands/export.ts +12 -67
- package/src/commands/pain.ts +91 -1
- package/src/commands/principle-rollback.ts +2 -1
- package/src/commands/promote-impl.ts +7 -43
- package/src/commands/rollback-impl.ts +2 -1
- package/src/commands/rollback.ts +2 -1
- package/src/commands/samples.ts +2 -1
- package/src/commands/thinking-os.ts +2 -1
- package/src/config/errors.ts +18 -2
- package/src/constants/diagnostician.ts +2 -2
- package/src/constants/tools.ts +2 -1
- package/src/core/__tests__/focus-history.test.ts +210 -0
- package/src/core/config.ts +1 -1
- package/src/core/correction-cue-learner.ts +2 -136
- package/src/core/correction-types.ts +16 -88
- package/src/core/dictionary.ts +19 -20
- package/src/core/empathy-keyword-matcher.ts +17 -289
- package/src/core/empathy-types.ts +18 -229
- package/src/core/event-log.ts +29 -132
- package/src/core/evolution-reducer.ts +21 -2
- package/src/core/evolution-types.ts +76 -464
- package/src/core/file-store.ts +80 -0
- package/src/core/focus-history.ts +228 -955
- package/src/core/local-worker-routing.ts +34 -314
- package/src/core/merge-gate-audit.ts +0 -195
- package/src/core/migration.ts +0 -1
- package/src/core/pain-diagnostic-gate.ts +154 -0
- package/src/core/pain-signal.ts +21 -138
- package/src/core/pain.ts +15 -88
- package/src/core/path-resolver.ts +0 -1
- package/src/core/paths.ts +0 -1
- package/src/core/pd-task-reconciler.ts +26 -115
- package/src/core/pd-task-service.ts +9 -9
- package/src/core/pd-task-types.ts +23 -127
- package/src/core/principle-compiler/__tests__/compiler-replay-gate.test.ts +174 -0
- package/src/core/principle-compiler/code-validator.ts +15 -42
- package/src/core/principle-compiler/compiler.ts +100 -15
- package/src/core/principle-compiler/index.ts +5 -2
- package/src/core/principle-compiler/template-generator.ts +4 -104
- package/src/core/principle-injection.ts +10 -202
- package/src/core/principle-internalization/filesystem-lifecycle-datasource.ts +42 -0
- package/src/core/principle-internalization/lifecycle-read-model.ts +39 -242
- package/src/core/principle-internalization/principle-lifecycle-service.ts +12 -10
- package/src/core/principle-tree-ledger-adapter.ts +145 -0
- package/src/core/principle-tree-ledger.ts +8 -6
- package/src/core/reflection/reflection-context.ts +14 -109
- package/src/core/replay-engine.ts +8 -500
- package/src/core/rule-host-helpers.ts +5 -35
- package/src/core/rule-host-types.ts +10 -82
- package/src/core/rule-host.ts +6 -63
- package/src/core/runtime-v2-prompt-activation-reader.ts +231 -0
- package/src/core/session-tracker.ts +87 -101
- package/src/core/shadow-observation-registry.ts +19 -48
- package/src/core/trajectory.ts +3 -1
- package/src/core/workflow-funnel-loader.ts +62 -68
- package/src/core/workspace-context.ts +46 -0
- package/src/core/workspace-dir-service.ts +1 -1
- package/src/core/workspace-dir-validation.ts +18 -9
- package/src/hooks/AGENTS.md +1 -1
- package/src/hooks/gate-block-helper.ts +71 -64
- package/src/hooks/gate.ts +183 -31
- package/src/hooks/lifecycle.ts +30 -32
- package/src/hooks/llm.ts +60 -32
- package/src/hooks/pain.ts +297 -103
- package/src/hooks/prompt.ts +400 -440
- package/src/hooks/subagent.ts +2 -29
- package/src/i18n/commands.ts +2 -10
- package/src/index.ts +95 -85
- package/src/openclaw-sdk.ts +311 -0
- package/src/service/central-database.ts +8 -4
- package/src/service/evolution-queue-migration.ts +2 -1
- package/src/service/evolution-worker.ts +163 -1786
- package/src/service/internalization-trigger-adapter.ts +302 -0
- package/src/service/keyword-optimization-service.ts +4 -4
- package/src/service/monitoring-query-service.ts +1 -215
- package/src/service/queue-io.ts +60 -331
- package/src/service/runtime-summary-service.ts +59 -16
- package/src/service/subagent-workflow/index.ts +0 -41
- package/src/service/subagent-workflow/types.ts +9 -120
- package/src/service/subagent-workflow/workflow-store.ts +2 -119
- package/src/service/workflow-watchdog.ts +0 -43
- package/src/types/event-payload.ts +16 -74
- package/src/types/event-types.ts +38 -547
- package/src/types/hygiene-types.ts +7 -30
- package/src/types/principle-tree-schema.ts +20 -222
- package/src/types/queue.ts +15 -70
- package/src/types/runtime-summary.ts +5 -49
- package/src/utils/io.ts +8 -20
- package/src/utils/retry.ts +1 -1
- package/src/utils/shadow-fingerprint.ts +2 -2
- package/src/utils/workspace-resolver.ts +50 -0
- package/templates/langs/en/core/AGENTS.md +7 -7
- package/templates/langs/en/core/BOOT.md +1 -1
- package/templates/langs/en/core/HEARTBEAT.md +2 -2
- package/templates/langs/en/principles/THINKING_OS.md +3 -2
- package/templates/langs/en/skills/ai-sprint-orchestration/references/agent-registry.json +1 -72
- package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +6 -6
- package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +6 -6
- package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +2 -12
- package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +2 -12
- package/templates/langs/en/skills/ai-sprint-orchestration/scripts/run.mjs +51 -15
- package/templates/langs/en/skills/evolve-task/SKILL.md +3 -3
- package/templates/langs/en/skills/pd-cli-operator/SKILL.md +67 -0
- package/templates/langs/en/skills/pd-diagnostician/SKILL.md +1 -1
- package/templates/langs/en/skills/pd-mentor/SKILL.md +2 -3
- package/templates/langs/en/skills/pd-pain-signal/SKILL.md +17 -39
- package/templates/langs/en/skills/pd-runtime-v2/SKILL.md +61 -0
- package/templates/langs/zh/core/AGENTS.md +7 -7
- package/templates/langs/zh/core/BOOT.md +1 -1
- package/templates/langs/zh/core/HEARTBEAT.md +2 -2
- package/templates/langs/zh/principles/THINKING_OS.md +3 -2
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/agent-registry.json +1 -72
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +6 -6
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +6 -6
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/nocturnal-trinity-quality-enhancement.json +8 -8
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +2 -12
- package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +2 -12
- package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/run.mjs +51 -15
- package/templates/langs/zh/skills/ai-sprint-orchestration/test/run.test.mjs +21 -5
- package/templates/langs/zh/skills/evolve-task/SKILL.md +4 -4
- package/templates/langs/zh/skills/pd-cli-operator/SKILL.md +67 -0
- package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +1 -1
- package/templates/langs/zh/skills/pd-mentor/SKILL.md +2 -3
- package/templates/langs/zh/skills/pd-pain-signal/SKILL.md +17 -38
- package/templates/langs/zh/skills/pd-runtime-v2/SKILL.md +61 -0
- package/tests/build-artifacts.test.ts +1 -3
- package/tests/commands/evolution-status.test.ts +0 -118
- package/tests/core/bootstrap-rules.test.ts +1 -1
- package/tests/core/config.test.ts +1 -1
- package/tests/core/event-log.test.ts +35 -0
- package/tests/core/evolution-engine.test.ts +610 -0
- package/tests/core/file-store.test.ts +102 -0
- package/tests/core/focus-history.test.ts +203 -11
- package/tests/core/merge-gate-audit.test.ts +2 -169
- package/tests/core/migration.test.ts +7 -7
- package/tests/core/model-deployment-registry.test.ts +7 -1
- package/tests/core/model-training-registry.test.ts +19 -0
- package/tests/core/observability.test.ts +0 -1
- package/tests/core/pain-diagnostic-gate.test.ts +498 -0
- package/tests/core/pain.test.ts +0 -1
- package/tests/core/path-resolver.test.ts +1 -1
- package/tests/core/paths-refactor.test.ts +0 -22
- package/tests/core/principle-internalization/deprecated-readiness.test.ts +2 -2
- package/tests/core/principle-internalization/lifecycle-metrics.test.ts +2 -2
- package/tests/core/principle-internalization/{internalization-routing-policy.test.ts → lifecycle-routing-policy.test.ts} +6 -6
- package/tests/core/principle-internalization/lineage-source-retired.test.ts +56 -0
- package/tests/core/principle-internalization/principle-lifecycle-service.test.ts +1 -23
- package/tests/core/principle-tree-ledger-adapter.test.ts +253 -0
- package/tests/core/reflection-context.test.ts +0 -14
- package/tests/core/replay-engine.test.ts +127 -215
- package/tests/core/rule-host-helpers.test.ts +2 -2
- package/tests/core/rule-implementation-runtime.test.ts +0 -27
- package/tests/core/workflow-funnel-loader.test.ts +162 -0
- package/tests/core/workspace-context.test.ts +2 -2
- package/tests/core/workspace-dir-validation.test.ts +8 -1
- package/tests/core-anti-growth.test.ts +191 -0
- package/tests/hook-workspace-nextaction-contract.test.ts +42 -0
- package/tests/hooks/confirm-first-removal.test.ts +188 -0
- package/tests/hooks/gate-auto-correct-shadow.test.ts +310 -0
- package/tests/hooks/gate-auto-correct.test.ts +665 -0
- package/tests/hooks/gate-no-path-write-tool.test.ts +172 -0
- package/tests/hooks/gate-rule-host-pipeline.test.ts +2 -1
- package/tests/hooks/pain.test.ts +269 -12
- package/tests/hooks/prompt-characterization.test.ts +500 -0
- package/tests/hooks/prompt-size-guard.test.ts +32 -17
- package/tests/hooks/runtime-v2-prompt-activation.test.ts +869 -0
- package/tests/index.test.ts +94 -1
- package/tests/integration/auto-entry-gate.test.ts +248 -0
- package/tests/integration/internalization-trigger-guard.test.ts +69 -0
- package/tests/integration/m8-legacy-paths.test.ts +63 -0
- package/tests/integration/runtime-v2-pain-guard.test.ts +125 -0
- package/tests/plugin-config-resolution-cutover.test.ts +359 -0
- package/tests/runtime-v2-discovery-guard.test.ts +154 -0
- package/tests/service/central-database.test.ts +457 -0
- package/tests/service/evolution-worker.correction-observer.test.ts +173 -0
- package/tests/service/evolution-worker.timeout.test.ts +11 -129
- package/tests/service/internalization-trigger-adapter.test.ts +251 -0
- package/tests/service/monitoring-query-service.test.ts +1 -47
- package/tests/service/queue-io.test.ts +1 -62
- package/tests/service/runtime-summary-service.test.ts +3 -1
- package/tests/service/workflow-watchdog.test.ts +0 -91
- package/tests/utils/file-lock.test.ts +5 -3
- package/tests/utils/session-key.test.ts +52 -0
- package/tests/utils/subagent-probe.test.ts +48 -1
- package/vitest.config.ts +4 -11
- package/.planning/codebase/ARCHITECTURE.md +0 -157
- package/.planning/codebase/CONCERNS.md +0 -145
- package/.planning/codebase/CONVENTIONS.md +0 -148
- package/.planning/codebase/INTEGRATIONS.md +0 -81
- package/.planning/codebase/STACK.md +0 -87
- package/.planning/codebase/STRUCTURE.md +0 -193
- package/.planning/codebase/TESTING.md +0 -243
- package/.planning/phases/01-basic-visualization/01-GAP-CLOSURE-VERIFICATION.md +0 -113
- package/docs/COMMAND_REFERENCE.md +0 -76
- package/docs/COMMAND_REFERENCE_EN.md +0 -79
- package/scripts/build-web.mjs +0 -46
- package/scripts/diagnose-nocturnal.mjs +0 -537
- package/scripts/seed-nocturnal-scenarios.mjs +0 -384
- package/src/commands/nocturnal-review.ts +0 -322
- package/src/commands/nocturnal-rollout.ts +0 -790
- package/src/commands/nocturnal-train.ts +0 -986
- package/src/commands/pd-reflect.ts +0 -88
- package/src/core/adaptive-thresholds.ts +0 -478
- package/src/core/diagnostician-task-store.ts +0 -192
- package/src/core/nocturnal-arbiter.ts +0 -715
- package/src/core/nocturnal-artifact-lineage.ts +0 -116
- package/src/core/nocturnal-artificer.ts +0 -257
- package/src/core/nocturnal-candidate-scoring.ts +0 -530
- package/src/core/nocturnal-compliance.ts +0 -1146
- package/src/core/nocturnal-dataset.ts +0 -763
- package/src/core/nocturnal-executability.ts +0 -428
- package/src/core/nocturnal-export.ts +0 -499
- package/src/core/nocturnal-paths.ts +0 -240
- package/src/core/nocturnal-reasoning-deriver.ts +0 -343
- package/src/core/nocturnal-rule-implementation-validator.ts +0 -246
- package/src/core/nocturnal-snapshot-contract.ts +0 -99
- package/src/core/nocturnal-trajectory-extractor.ts +0 -512
- package/src/core/nocturnal-trinity-types.ts +0 -218
- package/src/core/nocturnal-trinity.ts +0 -2680
- package/src/core/principle-internalization/deprecated-readiness.ts +0 -93
- package/src/core/principle-internalization/internalization-routing-policy.ts +0 -208
- package/src/core/principle-internalization/lifecycle-metrics.ts +0 -152
- package/src/http/principles-console-route.ts +0 -709
- package/src/service/central-health-service.ts +0 -49
- package/src/service/central-overview-service.ts +0 -138
- package/src/service/control-ui-query-service.ts +0 -900
- package/src/service/cooldown-strategy.ts +0 -97
- package/src/service/evolution-pain-context.ts +0 -79
- package/src/service/evolution-query-service.ts +0 -407
- package/src/service/health-query-service.ts +0 -1038
- package/src/service/nocturnal-config.ts +0 -214
- package/src/service/nocturnal-runtime.ts +0 -734
- package/src/service/nocturnal-service.ts +0 -1605
- package/src/service/nocturnal-target-selector.ts +0 -545
- package/src/service/sleep-cycle.ts +0 -157
- package/src/service/startup-reconciler.ts +0 -112
- package/src/service/subagent-workflow/correction-observer-types.ts +0 -82
- package/src/service/subagent-workflow/correction-observer-workflow-manager.ts +0 -250
- package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +0 -1
- package/src/service/subagent-workflow/dynamic-timeout.ts +0 -30
- package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +0 -268
- package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +0 -795
- package/src/service/subagent-workflow/runtime-direct-driver.ts +0 -268
- package/src/service/subagent-workflow/workflow-manager-base.ts +0 -580
- package/src/tools/write-pain-flag.ts +0 -215
- package/templates/langs/en/skills/plan-script/SKILL.md +0 -32
- package/templates/langs/zh/skills/plan-script/SKILL.md +0 -32
- package/tests/commands/nocturnal-review.test.ts +0 -448
- package/tests/commands/nocturnal-train.test.ts +0 -97
- package/tests/commands/pd-reflect.test.ts +0 -49
- package/tests/core/adaptive-thresholds.test.ts +0 -261
- package/tests/core/nocturnal-arbiter.test.ts +0 -559
- package/tests/core/nocturnal-artifact-lineage.test.ts +0 -53
- package/tests/core/nocturnal-artificer.test.ts +0 -241
- package/tests/core/nocturnal-candidate-scoring.test.ts +0 -532
- package/tests/core/nocturnal-compliance-p-principles.test.ts +0 -133
- package/tests/core/nocturnal-compliance.test.ts +0 -646
- package/tests/core/nocturnal-dataset.test.ts +0 -892
- package/tests/core/nocturnal-e2e.test.ts +0 -234
- package/tests/core/nocturnal-executability.test.ts +0 -357
- package/tests/core/nocturnal-export.test.ts +0 -517
- package/tests/core/nocturnal-reasoning-deriver.test.ts +0 -372
- package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +0 -428
- package/tests/core/nocturnal-rule-implementation-validator.test.ts +0 -127
- package/tests/core/nocturnal-snapshot-contract.test.ts +0 -121
- package/tests/core/nocturnal-trajectory-extractor.test.ts +0 -634
- package/tests/core/nocturnal-trinity.test.ts +0 -2053
- package/tests/core/pain-auto-repair.test.ts +0 -96
- package/tests/core/pain-integration.test.ts +0 -510
- package/tests/fixtures/nocturnal-reviewed-subset.json +0 -183
- package/tests/http/principles-console-route.test.ts +0 -162
- package/tests/integration/chaos-resilience.test.ts +0 -348
- package/tests/integration/empathy-workflow-integration.test.ts +0 -626
- package/tests/integration/pain-diagnostician-loop.e2e.test.ts +0 -380
- package/tests/service/control-ui-query-service.test.ts +0 -121
- package/tests/service/cooldown-strategy.test.ts +0 -164
- package/tests/service/data-endpoints-regression.test.ts +0 -834
- package/tests/service/empathy-observer-workflow-manager.test.ts +0 -175
- package/tests/service/evolution-worker.nocturnal.test.ts +0 -601
- package/tests/service/nocturnal-runtime-hardening.test.ts +0 -118
- package/tests/service/nocturnal-runtime.test.ts +0 -473
- package/tests/service/nocturnal-service-code-candidate.test.ts +0 -330
- package/tests/service/nocturnal-target-selector.test.ts +0 -615
- package/tests/service/startup-reconciler.test.ts +0 -148
- package/tests/tools/write-pain-flag.test.ts +0 -358
- package/ui/src/App.tsx +0 -45
- package/ui/src/api.ts +0 -220
- package/ui/src/charts.tsx +0 -955
- package/ui/src/components/ErrorState.tsx +0 -6
- package/ui/src/components/Loading.tsx +0 -13
- package/ui/src/components/ProtectedRoute.tsx +0 -12
- package/ui/src/components/Shell.tsx +0 -91
- package/ui/src/components/WorkspaceConfig.tsx +0 -178
- package/ui/src/components/index.ts +0 -5
- package/ui/src/context/auth.tsx +0 -80
- package/ui/src/context/theme.tsx +0 -66
- package/ui/src/hooks/useAutoRefresh.ts +0 -39
- package/ui/src/i18n/ui.ts +0 -473
- package/ui/src/main.tsx +0 -16
- package/ui/src/pages/EvolutionPage.tsx +0 -333
- package/ui/src/pages/FeedbackPage.tsx +0 -138
- package/ui/src/pages/GateMonitorPage.tsx +0 -136
- package/ui/src/pages/LoginPage.tsx +0 -89
- package/ui/src/pages/OverviewPage.tsx +0 -599
- package/ui/src/pages/SamplesPage.tsx +0 -174
- package/ui/src/pages/ThinkingModelsPage.tsx +0 -702
- package/ui/src/styles.css +0 -2020
- package/ui/src/types.ts +0 -384
- package/ui/src/utils/format.ts +0 -15
|
@@ -6,27 +6,28 @@ import {
|
|
|
6
6
|
} from '../principle-tree-ledger.js';
|
|
7
7
|
import type { PrincipleValueMetrics } from '../../types/principle-tree-schema.js';
|
|
8
8
|
import { buildLifecycleReadModel, type LifecycleReadModel, type PrincipleLifecycleEvidence } from './lifecycle-read-model.js';
|
|
9
|
+
import { FilesystemLifecycleDatasource } from './filesystem-lifecycle-datasource.js';
|
|
9
10
|
import {
|
|
10
11
|
computePrincipleAdherence,
|
|
11
12
|
computeRuleMetrics,
|
|
12
13
|
type PrincipleAdherenceResult,
|
|
13
14
|
type RuleMetricResult,
|
|
14
|
-
} from '
|
|
15
|
+
} from '@principles/core/runtime-v2';
|
|
15
16
|
import {
|
|
16
17
|
assessDeprecatedReadiness,
|
|
17
18
|
type DeprecatedReadinessAssessment,
|
|
18
|
-
} from '
|
|
19
|
+
} from '@principles/core/runtime-v2';
|
|
19
20
|
import {
|
|
20
|
-
|
|
21
|
-
type
|
|
22
|
-
} from '
|
|
21
|
+
recommendLifecycleRoute,
|
|
22
|
+
type LifecycleRouteRecommendation,
|
|
23
|
+
} from '@principles/core/runtime-v2';
|
|
23
24
|
|
|
24
25
|
export interface RecomputedPrincipleLifecycle {
|
|
25
26
|
principleId: string;
|
|
26
27
|
ruleMetrics: Record<string, RuleMetricResult>;
|
|
27
28
|
adherence: PrincipleAdherenceResult;
|
|
28
29
|
deprecatedReadiness: DeprecatedReadinessAssessment;
|
|
29
|
-
routeRecommendation:
|
|
30
|
+
routeRecommendation: LifecycleRouteRecommendation;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
export interface PrincipleLifecycleAssessment {
|
|
@@ -35,7 +36,7 @@ export interface PrincipleLifecycleAssessment {
|
|
|
35
36
|
ruleMetrics: Record<string, RuleMetricResult>;
|
|
36
37
|
adherence: PrincipleAdherenceResult;
|
|
37
38
|
deprecatedReadiness: DeprecatedReadinessAssessment;
|
|
38
|
-
routeRecommendation:
|
|
39
|
+
routeRecommendation: LifecycleRouteRecommendation;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
|
|
@@ -83,7 +84,8 @@ export class PrincipleLifecycleService {
|
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
buildReadModel(): LifecycleReadModel {
|
|
86
|
-
|
|
87
|
+
const datasource = new FilesystemLifecycleDatasource(this.workspaceDir, this.stateDir);
|
|
88
|
+
return buildLifecycleReadModel(datasource);
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
listAssessments(readModel = this.buildReadModel()): PrincipleLifecycleAssessment[] {
|
|
@@ -100,7 +102,7 @@ export class PrincipleLifecycleService {
|
|
|
100
102
|
ruleMetrics,
|
|
101
103
|
adherence,
|
|
102
104
|
);
|
|
103
|
-
const routeRecommendation =
|
|
105
|
+
const routeRecommendation = recommendLifecycleRoute(
|
|
104
106
|
principleEvidence,
|
|
105
107
|
ruleMetrics,
|
|
106
108
|
adherence,
|
|
@@ -117,7 +119,7 @@ export class PrincipleLifecycleService {
|
|
|
117
119
|
});
|
|
118
120
|
}
|
|
119
121
|
|
|
120
|
-
listRouteRecommendations(readModel = this.buildReadModel()):
|
|
122
|
+
listRouteRecommendations(readModel = this.buildReadModel()): LifecycleRouteRecommendation[] {
|
|
121
123
|
return this.listAssessments(readModel).map((assessment) => assessment.routeRecommendation);
|
|
122
124
|
}
|
|
123
125
|
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { CandidateIntakeError, INTAKE_ERROR_CODES } from '@principles/core/runtime-v2';
|
|
2
|
+
import type { LedgerAdapter, LedgerPrincipleEntry } from '@principles/core/runtime-v2';
|
|
3
|
+
import { addPrincipleToLedger, loadLedger } from './principle-tree-ledger.js';
|
|
4
|
+
import type { LedgerPrinciple } from './principle-tree-ledger.js';
|
|
5
|
+
|
|
6
|
+
const VALID_EVALUABILITIES = ['deterministic', 'weak_heuristic', 'manual_only'] as const;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* PrincipleTreeLedgerAdapter — bridges 11-field LedgerPrincipleEntry to 18+ field LedgerPrinciple.
|
|
10
|
+
*
|
|
11
|
+
* This adapter maintains an in-memory idempotency map. Create once and reuse
|
|
12
|
+
* across calls within the same process lifetime. Do not create a new instance
|
|
13
|
+
* per intake call.
|
|
14
|
+
*/
|
|
15
|
+
export class PrincipleTreeLedgerAdapter implements LedgerAdapter {
|
|
16
|
+
#stateDir: string;
|
|
17
|
+
#entryMap = new Map<string, LedgerPrincipleEntry>();
|
|
18
|
+
|
|
19
|
+
constructor(opts: { stateDir: string }) {
|
|
20
|
+
this.#stateDir = opts.stateDir;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Write a probation entry to the ledger.
|
|
25
|
+
*
|
|
26
|
+
* Idempotency: if the same candidateId was already written, returns the
|
|
27
|
+
* existing entry without writing again.
|
|
28
|
+
*
|
|
29
|
+
* @throws CandidateIntakeError with code LEDGER_WRITE_FAILED on write failure.
|
|
30
|
+
*/
|
|
31
|
+
writeProbationEntry(entry: LedgerPrincipleEntry): LedgerPrincipleEntry {
|
|
32
|
+
const candidateId = this.#extractCandidateId(entry.sourceRef);
|
|
33
|
+
const existing = this.#entryMap.get(candidateId);
|
|
34
|
+
if (existing) return existing;
|
|
35
|
+
|
|
36
|
+
const ledgerPrinciple = this.#expandToLedgerPrinciple(entry, candidateId);
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
addPrincipleToLedger(this.#stateDir, ledgerPrinciple);
|
|
40
|
+
} catch (err) {
|
|
41
|
+
throw new CandidateIntakeError(
|
|
42
|
+
INTAKE_ERROR_CODES.LEDGER_WRITE_FAILED,
|
|
43
|
+
`Failed to write principle ${entry.id} to ledger: ${String(err)}`,
|
|
44
|
+
{ cause: err },
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
this.#entryMap.set(candidateId, entry);
|
|
49
|
+
return entry;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Check if a ledger entry already exists for a given candidate.
|
|
54
|
+
*
|
|
55
|
+
* Queries both the in-memory Map (fast path for same-process repeat calls)
|
|
56
|
+
* and the ledger file (for cross-process idempotency across CLI invocations).
|
|
57
|
+
*
|
|
58
|
+
* @returns The existing LedgerPrincipleEntry if found, null otherwise.
|
|
59
|
+
*/
|
|
60
|
+
existsForCandidate(candidateId: string): LedgerPrincipleEntry | null {
|
|
61
|
+
// Fast path: check in-memory Map (covers same-process repeat calls)
|
|
62
|
+
const cached = this.#entryMap.get(candidateId);
|
|
63
|
+
if (cached) return cached;
|
|
64
|
+
|
|
65
|
+
// Cross-process path: check ledger file by derivedFromPainIds
|
|
66
|
+
const ledger = loadLedger(this.#stateDir);
|
|
67
|
+
const found = Object.values(ledger.tree.principles).find((p) =>
|
|
68
|
+
p.derivedFromPainIds.includes(candidateId),
|
|
69
|
+
);
|
|
70
|
+
if (!found) return null;
|
|
71
|
+
|
|
72
|
+
// Reconstruct LedgerPrincipleEntry from LedgerPrinciple fields
|
|
73
|
+
// Note: sourceRef, artifactRef, taskRef are not stored in LedgerPrinciple,
|
|
74
|
+
// so we cannot fully reconstruct the original LedgerPrincipleEntry.
|
|
75
|
+
// Return minimal entry sufficient for idempotency signaling.
|
|
76
|
+
return {
|
|
77
|
+
id: found.id,
|
|
78
|
+
title: '',
|
|
79
|
+
status: 'probation' as const,
|
|
80
|
+
sourceRef: `candidate://${candidateId}`,
|
|
81
|
+
artifactRef: '',
|
|
82
|
+
taskRef: '',
|
|
83
|
+
text: found.text,
|
|
84
|
+
triggerPattern: found.triggerPattern,
|
|
85
|
+
action: found.action,
|
|
86
|
+
evaluability: 'weak_heuristic' as const,
|
|
87
|
+
createdAt: found.createdAt,
|
|
88
|
+
} as LedgerPrincipleEntry;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Extract candidateId from sourceRef by stripping the 'candidate://' prefix.
|
|
93
|
+
*
|
|
94
|
+
* @internal
|
|
95
|
+
*/
|
|
96
|
+
#extractCandidateId(sourceRef: string): string {
|
|
97
|
+
if (sourceRef.startsWith('candidate://')) {
|
|
98
|
+
return sourceRef.slice('candidate://'.length);
|
|
99
|
+
}
|
|
100
|
+
return sourceRef;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Expand an 11-field LedgerPrincipleEntry to an 18+ field LedgerPrinciple.
|
|
105
|
+
*
|
|
106
|
+
* Applies the field expansion table from CONTEXT.md:
|
|
107
|
+
* - status: 'probation' → 'candidate'
|
|
108
|
+
* - triggerPattern/action: pass through (empty string if absent)
|
|
109
|
+
* - All defaults applied per CONTEXT.md expansion table
|
|
110
|
+
* - sourceRef/artifactRef/taskRef are NOT written to LedgerPrinciple (not stored)
|
|
111
|
+
* - title is NOT written to LedgerPrinciple — intentionally excluded; title
|
|
112
|
+
* is available in LedgerPrincipleEntry but LedgerPrinciple has no title field
|
|
113
|
+
*
|
|
114
|
+
* @internal
|
|
115
|
+
*/
|
|
116
|
+
#expandToLedgerPrinciple(entry: LedgerPrincipleEntry, candidateId: string): LedgerPrinciple {
|
|
117
|
+
if (!VALID_EVALUABILITIES.includes(entry.evaluability as (typeof VALID_EVALUABILITIES)[number])) {
|
|
118
|
+
throw new CandidateIntakeError(
|
|
119
|
+
INTAKE_ERROR_CODES.INPUT_INVALID,
|
|
120
|
+
`Invalid evaluability value: ${entry.evaluability}. Must be one of: ${VALID_EVALUABILITIES.join(', ')}`,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const result: LedgerPrinciple = {
|
|
125
|
+
id: entry.id,
|
|
126
|
+
version: 1,
|
|
127
|
+
text: entry.text,
|
|
128
|
+
triggerPattern: entry.triggerPattern ?? '',
|
|
129
|
+
action: entry.action ?? '',
|
|
130
|
+
status: 'candidate',
|
|
131
|
+
evaluability: entry.evaluability,
|
|
132
|
+
priority: 'P1',
|
|
133
|
+
scope: 'general',
|
|
134
|
+
valueScore: 0,
|
|
135
|
+
adherenceRate: 0,
|
|
136
|
+
painPreventedCount: 0,
|
|
137
|
+
derivedFromPainIds: [candidateId],
|
|
138
|
+
ruleIds: [],
|
|
139
|
+
conflictsWithPrincipleIds: [],
|
|
140
|
+
createdAt: entry.createdAt,
|
|
141
|
+
updatedAt: entry.createdAt,
|
|
142
|
+
};
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -294,7 +294,11 @@ function readLedgerFromFile(filePath: string): HybridLedgerStore {
|
|
|
294
294
|
}
|
|
295
295
|
|
|
296
296
|
try {
|
|
297
|
-
const
|
|
297
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
298
|
+
if (!content || content.trim() === '') {
|
|
299
|
+
return { trainingStore: {}, tree: createEmptyTree() };
|
|
300
|
+
}
|
|
301
|
+
const parsed = JSON.parse(content) as unknown;
|
|
298
302
|
const raw = isRecord(parsed) ? parsed : {};
|
|
299
303
|
// #219: Handle both formats:
|
|
300
304
|
// - New format: { trainingStore: {...}, tree: {...} }
|
|
@@ -305,11 +309,9 @@ function readLedgerFromFile(filePath: string): HybridLedgerStore {
|
|
|
305
309
|
trainingStore: parseLegacyTrainingStore(trainingStoreRaw),
|
|
306
310
|
tree: parseTree(treeRaw),
|
|
307
311
|
};
|
|
308
|
-
} catch {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
tree: createEmptyTree(),
|
|
312
|
-
};
|
|
312
|
+
} catch (err) {
|
|
313
|
+
console.error(`[principle-tree-ledger] Failed to load ledger from ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
314
|
+
return { trainingStore: {}, tree: createEmptyTree() };
|
|
313
315
|
}
|
|
314
316
|
}
|
|
315
317
|
|
|
@@ -1,62 +1,20 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ReflectionContextCollector — Unified Pipeline Input
|
|
3
|
-
* ====================================================
|
|
4
|
-
*
|
|
5
|
-
* PURPOSE: Collect all grounding context for a principle into a single
|
|
6
|
-
* ReflectionContext object. This is the input to the nocturnal reflection
|
|
7
|
-
* pipeline: principle + painEvents + sessionSnapshot + lineage.
|
|
8
|
-
*
|
|
9
|
-
* DESIGN DECISIONS:
|
|
10
|
-
* - If a principle has no derivedFromPainIds, collect() returns null
|
|
11
|
-
* (nothing to ground code on).
|
|
12
|
-
* - painId -> sessionId resolution is a known gap. For now, we attempt
|
|
13
|
-
* best-effort lookup but return what we have with sessionSnapshot = null
|
|
14
|
-
* if we can't resolve.
|
|
15
|
-
*
|
|
16
|
-
* REUSES:
|
|
17
|
-
* - principle-tree-ledger: loadLedger() for principle lookup
|
|
18
|
-
* - nocturnal-trajectory-extractor: for session snapshots
|
|
19
|
-
* - trajectory: TrajectoryDatabase for pain event queries
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
1
|
import { loadLedger, type LedgerPrinciple } from '../principle-tree-ledger.js';
|
|
23
|
-
import {
|
|
24
|
-
NocturnalTrajectoryExtractor,
|
|
25
|
-
type NocturnalPainEvent,
|
|
26
|
-
type NocturnalSessionSnapshot,
|
|
27
|
-
} from '../nocturnal-trajectory-extractor.js';
|
|
28
2
|
import type { TrajectoryDatabase } from '../trajectory.js';
|
|
29
3
|
import type { Principle } from '../../types/principle-tree-schema.js';
|
|
30
4
|
|
|
31
|
-
// ---------------------------------------------------------------------------
|
|
32
|
-
// Types
|
|
33
|
-
// ---------------------------------------------------------------------------
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Unified reflection context for the nocturnal pipeline.
|
|
37
|
-
*/
|
|
38
5
|
export interface ReflectionContext {
|
|
39
|
-
/** The principle being reflected upon */
|
|
40
6
|
principle: Principle;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
};
|
|
7
|
+
painEvents: Array<{ source: string; score: number; severity: string | null; reason: string | null; createdAt: string }>;
|
|
8
|
+
sessionSnapshot: {
|
|
9
|
+
toolCalls: Array<{
|
|
10
|
+
toolName: string;
|
|
11
|
+
outcome: string;
|
|
12
|
+
filePath: string | null;
|
|
13
|
+
errorType: string | null;
|
|
14
|
+
}>;
|
|
15
|
+
} | null;
|
|
50
16
|
}
|
|
51
17
|
|
|
52
|
-
// ---------------------------------------------------------------------------
|
|
53
|
-
// Collector
|
|
54
|
-
// ---------------------------------------------------------------------------
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Collects ReflectionContext for principles by joining ledger data with
|
|
58
|
-
* trajectory data.
|
|
59
|
-
*/
|
|
60
18
|
export class ReflectionContextCollector {
|
|
61
19
|
private readonly stateDir: string;
|
|
62
20
|
private readonly trajectory: TrajectoryDatabase;
|
|
@@ -66,13 +24,6 @@ export class ReflectionContextCollector {
|
|
|
66
24
|
this.trajectory = trajectory;
|
|
67
25
|
}
|
|
68
26
|
|
|
69
|
-
/**
|
|
70
|
-
* Collect full reflection context for a single principle.
|
|
71
|
-
*
|
|
72
|
-
* Returns null if:
|
|
73
|
-
* - The principle is not found in the ledger
|
|
74
|
-
* - The principle has no derivedFromPainIds (nothing to ground on)
|
|
75
|
-
*/
|
|
76
27
|
collect(principleId: string): ReflectionContext | null {
|
|
77
28
|
const ledger = loadLedger(this.stateDir);
|
|
78
29
|
const principle = ledger.tree.principles[principleId];
|
|
@@ -88,11 +39,6 @@ export class ReflectionContextCollector {
|
|
|
88
39
|
return this.buildContext(principle);
|
|
89
40
|
}
|
|
90
41
|
|
|
91
|
-
/**
|
|
92
|
-
* Collect reflection contexts for multiple principles, optionally filtered.
|
|
93
|
-
*
|
|
94
|
-
* Skips principles without derivedFromPainIds.
|
|
95
|
-
*/
|
|
96
42
|
collectBatch(filter?: { status?: string }): ReflectionContext[] {
|
|
97
43
|
const ledger = loadLedger(this.stateDir);
|
|
98
44
|
const principles = Object.values(ledger.tree.principles);
|
|
@@ -100,12 +46,10 @@ export class ReflectionContextCollector {
|
|
|
100
46
|
const results: ReflectionContext[] = [];
|
|
101
47
|
|
|
102
48
|
for (const principle of principles) {
|
|
103
|
-
// Apply status filter if provided
|
|
104
49
|
if (filter?.status && principle.status !== filter.status) {
|
|
105
50
|
continue;
|
|
106
51
|
}
|
|
107
52
|
|
|
108
|
-
// Skip principles without pain grounding
|
|
109
53
|
if (!principle.derivedFromPainIds || principle.derivedFromPainIds.length === 0) {
|
|
110
54
|
continue;
|
|
111
55
|
}
|
|
@@ -119,62 +63,26 @@ export class ReflectionContextCollector {
|
|
|
119
63
|
return results;
|
|
120
64
|
}
|
|
121
65
|
|
|
122
|
-
// -----------------------------------------------------------------------
|
|
123
|
-
// Private helpers
|
|
124
|
-
// -----------------------------------------------------------------------
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Build a ReflectionContext from a principle.
|
|
128
|
-
*
|
|
129
|
-
* Attempts to resolve painIds to sessions via best-effort lookup.
|
|
130
|
-
* Since painId -> sessionId mapping is a known gap, we may return
|
|
131
|
-
* empty painEvents and null sessionSnapshot.
|
|
132
|
-
*/
|
|
133
66
|
private buildContext(principle: LedgerPrinciple): ReflectionContext {
|
|
134
67
|
const sourcePainIds = principle.derivedFromPainIds;
|
|
135
|
-
|
|
136
|
-
// Best-effort: try to find a session containing pain events related to this principle.
|
|
137
|
-
// The pain_events table uses auto-increment IDs, not the string painIds stored in
|
|
138
|
-
// derivedFromPainIds. This is the known gap — for now we attempt session resolution
|
|
139
|
-
// but gracefully handle the case where we can't match.
|
|
140
|
-
const { painEvents, sessionId } = this.resolvePainEvents(sourcePainIds);
|
|
141
|
-
|
|
142
|
-
// If we found a session, get the snapshot
|
|
143
|
-
let sessionSnapshot: NocturnalSessionSnapshot | null = null;
|
|
144
|
-
if (sessionId) {
|
|
145
|
-
const extractor = new NocturnalTrajectoryExtractor(this.trajectory);
|
|
146
|
-
sessionSnapshot = extractor.getNocturnalSessionSnapshot(sessionId);
|
|
147
|
-
}
|
|
68
|
+
const { painEvents } = this.resolvePainEvents(sourcePainIds);
|
|
148
69
|
|
|
149
70
|
return {
|
|
150
71
|
principle,
|
|
151
72
|
painEvents,
|
|
152
|
-
sessionSnapshot,
|
|
153
|
-
lineage: {
|
|
154
|
-
sourcePainIds,
|
|
155
|
-
sessionId,
|
|
156
|
-
},
|
|
73
|
+
sessionSnapshot: null,
|
|
157
74
|
};
|
|
158
75
|
}
|
|
159
76
|
|
|
160
|
-
/**
|
|
161
|
-
* Attempt to resolve painIds to actual pain events and a session.
|
|
162
|
-
*
|
|
163
|
-
* Two-phase strategy:
|
|
164
|
-
* 1. Exact ID match: sourcePainIds are stringified pain_events row IDs.
|
|
165
|
-
* If any match String(pe.id) exactly, use those and stop.
|
|
166
|
-
* 2. Heuristic fallback: substring match on reason/origin fields.
|
|
167
|
-
* Only used when no exact matches are found.
|
|
168
|
-
*/
|
|
169
77
|
private resolvePainEvents(sourcePainIds: string[]): {
|
|
170
|
-
painEvents:
|
|
78
|
+
painEvents: Array<{ source: string; score: number; severity: string | null; reason: string | null; createdAt: string }>;
|
|
171
79
|
sessionId: string | null;
|
|
172
80
|
} {
|
|
173
81
|
const sessions = this.trajectory.listRecentSessions({ limit: 100 });
|
|
174
82
|
const sourcePainIdSet = new Set(sourcePainIds);
|
|
175
83
|
|
|
176
|
-
const exactMatches:
|
|
177
|
-
const heuristicMatches:
|
|
84
|
+
const exactMatches: Array<{ source: string; score: number; severity: string | null; reason: string | null; createdAt: string }> = [];
|
|
85
|
+
const heuristicMatches: Array<{ source: string; score: number; severity: string | null; reason: string | null; createdAt: string }> = [];
|
|
178
86
|
let exactSessionId: string | null = null;
|
|
179
87
|
let heuristicSessionId: string | null = null;
|
|
180
88
|
|
|
@@ -182,7 +90,6 @@ export class ReflectionContextCollector {
|
|
|
182
90
|
const sessionPainEvents = this.trajectory.listPainEventsForSession(session.sessionId);
|
|
183
91
|
|
|
184
92
|
for (const pe of sessionPainEvents) {
|
|
185
|
-
// Phase 1: exact ID match
|
|
186
93
|
if (sourcePainIdSet.has(String(pe.id))) {
|
|
187
94
|
exactMatches.push({
|
|
188
95
|
source: pe.source,
|
|
@@ -197,7 +104,6 @@ export class ReflectionContextCollector {
|
|
|
197
104
|
continue;
|
|
198
105
|
}
|
|
199
106
|
|
|
200
|
-
// Phase 2: heuristic substring match on reason/origin only
|
|
201
107
|
const peText = [pe.reason, pe.origin].filter(Boolean);
|
|
202
108
|
const isMatch = sourcePainIds.some((painId) =>
|
|
203
109
|
peText.some((field) => field?.includes(painId)),
|
|
@@ -218,7 +124,6 @@ export class ReflectionContextCollector {
|
|
|
218
124
|
}
|
|
219
125
|
}
|
|
220
126
|
|
|
221
|
-
// Prefer exact matches over heuristic matches
|
|
222
127
|
if (exactMatches.length > 0) {
|
|
223
128
|
return { painEvents: exactMatches, sessionId: exactSessionId };
|
|
224
129
|
}
|