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.
Files changed (59) hide show
  1. package/console/dist/server/index.js +8 -0
  2. package/console/dist/server/models/GovernanceConsoleModel.d.ts +27 -0
  3. package/console/dist/server/models/GovernanceConsoleModel.js +65 -16
  4. package/console/dist/server/models/GovernanceProjectionCollector.d.ts +16 -0
  5. package/console/dist/server/models/GovernanceProjectionCollector.js +540 -0
  6. package/console/dist/server/routes/principles.d.ts +5 -1
  7. package/console/dist/server/routes/principles.js +44 -1
  8. package/console/dist/ui/api.d.ts +3 -1
  9. package/console/dist/ui/api.js +5 -2
  10. package/console/dist/ui/i18n/en.json +82 -1
  11. package/console/dist/ui/i18n/zh-CN.json +82 -1
  12. package/console/dist/ui/pages/principles/PrincipleDetailPage.js +26 -5
  13. package/console/dist/ui/utils/validators.d.ts +2 -0
  14. package/console/dist/ui/utils/validators.js +82 -10
  15. package/console/dist/web/assets/app.css +16 -0
  16. package/console/dist/web/assets/app.js +304 -6
  17. package/core/dist/runtime-v2/__tests__/governance-projection-contract.test.d.ts +2 -0
  18. package/core/dist/runtime-v2/__tests__/governance-projection-contract.test.d.ts.map +1 -0
  19. package/core/dist/runtime-v2/__tests__/governance-projection-contract.test.js +78 -0
  20. package/core/dist/runtime-v2/__tests__/governance-projection-contract.test.js.map +1 -0
  21. package/core/dist/runtime-v2/__tests__/governance-projection.test.d.ts +2 -0
  22. package/core/dist/runtime-v2/__tests__/governance-projection.test.d.ts.map +1 -0
  23. package/core/dist/runtime-v2/__tests__/governance-projection.test.js +154 -0
  24. package/core/dist/runtime-v2/__tests__/governance-projection.test.js.map +1 -0
  25. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +15 -0
  26. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
  27. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
  28. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +1 -0
  29. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
  30. package/core/dist/runtime-v2/governance-projection-contract.d.ts +721 -0
  31. package/core/dist/runtime-v2/governance-projection-contract.d.ts.map +1 -0
  32. package/core/dist/runtime-v2/governance-projection-contract.js +136 -0
  33. package/core/dist/runtime-v2/governance-projection-contract.js.map +1 -0
  34. package/core/dist/runtime-v2/governance-projection.d.ts +4 -0
  35. package/core/dist/runtime-v2/governance-projection.d.ts.map +1 -0
  36. package/core/dist/runtime-v2/governance-projection.js +176 -0
  37. package/core/dist/runtime-v2/governance-projection.js.map +1 -0
  38. package/core/dist/runtime-v2/index.d.ts +3 -0
  39. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  40. package/core/dist/runtime-v2/index.js +2 -0
  41. package/core/dist/runtime-v2/index.js.map +1 -1
  42. package/package.json +2 -2
  43. package/pd-cli/dist/commands/__tests__/runtime-activation-nextaction.test.d.ts +15 -0
  44. package/pd-cli/dist/commands/__tests__/runtime-activation-nextaction.test.d.ts.map +1 -0
  45. package/pd-cli/dist/commands/__tests__/runtime-activation-nextaction.test.js +73 -0
  46. package/pd-cli/dist/commands/__tests__/runtime-activation-nextaction.test.js.map +1 -0
  47. package/pd-cli/dist/commands/runtime-activation.d.ts +19 -0
  48. package/pd-cli/dist/commands/runtime-activation.d.ts.map +1 -1
  49. package/pd-cli/dist/commands/runtime-activation.js +39 -22
  50. package/pd-cli/dist/commands/runtime-activation.js.map +1 -1
  51. package/pd-cli/dist/commands/runtime-artifact-repair.d.ts +58 -0
  52. package/pd-cli/dist/commands/runtime-artifact-repair.d.ts.map +1 -0
  53. package/pd-cli/dist/commands/runtime-artifact-repair.js +415 -0
  54. package/pd-cli/dist/commands/runtime-artifact-repair.js.map +1 -0
  55. package/pd-cli/dist/index.js +19 -0
  56. package/pd-cli/dist/index.js.map +1 -1
  57. package/plugin/dist/bundle.js +472 -472
  58. package/plugin/openclaw.plugin.json +1 -1
  59. 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
- let hasRetryWaitTasks = false;
92
- let hasFailedTasks = false;
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
- hasRetryWaitTasks = true;
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
- if (task.status === 'failed') {
105
- hasFailedTasks = true;
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 (hasRetryWaitTasks) {
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: `Internalization task waiting for retry: ${retryWaitReasons.join('; ')}`,
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 (hasFailedTasks) {
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: `Internalization task failed: ${failedReasons.join('; ')}`,
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
+ }