create-principles-disciple 1.114.0 → 1.116.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/console/dist/server/index.js +8 -0
- package/console/dist/server/models/GovernanceConsoleModel.d.ts +27 -0
- package/console/dist/server/models/GovernanceConsoleModel.js +65 -16
- package/console/dist/server/models/GovernanceProjectionCollector.d.ts +16 -0
- package/console/dist/server/models/GovernanceProjectionCollector.js +540 -0
- package/console/dist/server/routes/principles.d.ts +5 -1
- package/console/dist/server/routes/principles.js +44 -1
- package/console/dist/ui/api.d.ts +3 -1
- package/console/dist/ui/api.js +5 -2
- package/console/dist/ui/i18n/en.json +82 -1
- package/console/dist/ui/i18n/zh-CN.json +82 -1
- package/console/dist/ui/pages/principles/PrincipleDetailPage.js +26 -5
- package/console/dist/ui/utils/validators.d.ts +2 -0
- package/console/dist/ui/utils/validators.js +82 -10
- package/console/dist/web/assets/app.css +16 -0
- package/console/dist/web/assets/app.js +304 -6
- package/core/dist/runtime-v2/__tests__/governance-projection-contract.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/governance-projection-contract.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/governance-projection-contract.test.js +78 -0
- package/core/dist/runtime-v2/__tests__/governance-projection-contract.test.js.map +1 -0
- package/core/dist/runtime-v2/__tests__/governance-projection.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/governance-projection.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/governance-projection.test.js +154 -0
- package/core/dist/runtime-v2/__tests__/governance-projection.test.js.map +1 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +15 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +1 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
- package/core/dist/runtime-v2/governance-projection-contract.d.ts +721 -0
- package/core/dist/runtime-v2/governance-projection-contract.d.ts.map +1 -0
- package/core/dist/runtime-v2/governance-projection-contract.js +136 -0
- package/core/dist/runtime-v2/governance-projection-contract.js.map +1 -0
- package/core/dist/runtime-v2/governance-projection.d.ts +4 -0
- package/core/dist/runtime-v2/governance-projection.d.ts.map +1 -0
- package/core/dist/runtime-v2/governance-projection.js +176 -0
- package/core/dist/runtime-v2/governance-projection.js.map +1 -0
- package/core/dist/runtime-v2/index.d.ts +3 -0
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +2 -0
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/package.json +2 -2
- package/pd-cli/dist/commands/__tests__/runtime-activation-nextaction.test.d.ts +15 -0
- package/pd-cli/dist/commands/__tests__/runtime-activation-nextaction.test.d.ts.map +1 -0
- package/pd-cli/dist/commands/__tests__/runtime-activation-nextaction.test.js +73 -0
- package/pd-cli/dist/commands/__tests__/runtime-activation-nextaction.test.js.map +1 -0
- package/pd-cli/dist/commands/runtime-activation.d.ts +19 -0
- package/pd-cli/dist/commands/runtime-activation.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-activation.js +39 -22
- package/pd-cli/dist/commands/runtime-activation.js.map +1 -1
- package/pd-cli/dist/commands/runtime-artifact-repair.d.ts +58 -0
- package/pd-cli/dist/commands/runtime-artifact-repair.d.ts.map +1 -0
- package/pd-cli/dist/commands/runtime-artifact-repair.js +415 -0
- package/pd-cli/dist/commands/runtime-artifact-repair.js.map +1 -0
- package/pd-cli/dist/index.js +19 -0
- package/pd-cli/dist/index.js.map +1 -1
- package/plugin/dist/bundle.js +472 -472
- package/plugin/openclaw.plugin.json +1 -1
- package/plugin/package.json +1 -1
|
@@ -209,9 +209,11 @@ async function initServices(workspaceDir, authConfig) {
|
|
|
209
209
|
const pdFlags = computeFlagsFromLoadResult(configResult);
|
|
210
210
|
const feedbackChannelEnabled = pdFlags.flags.feedback_channel?.enabled ?? false;
|
|
211
211
|
const failedTasksObservabilityEnabled = pdFlags.flags.failed_tasks_observability?.enabled ?? true;
|
|
212
|
+
const governanceProjectionEnabled = pdFlags.flags.principle_governance_projection_v2?.enabled ?? false;
|
|
212
213
|
const feedbackFlags = {
|
|
213
214
|
feedback_channel: { enabled: feedbackChannelEnabled },
|
|
214
215
|
failed_tasks_observability: { enabled: failedTasksObservabilityEnabled },
|
|
216
|
+
principle_governance_projection_v2: { enabled: governanceProjectionEnabled },
|
|
215
217
|
};
|
|
216
218
|
if (!configResult.ok) {
|
|
217
219
|
console.warn('[pd-console] PD config loading failed (using defaults for feedback channel):', configResult.errors.map(e => e.reason).join('; '));
|
|
@@ -322,6 +324,12 @@ function handleRequest(services) {
|
|
|
322
324
|
asyncHandler(() => handlePrinciplesRoute({ req, res, workspaceDir: services.workspaceDir, subPath }))(req, res);
|
|
323
325
|
return;
|
|
324
326
|
}
|
|
327
|
+
// GET /api/v1/principles/:id/governance
|
|
328
|
+
if (urlPath.startsWith('/api/v1/principles/')) {
|
|
329
|
+
const subPath = urlPath.slice('/api/v1/principles'.length);
|
|
330
|
+
asyncHandler(() => handlePrinciplesRoute({ req, res, workspaceDir: services.workspaceDir, subPath, featureFlags: services.feedbackFlags }))(req, res);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
325
333
|
// Workspace management routes
|
|
326
334
|
if (urlPath === '/api/workspaces' || urlPath.startsWith('/api/workspaces/')) {
|
|
327
335
|
const subPath = urlPath.slice('/api/workspaces'.length);
|
|
@@ -31,6 +31,33 @@ export interface DegradedSignal {
|
|
|
31
31
|
nextAction: string;
|
|
32
32
|
/** Source of the degraded signal, e.g. 'internalization_task', 'source_unavailable' */
|
|
33
33
|
source: string;
|
|
34
|
+
/**
|
|
35
|
+
* PRI-556: bounded structured summary of the tasks behind this signal.
|
|
36
|
+
* `reason` carries the same content as one bounded string; this field keeps
|
|
37
|
+
* count + per-task details machine-readable for API consumers. The UI
|
|
38
|
+
* validator currently ignores it (additive field).
|
|
39
|
+
*/
|
|
40
|
+
failureSummary?: DegradedFailureSummary;
|
|
41
|
+
}
|
|
42
|
+
export interface DegradedFailureDetail {
|
|
43
|
+
/** Task kind, e.g. 'artificer' */
|
|
44
|
+
kind: string;
|
|
45
|
+
/**
|
|
46
|
+
* Short high-entropy task code — first 8 chars of the embedded UUID token
|
|
47
|
+
* when present, else the last 12 chars. Full task id remains visible on
|
|
48
|
+
* detail pages.
|
|
49
|
+
*/
|
|
50
|
+
taskId: string;
|
|
51
|
+
/** Bounded last_error excerpt */
|
|
52
|
+
reason: string;
|
|
53
|
+
}
|
|
54
|
+
export interface DegradedFailureSummary {
|
|
55
|
+
/** Bounded human-readable summary, e.g. "3 internalization failures require attention: …" */
|
|
56
|
+
summary: string;
|
|
57
|
+
/** Total number of in-window tasks behind this signal (may exceed details.length) */
|
|
58
|
+
count: number;
|
|
59
|
+
/** At most DEGRADED_SIGNAL_MAX_DETAILS entries */
|
|
60
|
+
details: DegradedFailureDetail[];
|
|
34
61
|
}
|
|
35
62
|
/**
|
|
36
63
|
* Machine-readable codes for governance state reason/nextAction.
|
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
import { SqliteConnection, SqliteApprovalQueueStore, SqlitePIArtifactStore, ApprovalQueue, } from '@principles/core/runtime-v2';
|
|
2
2
|
import * as fs from 'node:fs';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
|
+
/**
|
|
5
|
+
* PRI-556: only failures/retries whose updated_at falls inside this window
|
|
6
|
+
* drive the homepage degraded signal. Terminal `failed` rows have no cleanup
|
|
7
|
+
* path, so counting all history made 'degraded' permanent (signal pollution).
|
|
8
|
+
* Historical rows remain queryable on detail pages.
|
|
9
|
+
*/
|
|
10
|
+
const DEGRADED_SIGNAL_WINDOW_MS = 7 * 24 * 60 * 60 * 1000;
|
|
11
|
+
/** PRI-556: max per-task detail entries embedded in a degraded signal summary. */
|
|
12
|
+
const DEGRADED_SIGNAL_MAX_DETAILS = 5;
|
|
13
|
+
/**
|
|
14
|
+
* Canonical UUID token inside a task id (`<role>-<chain>-<uuid>-<channel>×N`).
|
|
15
|
+
* No `g` flag on purpose: stateless `match`, safe to share across calls.
|
|
16
|
+
*/
|
|
17
|
+
const TASK_ID_UUID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;
|
|
18
|
+
/**
|
|
19
|
+
* PRI-556: short display code for a task id. Prefers the high-entropy UUID
|
|
20
|
+
* head because most task ids end with the same repeated channel suffix
|
|
21
|
+
* (e.g. `…-prompt-prompt-prompt`) — a tail slice would collapse distinct
|
|
22
|
+
* tasks into identical short codes and defeat attribution. Falls back to the
|
|
23
|
+
* tail slice for ids without a canonical UUID token; never throws on
|
|
24
|
+
* unexpected id shapes (rc-1).
|
|
25
|
+
*/
|
|
26
|
+
function shortTaskId(taskId) {
|
|
27
|
+
const uuidMatch = TASK_ID_UUID_RE.exec(taskId);
|
|
28
|
+
if (uuidMatch)
|
|
29
|
+
return uuidMatch[0].slice(0, 8);
|
|
30
|
+
return taskId.length <= 12 ? taskId : taskId.slice(-12);
|
|
31
|
+
}
|
|
32
|
+
function buildFailureSummary(prefix, details) {
|
|
33
|
+
const shown = details.slice(0, DEGRADED_SIGNAL_MAX_DETAILS);
|
|
34
|
+
const shownText = shown.map((d) => `${d.kind}#${d.taskId} (${d.reason})`).join('; ');
|
|
35
|
+
const remaining = details.length - shown.length;
|
|
36
|
+
const summary = `${details.length} ${prefix}${shownText ? `: ${shownText}` : ''}${remaining > 0 ? `; +${remaining} more` : ''}`;
|
|
37
|
+
return { summary, count: details.length, details: shown };
|
|
38
|
+
}
|
|
4
39
|
function isMissingTableError(err) {
|
|
5
40
|
if (!(err instanceof Error))
|
|
6
41
|
return false;
|
|
@@ -87,24 +122,33 @@ export class GovernanceConsoleModel {
|
|
|
87
122
|
};
|
|
88
123
|
});
|
|
89
124
|
// 2. Check internalization pipeline activity (tasks)
|
|
125
|
+
// PRI-556: pipeline activity still counts ALL tasks (drives in_progress),
|
|
126
|
+
// but only in-window failures/retries produce degraded signals.
|
|
90
127
|
let hasInternalizationTasks = false;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const retryWaitReasons = [];
|
|
94
|
-
const failedReasons = [];
|
|
128
|
+
const retryWaitDetails = [];
|
|
129
|
+
const failedDetails = [];
|
|
95
130
|
try {
|
|
96
|
-
const tasks = db.prepare(`SELECT task_kind, status, last_error FROM tasks WHERE task_kind IN ('dreamer', 'philosopher', 'scribe', 'artificer', 'evaluator')`).all();
|
|
131
|
+
const tasks = db.prepare(`SELECT task_id, task_kind, status, last_error, updated_at FROM tasks WHERE task_kind IN ('dreamer', 'philosopher', 'scribe', 'artificer', 'evaluator')`).all();
|
|
97
132
|
hasInternalizationTasks = tasks.length > 0;
|
|
133
|
+
const actionableCutoff = Date.now() - DEGRADED_SIGNAL_WINDOW_MS;
|
|
98
134
|
for (const task of tasks) {
|
|
135
|
+
if (task.status !== 'retry_wait' && task.status !== 'failed')
|
|
136
|
+
continue;
|
|
137
|
+
// updated_at is untrusted row data — malformed timestamps fall
|
|
138
|
+
// outside the window rather than poisoning the signal (rc-1).
|
|
139
|
+
const updatedAtMs = new Date(task.updated_at).getTime();
|
|
140
|
+
if (Number.isNaN(updatedAtMs) || updatedAtMs < actionableCutoff)
|
|
141
|
+
continue;
|
|
142
|
+
const detail = {
|
|
143
|
+
kind: task.task_kind,
|
|
144
|
+
taskId: shortTaskId(task.task_id),
|
|
145
|
+
reason: task.last_error ? task.last_error.substring(0, 120) : 'unknown error',
|
|
146
|
+
};
|
|
99
147
|
if (task.status === 'retry_wait') {
|
|
100
|
-
|
|
101
|
-
const errText = task.last_error ? task.last_error.substring(0, 120) : 'unknown error';
|
|
102
|
-
retryWaitReasons.push(`${task.task_kind}: ${errText}`);
|
|
148
|
+
retryWaitDetails.push(detail);
|
|
103
149
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const errText = task.last_error ? task.last_error.substring(0, 120) : 'unknown error';
|
|
107
|
-
failedReasons.push(`${task.task_kind}: ${errText}`);
|
|
150
|
+
else {
|
|
151
|
+
failedDetails.push(detail);
|
|
108
152
|
}
|
|
109
153
|
}
|
|
110
154
|
}
|
|
@@ -130,22 +174,27 @@ export class GovernanceConsoleModel {
|
|
|
130
174
|
}
|
|
131
175
|
// 4. Degraded signals
|
|
132
176
|
const degradedSignals = [];
|
|
133
|
-
if (
|
|
177
|
+
if (retryWaitDetails.length > 0) {
|
|
178
|
+
// PRI-556: bounded structured summary instead of unbounded concatenation
|
|
179
|
+
const failureSummary = buildFailureSummary('internalization tasks waiting for retry', retryWaitDetails);
|
|
134
180
|
degradedSignals.push({
|
|
135
181
|
reasonCode: 'task_retry_wait',
|
|
136
182
|
nextActionCode: 'check_task_status',
|
|
137
|
-
reason:
|
|
183
|
+
reason: failureSummary.summary,
|
|
138
184
|
nextAction: 'Check internalization pipeline status, or wait for automatic retry.',
|
|
139
185
|
source: 'internalization_task',
|
|
186
|
+
failureSummary,
|
|
140
187
|
});
|
|
141
188
|
}
|
|
142
|
-
if (
|
|
189
|
+
if (failedDetails.length > 0) {
|
|
190
|
+
const failureSummary = buildFailureSummary('internalization failures require attention', failedDetails);
|
|
143
191
|
degradedSignals.push({
|
|
144
192
|
reasonCode: 'task_failed',
|
|
145
193
|
nextActionCode: 'fix_and_retry',
|
|
146
|
-
reason:
|
|
194
|
+
reason: failureSummary.summary,
|
|
147
195
|
nextAction: 'Check failure details, fix the issue and retry.',
|
|
148
196
|
source: 'internalization_task',
|
|
197
|
+
failureSummary,
|
|
149
198
|
});
|
|
150
199
|
}
|
|
151
200
|
if (missingApprovalTable) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GovernanceFacts } from '@principles/core/runtime-v2';
|
|
2
|
+
export declare class GovernanceProjectionCollectionError extends Error {
|
|
3
|
+
readonly reasonCode: 'principle_not_found' | 'governance_projection_error';
|
|
4
|
+
readonly nextActionCode: string;
|
|
5
|
+
constructor(reasonCode: 'principle_not_found' | 'governance_projection_error', nextActionCode: string);
|
|
6
|
+
}
|
|
7
|
+
export declare class GovernanceProjectionCollector {
|
|
8
|
+
private readonly workspaceDir;
|
|
9
|
+
constructor(workspaceDir: string);
|
|
10
|
+
collect(principleId: string, asOf: string): Promise<GovernanceFacts>;
|
|
11
|
+
private readPrinciple;
|
|
12
|
+
private static parseStringArrayJson;
|
|
13
|
+
private static parseTaskRow;
|
|
14
|
+
private static connectedTaskIds;
|
|
15
|
+
private static finish;
|
|
16
|
+
}
|