create-principles-disciple 1.124.2 → 1.125.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/core/dist/index.d.ts +3 -3
- package/core/dist/index.js +3 -3
- package/core/dist/runtime-v2/__tests__/pain-signal-observability.test.js +93 -0
- package/core/dist/runtime-v2/__tests__/pain-signal-observability.test.js.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +2 -0
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/runtime-v2/pain-signal-bridge.d.ts +8 -1
- package/core/dist/runtime-v2/pain-signal-bridge.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-bridge.js.map +1 -1
- package/core/dist/runtime-v2/pain-signal-observability.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-observability.js +25 -10
- package/core/dist/runtime-v2/pain-signal-observability.js.map +1 -1
- package/core/package.json +0 -1
- package/host-runtime/dist/governance-signal-admission.js +11 -5
- package/host-runtime/dist/index.d.ts +3 -0
- package/host-runtime/dist/index.js +1 -0
- package/host-runtime/dist/production-pain-evidence.d.ts +7 -0
- package/host-runtime/dist/production-pain-evidence.js +9 -4
- package/package.json +1 -1
- package/pd-cli/dist/commands/pain-list.d.ts +45 -0
- package/pd-cli/dist/commands/pain-list.d.ts.map +1 -0
- package/pd-cli/dist/commands/pain-list.js +165 -0
- package/pd-cli/dist/commands/pain-list.js.map +1 -0
- package/pd-cli/dist/index.js +11 -0
- package/pd-cli/dist/index.js.map +1 -1
- package/plugin/dist/bundle.js +27 -23
- package/plugin/dist/core/trajectory-types.d.ts +2 -0
- package/plugin/dist/rulehost-evidence.js +9 -7
- package/core/dist/adapters/__tests__/code-review-pain-adapter.test.d.ts +0 -2
- package/core/dist/adapters/__tests__/code-review-pain-adapter.test.d.ts.map +0 -1
- package/core/dist/adapters/__tests__/code-review-pain-adapter.test.js +0 -346
- package/core/dist/adapters/__tests__/code-review-pain-adapter.test.js.map +0 -1
- package/core/dist/adapters/__tests__/openclaw-pain-adapter.test.d.ts +0 -2
- package/core/dist/adapters/__tests__/openclaw-pain-adapter.test.d.ts.map +0 -1
- package/core/dist/adapters/__tests__/openclaw-pain-adapter.test.js +0 -290
- package/core/dist/adapters/__tests__/openclaw-pain-adapter.test.js.map +0 -1
- package/core/dist/adapters/__tests__/writing-pain-adapter.test.d.ts +0 -2
- package/core/dist/adapters/__tests__/writing-pain-adapter.test.d.ts.map +0 -1
- package/core/dist/adapters/__tests__/writing-pain-adapter.test.js +0 -239
- package/core/dist/adapters/__tests__/writing-pain-adapter.test.js.map +0 -1
- package/core/dist/adapters/code-review/code-review-pain-adapter.d.ts +0 -13
- package/core/dist/adapters/code-review/code-review-pain-adapter.d.ts.map +0 -1
- package/core/dist/adapters/code-review/code-review-pain-adapter.js +0 -139
- package/core/dist/adapters/code-review/code-review-pain-adapter.js.map +0 -1
- package/core/dist/adapters/code-review/index.d.ts +0 -6
- package/core/dist/adapters/code-review/index.d.ts.map +0 -1
- package/core/dist/adapters/code-review/index.js +0 -2
- package/core/dist/adapters/code-review/index.js.map +0 -1
- package/core/dist/adapters/code-review/review-event-types.d.ts +0 -54
- package/core/dist/adapters/code-review/review-event-types.d.ts.map +0 -1
- package/core/dist/adapters/code-review/review-event-types.js +0 -8
- package/core/dist/adapters/code-review/review-event-types.js.map +0 -1
- package/core/dist/adapters/coding/index.d.ts +0 -6
- package/core/dist/adapters/coding/index.d.ts.map +0 -1
- package/core/dist/adapters/coding/index.js +0 -5
- package/core/dist/adapters/coding/index.js.map +0 -1
- package/core/dist/adapters/coding/openclaw-event-types.d.ts +0 -26
- package/core/dist/adapters/coding/openclaw-event-types.d.ts.map +0 -1
- package/core/dist/adapters/coding/openclaw-event-types.js +0 -9
- package/core/dist/adapters/coding/openclaw-event-types.js.map +0 -1
- package/core/dist/adapters/coding/openclaw-pain-adapter.d.ts +0 -27
- package/core/dist/adapters/coding/openclaw-pain-adapter.d.ts.map +0 -1
- package/core/dist/adapters/coding/openclaw-pain-adapter.js +0 -102
- package/core/dist/adapters/coding/openclaw-pain-adapter.js.map +0 -1
- package/core/dist/adapters/writing/index.d.ts +0 -6
- package/core/dist/adapters/writing/index.d.ts.map +0 -1
- package/core/dist/adapters/writing/index.js +0 -5
- package/core/dist/adapters/writing/index.js.map +0 -1
- package/core/dist/adapters/writing/writing-pain-adapter.d.ts +0 -22
- package/core/dist/adapters/writing/writing-pain-adapter.d.ts.map +0 -1
- package/core/dist/adapters/writing/writing-pain-adapter.js +0 -62
- package/core/dist/adapters/writing/writing-pain-adapter.js.map +0 -1
- package/core/dist/adapters/writing/writing-types.d.ts +0 -34
- package/core/dist/adapters/writing/writing-types.d.ts.map +0 -1
- package/core/dist/adapters/writing/writing-types.js +0 -9
- package/core/dist/adapters/writing/writing-types.js.map +0 -1
- package/core/dist/pain-signal-adapter.d.ts +0 -37
- package/core/dist/pain-signal-adapter.d.ts.map +0 -1
- package/core/dist/pain-signal-adapter.js +0 -2
- package/core/dist/pain-signal-adapter.js.map +0 -1
- package/core/dist/pain-signal.d.ts +0 -16
- package/core/dist/pain-signal.d.ts.map +0 -1
- package/core/dist/pain-signal.js +0 -15
- package/core/dist/pain-signal.js.map +0 -1
- package/core/dist/runtime-v2/__tests__/pain-signal-unification.test.d.ts +0 -2
- package/core/dist/runtime-v2/__tests__/pain-signal-unification.test.d.ts.map +0 -1
- package/core/dist/runtime-v2/__tests__/pain-signal-unification.test.js +0 -150
- package/core/dist/runtime-v2/__tests__/pain-signal-unification.test.js.map +0 -1
|
@@ -138,6 +138,7 @@ function ensureTrajectorySchema(db) {
|
|
|
138
138
|
text TEXT,
|
|
139
139
|
canonical_pain_id TEXT,
|
|
140
140
|
runtime_task_id TEXT,
|
|
141
|
+
host_kind TEXT,
|
|
141
142
|
created_at TEXT NOT NULL
|
|
142
143
|
);
|
|
143
144
|
CREATE TABLE IF NOT EXISTS gate_blocks (
|
|
@@ -252,6 +253,9 @@ function ensureTrajectorySchema(db) {
|
|
|
252
253
|
for (const col of [
|
|
253
254
|
{ name: 'canonical_pain_id', type: 'TEXT' },
|
|
254
255
|
{ name: 'runtime_task_id', type: 'TEXT' },
|
|
256
|
+
// PRI-640: host attribution — observability metadata only, orthogonal to
|
|
257
|
+
// `origin` (evidence semantics) and excluded from canonical pain identity.
|
|
258
|
+
{ name: 'host_kind', type: 'TEXT' },
|
|
255
259
|
]) {
|
|
256
260
|
try {
|
|
257
261
|
db.exec(`ALTER TABLE pain_events ADD COLUMN ${col.name} ${col.type}`);
|
|
@@ -325,6 +329,7 @@ function ensureTrajectorySchema(db) {
|
|
|
325
329
|
`);
|
|
326
330
|
return { tables, warnings };
|
|
327
331
|
}
|
|
332
|
+
/** PRI-640: id of the pain_events row (undefined when the dedup row could not be re-read); warnings carry host_kind conflict evidence. */
|
|
328
333
|
function recordTrajectoryPainEvent(opts) {
|
|
329
334
|
const { stateDir, data, timestamp, workspaceDir, canonicalPainId, runtimeTaskId } = opts;
|
|
330
335
|
const dbPath = nodePath.join(stateDir, 'trajectory.db');
|
|
@@ -352,14 +357,15 @@ function recordTrajectoryPainEvent(opts) {
|
|
|
352
357
|
// Try INSERT; on UNIQUE constraint violation for canonical_pain_id, do UPDATE instead.
|
|
353
358
|
// SQLite UPSERT (ON CONFLICT) does not support partial unique indexes, so we
|
|
354
359
|
// handle the conflict manually.
|
|
360
|
+
const warnings = [];
|
|
355
361
|
try {
|
|
356
362
|
const result = db.prepare(`
|
|
357
363
|
INSERT INTO pain_events (
|
|
358
364
|
session_id, source, score, reason, severity, origin, confidence, text, created_at,
|
|
359
|
-
canonical_pain_id, runtime_task_id
|
|
360
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
361
|
-
`).run(sessionId, data.source, data.score ?? 80, sanitizeString(data.reason ?? '', workspaceDir), severityFromScore(data.score ?? 80), data.source === 'manual' ? 'user_manual' : 'system_infer', 1, sanitizeString(data.reason ?? '', workspaceDir), timestamp, canonicalPainId ?? null, runtimeTaskId ?? null);
|
|
362
|
-
return Number(result.lastInsertRowid);
|
|
365
|
+
canonical_pain_id, runtime_task_id, host_kind
|
|
366
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
367
|
+
`).run(sessionId, data.source, data.score ?? 80, sanitizeString(data.reason ?? '', workspaceDir), severityFromScore(data.score ?? 80), data.source === 'manual' ? 'user_manual' : 'system_infer', 1, sanitizeString(data.reason ?? '', workspaceDir), timestamp, canonicalPainId ?? null, runtimeTaskId ?? null, data.hostKind ?? null);
|
|
368
|
+
return { id: Number(result.lastInsertRowid), warnings };
|
|
363
369
|
}
|
|
364
370
|
catch (insertErr) {
|
|
365
371
|
// If UNIQUE constraint violation on canonical_pain_id, upsert manually
|
|
@@ -369,15 +375,22 @@ function recordTrajectoryPainEvent(opts) {
|
|
|
369
375
|
insertErr.message.includes('canonical_pain_id')) {
|
|
370
376
|
db.prepare(`
|
|
371
377
|
UPDATE pain_events
|
|
372
|
-
SET runtime_task_id = COALESCE(?, runtime_task_id)
|
|
378
|
+
SET runtime_task_id = COALESCE(?, runtime_task_id),
|
|
379
|
+
host_kind = COALESCE(host_kind, ?)
|
|
373
380
|
WHERE canonical_pain_id = ?
|
|
374
|
-
`).run(runtimeTaskId ?? null, canonicalPainId);
|
|
375
|
-
const rawRow = db.prepare('SELECT id FROM pain_events WHERE canonical_pain_id = ?').get(canonicalPainId);
|
|
381
|
+
`).run(runtimeTaskId ?? null, data.hostKind ?? null, canonicalPainId);
|
|
382
|
+
const rawRow = db.prepare('SELECT id, host_kind FROM pain_events WHERE canonical_pain_id = ?').get(canonicalPainId);
|
|
376
383
|
// Runtime Contract #1/#2: validate DB row instead of `as` cast
|
|
377
384
|
if (rawRow && typeof rawRow === 'object' && Object.hasOwn(rawRow, 'id') && typeof rawRow.id === 'number') {
|
|
378
|
-
|
|
385
|
+
// PRI-640 §16: keep the first durable host attribution; never overwrite.
|
|
386
|
+
// A differing re-attempt is surfaced as a bounded warning (rc-9-no-silent-fallback).
|
|
387
|
+
const durableHostKind = Object.getOwnPropertyDescriptor(rawRow, 'host_kind')?.value;
|
|
388
|
+
if (data.hostKind && typeof durableHostKind === 'string' && durableHostKind !== data.hostKind) {
|
|
389
|
+
warnings.push(`host_kind_conflict:kept=${durableHostKind},rejected=${data.hostKind}`);
|
|
390
|
+
}
|
|
391
|
+
return { id: rawRow.id, warnings };
|
|
379
392
|
}
|
|
380
|
-
return undefined;
|
|
393
|
+
return { id: undefined, warnings };
|
|
381
394
|
}
|
|
382
395
|
throw insertErr;
|
|
383
396
|
}
|
|
@@ -445,10 +458,12 @@ export function recordPainSignalObservability(opts) {
|
|
|
445
458
|
warnings.push(`evolution stream write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
446
459
|
}
|
|
447
460
|
try {
|
|
448
|
-
|
|
461
|
+
const trajectory = recordTrajectoryPainEvent({
|
|
449
462
|
stateDir: opts.stateDir, data: opts.data, timestamp, workspaceDir: opts.workspaceDir,
|
|
450
463
|
canonicalPainId: opts.canonicalPainId, runtimeTaskId: opts.runtimeTaskId,
|
|
451
464
|
});
|
|
465
|
+
result.trajectoryPainEventId = trajectory.id;
|
|
466
|
+
warnings.push(...trajectory.warnings);
|
|
452
467
|
}
|
|
453
468
|
catch (err) {
|
|
454
469
|
warnings.push(`trajectory pain_events write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pain-signal-observability.js","sourceRoot":"","sources":["../../src/runtime-v2/pain-signal-observability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,QAAQ,MAAM,MAAM,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAmBzD,SAAS,MAAM;IACb,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAED,SAAS,QAAQ,CAAC,EAAU;IAC1B,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACtC,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,QAAQ,CAAC;IACjC,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,UAAU,CAAC;IACnC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,cAAc,CAAC,QAAgB,EAAE,KAAc;IACtD,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,kBAAkB,CAAC,EAAqB;IAC/C,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,GAAG,EAAwB,CAAC;IACnF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAS,sBAAsB,CAAC,EAAqB;IACnD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG;QACb,gBAAgB,EAAE,mBAAmB,EAAE,UAAU,EAAE,iBAAiB;QACpE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe;QACzE,kBAAkB,EAAE,eAAe,EAAE,oBAAoB,EAAE,gBAAgB;QAC3E,eAAe,EAAE,iBAAiB,EAAE,kBAAkB;KACvD,CAAC;IAEF,EAAE,CAAC,IAAI,CAAC
|
|
1
|
+
{"version":3,"file":"pain-signal-observability.js","sourceRoot":"","sources":["../../src/runtime-v2/pain-signal-observability.ts"],"names":[],"mappings":"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"}
|
package/core/package.json
CHANGED
|
@@ -342,9 +342,9 @@ function insertCorrectionPain({ db, candidate, workspaceDir, painId, detection,
|
|
|
342
342
|
// is NOT used here: buildEvidence already truncated it upstream, so a token
|
|
343
343
|
// straddling that cut would survive sanitization the same way.
|
|
344
344
|
const excerpt = sanitizeString(candidate.text, workspaceDir);
|
|
345
|
-
db.prepare(`INSERT INTO pain_events (session_id, source, score, reason, severity, origin, confidence, text, canonical_pain_id, runtime_task_id, created_at)
|
|
346
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
347
|
-
.run(candidate.rootSessionId, 'user_correction', GOVERNANCE_STRONG_PAIN_SCORE, reason.slice(0, MAX_REASON_BOUND), 'severe', 'system_infer', null, excerpt, painId, null, nowIso);
|
|
345
|
+
db.prepare(`INSERT INTO pain_events (session_id, source, score, reason, severity, origin, confidence, text, canonical_pain_id, runtime_task_id, host_kind, created_at)
|
|
346
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
347
|
+
.run(candidate.rootSessionId, 'user_correction', GOVERNANCE_STRONG_PAIN_SCORE, reason.slice(0, MAX_REASON_BOUND), 'severe', 'system_infer', null, excerpt, painId, null, candidate.hostKind, nowIso);
|
|
348
348
|
return reason;
|
|
349
349
|
}
|
|
350
350
|
function taskSubmissionPayload(candidate, workspaceDir, reason) {
|
|
@@ -415,6 +415,9 @@ function admitCorrection({ db, candidate, workspaceDir, now, nowIso, keywordStor
|
|
|
415
415
|
// Live + transcript duplicate or a crash-replay: the canonical pain
|
|
416
416
|
// already exists — no second row, no second quota consumption.
|
|
417
417
|
duplicate = true;
|
|
418
|
+
// PRI-640 §17: enrich unknown → codex from proven governance lineage;
|
|
419
|
+
// the IS NULL guard keeps any durable attribution (never overwrites).
|
|
420
|
+
db.prepare('UPDATE pain_events SET host_kind = ? WHERE canonical_pain_id = ? AND host_kind IS NULL').run(candidate.hostKind, painId);
|
|
418
421
|
}
|
|
419
422
|
else {
|
|
420
423
|
if (!tryConsumeRateLimit({ db, rootSessionId: candidate.rootSessionId, ruleVersion: detection.ruleVersion, now })) {
|
|
@@ -488,9 +491,12 @@ function admitToolFailure({ db, candidate, workspaceDir, nowIso }) {
|
|
|
488
491
|
db.prepare(`INSERT INTO tool_calls (session_id, tool_name, outcome, duration_ms, exit_code, error_type, error_message, gfi_before, gfi_after, params_json, result_preview, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
489
492
|
.run(candidate.rootSessionId, candidate.toolName, outcome.failure ? 'failure' : 'success', outcome.durationMs ?? null, outcome.exitCode, outcome.error ? outcome.error.split(/[\s:]/, 1)[0] : null, outcome.error ?? null, null, null, paramsJson, resultPreview, nowIso);
|
|
490
493
|
reason = `tool=${candidate.toolName}; error=${outcome.error ?? `exit=${outcome.exitCode}`}; path=${relativePath}`;
|
|
491
|
-
db.prepare(`INSERT INTO pain_events (session_id, source, score, reason, severity, origin, confidence, text, canonical_pain_id, runtime_task_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
492
|
-
.run(candidate.rootSessionId, sourceObservation.failureSource ?? 'tool_failure', painScore, reason, painScore >= 70 ? 'severe' : painScore >= 40 ? 'moderate' : 'mild', 'system_infer', null, null, painId, null, nowIso);
|
|
494
|
+
db.prepare(`INSERT INTO pain_events (session_id, source, score, reason, severity, origin, confidence, text, canonical_pain_id, runtime_task_id, host_kind, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
495
|
+
.run(candidate.rootSessionId, sourceObservation.failureSource ?? 'tool_failure', painScore, reason, painScore >= 70 ? 'severe' : painScore >= 40 ? 'moderate' : 'mild', 'system_infer', null, null, painId, null, candidate.hostKind, nowIso);
|
|
493
496
|
}
|
|
497
|
+
// PRI-640 §17: enrich unknown → codex on the already-admitted duplicate
|
|
498
|
+
// pain row; the IS NULL guard keeps any durable attribution.
|
|
499
|
+
db.prepare('UPDATE pain_events SET host_kind = ? WHERE canonical_pain_id = ? AND host_kind IS NULL').run(candidate.hostKind, painId);
|
|
494
500
|
if (!duplicateWithoutPain) {
|
|
495
501
|
insertAdmissionMarker({ db, candidate, workspaceDir, canonicalPainId: painId, ruleVersion: null, reason: sanitizeString(reason, workspaceDir), nowIso });
|
|
496
502
|
}
|
|
@@ -3,6 +3,7 @@ import { buildActivePrinciplePromptContext } from './active-principle-prompt.js'
|
|
|
3
3
|
import { type RuleContextProvider, type RuleInputEnrichmentProvider } from './production-rulehost-gate.js';
|
|
4
4
|
import type { RuleImplementationRuntime } from './rule-implementation-runtime.js';
|
|
5
5
|
import { type PainDatabaseFactory, type PainEnrichmentProvider } from './production-pain-evidence.js';
|
|
6
|
+
import type { GovernanceHostKind } from '@principles/core/runtime-v2';
|
|
6
7
|
export * from './active-principle-prompt.js';
|
|
7
8
|
export * from './pd-config.js';
|
|
8
9
|
export * from './production-rulehost-gate.js';
|
|
@@ -53,4 +54,6 @@ export declare function createProductionHostRuntime(options?: Partial<Pick<HostR
|
|
|
53
54
|
ruleImplementationRuntime?: RuleImplementationRuntime;
|
|
54
55
|
painEnrichmentProvider?: PainEnrichmentProvider;
|
|
55
56
|
painDatabaseFactory?: PainDatabaseFactory;
|
|
57
|
+
/** PRI-640: host attribution supplied by the constructing host adapter (OpenClaw / Codex). */
|
|
58
|
+
hostKind?: GovernanceHostKind;
|
|
56
59
|
}): HostRuntime;
|
|
@@ -146,6 +146,7 @@ export function createProductionHostRuntime(options = {}) {
|
|
|
146
146
|
afterToolCall: options.afterToolCall ?? createProductionPainEvidenceHandler({
|
|
147
147
|
...(options.painEnrichmentProvider ? { painEnrichmentProvider: options.painEnrichmentProvider } : {}),
|
|
148
148
|
...(options.painDatabaseFactory ? { painDatabaseFactory: options.painDatabaseFactory } : {}),
|
|
149
|
+
...(options.hostKind ? { hostKind: options.hostKind } : {}),
|
|
149
150
|
}),
|
|
150
151
|
beforeToolCall: options.beforeToolCall ?? productionGate,
|
|
151
152
|
async beforePromptBuild(event) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Database from 'better-sqlite3';
|
|
2
|
+
import type { GovernanceHostKind } from '@principles/core/runtime-v2';
|
|
2
3
|
import type { HostEvent, HostEventResult } from '@principles/core/host';
|
|
3
4
|
/** Shared with the governance admission path so both gate tool failures identically. */
|
|
4
5
|
export declare const PRODUCTION_WRITE_TOOLS: ReadonlySet<string>;
|
|
@@ -75,9 +76,15 @@ export declare function deriveProductionCorrectionPainIdentity(fields: {
|
|
|
75
76
|
painId: string;
|
|
76
77
|
};
|
|
77
78
|
declare function hasCanonicalSchema(db: Database.Database): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* PRI-640: host attribution is supplied by the host adapter that constructs
|
|
81
|
+
* this shared handler (OpenClaw / Codex adapters) — never guessed inside the
|
|
82
|
+
* writer. Omitted -> NULL (unknown).
|
|
83
|
+
*/
|
|
78
84
|
export declare function createProductionPainEvidenceHandler(options?: {
|
|
79
85
|
painEnrichmentProvider?: PainEnrichmentProvider;
|
|
80
86
|
painDatabaseFactory?: PainDatabaseFactory;
|
|
87
|
+
hostKind?: GovernanceHostKind;
|
|
81
88
|
}): (event: HostEvent) => Promise<HostEventResult>;
|
|
82
89
|
export declare function resetProductionPainCooldownForTest(): void;
|
|
83
90
|
export declare function productionPainCooldownEntryCountForTest(): number;
|
|
@@ -173,7 +173,7 @@ export function deriveProductionCorrectionPainIdentity(fields) {
|
|
|
173
173
|
const REQUIRED_COLUMNS = {
|
|
174
174
|
sessions: { session_id: 'TEXT', started_at: 'TEXT', updated_at: 'TEXT' },
|
|
175
175
|
tool_calls: { session_id: 'TEXT', tool_name: 'TEXT', outcome: 'TEXT', duration_ms: 'INTEGER', exit_code: 'INTEGER', error_type: 'TEXT', error_message: 'TEXT', gfi_before: 'REAL', gfi_after: 'REAL', params_json: 'TEXT', result_preview: 'TEXT', created_at: 'TEXT' },
|
|
176
|
-
pain_events: { session_id: 'TEXT', source: 'TEXT', score: 'REAL', reason: 'TEXT', severity: 'TEXT', origin: 'TEXT', confidence: 'REAL', text: 'TEXT', canonical_pain_id: 'TEXT', runtime_task_id: 'TEXT', created_at: 'TEXT' },
|
|
176
|
+
pain_events: { session_id: 'TEXT', source: 'TEXT', score: 'REAL', reason: 'TEXT', severity: 'TEXT', origin: 'TEXT', confidence: 'REAL', text: 'TEXT', canonical_pain_id: 'TEXT', runtime_task_id: 'TEXT', host_kind: 'TEXT', created_at: 'TEXT' },
|
|
177
177
|
};
|
|
178
178
|
function pragmaField(row, key) {
|
|
179
179
|
return isRecord(row) && Object.hasOwn(row, key) ? Object.getOwnPropertyDescriptor(row, key)?.value : undefined;
|
|
@@ -224,9 +224,14 @@ function hasCanonicalSchema(db) {
|
|
|
224
224
|
db.prepare('SELECT 1 FROM pain_events WHERE canonical_pain_id = ?');
|
|
225
225
|
db.prepare('INSERT INTO sessions (session_id, started_at, updated_at) VALUES (?, ?, ?) ON CONFLICT(session_id) DO UPDATE SET updated_at = excluded.updated_at');
|
|
226
226
|
db.prepare('INSERT INTO tool_calls (session_id, tool_name, outcome, duration_ms, exit_code, error_type, error_message, gfi_before, gfi_after, params_json, result_preview, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
227
|
-
db.prepare('INSERT INTO pain_events (session_id, source, score, reason, severity, origin, confidence, text, canonical_pain_id, runtime_task_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
227
|
+
db.prepare('INSERT INTO pain_events (session_id, source, score, reason, severity, origin, confidence, text, canonical_pain_id, runtime_task_id, host_kind, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
228
228
|
return true;
|
|
229
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* PRI-640: host attribution is supplied by the host adapter that constructs
|
|
232
|
+
* this shared handler (OpenClaw / Codex adapters) — never guessed inside the
|
|
233
|
+
* writer. Omitted -> NULL (unknown).
|
|
234
|
+
*/
|
|
230
235
|
export function createProductionPainEvidenceHandler(options = {}) {
|
|
231
236
|
return async (event) => {
|
|
232
237
|
const dbPath = path.join(event.context.workspaceDir, '.state', 'trajectory.db');
|
|
@@ -319,8 +324,8 @@ export function createProductionPainEvidenceHandler(options = {}) {
|
|
|
319
324
|
// declared enum (event-types.ts: who reported the pain), not an
|
|
320
325
|
// attribution claim.
|
|
321
326
|
const reason = `tool=${toolName}; error=${outcome.error ?? `exit=${outcome.exitCode}`}; path=${relativePath}`;
|
|
322
|
-
db.prepare(`INSERT INTO pain_events (session_id, source, score, reason, severity, origin, confidence, text, canonical_pain_id, runtime_task_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
323
|
-
.run(event.context.sessionId, sourceObservation.failureSource ?? 'tool_failure', painScore, reason, painScore >= 70 ? 'severe' : painScore >= 40 ? 'moderate' : 'mild', 'system_infer', null, enrichment.evidence?.map((entry) => `${entry.sourceRef}: ${entry.note}`).join('\n') ?? null, painId, null, createdAt);
|
|
327
|
+
db.prepare(`INSERT INTO pain_events (session_id, source, score, reason, severity, origin, confidence, text, canonical_pain_id, runtime_task_id, host_kind, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
328
|
+
.run(event.context.sessionId, sourceObservation.failureSource ?? 'tool_failure', painScore, reason, painScore >= 70 ? 'severe' : painScore >= 40 ? 'moderate' : 'mild', 'system_infer', null, enrichment.evidence?.map((entry) => `${entry.sourceRef}: ${entry.note}`).join('\n') ?? null, painId, null, options.hostKind ?? null, createdAt);
|
|
324
329
|
}
|
|
325
330
|
})();
|
|
326
331
|
if (admitted && !duplicate) {
|
package/package.json
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pd pain list command — PRI-640 (Governance Signal Host Attribution v0.1)
|
|
3
|
+
*
|
|
4
|
+
* Read-only: lists canonical pain_events rows from trajectory.db with their
|
|
5
|
+
* host attribution. `--host` filters by openclaw / codex / unknown.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* pd pain list [--workspace <path>] [--limit N] [--host openclaw|codex|unknown] [--json]
|
|
9
|
+
*
|
|
10
|
+
* Host semantics (SPEC §6/§12): host_kind is observability metadata only.
|
|
11
|
+
* NULL (legacy / manual / unprovable) is reported as `unknown` — never guessed.
|
|
12
|
+
* On a pre-PRI-640 database without the host_kind column every row reports
|
|
13
|
+
* `unknown` and a `host_kind_column_missing` warning is emitted (rc-9).
|
|
14
|
+
*/
|
|
15
|
+
export type PainListHostFilter = 'openclaw' | 'codex' | 'unknown';
|
|
16
|
+
export interface PainListOptions {
|
|
17
|
+
workspace?: string;
|
|
18
|
+
limit?: number;
|
|
19
|
+
host?: string;
|
|
20
|
+
json?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface PainListEntry {
|
|
23
|
+
/** Canonical pain identity; `row:<id>` when the legacy row has none. */
|
|
24
|
+
painId: string;
|
|
25
|
+
source: string;
|
|
26
|
+
/** 'openclaw' | 'codex' | 'unknown' — unknown covers NULL/unprovable. */
|
|
27
|
+
host: PainListHostFilter | 'unknown';
|
|
28
|
+
score: number;
|
|
29
|
+
severity: string | null;
|
|
30
|
+
createdAt: string;
|
|
31
|
+
runtimeTaskId: string | null;
|
|
32
|
+
}
|
|
33
|
+
export interface PainListResult {
|
|
34
|
+
count: number;
|
|
35
|
+
pains: PainListEntry[];
|
|
36
|
+
workspace: string;
|
|
37
|
+
hostFilter: PainListHostFilter | null;
|
|
38
|
+
warnings: string[];
|
|
39
|
+
}
|
|
40
|
+
export declare function listPains(dbPath: string, options?: {
|
|
41
|
+
limit?: number;
|
|
42
|
+
host?: PainListHostFilter;
|
|
43
|
+
}): Promise<PainListResult>;
|
|
44
|
+
export declare function handlePainList(opts: PainListOptions): Promise<void>;
|
|
45
|
+
//# sourceMappingURL=pain-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pain-list.d.ts","sourceRoot":"","sources":["../../src/commands/pain-list.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AAElE,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,IAAI,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACtC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAoCD,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,kBAAkB,CAAA;CAAO,GAAG,OAAO,CAAC,cAAc,CAAC,CA+CpI;AAoBD,wBAAsB,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDzE"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pd pain list command — PRI-640 (Governance Signal Host Attribution v0.1)
|
|
3
|
+
*
|
|
4
|
+
* Read-only: lists canonical pain_events rows from trajectory.db with their
|
|
5
|
+
* host attribution. `--host` filters by openclaw / codex / unknown.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* pd pain list [--workspace <path>] [--limit N] [--host openclaw|codex|unknown] [--json]
|
|
9
|
+
*
|
|
10
|
+
* Host semantics (SPEC §6/§12): host_kind is observability metadata only.
|
|
11
|
+
* NULL (legacy / manual / unprovable) is reported as `unknown` — never guessed.
|
|
12
|
+
* On a pre-PRI-640 database without the host_kind column every row reports
|
|
13
|
+
* `unknown` and a `host_kind_column_missing` warning is emitted (rc-9).
|
|
14
|
+
*/
|
|
15
|
+
import * as fs from 'fs';
|
|
16
|
+
import * as path from 'path';
|
|
17
|
+
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
18
|
+
function isRecord(value) {
|
|
19
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
20
|
+
}
|
|
21
|
+
function ownField(row, key) {
|
|
22
|
+
return isRecord(row) && Object.hasOwn(row, key) ? row[key] : undefined;
|
|
23
|
+
}
|
|
24
|
+
/** Runtime Contract #1/#4: validate each DB row; skip malformed rows loudly. */
|
|
25
|
+
function toPainEntry(row) {
|
|
26
|
+
const id = ownField(row, 'id');
|
|
27
|
+
const source = ownField(row, 'source');
|
|
28
|
+
const score = ownField(row, 'score');
|
|
29
|
+
const createdAt = ownField(row, 'created_at');
|
|
30
|
+
if (typeof id !== 'number' || typeof source !== 'string' || typeof score !== 'number' || typeof createdAt !== 'string') {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const canonicalPainId = ownField(row, 'canonical_pain_id');
|
|
34
|
+
const hostKind = ownField(row, 'host_kind');
|
|
35
|
+
const severity = ownField(row, 'severity');
|
|
36
|
+
const runtimeTaskId = ownField(row, 'runtime_task_id');
|
|
37
|
+
const host = hostKind === 'openclaw' || hostKind === 'codex' ? hostKind : 'unknown';
|
|
38
|
+
return {
|
|
39
|
+
painId: typeof canonicalPainId === 'string' && canonicalPainId.length > 0 ? canonicalPainId : `row:${id}`,
|
|
40
|
+
source,
|
|
41
|
+
host,
|
|
42
|
+
score,
|
|
43
|
+
severity: typeof severity === 'string' ? severity : null,
|
|
44
|
+
createdAt,
|
|
45
|
+
runtimeTaskId: typeof runtimeTaskId === 'string' && runtimeTaskId.length > 0 ? runtimeTaskId : null,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export async function listPains(dbPath, options = {}) {
|
|
49
|
+
const Database = (await import('better-sqlite3')).default;
|
|
50
|
+
const db = new Database(dbPath, { readonly: true });
|
|
51
|
+
try {
|
|
52
|
+
const warnings = [];
|
|
53
|
+
const columns = db.prepare('PRAGMA table_info(pain_events)').all();
|
|
54
|
+
const hasHostKindColumn = columns.some((row) => ownField(row, 'name') === 'host_kind');
|
|
55
|
+
if (!hasHostKindColumn) {
|
|
56
|
+
warnings.push('host_kind_column_missing');
|
|
57
|
+
}
|
|
58
|
+
const params = [];
|
|
59
|
+
let query = 'SELECT id, source, score, severity, created_at, canonical_pain_id, runtime_task_id';
|
|
60
|
+
query += hasHostKindColumn ? ', host_kind' : ", NULL AS host_kind";
|
|
61
|
+
query += ' FROM pain_events WHERE 1=1';
|
|
62
|
+
if (options.host === 'unknown') {
|
|
63
|
+
query += hasHostKindColumn ? ' AND host_kind IS NULL' : '';
|
|
64
|
+
}
|
|
65
|
+
else if (options.host === 'openclaw' || options.host === 'codex') {
|
|
66
|
+
if (!hasHostKindColumn) {
|
|
67
|
+
return { count: 0, pains: [], workspace: path.dirname(path.dirname(dbPath)), hostFilter: options.host, warnings };
|
|
68
|
+
}
|
|
69
|
+
query += ' AND host_kind = ?';
|
|
70
|
+
params.push(options.host);
|
|
71
|
+
}
|
|
72
|
+
query += ' ORDER BY created_at DESC, id DESC';
|
|
73
|
+
const limit = options.limit ?? 20;
|
|
74
|
+
query += ' LIMIT ?';
|
|
75
|
+
params.push(limit);
|
|
76
|
+
const rawRows = db.prepare(query).all(...params);
|
|
77
|
+
const skipped = rawRows.length - rawRows.map(toPainEntry).filter((entry) => entry !== null).length;
|
|
78
|
+
if (skipped > 0) {
|
|
79
|
+
warnings.push(`malformed_rows_skipped:${skipped}`);
|
|
80
|
+
}
|
|
81
|
+
const pains = rawRows
|
|
82
|
+
.map(toPainEntry)
|
|
83
|
+
.filter((entry) => entry !== null);
|
|
84
|
+
return {
|
|
85
|
+
count: pains.length,
|
|
86
|
+
pains,
|
|
87
|
+
workspace: path.dirname(path.dirname(dbPath)),
|
|
88
|
+
hostFilter: options.host ?? null,
|
|
89
|
+
warnings,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
db.close();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function printHuman(result) {
|
|
97
|
+
const filterNote = result.hostFilter ? ` (host: ${result.hostFilter})` : '';
|
|
98
|
+
console.log(`Pain events — ${result.count} shown${filterNote}`);
|
|
99
|
+
console.log('─'.repeat(96));
|
|
100
|
+
for (const pain of result.pains) {
|
|
101
|
+
const painId = pain.painId.length > 40 ? `${pain.painId.slice(0, 37)}...` : pain.painId;
|
|
102
|
+
console.log(` ${pain.createdAt} host=${pain.host.padEnd(8)} score=${String(pain.score).padEnd(3)} ${pain.severity ?? '-'.padEnd(6)} ${pain.source}`);
|
|
103
|
+
console.log(` id: ${painId}${pain.runtimeTaskId ? ` | task: ${pain.runtimeTaskId}` : ''}`);
|
|
104
|
+
}
|
|
105
|
+
console.log('─'.repeat(96));
|
|
106
|
+
for (const warning of result.warnings) {
|
|
107
|
+
console.error(`WARN: ${warning}`);
|
|
108
|
+
}
|
|
109
|
+
if (result.warnings.includes('host_kind_column_missing')) {
|
|
110
|
+
console.error('Next: run `pd runtime init --workspace <dir>` (or restart the OpenClaw plugin) to migrate this workspace schema.');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export async function handlePainList(opts) {
|
|
114
|
+
const { workspace, limit: rawLimit, host: rawHost, json } = opts;
|
|
115
|
+
if (rawHost !== undefined && rawHost !== 'openclaw' && rawHost !== 'codex' && rawHost !== 'unknown') {
|
|
116
|
+
const message = `invalid host filter: expected openclaw | codex | unknown, got ${rawHost}`;
|
|
117
|
+
if (json) {
|
|
118
|
+
console.log(JSON.stringify({ status: 'failed', reason: 'invalid_host_filter', message, nextAction: 'Pass --host openclaw, --host codex, or --host unknown.' }));
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
console.error('Error: ' + message);
|
|
122
|
+
console.error('Next: Pass --host openclaw, --host codex, or --host unknown.');
|
|
123
|
+
}
|
|
124
|
+
process.exit(1);
|
|
125
|
+
return; // guard: test stubs of process.exit continue execution (cli-2-exit-stops)
|
|
126
|
+
}
|
|
127
|
+
const hostFilter = rawHost;
|
|
128
|
+
let effectiveLimit = 20;
|
|
129
|
+
if (rawLimit !== undefined) {
|
|
130
|
+
if (!Number.isInteger(rawLimit) || rawLimit < 1 || rawLimit > 10000) {
|
|
131
|
+
const message = `invalid limit: limit must be an integer between 1 and 10000, got ${rawLimit}`;
|
|
132
|
+
if (json) {
|
|
133
|
+
console.log(JSON.stringify({ status: 'failed', reason: 'invalid_limit', message, nextAction: 'Pass --limit with a valid integer (1-10000).' }));
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
console.error('Error: ' + message);
|
|
137
|
+
console.error('Next: Pass --limit with a valid integer (1-10000).');
|
|
138
|
+
}
|
|
139
|
+
process.exit(1);
|
|
140
|
+
return; // guard: test stubs of process.exit continue execution (cli-2-exit-stops)
|
|
141
|
+
}
|
|
142
|
+
effectiveLimit = rawLimit;
|
|
143
|
+
}
|
|
144
|
+
const workspaceDir = resolveWorkspaceDir(workspace);
|
|
145
|
+
const dbPath = path.join(workspaceDir, '.state', 'trajectory.db');
|
|
146
|
+
if (!fs.existsSync(dbPath)) {
|
|
147
|
+
const message = `trajectory database not found at ${dbPath}`;
|
|
148
|
+
if (json) {
|
|
149
|
+
console.log(JSON.stringify({ status: 'failed', reason: 'trajectory_db_not_found', message, nextAction: 'Initialize the PD workspace first (pd runtime init), or pass --workspace pointing at an initialized workspace.' }));
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
console.error('Error: ' + message);
|
|
153
|
+
console.error('Next: Initialize the PD workspace first (pd runtime init), or pass --workspace pointing at an initialized workspace.');
|
|
154
|
+
}
|
|
155
|
+
process.exit(1);
|
|
156
|
+
return; // guard: test stubs of process.exit continue execution (cli-2-exit-stops)
|
|
157
|
+
}
|
|
158
|
+
const result = await listPains(dbPath, { limit: effectiveLimit, ...(hostFilter ? { host: hostFilter } : {}) });
|
|
159
|
+
if (json) {
|
|
160
|
+
console.log(JSON.stringify(result, null, 2));
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
printHuman(result);
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=pain-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pain-list.js","sourceRoot":"","sources":["../../src/commands/pain-list.ts"],"names":[],"mappings":"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"}
|
package/pd-cli/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { Command } from 'commander';
|
|
|
9
9
|
import { handlePainRecord } from './commands/pain-record.js';
|
|
10
10
|
import { registerPainRetryCommand } from './commands/pain-retry.js';
|
|
11
11
|
import { handlePainEvidence } from './commands/pain-evidence.js';
|
|
12
|
+
import { handlePainList } from './commands/pain-list.js';
|
|
12
13
|
import { handleSamplesList } from './commands/samples-list.js';
|
|
13
14
|
import { handleSamplesReview } from './commands/samples-review.js';
|
|
14
15
|
import { handleEvolutionTasksList } from './commands/evolution-tasks-list.js';
|
|
@@ -113,6 +114,16 @@ painCmd
|
|
|
113
114
|
await handlePainRecord(opts);
|
|
114
115
|
});
|
|
115
116
|
registerPainRetryCommand(painCmd);
|
|
117
|
+
painCmd
|
|
118
|
+
.command('list')
|
|
119
|
+
.description('List canonical pain events with host attribution (PRI-640)')
|
|
120
|
+
.option('-w, --workspace <path>', 'Workspace directory')
|
|
121
|
+
.option('-l, --limit <number>', 'Max entries to show (default: 20)', parseInt)
|
|
122
|
+
.option('--host <kind>', 'Filter by host: openclaw | codex | unknown')
|
|
123
|
+
.option('--json', 'Output raw JSON')
|
|
124
|
+
.action(async (opts) => {
|
|
125
|
+
await handlePainList(opts);
|
|
126
|
+
});
|
|
116
127
|
painCmd
|
|
117
128
|
.command('evidence')
|
|
118
129
|
.description('Show recent TRIGGER_DECISION log entries — pain admission gate decisions only (PEAT-B2)')
|