@principles/pd-cli 1.152.12 → 1.152.13
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/package.json +13 -7
- package/CHANGELOG.md +0 -23
- package/dist/commands/__tests__/intent-flag-wiring.test.d.ts +0 -9
- package/dist/commands/__tests__/intent-flag-wiring.test.d.ts.map +0 -1
- package/dist/commands/__tests__/intent-flag-wiring.test.js +0 -237
- package/dist/commands/__tests__/intent-flag-wiring.test.js.map +0 -1
- package/dist/commands/__tests__/legacy-cleanup.test.d.ts +0 -18
- package/dist/commands/__tests__/legacy-cleanup.test.d.ts.map +0 -1
- package/dist/commands/__tests__/legacy-cleanup.test.js +0 -467
- package/dist/commands/__tests__/legacy-cleanup.test.js.map +0 -1
- package/dist/commands/__tests__/mvp-smoke.test.d.ts +0 -15
- package/dist/commands/__tests__/mvp-smoke.test.d.ts.map +0 -1
- package/dist/commands/__tests__/mvp-smoke.test.js +0 -262
- package/dist/commands/__tests__/mvp-smoke.test.js.map +0 -1
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.d.ts +0 -2
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.d.ts.map +0 -1
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.js +0 -60
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.js.map +0 -1
- package/dist/commands/__tests__/rulecode-flag-wiring.test.d.ts +0 -21
- package/dist/commands/__tests__/rulecode-flag-wiring.test.d.ts.map +0 -1
- package/dist/commands/__tests__/rulecode-flag-wiring.test.js +0 -186
- package/dist/commands/__tests__/rulecode-flag-wiring.test.js.map +0 -1
- package/dist/commands/__tests__/rulecode-handler.test.d.ts +0 -16
- package/dist/commands/__tests__/rulecode-handler.test.d.ts.map +0 -1
- package/dist/commands/__tests__/rulecode-handler.test.js +0 -285
- package/dist/commands/__tests__/rulecode-handler.test.js.map +0 -1
- package/dist/commands/__tests__/run-rulehost-flag-wiring.test.d.ts +0 -24
- package/dist/commands/__tests__/run-rulehost-flag-wiring.test.d.ts.map +0 -1
- package/dist/commands/__tests__/run-rulehost-flag-wiring.test.js +0 -232
- package/dist/commands/__tests__/run-rulehost-flag-wiring.test.js.map +0 -1
- package/dist/commands/__tests__/runtime-activation-nextaction.test.d.ts +0 -15
- package/dist/commands/__tests__/runtime-activation-nextaction.test.d.ts.map +0 -1
- package/dist/commands/__tests__/runtime-activation-nextaction.test.js +0 -73
- package/dist/commands/__tests__/runtime-activation-nextaction.test.js.map +0 -1
- package/dist/commands/__tests__/runtime-probe-config.test.d.ts +0 -20
- package/dist/commands/__tests__/runtime-probe-config.test.d.ts.map +0 -1
- package/dist/commands/__tests__/runtime-probe-config.test.js +0 -389
- package/dist/commands/__tests__/runtime-probe-config.test.js.map +0 -1
- package/dist/commands/__tests__/telemetry-flag-wiring.test.d.ts +0 -9
- package/dist/commands/__tests__/telemetry-flag-wiring.test.d.ts.map +0 -1
- package/dist/commands/__tests__/telemetry-flag-wiring.test.js +0 -76
- package/dist/commands/__tests__/telemetry-flag-wiring.test.js.map +0 -1
- package/dist/commands/__tests__/version.test.d.ts +0 -2
- package/dist/commands/__tests__/version.test.d.ts.map +0 -1
- package/dist/commands/__tests__/version.test.js +0 -238
- package/dist/commands/__tests__/version.test.js.map +0 -1
- package/dist/commands/runtime-uat.guard.test.d.ts +0 -2
- package/dist/commands/runtime-uat.guard.test.d.ts.map +0 -1
- package/dist/commands/runtime-uat.guard.test.js +0 -153
- package/dist/commands/runtime-uat.guard.test.js.map +0 -1
- package/dist/services/__tests__/cli-output.test.d.ts +0 -18
- package/dist/services/__tests__/cli-output.test.d.ts.map +0 -1
- package/dist/services/__tests__/cli-output.test.js +0 -103
- package/dist/services/__tests__/cli-output.test.js.map +0 -1
- package/dist/services/__tests__/evaluator-runner-deps.test.d.ts +0 -2
- package/dist/services/__tests__/evaluator-runner-deps.test.d.ts.map +0 -1
- package/dist/services/__tests__/evaluator-runner-deps.test.js +0 -343
- package/dist/services/__tests__/evaluator-runner-deps.test.js.map +0 -1
- package/dist/services/__tests__/rulehost-readiness.test.d.ts +0 -2
- package/dist/services/__tests__/rulehost-readiness.test.d.ts.map +0 -1
- package/dist/services/__tests__/rulehost-readiness.test.js +0 -311
- package/dist/services/__tests__/rulehost-readiness.test.js.map +0 -1
- package/dist/services/__tests__/runtime-adapter-resolver.test.d.ts +0 -18
- package/dist/services/__tests__/runtime-adapter-resolver.test.d.ts.map +0 -1
- package/dist/services/__tests__/runtime-adapter-resolver.test.js +0 -673
- package/dist/services/__tests__/runtime-adapter-resolver.test.js.map +0 -1
- package/dist/utils/production-workspace-guard.test.d.ts +0 -2
- package/dist/utils/production-workspace-guard.test.d.ts.map +0 -1
- package/dist/utils/production-workspace-guard.test.js +0 -137
- package/dist/utils/production-workspace-guard.test.js.map +0 -1
- package/scripts/llm-dogfood.ts +0 -456
- package/scripts/migrate-illegal-expected-decision.ts +0 -252
- package/src/commands/__tests__/intent-flag-wiring.test.ts +0 -282
- package/src/commands/__tests__/legacy-cleanup.test.ts +0 -602
- package/src/commands/__tests__/mvp-smoke.test.ts +0 -300
- package/src/commands/__tests__/pain-retry-maxTokens-flag.test.ts +0 -73
- package/src/commands/__tests__/rulecode-flag-wiring.test.ts +0 -237
- package/src/commands/__tests__/rulecode-handler.test.ts +0 -369
- package/src/commands/__tests__/run-rulehost-flag-wiring.test.ts +0 -292
- package/src/commands/__tests__/runtime-activation-nextaction.test.ts +0 -81
- package/src/commands/__tests__/runtime-probe-config.test.ts +0 -432
- package/src/commands/__tests__/telemetry-flag-wiring.test.ts +0 -84
- package/src/commands/__tests__/version.test.ts +0 -251
- package/src/commands/admission-gate.ts +0 -30
- package/src/commands/artifact.ts +0 -82
- package/src/commands/build-trajectory-evidence.ts +0 -298
- package/src/commands/candidate.ts +0 -1250
- package/src/commands/codex-ingest-catchup.ts +0 -114
- package/src/commands/codex-ingest-quarantine.ts +0 -127
- package/src/commands/codex-reconcile.ts +0 -84
- package/src/commands/codex-setup.ts +0 -476
- package/src/commands/codex-worker.ts +0 -185
- package/src/commands/command-helpers.ts +0 -24
- package/src/commands/config-doctor.ts +0 -193
- package/src/commands/console.ts +0 -797
- package/src/commands/context.ts +0 -72
- package/src/commands/demo-story-a.ts +0 -241
- package/src/commands/diagnose.ts +0 -756
- package/src/commands/errors-list.ts +0 -441
- package/src/commands/evolution-tasks-list.ts +0 -48
- package/src/commands/evolution-tasks-show.ts +0 -62
- package/src/commands/flow.ts +0 -60
- package/src/commands/health-codex.ts +0 -576
- package/src/commands/health.ts +0 -315
- package/src/commands/history.ts +0 -63
- package/src/commands/intent.ts +0 -457
- package/src/commands/legacy-cleanup.ts +0 -531
- package/src/commands/legacy-import.ts +0 -104
- package/src/commands/mvp-smoke.ts +0 -160
- package/src/commands/pain-evidence.ts +0 -226
- package/src/commands/pain-list.ts +0 -239
- package/src/commands/pain-record.ts +0 -612
- package/src/commands/pain-retry.ts +0 -916
- package/src/commands/principles-stats.ts +0 -700
- package/src/commands/proven-channel-baseline.ts +0 -115
- package/src/commands/quality-scorecard.ts +0 -272
- package/src/commands/remediation-output.ts +0 -66
- package/src/commands/rulecode.ts +0 -465
- package/src/commands/run.ts +0 -89
- package/src/commands/runtime-activation.ts +0 -1629
- package/src/commands/runtime-artifact-repair.ts +0 -524
- package/src/commands/runtime-canary.ts +0 -395
- package/src/commands/runtime-compatibility-scan.ts +0 -105
- package/src/commands/runtime-diagnostics-export.ts +0 -229
- package/src/commands/runtime-features.ts +0 -153
- package/src/commands/runtime-gfi-snapshot.ts +0 -135
- package/src/commands/runtime-health-snapshot.ts +0 -108
- package/src/commands/runtime-init.ts +0 -429
- package/src/commands/runtime-internalization-enqueue-successors.ts +0 -530
- package/src/commands/runtime-internalization-integrity-repair.ts +0 -79
- package/src/commands/runtime-internalization-integrity.ts +0 -107
- package/src/commands/runtime-internalization-queue.ts +0 -135
- package/src/commands/runtime-internalization-retry.ts +0 -191
- package/src/commands/runtime-internalization-run-once.ts +0 -791
- package/src/commands/runtime-internalization-run-rulehost.ts +0 -749
- package/src/commands/runtime-internalization-wake-once.ts +0 -87
- package/src/commands/runtime-pain-flood-simulation.ts +0 -121
- package/src/commands/runtime-pruning.ts +0 -438
- package/src/commands/runtime-recovery-failed-tasks.ts +0 -258
- package/src/commands/runtime-recovery.ts +0 -109
- package/src/commands/runtime-synthetic-baseline.ts +0 -70
- package/src/commands/runtime-uat.guard.test.ts +0 -175
- package/src/commands/runtime-uat.ts +0 -380
- package/src/commands/runtime.ts +0 -473
- package/src/commands/samples-list.ts +0 -39
- package/src/commands/samples-review.ts +0 -36
- package/src/commands/task.ts +0 -271
- package/src/commands/telemetry.ts +0 -349
- package/src/commands/trace.ts +0 -174
- package/src/commands/trajectory-db-unavailable.ts +0 -19
- package/src/commands/trajectory.ts +0 -64
- package/src/commands/version.ts +0 -49
- package/src/config-reader.ts +0 -122
- package/src/index.ts +0 -1276
- package/src/legacy/legacy-import.ts +0 -179
- package/src/legacy/session-history-import.ts +0 -203
- package/src/resolve-workspace.ts +0 -106
- package/src/services/__tests__/cli-output.test.ts +0 -130
- package/src/services/__tests__/evaluator-runner-deps.test.ts +0 -382
- package/src/services/__tests__/rulehost-readiness.test.ts +0 -363
- package/src/services/__tests__/runtime-adapter-resolver.test.ts +0 -793
- package/src/services/cli-output.ts +0 -95
- package/src/services/config-doctor.ts +0 -697
- package/src/services/console-launcher.ts +0 -537
- package/src/services/demo-rule-compiler.ts +0 -40
- package/src/services/demo-story-a-runner.ts +0 -471
- package/src/services/mainline-snapshot-assembler.ts +0 -579
- package/src/services/pain-flood-simulation-runner.ts +0 -462
- package/src/services/pd-config-loader.ts +0 -433
- package/src/services/proven-channel-baseline-runner.ts +0 -157
- package/src/services/quality-scorecard/data-extractor.ts +0 -150
- package/src/services/quality-scorecard/local-evaluator.ts +0 -142
- package/src/services/quality-scorecard/strong-model-gate.ts +0 -202
- package/src/services/resolve-runtime-from-pd-config.ts +0 -230
- package/src/services/rulehost-pipeline-runner.ts +0 -1214
- package/src/services/rulehost-readiness.ts +0 -326
- package/src/services/runtime-adapter-resolver.ts +0 -364
- package/src/services/synthetic-baseline-runner.ts +0 -400
- package/src/services/version-report.ts +0 -253
- package/src/services/workspace-tool-semantics.ts +0 -26
- package/src/utils/path-security.ts +0 -96
- package/src/utils/production-workspace-guard.test.ts +0 -157
- package/src/utils/production-workspace-guard.ts +0 -210
- package/tests/bdd/cli-contract.steps.ts +0 -346
- package/tests/bdd/principles-stats.steps.ts +0 -211
- package/tests/bdd/support/gherkin-loader.ts +0 -147
- package/tests/bdd/support/repo-root.ts +0 -62
- package/tests/bdd/support/vitest-bdd.ts +0 -179
- package/tests/commands/admission-gate-coverage.test.ts +0 -79
- package/tests/commands/build-trajectory-evidence.test.ts +0 -508
- package/tests/commands/candidate-audit-repair.test.ts +0 -421
- package/tests/commands/candidate-intake.test.ts +0 -732
- package/tests/commands/candidate-internalization-backfill.test.ts +0 -548
- package/tests/commands/candidate-internalize-lineage.test.ts +0 -628
- package/tests/commands/candidate-internalize.test.ts +0 -299
- package/tests/commands/candidate-route.test.ts +0 -329
- package/tests/commands/candidate-show.test.ts +0 -95
- package/tests/commands/cli-command-tree.test.ts +0 -144
- package/tests/commands/cli-help-snapshot.test.ts +0 -155
- package/tests/commands/cli-skill-contract.test.ts +0 -121
- package/tests/commands/codex-consent-reversibility.steps.test.ts +0 -299
- package/tests/commands/codex-ingest-quarantine.test.ts +0 -136
- package/tests/commands/codex-setup.test.ts +0 -297
- package/tests/commands/codex-worker-daemon.test.ts +0 -95
- package/tests/commands/codex-worker-registration.test.ts +0 -207
- package/tests/commands/config-doctor.test.ts +0 -336
- package/tests/commands/console-launcher-edge-cases.test.ts +0 -388
- package/tests/commands/console-open.test.ts +0 -1381
- package/tests/commands/context.test.ts +0 -114
- package/tests/commands/demo-story-a.test.ts +0 -318
- package/tests/commands/diagnose.test.ts +0 -1803
- package/tests/commands/errors-list.test.ts +0 -679
- package/tests/commands/evolution-tasks-list.test.ts +0 -41
- package/tests/commands/evolution-tasks-show.test.ts +0 -46
- package/tests/commands/health-codex.test.ts +0 -349
- package/tests/commands/health-host-wiring.test.ts +0 -76
- package/tests/commands/health-reliability.test.ts +0 -99
- package/tests/commands/health.test.ts +0 -413
- package/tests/commands/intent.test.ts +0 -321
- package/tests/commands/legacy-cleanup.test.ts +0 -148
- package/tests/commands/pain-evidence.test.ts +0 -518
- package/tests/commands/pain-list.test.ts +0 -219
- package/tests/commands/pain-record-async.test.ts +0 -335
- package/tests/commands/pain-record-session-parser.test.ts +0 -228
- package/tests/commands/pain-record.test.ts +0 -851
- package/tests/commands/pain-retry.test.ts +0 -1121
- package/tests/commands/plugin-config-resolution-cutover.test.ts +0 -229
- package/tests/commands/pri-393-runtime-config-unification.test.ts +0 -443
- package/tests/commands/principles-stats-wiring.test.ts +0 -135
- package/tests/commands/principles-stats.test.ts +0 -274
- package/tests/commands/product-path-regression.test.ts +0 -86
- package/tests/commands/proven-channel-baseline.test.ts +0 -441
- package/tests/commands/rulecode.test.ts +0 -177
- package/tests/commands/run-rulehost-handler.test.ts +0 -908
- package/tests/commands/runtime-activation-approve-flag-wiring.test.ts +0 -227
- package/tests/commands/runtime-activation-deactivate-flag-wiring.test.ts +0 -167
- package/tests/commands/runtime-activation-dispatch-flag-wiring.test.ts +0 -262
- package/tests/commands/runtime-activation-governance-audit.test.ts +0 -95
- package/tests/commands/runtime-activation-list-flag-wiring.test.ts +0 -193
- package/tests/commands/runtime-activation-promote-flag-wiring.test.ts +0 -248
- package/tests/commands/runtime-activation-shadow-telemetry.test.ts +0 -130
- package/tests/commands/runtime-activation.test.ts +0 -2052
- package/tests/commands/runtime-artifact-repair-registration.test.ts +0 -74
- package/tests/commands/runtime-artifact-repair.test.ts +0 -404
- package/tests/commands/runtime-canary.test.ts +0 -430
- package/tests/commands/runtime-compatibility-scan.test.ts +0 -146
- package/tests/commands/runtime-diagnostics-export.test.ts +0 -175
- package/tests/commands/runtime-features.test.ts +0 -249
- package/tests/commands/runtime-health-snapshot.test.ts +0 -358
- package/tests/commands/runtime-init-empty-workspace.test.ts +0 -252
- package/tests/commands/runtime-init.test.ts +0 -420
- package/tests/commands/runtime-internalization-enqueue-successors.test.ts +0 -782
- package/tests/commands/runtime-internalization-integrity-repair.test.ts +0 -239
- package/tests/commands/runtime-internalization-integrity.test.ts +0 -140
- package/tests/commands/runtime-internalization-queue.test.ts +0 -380
- package/tests/commands/runtime-internalization-retry-owner-authority.test.ts +0 -431
- package/tests/commands/runtime-internalization-run-once-evaluator-parity.test.ts +0 -269
- package/tests/commands/runtime-internalization-run-once-language.test.ts +0 -303
- package/tests/commands/runtime-internalization-run-once-real-config.test.ts +0 -237
- package/tests/commands/runtime-internalization-run-once-rollout-parity.test.ts +0 -706
- package/tests/commands/runtime-internalization-run-once.test.ts +0 -1791
- package/tests/commands/runtime-internalization-wake-once.test.ts +0 -171
- package/tests/commands/runtime-internalization.test.ts +0 -53
- package/tests/commands/runtime-pain-flood-simulation.test.ts +0 -418
- package/tests/commands/runtime-pruning.test.ts +0 -694
- package/tests/commands/runtime-recovery-failed-tasks.test.ts +0 -328
- package/tests/commands/runtime-recovery.test.ts +0 -120
- package/tests/commands/runtime-synthetic-baseline.test.ts +0 -249
- package/tests/commands/runtime-uat.test.ts +0 -397
- package/tests/commands/runtime.test.ts +0 -392
- package/tests/commands/samples-list.test.ts +0 -43
- package/tests/commands/samples-review.test.ts +0 -41
- package/tests/commands/task.test.ts +0 -153
- package/tests/commands/telemetry.test.ts +0 -190
- package/tests/commands/trace.test.ts +0 -316
- package/tests/config-reader.test.ts +0 -143
- package/tests/e2e/candidate-intake-e2e.test.ts +0 -338
- package/tests/e2e/cli-full-flow.test.ts +0 -233
- package/tests/e2e/cross-package-acceptance.test.ts +0 -635
- package/tests/helpers/pd-cli-path.ts +0 -5
- package/tests/pd-cli-smoke.test.ts +0 -13
- package/tests/resolve-workspace.test.ts +0 -196
- package/tests/services/config-doctor-signal-health.test.ts +0 -109
- package/tests/services/console-launcher.test.ts +0 -114
- package/tests/services/demo-rule-compiler.test.ts +0 -242
- package/tests/services/mainline-snapshot-assembler.test.ts +0 -572
- package/tests/services/pd-config-loader.test.ts +0 -505
- package/tests/services/proven-channel-baseline-runner.test.ts +0 -30
- package/tests/services/quality-scorecard/strong-model-gate.test.ts +0 -133
- package/tests/services/resolve-runtime-from-pd-config.test.ts +0 -485
- package/tests/services/rulehost-pipeline-e2e.test.ts +0 -538
- package/tests/services/rulehost-pipeline-runner.test.ts +0 -1242
- package/tests/services/workspace-tool-semantics.test.ts +0 -76
- package/tests/utils/path-security.test.ts +0 -180
- package/tsconfig.json +0 -26
- package/vitest.config.ts +0 -10
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
import * as path from 'path';
|
|
2
|
-
import * as fs from 'fs';
|
|
3
|
-
import {
|
|
4
|
-
OperatorHealthReadModel,
|
|
5
|
-
SchemaConformanceReadModel,
|
|
6
|
-
PruningReadModel,
|
|
7
|
-
createInternalizationQueueReadModel,
|
|
8
|
-
InternalizationChainIntegrityReadModel,
|
|
9
|
-
auditCandidateLedgerConsistency,
|
|
10
|
-
buildGfiWorkspaceSnapshot,
|
|
11
|
-
} from '@principles/core/runtime-v2';
|
|
12
|
-
import { runCanaryChecks } from './runtime-canary.js';
|
|
13
|
-
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
14
|
-
|
|
15
|
-
export interface BundleManifestArtifact {
|
|
16
|
-
name: string;
|
|
17
|
-
path: string;
|
|
18
|
-
status: 'ok' | 'failed';
|
|
19
|
-
error?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface BundleManifest {
|
|
23
|
-
generatedAt: string;
|
|
24
|
-
workspace: string;
|
|
25
|
-
outputDir: string;
|
|
26
|
-
artifacts: BundleManifestArtifact[];
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface DiagnosticsExportOptions {
|
|
30
|
-
workspace?: string;
|
|
31
|
-
out?: string;
|
|
32
|
-
json?: boolean;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function validateOutputPath(outDir: string, workspaceDir: string): string {
|
|
36
|
-
const resolvedOut = path.resolve(outDir);
|
|
37
|
-
const resolvedWs = path.resolve(workspaceDir);
|
|
38
|
-
const relative = path.relative(resolvedWs, resolvedOut);
|
|
39
|
-
if (relative.startsWith('..') || path.isAbsolute(relative)) {
|
|
40
|
-
throw new Error('Output path must be within workspace directory');
|
|
41
|
-
}
|
|
42
|
-
return resolvedOut;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function sanitizeForExport(data: unknown): unknown {
|
|
46
|
-
if (data === null || data === undefined) return data;
|
|
47
|
-
if (typeof data === 'string') {
|
|
48
|
-
return data.replace(/(?:api[_-]?key|secret|token|password|authorization|bearer)\s*[:=]\s*\S+/gi, '[REDACTED]');
|
|
49
|
-
}
|
|
50
|
-
if (Array.isArray(data)) return data.map(sanitizeForExport);
|
|
51
|
-
if (typeof data === 'object') {
|
|
52
|
-
const result: Record<string, unknown> = {};
|
|
53
|
-
for (const [key, value] of Object.entries(data as Record<string, unknown>)) {
|
|
54
|
-
const lowerKey = key.toLowerCase();
|
|
55
|
-
if (/key|secret|token|password|auth|bearer|credential/i.test(lowerKey)) {
|
|
56
|
-
result[key] = '[REDACTED]';
|
|
57
|
-
} else {
|
|
58
|
-
result[key] = sanitizeForExport(value);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return result;
|
|
62
|
-
}
|
|
63
|
-
return data;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
interface CollectArtifactContext {
|
|
67
|
-
name: string;
|
|
68
|
-
fileName: string;
|
|
69
|
-
outputDir: string;
|
|
70
|
-
collector: () => Promise<unknown> | unknown;
|
|
71
|
-
artifacts: BundleManifestArtifact[];
|
|
72
|
-
errors: { artifact: string; error: string }[];
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async function collectArtifact(ctx: CollectArtifactContext): Promise<void> {
|
|
76
|
-
try {
|
|
77
|
-
const data = await ctx.collector();
|
|
78
|
-
const sanitized = sanitizeForExport(data);
|
|
79
|
-
const filePath = path.join(ctx.outputDir, ctx.fileName);
|
|
80
|
-
fs.writeFileSync(filePath, JSON.stringify(sanitized, null, 2), 'utf8');
|
|
81
|
-
ctx.artifacts.push({ name: ctx.name, path: ctx.fileName, status: 'ok' });
|
|
82
|
-
} catch (err) {
|
|
83
|
-
ctx.artifacts.push({ name: ctx.name, path: ctx.fileName, status: 'failed', error: String(err) });
|
|
84
|
-
ctx.errors.push({ artifact: ctx.name, error: String(err) });
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export async function exportDiagnosticsBundle(workspaceDir: string, outDir: string): Promise<BundleManifest> {
|
|
89
|
-
const generatedAt = new Date().toISOString();
|
|
90
|
-
const resolvedOut = validateOutputPath(outDir, workspaceDir);
|
|
91
|
-
const artifacts: BundleManifestArtifact[] = [];
|
|
92
|
-
const errors: { artifact: string; error: string }[] = [];
|
|
93
|
-
|
|
94
|
-
fs.mkdirSync(resolvedOut, { recursive: true });
|
|
95
|
-
|
|
96
|
-
const baseCtx = { outputDir: resolvedOut, artifacts, errors };
|
|
97
|
-
|
|
98
|
-
await collectArtifact({ ...baseCtx, name: 'runtime-health', fileName: 'runtime-health.json', collector: async () => {
|
|
99
|
-
const model = new OperatorHealthReadModel({ workspaceDir });
|
|
100
|
-
try {
|
|
101
|
-
return await model.getSnapshot();
|
|
102
|
-
} finally {
|
|
103
|
-
await model.close();
|
|
104
|
-
}
|
|
105
|
-
} });
|
|
106
|
-
|
|
107
|
-
await collectArtifact({ ...baseCtx, name: 'canary', fileName: 'canary.json', collector: async () => {
|
|
108
|
-
return await runCanaryChecks(workspaceDir);
|
|
109
|
-
} });
|
|
110
|
-
|
|
111
|
-
await collectArtifact({ ...baseCtx, name: 'schema-conformance', fileName: 'schema-conformance.json', collector: () => {
|
|
112
|
-
const model = new SchemaConformanceReadModel({ workspaceDir });
|
|
113
|
-
return model.check();
|
|
114
|
-
} });
|
|
115
|
-
|
|
116
|
-
await collectArtifact({ ...baseCtx, name: 'candidate-audit', fileName: 'candidate-audit.json', collector: async () => {
|
|
117
|
-
return await auditCandidateLedgerConsistency(workspaceDir);
|
|
118
|
-
} });
|
|
119
|
-
|
|
120
|
-
await collectArtifact({ ...baseCtx, name: 'gfi-snapshot', fileName: 'gfi-snapshot.json', collector: () => {
|
|
121
|
-
const sessionDir = path.join(workspaceDir, '.state', 'sessions');
|
|
122
|
-
const sessions: { sessionId: string; currentGfi: number; lastActivityAt: number; consecutiveErrors: number }[] = [];
|
|
123
|
-
if (fs.existsSync(sessionDir)) {
|
|
124
|
-
for (const file of fs.readdirSync(sessionDir)) {
|
|
125
|
-
if (!file.endsWith('.json')) continue;
|
|
126
|
-
try {
|
|
127
|
-
const raw = fs.readFileSync(path.join(sessionDir, file), 'utf8');
|
|
128
|
-
const parsed = JSON.parse(raw);
|
|
129
|
-
if (parsed?.sessionId) {
|
|
130
|
-
sessions.push({
|
|
131
|
-
sessionId: parsed.sessionId,
|
|
132
|
-
currentGfi: parsed.currentGfi ?? 0,
|
|
133
|
-
lastActivityAt: parsed.lastActivityAt ?? parsed.lastControlActivityAt ?? 0,
|
|
134
|
-
consecutiveErrors: parsed.consecutiveErrors ?? 0,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
} catch { /* skip malformed */ }
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return buildGfiWorkspaceSnapshot({ sessions, nowMs: Date.now() });
|
|
141
|
-
} });
|
|
142
|
-
|
|
143
|
-
await collectArtifact({ ...baseCtx, name: 'pruning-orphans', fileName: 'pruning-orphans.json', collector: () => {
|
|
144
|
-
const model = new PruningReadModel({ workspaceDir });
|
|
145
|
-
return model.getOrphanDerivedCandidates();
|
|
146
|
-
} });
|
|
147
|
-
|
|
148
|
-
await collectArtifact({ ...baseCtx, name: 'internalization-queue', fileName: 'internalization-queue.json', collector: async () => {
|
|
149
|
-
const { readModel, close } = await createInternalizationQueueReadModel({ workspaceDir, readonly: true });
|
|
150
|
-
try {
|
|
151
|
-
return await readModel.getSnapshot();
|
|
152
|
-
} finally {
|
|
153
|
-
await close();
|
|
154
|
-
}
|
|
155
|
-
} });
|
|
156
|
-
|
|
157
|
-
await collectArtifact({ ...baseCtx, name: 'internalization-integrity', fileName: 'internalization-integrity.json', collector: () => {
|
|
158
|
-
const model = new InternalizationChainIntegrityReadModel({ workspaceDir });
|
|
159
|
-
return model.check();
|
|
160
|
-
} });
|
|
161
|
-
|
|
162
|
-
await collectArtifact({ ...baseCtx, name: 'recent-session-summary', fileName: 'recent-session-summary.json', collector: () => {
|
|
163
|
-
const sessionDir = path.join(workspaceDir, '.state', 'sessions');
|
|
164
|
-
const summaries: { sessionId: string; status: string; lastActivityAt: number }[] = [];
|
|
165
|
-
if (fs.existsSync(sessionDir)) {
|
|
166
|
-
for (const file of fs.readdirSync(sessionDir)) {
|
|
167
|
-
if (!file.endsWith('.json')) continue;
|
|
168
|
-
try {
|
|
169
|
-
const raw = fs.readFileSync(path.join(sessionDir, file), 'utf8');
|
|
170
|
-
const parsed = JSON.parse(raw);
|
|
171
|
-
if (parsed?.sessionId) {
|
|
172
|
-
summaries.push({
|
|
173
|
-
sessionId: parsed.sessionId,
|
|
174
|
-
status: parsed.status ?? 'unknown',
|
|
175
|
-
lastActivityAt: parsed.lastActivityAt ?? parsed.lastControlActivityAt ?? 0,
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
} catch { /* skip */ }
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
return { sessionCount: summaries.length, sessions: summaries.slice(0, 20) };
|
|
182
|
-
} });
|
|
183
|
-
|
|
184
|
-
if (errors.length > 0) {
|
|
185
|
-
await collectArtifact({ outputDir: resolvedOut, artifacts, errors: [], name: 'errors', fileName: 'errors.json', collector: () => errors });
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const manifest: BundleManifest = {
|
|
189
|
-
generatedAt,
|
|
190
|
-
workspace: workspaceDir,
|
|
191
|
-
outputDir: resolvedOut,
|
|
192
|
-
artifacts,
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
fs.writeFileSync(
|
|
196
|
-
path.join(resolvedOut, 'manifest.json'),
|
|
197
|
-
JSON.stringify(manifest, null, 2),
|
|
198
|
-
'utf8',
|
|
199
|
-
);
|
|
200
|
-
|
|
201
|
-
return manifest;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
export async function handleRuntimeDiagnosticsExport(opts: DiagnosticsExportOptions): Promise<void> {
|
|
205
|
-
const workspaceDir = opts.workspace
|
|
206
|
-
? path.resolve(opts.workspace)
|
|
207
|
-
: resolveWorkspaceDir();
|
|
208
|
-
|
|
209
|
-
const outDir = opts.out
|
|
210
|
-
? path.resolve(workspaceDir, opts.out)
|
|
211
|
-
: path.resolve(workspaceDir, '.state', 'control-plane-observation', 'snapshots');
|
|
212
|
-
|
|
213
|
-
const manifest = await exportDiagnosticsBundle(workspaceDir, outDir);
|
|
214
|
-
|
|
215
|
-
if (opts.json) {
|
|
216
|
-
console.log(JSON.stringify(manifest, null, 2));
|
|
217
|
-
} else {
|
|
218
|
-
console.log(`Diagnostic bundle exported to: ${manifest.outputDir}`);
|
|
219
|
-
console.log(`Artifacts: ${manifest.artifacts.length}`);
|
|
220
|
-
for (const artifact of manifest.artifacts) {
|
|
221
|
-
const icon = artifact.status === 'ok' ? '✓' : '✗';
|
|
222
|
-
console.log(` ${icon} ${artifact.name} (${artifact.path})`);
|
|
223
|
-
}
|
|
224
|
-
const failedCount = manifest.artifacts.filter(a => a.status === 'failed').length;
|
|
225
|
-
if (failedCount > 0) {
|
|
226
|
-
console.log(`\n${failedCount} artifact(s) failed to generate. See errors.json for details.`);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* pd runtime features — Show effective feature flags from .pd/config.yaml.
|
|
3
|
-
*
|
|
4
|
-
* PRI-305: Cutover from .pd/feature-flags.yaml to .pd/config.yaml.
|
|
5
|
-
* Uses core computeFeatureFlagsFromConfig for flag computation.
|
|
6
|
-
* --json outputs a single parseable JSON object.
|
|
7
|
-
* Missing config uses core defaults with nextAction.
|
|
8
|
-
* Malformed config fails loud with reason and nextAction.
|
|
9
|
-
* No secret output.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import * as path from 'path';
|
|
13
|
-
import { loadPdConfig, computeFlagsFromLoadResult } from '../services/pd-config-loader.js';
|
|
14
|
-
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
15
|
-
import { emitResult } from '../services/cli-output.js';
|
|
16
|
-
|
|
17
|
-
// ── Output types ─────────────────────────────────────────────────────────────
|
|
18
|
-
|
|
19
|
-
export interface RuntimeFeaturesOutput {
|
|
20
|
-
status: 'ok' | 'degraded' | 'failed';
|
|
21
|
-
source: 'defaults' | 'user_config' | 'malformed';
|
|
22
|
-
configPath: string;
|
|
23
|
-
features: {
|
|
24
|
-
id: string;
|
|
25
|
-
category: string;
|
|
26
|
-
enabled: boolean;
|
|
27
|
-
}[];
|
|
28
|
-
enabledMvpChannels: string[];
|
|
29
|
-
totalFlags: number;
|
|
30
|
-
enabledCount: number;
|
|
31
|
-
disabledCount: number;
|
|
32
|
-
warnings: string[];
|
|
33
|
-
reason?: string;
|
|
34
|
-
nextAction?: string;
|
|
35
|
-
/** Malformed config errors (only present when source=malformed) */
|
|
36
|
-
errors?: { path: string; reason: string; nextAction: string }[];
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// ── Build output ─────────────────────────────────────────────────────────────
|
|
40
|
-
|
|
41
|
-
export function buildRuntimeFeaturesStatus(workspaceDir: string): RuntimeFeaturesOutput {
|
|
42
|
-
const loadResult = loadPdConfig(workspaceDir);
|
|
43
|
-
const flags = computeFlagsFromLoadResult(loadResult);
|
|
44
|
-
|
|
45
|
-
const allFlags = Object.values(flags.flags);
|
|
46
|
-
const enabledCount = allFlags.filter(f => f.enabled).length;
|
|
47
|
-
const features = allFlags.map(f => ({
|
|
48
|
-
id: f.id,
|
|
49
|
-
category: f.category,
|
|
50
|
-
enabled: f.enabled,
|
|
51
|
-
}));
|
|
52
|
-
|
|
53
|
-
// Determine status
|
|
54
|
-
let status: RuntimeFeaturesOutput['status'] = 'ok';
|
|
55
|
-
const warnings = [...loadResult.warnings, ...flags.warnings];
|
|
56
|
-
|
|
57
|
-
if (!loadResult.ok) {
|
|
58
|
-
status = 'failed';
|
|
59
|
-
} else if (warnings.length > 0) {
|
|
60
|
-
status = 'degraded';
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const output: RuntimeFeaturesOutput = {
|
|
64
|
-
status,
|
|
65
|
-
source: loadResult.ok ? loadResult.source : 'malformed',
|
|
66
|
-
configPath: loadResult.configPath,
|
|
67
|
-
features,
|
|
68
|
-
enabledMvpChannels: [...flags.enabledChannels],
|
|
69
|
-
totalFlags: allFlags.length,
|
|
70
|
-
enabledCount,
|
|
71
|
-
disabledCount: allFlags.length - enabledCount,
|
|
72
|
-
warnings,
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
// Add reason and nextAction for non-ok states
|
|
76
|
-
if (!loadResult.ok) {
|
|
77
|
-
output.reason = `Config validation failed: ${loadResult.errors.map(e => e.reason).join('; ')}`;
|
|
78
|
-
output.nextAction = loadResult.errors[0]?.nextAction ?? 'Fix .pd/config.yaml and retry';
|
|
79
|
-
output.errors = loadResult.errors;
|
|
80
|
-
} else if (warnings.length > 0) {
|
|
81
|
-
output.reason = `Config warnings: ${warnings.slice(0, 3).join('; ')}`;
|
|
82
|
-
output.nextAction = 'Review .pd/config.yaml for warnings';
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return output;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// ── Text formatting ──────────────────────────────────────────────────────────
|
|
89
|
-
|
|
90
|
-
function formatTextOutput(output: RuntimeFeaturesOutput): string {
|
|
91
|
-
const lines: string[] = [];
|
|
92
|
-
|
|
93
|
-
lines.push('PD Runtime Features');
|
|
94
|
-
lines.push(`source: ${output.source}`);
|
|
95
|
-
lines.push(`config: ${output.configPath}`);
|
|
96
|
-
lines.push('');
|
|
97
|
-
|
|
98
|
-
const categoryOrder = ['core', 'quiet', 'gone'] as const;
|
|
99
|
-
for (const category of categoryOrder) {
|
|
100
|
-
const categoryFlags = output.features.filter(f => f.category === category);
|
|
101
|
-
if (categoryFlags.length === 0) continue;
|
|
102
|
-
|
|
103
|
-
lines.push(` ${category.toUpperCase()} (${categoryFlags.length})`);
|
|
104
|
-
for (const flag of categoryFlags) {
|
|
105
|
-
const icon = flag.enabled ? '+' : '-';
|
|
106
|
-
lines.push(` [${icon}] ${flag.id}`);
|
|
107
|
-
}
|
|
108
|
-
lines.push('');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
lines.push(`Total: ${output.totalFlags} flags, ${output.enabledCount} enabled, ${output.disabledCount} disabled`);
|
|
112
|
-
lines.push(`MVP channels: ${output.enabledMvpChannels.length > 0 ? output.enabledMvpChannels.join(', ') : '(none)'}`);
|
|
113
|
-
|
|
114
|
-
if (output.warnings.length > 0) {
|
|
115
|
-
lines.push('');
|
|
116
|
-
lines.push('Warnings:');
|
|
117
|
-
for (const w of output.warnings) {
|
|
118
|
-
lines.push(` [!] ${w}`);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (output.errors && output.errors.length > 0) {
|
|
123
|
-
lines.push('');
|
|
124
|
-
lines.push('Errors:');
|
|
125
|
-
for (const e of output.errors) {
|
|
126
|
-
lines.push(` [x] ${e.path}: ${e.reason}`);
|
|
127
|
-
lines.push(` → ${e.nextAction}`);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return lines.join('\n');
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// ── CLI handler ──────────────────────────────────────────────────────────────
|
|
135
|
-
|
|
136
|
-
interface FeaturesOptions {
|
|
137
|
-
workspace?: string;
|
|
138
|
-
json?: boolean;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export async function handleRuntimeFeaturesStatus(opts: FeaturesOptions): Promise<void> {
|
|
142
|
-
const workspaceDir = opts.workspace
|
|
143
|
-
? path.resolve(opts.workspace)
|
|
144
|
-
: resolveWorkspaceDir();
|
|
145
|
-
|
|
146
|
-
const output = buildRuntimeFeaturesStatus(workspaceDir);
|
|
147
|
-
|
|
148
|
-
emitResult(output, { json: opts.json ?? false, formatText: formatTextOutput });
|
|
149
|
-
|
|
150
|
-
if (output.status === 'failed') {
|
|
151
|
-
process.exitCode = 1;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* pd runtime gfi snapshot command — GFI workspace snapshot for Runtime V2.
|
|
3
|
-
*
|
|
4
|
-
* Usage:
|
|
5
|
-
* pd runtime gfi snapshot --workspace <path> --json
|
|
6
|
-
* pd runtime health gfi --workspace <path> --json (alias)
|
|
7
|
-
*
|
|
8
|
-
* Shows active vs stale session breakdown for GFI visibility.
|
|
9
|
-
* Stale sessions (>2h inactive) do NOT influence the active snapshot.
|
|
10
|
-
*
|
|
11
|
-
* PRI-78/PRI-82: GFI Observability
|
|
12
|
-
*/
|
|
13
|
-
import * as path from 'path';
|
|
14
|
-
import * as fs from 'fs';
|
|
15
|
-
import { buildGfiWorkspaceSnapshot } from '@principles/core/runtime-v2';
|
|
16
|
-
import type { GfiWorkspaceSnapshot } from '@principles/core/runtime-v2';
|
|
17
|
-
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
18
|
-
|
|
19
|
-
interface GfiSnapshotOptions {
|
|
20
|
-
workspace?: string;
|
|
21
|
-
json?: boolean;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function formatTextOutput(snapshot: GfiWorkspaceSnapshot): string {
|
|
25
|
-
const lines: string[] = [];
|
|
26
|
-
|
|
27
|
-
lines.push('GFI Workspace Snapshot');
|
|
28
|
-
lines.push(`generatedAt: ${snapshot.generatedAt}`);
|
|
29
|
-
lines.push('');
|
|
30
|
-
|
|
31
|
-
if (snapshot.active) {
|
|
32
|
-
const a = snapshot.active;
|
|
33
|
-
lines.push('ACTIVE SESSION');
|
|
34
|
-
lines.push(` currentGfi: ${a.currentGfi} stage: ${a.stage}`);
|
|
35
|
-
lines.push(` dominantSource: ${a.dominantSource ?? '(none)'}`);
|
|
36
|
-
lines.push(` consecutiveErrors: ${a.consecutiveErrors}`);
|
|
37
|
-
lines.push(` dailyGfiPeak: ${a.dailyGfiPeak ?? '(none)'}`);
|
|
38
|
-
lines.push(` attitudeMode: ${a.consumers.attitudeMode}`);
|
|
39
|
-
lines.push(` painDiagnosticReason: ${a.consumers.painDiagnosticReason}`);
|
|
40
|
-
} else {
|
|
41
|
-
lines.push('ACTIVE SESSION: (none)');
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
lines.push('');
|
|
45
|
-
|
|
46
|
-
if (snapshot.staleSessionCount > 0 && snapshot.staleGfiRange) {
|
|
47
|
-
lines.push(`STALE SESSIONS: ${snapshot.staleSessionCount} session(s)` +
|
|
48
|
-
` (GFI range: ${snapshot.staleGfiRange.min}-${snapshot.staleGfiRange.max})`);
|
|
49
|
-
} else {
|
|
50
|
-
lines.push('STALE SESSIONS: 0');
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
lines.push('');
|
|
54
|
-
lines.push(`TOTAL: ${snapshot.totalSessionCount} session(s) (${snapshot.activeSessionCount} active)`);
|
|
55
|
-
|
|
56
|
-
return lines.join('\n');
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function readPersistedSessions(workspaceDir: string): {
|
|
60
|
-
sessionId: string;
|
|
61
|
-
currentGfi: number;
|
|
62
|
-
gfiBySource?: Record<string, number>;
|
|
63
|
-
lastErrorSource?: string;
|
|
64
|
-
consecutiveErrors: number;
|
|
65
|
-
lastGfiDecayAt?: number;
|
|
66
|
-
dailyGfiPeak?: number;
|
|
67
|
-
lastActivityAt: number;
|
|
68
|
-
}[] {
|
|
69
|
-
const sessionDir = path.join(workspaceDir, '.state', 'sessions');
|
|
70
|
-
|
|
71
|
-
if (!fs.existsSync(sessionDir)) {
|
|
72
|
-
return [];
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const sessions: {
|
|
76
|
-
sessionId: string;
|
|
77
|
-
currentGfi: number;
|
|
78
|
-
gfiBySource?: Record<string, number>;
|
|
79
|
-
lastErrorSource?: string;
|
|
80
|
-
consecutiveErrors: number;
|
|
81
|
-
lastGfiDecayAt?: number;
|
|
82
|
-
dailyGfiPeak?: number;
|
|
83
|
-
lastActivityAt: number;
|
|
84
|
-
}[] = [];
|
|
85
|
-
let skippedCount = 0;
|
|
86
|
-
|
|
87
|
-
for (const file of fs.readdirSync(sessionDir)) {
|
|
88
|
-
if (!file.endsWith('.json')) continue;
|
|
89
|
-
try {
|
|
90
|
-
const raw = fs.readFileSync(path.join(sessionDir, file), 'utf8');
|
|
91
|
-
const parsed = JSON.parse(raw);
|
|
92
|
-
if (parsed?.sessionId) {
|
|
93
|
-
sessions.push({
|
|
94
|
-
sessionId: parsed.sessionId ?? file.replace('.json', ''),
|
|
95
|
-
currentGfi: parsed.currentGfi ?? 0,
|
|
96
|
-
gfiBySource: parsed.gfiBySource,
|
|
97
|
-
lastErrorSource: parsed.lastErrorSource,
|
|
98
|
-
consecutiveErrors: parsed.consecutiveErrors ?? 0,
|
|
99
|
-
lastGfiDecayAt: parsed.lastGfiDecayAt,
|
|
100
|
-
dailyGfiPeak: parsed.dailyGfiPeak,
|
|
101
|
-
lastActivityAt: parsed.lastActivityAt ?? parsed.lastControlActivityAt ?? 0,
|
|
102
|
-
});
|
|
103
|
-
} else {
|
|
104
|
-
skippedCount++;
|
|
105
|
-
}
|
|
106
|
-
} catch {
|
|
107
|
-
skippedCount++;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (skippedCount > 0) {
|
|
112
|
-
console.warn(`[runtime-gfi-snapshot] Skipped ${skippedCount} malformed session file(s)`);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return sessions;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export async function handleRuntimeGfiSnapshot(opts: GfiSnapshotOptions): Promise<void> {
|
|
119
|
-
const workspaceDir = opts.workspace
|
|
120
|
-
? path.resolve(opts.workspace)
|
|
121
|
-
: resolveWorkspaceDir();
|
|
122
|
-
|
|
123
|
-
const sessions = readPersistedSessions(workspaceDir);
|
|
124
|
-
|
|
125
|
-
const snapshot = buildGfiWorkspaceSnapshot({
|
|
126
|
-
sessions,
|
|
127
|
-
nowMs: Date.now(),
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
if (opts.json) {
|
|
131
|
-
console.log(JSON.stringify(snapshot, null, 2));
|
|
132
|
-
} else {
|
|
133
|
-
console.log(formatTextOutput(snapshot));
|
|
134
|
-
}
|
|
135
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* pd runtime health snapshot command — Operator health snapshot for Runtime V2.
|
|
3
|
-
*
|
|
4
|
-
* Usage:
|
|
5
|
-
* pd runtime health snapshot --workspace <path> --json
|
|
6
|
-
*
|
|
7
|
-
* Aggregates chain reliability, candidate/ledger consistency, and pruning
|
|
8
|
-
* lifecycle signals into a single operator-facing read-only snapshot.
|
|
9
|
-
*
|
|
10
|
-
* PRI-28: Operator health snapshot.
|
|
11
|
-
*/
|
|
12
|
-
import * as path from 'path';
|
|
13
|
-
import { OperatorHealthReadModel } from '@principles/core/runtime-v2';
|
|
14
|
-
import type { OperatorHealthSnapshot } from '@principles/core/runtime-v2';
|
|
15
|
-
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
16
|
-
|
|
17
|
-
interface HealthSnapshotOptions {
|
|
18
|
-
workspace?: string;
|
|
19
|
-
json?: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function formatTextOutput(snapshot: OperatorHealthSnapshot): string {
|
|
23
|
-
const lines: string[] = [];
|
|
24
|
-
const statusIcon = snapshot.overallStatus === 'healthy' ? '✓' : '✗';
|
|
25
|
-
|
|
26
|
-
lines.push(`Operator Health Snapshot`);
|
|
27
|
-
lines.push(`generatedAt: ${snapshot.generatedAt}`);
|
|
28
|
-
lines.push(`workspace: ${snapshot.workspace}`);
|
|
29
|
-
lines.push('');
|
|
30
|
-
lines.push(`OVERALL: ${statusIcon} ${snapshot.overallStatus.toUpperCase()}`);
|
|
31
|
-
lines.push('');
|
|
32
|
-
|
|
33
|
-
// Pain chain
|
|
34
|
-
lines.push('painChain:');
|
|
35
|
-
if (snapshot.painChain.lastSuccessfulChain) {
|
|
36
|
-
const c = snapshot.painChain.lastSuccessfulChain;
|
|
37
|
-
lines.push(` lastChain: ${c.painId} → ${c.taskId} → ${c.runId ?? '-'} → ${c.artifactId ?? '-'}`);
|
|
38
|
-
lines.push(` candidates: ${c.candidateIds.length}, ledgerEntries: ${c.ledgerEntryIds.length}`);
|
|
39
|
-
} else {
|
|
40
|
-
lines.push(' lastChain: (none)');
|
|
41
|
-
}
|
|
42
|
-
lines.push('');
|
|
43
|
-
|
|
44
|
-
// Candidate/ledger
|
|
45
|
-
lines.push('candidateLedger:');
|
|
46
|
-
lines.push(` status: ${snapshot.candidateLedger.auditStatus}`);
|
|
47
|
-
if (snapshot.candidateLedger.missingLedgerCount > 0) {
|
|
48
|
-
lines.push(` missingLedger: ${snapshot.candidateLedger.missingLedgerCount}`);
|
|
49
|
-
}
|
|
50
|
-
lines.push('');
|
|
51
|
-
|
|
52
|
-
// Pruning
|
|
53
|
-
lines.push('pruning:');
|
|
54
|
-
lines.push(` watchCount: ${snapshot.pruning.watchCount}, reviewCount: ${snapshot.pruning.reviewCount}`);
|
|
55
|
-
if (snapshot.pruning.orphanDerivedCandidateCount > 0) {
|
|
56
|
-
lines.push(` orphanDerivedCandidates: ${snapshot.pruning.orphanDerivedCandidateCount}`);
|
|
57
|
-
}
|
|
58
|
-
lines.push('');
|
|
59
|
-
|
|
60
|
-
// GFI
|
|
61
|
-
if (snapshot.gfi.active) {
|
|
62
|
-
const g = snapshot.gfi.active;
|
|
63
|
-
lines.push(`gfi: stage=${g.stage} currentGfi=${g.currentGfi} dominantSource=${g.dominantSource ?? '-'} sessions=${snapshot.gfi.activeSessionCount}active/${snapshot.gfi.staleSessionCount}stale`);
|
|
64
|
-
} else {
|
|
65
|
-
lines.push('gfi: (no active sessions)');
|
|
66
|
-
}
|
|
67
|
-
lines.push('');
|
|
68
|
-
|
|
69
|
-
// Actions
|
|
70
|
-
if (snapshot.recommendedActions.length === 0) {
|
|
71
|
-
lines.push('No actions recommended.');
|
|
72
|
-
} else {
|
|
73
|
-
lines.push('Recommended actions:');
|
|
74
|
-
for (const action of snapshot.recommendedActions) {
|
|
75
|
-
lines.push(` [!] ${action}`);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return lines.join('\n');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export async function handleRuntimeHealthSnapshot(opts: HealthSnapshotOptions): Promise<void> {
|
|
83
|
-
const workspaceDir = opts.workspace
|
|
84
|
-
? path.resolve(opts.workspace)
|
|
85
|
-
: resolveWorkspaceDir();
|
|
86
|
-
|
|
87
|
-
const model = new OperatorHealthReadModel({ workspaceDir });
|
|
88
|
-
|
|
89
|
-
try {
|
|
90
|
-
const snapshot = await model.getSnapshot();
|
|
91
|
-
|
|
92
|
-
if (opts.json) {
|
|
93
|
-
console.log(JSON.stringify(snapshot, null, 2));
|
|
94
|
-
} else {
|
|
95
|
-
console.log(formatTextOutput(snapshot));
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (snapshot.overallStatus !== 'healthy') {
|
|
99
|
-
if (!opts.json) {
|
|
100
|
-
console.error('');
|
|
101
|
-
console.error(`FAIL: overallStatus=${snapshot.overallStatus}`);
|
|
102
|
-
}
|
|
103
|
-
process.exitCode = 1;
|
|
104
|
-
}
|
|
105
|
-
} finally {
|
|
106
|
-
await model.close();
|
|
107
|
-
}
|
|
108
|
-
}
|