create-principles-disciple 1.147.1 → 1.147.3
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/_release/product-identity.json +1 -1
- package/codex-adapter/dist/ingestion/admission.d.ts +5 -10
- package/codex-adapter/dist/ingestion/admission.js +19 -77
- package/codex-adapter/dist/ingestion/explicit-owner-statement.js +1 -1
- package/codex-adapter/dist/ingestion/ingestion.d.ts +0 -2
- package/codex-adapter/dist/ingestion/ingestion.js +6 -4
- package/codex-adapter/dist/pd-hook.js +5 -7
- package/codex-adapter/package.json +1 -1
- package/core/dist/runtime-v2/evidence-triage/index.d.ts +0 -1
- package/core/dist/runtime-v2/evidence-triage/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/evidence-triage/index.js +0 -2
- package/core/dist/runtime-v2/evidence-triage/index.js.map +1 -1
- package/core/dist/runtime-v2/evidence-triage/source-descriptors.d.ts +3 -8
- package/core/dist/runtime-v2/evidence-triage/source-descriptors.d.ts.map +1 -1
- package/core/dist/runtime-v2/evidence-triage/source-descriptors.js +5 -17
- package/core/dist/runtime-v2/evidence-triage/source-descriptors.js.map +1 -1
- package/core/dist/runtime-v2/evidence-triage/triage-policy.d.ts +11 -9
- package/core/dist/runtime-v2/evidence-triage/triage-policy.d.ts.map +1 -1
- package/core/dist/runtime-v2/evidence-triage/triage-policy.js +10 -103
- package/core/dist/runtime-v2/evidence-triage/triage-policy.js.map +1 -1
- package/core/dist/runtime-v2/evidence-triage/trigger-controller.js +1 -1
- package/core/dist/runtime-v2/evidence-triage/trigger-controller.js.map +1 -1
- package/core/dist/runtime-v2/evidence-triage/types.d.ts +4 -16
- package/core/dist/runtime-v2/evidence-triage/types.d.ts.map +1 -1
- package/core/dist/runtime-v2/evidence-triage/types.js.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +1 -1
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +1 -1
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/package.json +1 -1
- package/dist/installer.d.ts +20 -0
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +49 -97
- package/dist/installer.js.map +1 -1
- package/dist/mvp-config.d.ts +11 -0
- package/dist/mvp-config.d.ts.map +1 -1
- package/dist/mvp-config.js.map +1 -1
- package/dist/update/release-metadata.d.ts +13 -5
- package/dist/update/release-metadata.d.ts.map +1 -1
- package/dist/update/release-metadata.js.map +1 -1
- package/host-runtime/dist/governance-signal-admission.d.ts +1 -77
- package/host-runtime/dist/governance-signal-admission.js +34 -294
- package/host-runtime/dist/production-pain-evidence.d.ts +8 -69
- package/host-runtime/dist/production-pain-evidence.js +19 -157
- package/host-runtime/package.json +1 -1
- package/package.json +4 -3
- package/pd-cli/package.json +1 -1
- package/pd-mcp-server/dist/version.d.ts +1 -1
- package/pd-mcp-server/dist/version.js +1 -1
- package/pd-mcp-server/package.json +1 -1
- package/plugin/dist/bundle.js +411 -412
- package/plugin/dist/hooks/after-tool-call-helpers.d.ts +2 -35
- package/plugin/dist/hooks/after-tool-call-types.d.ts +1 -30
- package/plugin/dist/hooks/pain.d.ts +6 -19
- package/plugin/dist/hooks/trajectory-evidence.d.ts +3 -10
- package/plugin/dist/hooks/triage-adapter.d.ts +7 -20
- package/plugin/dist/host-runtime/openclaw-host-runtime.d.ts +0 -1
- package/plugin/dist/openclaw.plugin.json +1 -1
- package/plugin/openclaw.plugin.json +1 -1
- package/plugin/package.json +1 -1
- package/release-manager/dist/installer.js +49 -97
- package/release-manager/package.json +2 -1
- package/workbuddy-adapter/dist/pd-hook.js +0 -26
- package/workbuddy-adapter/dist/worker/workspace-worker.d.ts +1 -7
- package/workbuddy-adapter/dist/worker/workspace-worker.js +11 -21
- package/workbuddy-adapter/package.json +1 -1
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Extracted functions from handleAfterToolCall that implement
|
|
5
5
|
* individual pipeline stages. Each function has a focused responsibility.
|
|
6
6
|
*
|
|
7
|
-
* Pipeline order: classify → record →
|
|
7
|
+
* Pipeline order: classify → record → friction tracking → hygiene
|
|
8
8
|
*
|
|
9
9
|
* ERR checklist:
|
|
10
10
|
* - ERR-001: No `as` casts on untrusted runtime values.
|
|
@@ -16,7 +16,7 @@ import { normalizeProfile } from '../core/profile.js';
|
|
|
16
16
|
import { type SessionState } from '../core/session-tracker.js';
|
|
17
17
|
import { WorkspaceContext } from '../core/workspace-context.js';
|
|
18
18
|
import type { PluginHookAfterToolCallEvent } from '../openclaw-sdk.js';
|
|
19
|
-
import type { ToolCallOutcome, ToolCallObservation
|
|
19
|
+
import type { ToolCallOutcome, ToolCallObservation } from './after-tool-call-types.js';
|
|
20
20
|
/**
|
|
21
21
|
* Extract a preview string from tool call result for diagnostic evidence.
|
|
22
22
|
* Pure function — no I/O, no side effects. ERR-001 / ERR-014 compliant.
|
|
@@ -59,36 +59,3 @@ export declare function handleFrictionTrackingForSuccess(sessionId: string, even
|
|
|
59
59
|
* Record hygiene tracking for memory/plan persistence actions on success.
|
|
60
60
|
*/
|
|
61
61
|
export declare function recordHygieneTracking(event: PluginHookAfterToolCallEvent, observation: ToolCallObservation, wctx: WorkspaceContext): void;
|
|
62
|
-
/**
|
|
63
|
-
* Evaluate whether a tool failure should trigger pain diagnosis.
|
|
64
|
-
*
|
|
65
|
-
* PRI-363: Single-gate architecture — only TriggerController decides.
|
|
66
|
-
*
|
|
67
|
-
* Combines:
|
|
68
|
-
* 1. Write-tool check — only write tools on failures enter this path
|
|
69
|
-
* 2. PEAT-B1 triage — evidence triage (always enabled now)
|
|
70
|
-
* 3. PEAT-B2 trigger controller — single source of truth for task creation
|
|
71
|
-
* 4. Cooldown tracking — plugin layer owns this state
|
|
72
|
-
*
|
|
73
|
-
* Returns a structured decision with reason and stage.
|
|
74
|
-
*/
|
|
75
|
-
export declare function evaluatePainAdmissionForToolCall(event: PluginHookAfterToolCallEvent, observation: ToolCallObservation, outcome: ToolCallOutcome, latestFailureState: SessionState | undefined, sessionState: SessionState | undefined, sessionId: string, workspaceDir: string, _config: {
|
|
76
|
-
get: (key: string) => unknown;
|
|
77
|
-
}): PainAdmissionDecision;
|
|
78
|
-
/**
|
|
79
|
-
* Emit pain signal after admission.
|
|
80
|
-
*
|
|
81
|
-
* Records to trajectory, event log, principle value tracker,
|
|
82
|
-
* and emits the pain_detected event.
|
|
83
|
-
*
|
|
84
|
-
* Only called when the admission decision is 'admitted'.
|
|
85
|
-
*/
|
|
86
|
-
export declare function emitPainIfAdmitted(wctx: WorkspaceContext, event: PluginHookAfterToolCallEvent, observation: ToolCallObservation, outcome: ToolCallOutcome, admission: PainAdmissionDecision, sessionId: string, agentId: string | undefined, workspaceDir: string, emitPainDetectedEvent: (wctx: WorkspaceContext, event: import('../core/evolution-types.js').EvolutionLoopEvent, options?: {
|
|
87
|
-
recordObservability?: boolean;
|
|
88
|
-
}) => Promise<void>): void;
|
|
89
|
-
export { buildTrajectoryEvidence } from './trajectory-evidence.js';
|
|
90
|
-
/**
|
|
91
|
-
* Reset trigger cooldown state (for tests).
|
|
92
|
-
* PRI-454: Delegates to shared cooldown Map reset.
|
|
93
|
-
*/
|
|
94
|
-
export declare function resetTriggerCooldownForTest(): void;
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
* - ERR-002: Every decision/result carries structured reason + nextAction.
|
|
11
11
|
* - EP-01: These types document boundaries, not runtime validation targets.
|
|
12
12
|
*/
|
|
13
|
-
import type { SessionState } from '../core/session-tracker.js';
|
|
14
13
|
/**
|
|
15
14
|
* Result of classifying what happened in a tool call event.
|
|
16
15
|
*
|
|
@@ -27,7 +26,7 @@ export interface ToolCallOutcome {
|
|
|
27
26
|
/**
|
|
28
27
|
* Normalized observation built from the tool call event and context.
|
|
29
28
|
*
|
|
30
|
-
* Used by friction tracking, event recording, and
|
|
29
|
+
* Used by friction tracking, event log recording, and trajectory recording.
|
|
31
30
|
* Constructed after classification, before any I/O.
|
|
32
31
|
*/
|
|
33
32
|
export interface ToolCallObservation {
|
|
@@ -56,31 +55,3 @@ export interface ToolCallObservation {
|
|
|
56
55
|
/** Trace ID for this observation chain */
|
|
57
56
|
readonly traceId: string;
|
|
58
57
|
}
|
|
59
|
-
/**
|
|
60
|
-
* Result of evaluating whether a tool failure should trigger pain diagnosis.
|
|
61
|
-
*
|
|
62
|
-
* Encapsulates the single-gate trigger controller decision.
|
|
63
|
-
*/
|
|
64
|
-
export interface PainAdmissionDecision {
|
|
65
|
-
/** Whether the tool failure should proceed to pain emission */
|
|
66
|
-
readonly admitted: boolean;
|
|
67
|
-
/** The admission stage that made the decision */
|
|
68
|
-
readonly stage: 'not_applicable' | 'trigger_admitted' | 'trigger_rejected';
|
|
69
|
-
/** Human-readable reason for the decision */
|
|
70
|
-
readonly reason: string;
|
|
71
|
-
/** Detail about the decision */
|
|
72
|
-
readonly detail: string;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Result of friction tracking for a tool call.
|
|
76
|
-
*/
|
|
77
|
-
export interface FrictionUpdateResult {
|
|
78
|
-
/** GFI before this update */
|
|
79
|
-
readonly gfiBefore: number;
|
|
80
|
-
/** GFI after this update */
|
|
81
|
-
readonly gfiAfter: number;
|
|
82
|
-
/** Updated session state (if failure) */
|
|
83
|
-
readonly sessionState: SessionState | undefined;
|
|
84
|
-
/** The error hash used for tracking */
|
|
85
|
-
readonly errorHash: string;
|
|
86
|
-
}
|
|
@@ -1,32 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pain Hook — PRI-326 decomposed
|
|
3
3
|
*
|
|
4
|
-
* After-tool-call hook
|
|
4
|
+
* After-tool-call hook. Phase A retired every automatic Pain admission that
|
|
5
|
+
* was triggered by a technical tool failure: failures are still classified,
|
|
6
|
+
* recorded in the trajectory, and tracked for GFI health, but they never
|
|
7
|
+
* create a Pain Event or a Diagnostician task by themselves.
|
|
5
8
|
*
|
|
6
|
-
*
|
|
9
|
+
* Remaining stages (delegated to after-tool-call-helpers):
|
|
7
10
|
* 1. classifyToolCallOutcome — determine failure/success + source
|
|
8
11
|
* 2. buildToolCallObservation — normalize event into observation
|
|
9
12
|
* 3. handleFrictionTracking — GFI, event log, trajectory recording
|
|
10
|
-
* 4. evaluatePainAdmission — triage + gate evaluation
|
|
11
|
-
* 5. emitPainIfAdmitted — pain signal emission
|
|
12
13
|
*
|
|
13
14
|
* The manual pain path (toolName === 'pain') remains inline because it
|
|
14
|
-
* has a different control flow (early return,
|
|
15
|
+
* has a different control flow (early return, Owner-explicit admission).
|
|
15
16
|
*/
|
|
16
17
|
import { WorkspaceContext } from '../core/workspace-context.js';
|
|
17
18
|
import type { EvolutionLoopEvent } from '../core/evolution-types.js';
|
|
18
19
|
import type { PluginHookAfterToolCallEvent, PluginHookToolContext, OpenClawPluginApi } from '../openclaw-sdk.js';
|
|
19
20
|
import type { ProductionPainEnrichment } from '@principles/host-runtime';
|
|
20
|
-
import type { HostEventResult } from '@principles/core/host';
|
|
21
|
-
import { buildTrajectoryEvidence } from './trajectory-evidence.js';
|
|
22
|
-
export { buildTrajectoryEvidence };
|
|
23
|
-
/**
|
|
24
|
-
* Host-owned best-effort continuation after durable shared persistence.
|
|
25
|
-
* The hook may return once SQLite commits, while rejections remain observable
|
|
26
|
-
* and tests/shutdown code can explicitly drain scheduled work.
|
|
27
|
-
*/
|
|
28
|
-
export declare function schedulePainContinuation(workspaceDir: string, continuation: Promise<void>): void;
|
|
29
|
-
export declare function drainPainContinuationsForTest(): Promise<void>;
|
|
30
21
|
export declare function emitPainDetectedEvent(wctx: WorkspaceContext, event: EvolutionLoopEvent, options?: {
|
|
31
22
|
recordObservability?: boolean;
|
|
32
23
|
}): Promise<void>;
|
|
@@ -50,7 +41,3 @@ export declare function prepareOrdinaryAfterToolCallForSharedRuntime(event: Plug
|
|
|
50
41
|
workspaceDir: string;
|
|
51
42
|
pluginConfig?: Record<string, unknown>;
|
|
52
43
|
}): ProductionPainEnrichment;
|
|
53
|
-
/** Restore OpenClaw-owned pain UX/diagnosis after the shared atomic evidence write. */
|
|
54
|
-
export declare function handleSharedPainEvidenceResult(event: PluginHookAfterToolCallEvent, ctx: PluginHookToolContext & {
|
|
55
|
-
workspaceDir: string;
|
|
56
|
-
}, result: HostEventResult): void;
|
|
@@ -7,10 +7,9 @@
|
|
|
7
7
|
* Pure data extraction — reads from trajectory DB, sanitizes, returns evidence entries.
|
|
8
8
|
*
|
|
9
9
|
* PRI-642 Scope A adds the typed acquisition API `acquireTrajectoryEvidence`
|
|
10
|
-
* (discriminated available/unavailable, SPEC §7.2).
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* those consumers (frozen decision #3).
|
|
10
|
+
* (discriminated available/unavailable, SPEC §7.2). Phase A retired the last
|
|
11
|
+
* automatic emitter, so the legacy untyped array wrapper was removed: the
|
|
12
|
+
* Owner manual pain path is the only consumer and it uses the typed API.
|
|
14
13
|
*/
|
|
15
14
|
import type { PainEvidenceEntry } from '@principles/core/runtime-v2';
|
|
16
15
|
import type { WorkspaceContext } from '../core/workspace-context.js';
|
|
@@ -34,9 +33,3 @@ export type TrajectoryEvidenceAcquisition = {
|
|
|
34
33
|
* as available evidence.
|
|
35
34
|
*/
|
|
36
35
|
export declare function acquireTrajectoryEvidence(wctx: WorkspaceContext, sessionId: string): TrajectoryEvidenceAcquisition;
|
|
37
|
-
/**
|
|
38
|
-
* Legacy array API (compatibility wrapper, PRI-642 frozen decision #3).
|
|
39
|
-
* Automatic emitters still consume this shape; Scope B migrates them to the
|
|
40
|
-
* typed API one family at a time before this wrapper may be removed.
|
|
41
|
-
*/
|
|
42
|
-
export declare function buildTrajectoryEvidence(wctx: WorkspaceContext, sessionId: string): PainEvidenceEntry[];
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
* (TriggerController) is the only admission authority.
|
|
15
15
|
* Core only sees SourceKind and TriageResult.
|
|
16
16
|
*
|
|
17
|
+
* Phase A: the context-driven upgrade flags (unsafe-high-confidence,
|
|
18
|
+
* risky-high-score, repeated-failure) are retired. A descriptor decision is
|
|
19
|
+
* final; technical failures and RuleHost blocks never self-admit as Pain.
|
|
20
|
+
*
|
|
17
21
|
* ERR checklist:
|
|
18
22
|
* - ERR-001: Source kind derived from runtime values with guards, not `as` casts.
|
|
19
23
|
* - ERR-002: Every triage result carries reason + nextAction.
|
|
@@ -30,30 +34,13 @@ import { type TriageResult, type SourceKind } from '@principles/core/runtime-v2'
|
|
|
30
34
|
*/
|
|
31
35
|
export { resolveSourceKind, buildToolFailureObservation, type RawObservation } from './raw-observation-adapter.js';
|
|
32
36
|
/**
|
|
33
|
-
* Evaluate evidence triage for a given source kind and
|
|
37
|
+
* Evaluate evidence triage for a given source kind and score.
|
|
34
38
|
*
|
|
35
39
|
* This is the main entry point for hooks. It calls the pure triage policy
|
|
36
|
-
* from principles-core and returns the
|
|
40
|
+
* from principles-core and returns the descriptor decision unchanged.
|
|
37
41
|
*
|
|
38
42
|
* PRI-752 reality check: the painEvidenceAdmission flag is NOT consulted by
|
|
39
43
|
* any caller on this path — Gate B admission is unconditional. This doc block
|
|
40
44
|
* previously described a flag check / fallback that does not exist as code.
|
|
41
45
|
*/
|
|
42
|
-
export declare function evaluateEvidenceTriage(sourceKind: SourceKind, score: number
|
|
43
|
-
isUnsafeHighConfidence?: boolean;
|
|
44
|
-
provenance?: 'host_context_bound' | 'owner_reported_no_host_trace' | 'automatic_hook';
|
|
45
|
-
consecutiveErrors?: number;
|
|
46
|
-
isRisky?: boolean;
|
|
47
|
-
}): TriageResult;
|
|
48
|
-
/**
|
|
49
|
-
* Determine if a gate-blocked action is a high-confidence unsafe action.
|
|
50
|
-
*
|
|
51
|
-
* This is a heuristic that the plugin adapter owns. Core does not know about
|
|
52
|
-
* these heuristics — it only receives the boolean flag.
|
|
53
|
-
*
|
|
54
|
-
* Criteria for high-confidence unsafe:
|
|
55
|
-
* - Score >= 70 (high severity)
|
|
56
|
-
* - Tool is in the risky write set
|
|
57
|
-
* - Action would be irreversible (file deletion, force push, etc.)
|
|
58
|
-
*/
|
|
59
|
-
export declare function isHighConfidenceUnsafeAction(score: number, isRisky: boolean): boolean;
|
|
46
|
+
export declare function evaluateEvidenceTriage(sourceKind: SourceKind, score: number): TriageResult;
|
|
@@ -7,7 +7,6 @@ export interface OpenClawHostRuntimeOptions {
|
|
|
7
7
|
ruleInputEnrichmentProvider?(event: PluginHookBeforeToolCallEvent, context: PluginHookToolContext, request: ProductionRuleContextRequest): unknown | Promise<unknown>;
|
|
8
8
|
onBeforeToolResult?(event: PluginHookBeforeToolCallEvent, context: PluginHookToolContext, result: HostEventResult): PluginHookBeforeToolCallResult | void;
|
|
9
9
|
painEnrichmentProvider?(event: PluginHookAfterToolCallEvent, context: PluginHookToolContext): ProductionPainEnrichment | Promise<ProductionPainEnrichment>;
|
|
10
|
-
onAfterToolResult?(event: PluginHookAfterToolCallEvent, context: PluginHookToolContext, result: HostEventResult): void | Promise<void>;
|
|
11
10
|
}
|
|
12
11
|
export interface OpenClawHostRuntime {
|
|
13
12
|
readonly runtime: HostRuntime;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "principles-disciple",
|
|
3
3
|
"name": "Principles Disciple",
|
|
4
4
|
"description": "Principles Disciple is an AI Agent Governance System. Stop correcting the same AI behavior across sessions. Turn repeated Agent corrections into Owner-approved, observable, reversible behavior principles.",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.5.0",
|
|
6
6
|
"activation": {
|
|
7
7
|
"onStartup": true,
|
|
8
8
|
"onCapabilities": [
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "principles-disciple",
|
|
3
3
|
"name": "Principles Disciple",
|
|
4
4
|
"description": "Principles Disciple is an AI Agent Governance System. Stop correcting the same AI behavior across sessions. Turn repeated Agent corrections into Owner-approved, observable, reversible behavior principles.",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.5.0",
|
|
6
6
|
"activation": {
|
|
7
7
|
"onStartup": true,
|
|
8
8
|
"onCapabilities": [
|
package/plugin/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "principles-disciple",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Principles Disciple is an AI Agent Governance System. Stop correcting the same AI behavior across sessions. Turn repeated Agent corrections into Owner-approved, observable, reversible behavior principles.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -133,9 +133,6 @@ function installsOpenClaw(host) {
|
|
|
133
133
|
function installsWorkbuddy(host) {
|
|
134
134
|
return host === 'workbuddy' || host === 'all';
|
|
135
135
|
}
|
|
136
|
-
function installedPluginDir() {
|
|
137
|
-
return getInstalledPluginDir();
|
|
138
|
-
}
|
|
139
136
|
function pluginInstallDirs() {
|
|
140
137
|
return installsOpenClaw(activeHostTarget)
|
|
141
138
|
? [getInstalledPluginDir(), getPluginExtDir()]
|
|
@@ -1909,77 +1906,13 @@ function syncPdCli(pluginDir) {
|
|
|
1909
1906
|
if (existsSync(bundledNodeModules)) {
|
|
1910
1907
|
cpSync(bundledNodeModules, path.join(installedPdCliDir, 'node_modules'), { recursive: true });
|
|
1911
1908
|
}
|
|
1912
|
-
//
|
|
1913
|
-
//
|
|
1914
|
-
//
|
|
1915
|
-
//
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
const coreLinkPath = path.join(coreLinkDir, 'core');
|
|
1920
|
-
if (!existsSync(coreLinkPath)) {
|
|
1921
|
-
if (isWindows()) {
|
|
1922
|
-
// On Windows, use a junction (directory symlink) which doesn't require elevated privileges
|
|
1923
|
-
symlinkSync(coreLinkTarget, coreLinkPath, 'junction');
|
|
1924
|
-
}
|
|
1925
|
-
else {
|
|
1926
|
-
// On Unix, use a relative symlink for portability
|
|
1927
|
-
symlinkSync('../../../core', coreLinkPath, 'dir');
|
|
1928
|
-
}
|
|
1929
|
-
}
|
|
1930
|
-
// Create node_modules/@principles/host-runtime symlink so pd-cli can resolve
|
|
1931
|
-
// its @principles/host-runtime dependency (rewritten to "file:../host-runtime"
|
|
1932
|
-
// by bundle-plugin.mjs). Without this, `pd --version` crashes with
|
|
1933
|
-
// ERR_MODULE_NOT_FOUND because pd-cli statically imports createProductionHostRuntime.
|
|
1934
|
-
// host-runtime's own better-sqlite3 / js-yaml / @principles/core dependencies
|
|
1935
|
-
// resolve through the plugin's <ext>/node_modules/ (shared via Node's upward
|
|
1936
|
-
// module resolution), so no separate npm install is needed.
|
|
1937
|
-
const hostRuntimeLinkTarget = path.join(getPdRuntimeDir(), 'host-runtime');
|
|
1938
|
-
const hostRuntimeLinkPath = path.join(coreLinkDir, 'host-runtime');
|
|
1939
|
-
if (!existsSync(hostRuntimeLinkPath)) {
|
|
1940
|
-
if (isWindows()) {
|
|
1941
|
-
symlinkSync(hostRuntimeLinkTarget, hostRuntimeLinkPath, 'junction');
|
|
1942
|
-
}
|
|
1943
|
-
else {
|
|
1944
|
-
symlinkSync('../../../host-runtime', hostRuntimeLinkPath, 'dir');
|
|
1945
|
-
}
|
|
1946
|
-
}
|
|
1947
|
-
// Create node_modules/@principles/codex-adapter symlink so pd-cli can resolve
|
|
1948
|
-
// its @principles/codex-adapter dependency (rewritten to
|
|
1949
|
-
// "file:../codex-adapter" by bundle-plugin.mjs). Without this, `pd codex
|
|
1950
|
-
// worker` crashes with ERR_MODULE_NOT_FOUND (PRI-624).
|
|
1951
|
-
const codexAdapterLinkTarget = path.join(getPdRuntimeDir(), 'codex-adapter');
|
|
1952
|
-
const codexAdapterLinkPath = path.join(coreLinkDir, 'codex-adapter');
|
|
1953
|
-
if (!existsSync(codexAdapterLinkPath)) {
|
|
1954
|
-
if (isWindows()) {
|
|
1955
|
-
symlinkSync(codexAdapterLinkTarget, codexAdapterLinkPath, 'junction');
|
|
1956
|
-
}
|
|
1957
|
-
else {
|
|
1958
|
-
symlinkSync('../../../codex-adapter', codexAdapterLinkPath, 'dir');
|
|
1959
|
-
}
|
|
1960
|
-
}
|
|
1961
|
-
// Create node_modules/principles-disciple symlink so pd-cli can resolve
|
|
1962
|
-
// its principles-disciple dependency (the plugin package, rewritten to
|
|
1963
|
-
// "file:../plugin" by bundle-plugin.mjs). The plugin is installed at the
|
|
1964
|
-
// extension dir root (getPluginExtDir()), so the symlink target is the
|
|
1965
|
-
// ext dir itself — Node resolves `import 'principles-disciple'` via the
|
|
1966
|
-
// plugin's package.json exports field.
|
|
1967
|
-
// Without this, `pd runtime init` crashes with ERR_MODULE_NOT_FOUND
|
|
1968
|
-
// because runtime-init.ts statically imports initTrajectorySchema.
|
|
1969
|
-
const pdLinkDir = path.join(installedPdCliDir, 'node_modules');
|
|
1970
|
-
const pdLinkTarget = installedPluginDir();
|
|
1971
|
-
mkdirSync(pdLinkDir, { recursive: true });
|
|
1972
|
-
const pdLinkPath = path.join(pdLinkDir, 'principles-disciple');
|
|
1973
|
-
if (!existsSync(pdLinkPath)) {
|
|
1974
|
-
if (isWindows()) {
|
|
1975
|
-
symlinkSync(pdLinkTarget, pdLinkPath, 'junction');
|
|
1976
|
-
}
|
|
1977
|
-
else {
|
|
1978
|
-
// Relative from <ext>/pd-cli/node_modules/ to <ext>/: go up twice
|
|
1979
|
-
// (node_modules → pd-cli → ext)
|
|
1980
|
-
symlinkSync('../../', pdLinkPath, 'dir');
|
|
1981
|
-
}
|
|
1982
|
-
}
|
|
1909
|
+
// G3 §10.5: the pd-cli sibling links (core / host-runtime / codex-adapter /
|
|
1910
|
+
// workbuddy-adapter / install-layout / principles-disciple) are NO LONGER
|
|
1911
|
+
// hand-rolled here. install() materializes them via
|
|
1912
|
+
// ensurePdCliResolution() AFTER installPdCliDependencies(), so a physical
|
|
1913
|
+
// copy produced by the dependency stage can never be silently kept — this
|
|
1914
|
+
// block used to short-circuit on existsSync() and leave npm-materialized
|
|
1915
|
+
// copies in place.
|
|
1983
1916
|
tryUpgradePdCliFromNpm(installedPdCliDir);
|
|
1984
1917
|
const installedBinDir = getInstalledBinDir();
|
|
1985
1918
|
mkdirSync(installedBinDir, { recursive: true });
|
|
@@ -2157,29 +2090,11 @@ function installConsole(consoleDir) {
|
|
|
2157
2090
|
}
|
|
2158
2091
|
rmSync(consoleDest, { recursive: true, force: true });
|
|
2159
2092
|
cpSync(consoleSrc, consoleDest, { recursive: true });
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
}
|
|
2166
|
-
else {
|
|
2167
|
-
symlinkSync(path.relative(path.dirname(pluginLinkPath), installedPluginDir()), pluginLinkPath, 'dir');
|
|
2168
|
-
}
|
|
2169
|
-
}
|
|
2170
|
-
// PRI-672: console resolves its create-principles-disciple dependency (the
|
|
2171
|
-
// ReleaseManager authority module, rewritten to file:../release-manager by
|
|
2172
|
-
// bundle-plugin.mjs) through this link into ~/.pd/runtime.
|
|
2173
|
-
const releaseManagerLinkPath = path.join(consoleDest, 'node_modules', 'create-principles-disciple');
|
|
2174
|
-
if (!existsSync(releaseManagerLinkPath)) {
|
|
2175
|
-
mkdirSync(path.dirname(releaseManagerLinkPath), { recursive: true });
|
|
2176
|
-
if (isWindows()) {
|
|
2177
|
-
symlinkSync(getInstalledReleaseManagerDir(), releaseManagerLinkPath, 'junction');
|
|
2178
|
-
}
|
|
2179
|
-
else {
|
|
2180
|
-
symlinkSync(path.relative(path.dirname(releaseManagerLinkPath), getInstalledReleaseManagerDir()), releaseManagerLinkPath, 'dir');
|
|
2181
|
-
}
|
|
2182
|
-
}
|
|
2093
|
+
// G3 §10.5: the console's sibling links (core / host-runtime / install-layout
|
|
2094
|
+
// / principles-disciple / create-principles-disciple) are materialized by
|
|
2095
|
+
// ensureConsoleResolution() AFTER installConsoleDependencies() — see
|
|
2096
|
+
// ensurePdCliResolution() for why the old existsSync() short-circuit was
|
|
2097
|
+
// removed instead of kept.
|
|
2183
2098
|
}
|
|
2184
2099
|
function getInstalledCoreDir() {
|
|
2185
2100
|
return path.join(getPdRuntimeDir(), 'core');
|
|
@@ -2312,6 +2227,11 @@ function ensureComponentFileDependencyLinks(componentDir, componentLabel) {
|
|
|
2312
2227
|
if (!existsSync(siblingDir)) {
|
|
2313
2228
|
throw new Error(`${componentLabel} depends on ${ref} but the sibling runtime component is missing: ${siblingDir}`);
|
|
2314
2229
|
}
|
|
2230
|
+
// rc-1: the dependency NAME is manifest input too — it becomes a path
|
|
2231
|
+
// segment under node_modules, so a crafted name must not escape it.
|
|
2232
|
+
if (!/^(@[A-Za-z0-9._-]+\/)?[A-Za-z0-9._-]+$/.test(name)) {
|
|
2233
|
+
throw new Error(`Installed ${componentLabel} declares an unsupported dependency name "${name}".`);
|
|
2234
|
+
}
|
|
2315
2235
|
const linkPath = path.join(componentDir, 'node_modules', name);
|
|
2316
2236
|
let stat;
|
|
2317
2237
|
try {
|
|
@@ -2341,6 +2261,30 @@ function ensureComponentFileDependencyLinks(componentDir, componentLabel) {
|
|
|
2341
2261
|
}
|
|
2342
2262
|
}
|
|
2343
2263
|
}
|
|
2264
|
+
/**
|
|
2265
|
+
* G3 §10.5: materialize the INSTALLED pd-cli's `file:../` sibling links
|
|
2266
|
+
* (core / host-runtime / codex-adapter / workbuddy-adapter / install-layout /
|
|
2267
|
+
* principles-disciple) through the shared helper. Replaces the hand-rolled
|
|
2268
|
+
* per-dependency blocks that used to live in syncPdCli(): those short-circuited
|
|
2269
|
+
* on existsSync(), so an npm-materialized physical copy silently won over the
|
|
2270
|
+
* intended runtime sibling.
|
|
2271
|
+
*
|
|
2272
|
+
* Ordering contract: MUST run after installPdCliDependencies() (the dependency
|
|
2273
|
+
* stage is what can (re)materialize node_modules) AND after every sibling is
|
|
2274
|
+
* deployed. A missing sibling fails the install loud (the helper).
|
|
2275
|
+
*/
|
|
2276
|
+
export function ensurePdCliResolution() {
|
|
2277
|
+
ensureComponentFileDependencyLinks(getInstalledPdCliDir(), '@principles/pd-cli');
|
|
2278
|
+
}
|
|
2279
|
+
/**
|
|
2280
|
+
* G3 §10.5: same contract for the INSTALLED pd-console (core / host-runtime /
|
|
2281
|
+
* install-layout / principles-disciple / create-principles-disciple). Runs
|
|
2282
|
+
* after installConsoleDependencies() so npm-materialized copies are corrected
|
|
2283
|
+
* instead of silently kept.
|
|
2284
|
+
*/
|
|
2285
|
+
export function ensureConsoleResolution() {
|
|
2286
|
+
ensureComponentFileDependencyLinks(getInstalledConsoleDir(), '@principles/pd-console');
|
|
2287
|
+
}
|
|
2344
2288
|
/**
|
|
2345
2289
|
* PRI-711: materialize node_modules links for the INSTALLED codex-adapter so
|
|
2346
2290
|
* its declared `file:../<component>` dependencies resolve under ESM realpath
|
|
@@ -3805,6 +3749,10 @@ transaction) {
|
|
|
3805
3749
|
if (pdCliSync.globalShim !== null)
|
|
3806
3750
|
globalShimRecord = pdCliSync.globalShim;
|
|
3807
3751
|
await installPdCliDependencies();
|
|
3752
|
+
// G3 §10.5: materialize the sibling links AFTER the dependency stage — every
|
|
3753
|
+
// sibling component is already deployed at this point, and a physical copy
|
|
3754
|
+
// the dependency stage produced is now corrected rather than silently kept.
|
|
3755
|
+
ensurePdCliResolution();
|
|
3808
3756
|
stepIndex++;
|
|
3809
3757
|
if (spinner)
|
|
3810
3758
|
updateProgress(spinner, stepIndex, 'Preparing core library for pd-cli...');
|
|
@@ -3836,6 +3784,10 @@ transaction) {
|
|
|
3836
3784
|
if (spinner)
|
|
3837
3785
|
updateProgress(spinner, stepIndex, 'Validating bundled console dependencies...');
|
|
3838
3786
|
await installConsoleDependencies();
|
|
3787
|
+
// G3 §10.5: same ordering contract as pd-cli — links after the dependency
|
|
3788
|
+
// stage, with every console sibling (plugin / release-manager / core /
|
|
3789
|
+
// host-runtime / install-layout) already deployed.
|
|
3790
|
+
ensureConsoleResolution();
|
|
3839
3791
|
stepIndex++;
|
|
3840
3792
|
// PRI-912 (SPEC-P1′-A): dedup the plugin's bundled @principles/core copy
|
|
3841
3793
|
// into a canonical junction only after EVERY component is deployed, so a
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-principles-disciple",
|
|
3
|
-
"version": "1.147.
|
|
3
|
+
"version": "1.147.3",
|
|
4
4
|
"description": "Interactive CLI installer for Principles Disciple OpenClaw plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"prepublishOnly": "npm run build:deps && npm run build && npm run bundle",
|
|
48
48
|
"test": "vitest run",
|
|
49
49
|
"test:fast": "vitest run --exclude tests/smoke-packaged-install.test.ts --exclude tests/release-asset-smoke.test.ts --exclude tests/release-upgrade-gate.test.ts --exclude tests/release-junction-lifecycle.test.ts",
|
|
50
|
+
"typecheck:tests": "tsc -p tsconfig.tests.json",
|
|
50
51
|
"test:smoke:packaged": "vitest run tests/smoke-packaged-install.test.ts",
|
|
51
52
|
"test:smoke:release-asset": "vitest run tests/release-asset-smoke.test.ts"
|
|
52
53
|
},
|
|
@@ -400,32 +400,6 @@ export async function processWorkbuddyHookInvocation(rawStdin, channelEventName,
|
|
|
400
400
|
currentToolCallId: event.context.toolCallId ?? '',
|
|
401
401
|
toolSemantics: WORKBUDDY_TOOL_SEMANTICS,
|
|
402
402
|
}),
|
|
403
|
-
// Remediation R2 (candidate-level admission): the diagnostician's
|
|
404
|
-
// candidates are admitted ONLY with input evidence (needs_evidence
|
|
405
|
-
// otherwise), and Codex-style transcript promotion does not exist on
|
|
406
|
-
// this host. OpenClaw-parity: the HOOK supplies the evidence — a
|
|
407
|
-
// sourceRef to the durable raw event line (idempotent replay source,
|
|
408
|
-
// SPEC §13.7) plus a bounded failure note. No raw tool output is copied
|
|
409
|
-
// (ADR-0027 hook-log content rule).
|
|
410
|
-
painEnrichmentProvider: (hostEvent) => {
|
|
411
|
-
if (hostEvent.kind !== 'after_tool_call')
|
|
412
|
-
return {};
|
|
413
|
-
const toolName = hostEvent.context.toolName ?? 'unknown-tool';
|
|
414
|
-
const output = hostEvent.context.toolOutput;
|
|
415
|
-
const detail = typeof output === 'object' && output !== null && !Array.isArray(output)
|
|
416
|
-
? Object.hasOwn(output, 'tool_error_code')
|
|
417
|
-
? `tool_error_code=${String(output.tool_error_code)}`
|
|
418
|
-
: Object.hasOwn(output, 'exitCode')
|
|
419
|
-
? `exitCode=${String(output.exitCode)}`
|
|
420
|
-
: 'failure'
|
|
421
|
-
: 'failure';
|
|
422
|
-
return {
|
|
423
|
-
evidence: [{
|
|
424
|
-
sourceRef: `workbuddy-pd-hook-event-log:${hostEvent.context.sessionId}`,
|
|
425
|
-
note: `${toolName} failed (${detail}); raw payload in the durable workbuddy hook event log for this session`,
|
|
426
|
-
}],
|
|
427
|
-
};
|
|
428
|
-
},
|
|
429
403
|
}).dispatch(event);
|
|
430
404
|
const evaluationDiagnostics = recordRuleHostEvaluations(stateDir, event.context.sessionId, result.metadata?.evaluations);
|
|
431
405
|
// Encode BEFORE recording an attributed deny: a runtime_verified
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type InternalizationConsumerCycleOutcome, type ConsumerCycleLogger, type ReconcileGovernanceContinuationResult, type SignalLlmClassifier, type Stage2CorrectionCycleReport } from '@principles/host-runtime';
|
|
2
2
|
export type WorkbuddyWorkerMode = 'ready' | 'manual_action_required' | 'paused' | 'degraded';
|
|
3
3
|
export interface WorkbuddyWorkerCycleStepReport {
|
|
4
4
|
readonly reconcile: ReconcileGovernanceContinuationResult;
|
|
5
|
-
/**
|
|
6
|
-
* Bare-pain admission sweep (review R2/P1): the WorkBuddy hook writes bare
|
|
7
|
-
* failure pains with no inline admission, so the worker admits them into the
|
|
8
|
-
* shared governance queue before the diagnostician step.
|
|
9
|
-
*/
|
|
10
|
-
readonly admission: AdmitBareHostPainsResult;
|
|
11
5
|
/** At most ONE diagnostician execution per cycle (bounded work). */
|
|
12
6
|
readonly diagnostician: {
|
|
13
7
|
readonly taskId: string;
|
|
@@ -7,10 +7,7 @@
|
|
|
7
7
|
* the WorkBuddy MVP excludes transcript ingestion (SPEC §1 Excluded; the
|
|
8
8
|
* hook itself is the only evidence producer):
|
|
9
9
|
*
|
|
10
|
-
* 1. run the idempotent reconciliation pass (shared host-runtime authority)
|
|
11
|
-
* then admit the hook's BARE failure pains into the same governance
|
|
12
|
-
* queue (review R2/P1 — no inline admission exists on this host; the
|
|
13
|
-
* sweep reuses the ONE admission table and the crash-safe task ensure)
|
|
10
|
+
* 1. run the idempotent reconciliation pass (shared host-runtime authority)
|
|
14
11
|
* 2. lease + run one Diagnostician execution, then ONE bounded downstream
|
|
15
12
|
* consumer cycle through the SHARED host-neutral executor
|
|
16
13
|
* (internalization_auto_consumer = workspace execution authority)
|
|
@@ -33,7 +30,7 @@
|
|
|
33
30
|
import fs from 'node:fs';
|
|
34
31
|
import path from 'node:path';
|
|
35
32
|
import { computeFeatureFlagsFromConfig, createRuntimeStateHandle, createPainSignalBridge, isRetryWaitBackoffElapsed, PrincipleTreeLedgerAdapter, resolveDiagnosticianCapability, } from '@principles/core/runtime-v2';
|
|
36
|
-
import {
|
|
33
|
+
import { loadPdConfigForPlugin, loadFeatureFlagFromConfig, reconcileGovernanceContinuation, runInternalizationConsumerCycle, runStage2CorrectionCycle, createSignalClassifierForWorkspace, saveHostToolDeclaration, } from '@principles/host-runtime';
|
|
37
34
|
import { WORKBUDDY_TOOL_SEMANTICS, WORKBUDDY_TOOL_SEMANTIC_MAPPINGS } from '../tool-semantics.js';
|
|
38
35
|
const WORKER_OWNER = 'companion-worker';
|
|
39
36
|
const DEFAULT_DIAG_CANDIDATE_LIMIT = 5;
|
|
@@ -103,12 +100,6 @@ export async function runWorkbuddyWorkspaceWorkerCycle(options) {
|
|
|
103
100
|
const diagnosticianDisabled = !capability.available;
|
|
104
101
|
// Step 2 — Idempotent reconciliation (always runs; creates no LLM work).
|
|
105
102
|
const reconcile = await reconcileGovernanceContinuation({ workspaceDir, conversationIngestionEnabled: false });
|
|
106
|
-
// Step 2b — Bare-pain admission (review R2/P1): the hook leaves bare
|
|
107
|
-
// workbuddy failure pains that no inline admission exists for. Without this
|
|
108
|
-
// sweep the evidence rows never reach the diagnostician queue. Runs AFTER
|
|
109
|
-
// reconcile (which continues already-admitted markers) and ensures tasks
|
|
110
|
-
// through the same crash-safe seam; bounded and idempotent.
|
|
111
|
-
const admission = await admitBareHostPains({ workspaceDir, hostKind: 'workbuddy' });
|
|
112
103
|
// Steps 3–5 — execution authority: internalization_auto_consumer.
|
|
113
104
|
let diagnostician = null;
|
|
114
105
|
if (diagnosticianDisabled) {
|
|
@@ -125,7 +116,7 @@ export async function runWorkbuddyWorkspaceWorkerCycle(options) {
|
|
|
125
116
|
mode: 'paused',
|
|
126
117
|
reason: 'internalization_auto_consumer_disabled',
|
|
127
118
|
nextAction: 'Automatic internalization execution is paused for this governance workspace; manual commands remain available: pd diagnose, pd runtime internalization run-once.',
|
|
128
|
-
report: { reconcile,
|
|
119
|
+
report: { reconcile, diagnostician: null, downstream: null },
|
|
129
120
|
};
|
|
130
121
|
}
|
|
131
122
|
else {
|
|
@@ -174,7 +165,7 @@ export async function runWorkbuddyWorkspaceWorkerCycle(options) {
|
|
|
174
165
|
mode: 'degraded',
|
|
175
166
|
reason: `diagnostician_execution_failed:${detail}`,
|
|
176
167
|
nextAction: 'Inspect the governance workspace runtime profile and provider configuration; the task keeps its pending/retry state and no evidence was mutated.',
|
|
177
|
-
report: { reconcile,
|
|
168
|
+
report: { reconcile, diagnostician: null, downstream: null },
|
|
178
169
|
};
|
|
179
170
|
}
|
|
180
171
|
}
|
|
@@ -194,7 +185,7 @@ export async function runWorkbuddyWorkspaceWorkerCycle(options) {
|
|
|
194
185
|
mode: 'degraded',
|
|
195
186
|
reason: `host_tool_declaration_persist_failed:${declared.reason}`,
|
|
196
187
|
nextAction: 'Repair WorkBuddy host declaration persistence (.pd/host-tool-semantics/workbuddy.json) before running the downstream internalization cycle; the worker retries automatically on the next cycle.',
|
|
197
|
-
report: { reconcile,
|
|
188
|
+
report: { reconcile, diagnostician, downstream: null },
|
|
198
189
|
};
|
|
199
190
|
}
|
|
200
191
|
const downstream = await runInternalizationConsumerCycle(workspaceDir, {
|
|
@@ -226,16 +217,15 @@ export async function runWorkbuddyWorkspaceWorkerCycle(options) {
|
|
|
226
217
|
onEvent: emitEvent,
|
|
227
218
|
});
|
|
228
219
|
const degradedReason = !reconcile.ok ? `reconcile:${reconcile.reason ?? 'failed'}`
|
|
229
|
-
:
|
|
230
|
-
: diagnostician?.status === '
|
|
231
|
-
:
|
|
232
|
-
:
|
|
233
|
-
:
|
|
234
|
-
: undefined;
|
|
220
|
+
: diagnostician?.status === 'failed' && diagnostician.errorCategory !== 'lease_conflict' ? `diagnostician_failed:${diagnostician.message ?? 'max_attempts_exceeded'}`
|
|
221
|
+
: diagnostician?.status === 'degraded' ? `diagnostician_degraded:${diagnostician.message ?? 'unknown'}`
|
|
222
|
+
: downstream.skipReason === 'runtime_config_error' || downstream.skipReason === 'cycle_error' || downstream.skipReason === 'config_malformed' ? `downstream:${downstream.skipReason}`
|
|
223
|
+
: !stage2.ok ? `stage2:${stage2.reason ?? 'failed'}`
|
|
224
|
+
: undefined;
|
|
235
225
|
return {
|
|
236
226
|
...base,
|
|
237
227
|
mode: degradedReason !== undefined ? 'degraded' : 'ready',
|
|
238
228
|
...(degradedReason !== undefined ? { reason: degradedReason, nextAction: 'Inspect the governance workspace .pd/config.yaml runtime profile and the per-step report above; the worker retries automatically on the next cycle.' } : {}),
|
|
239
|
-
report: { reconcile,
|
|
229
|
+
report: { reconcile, diagnostician, downstream, stage2 },
|
|
240
230
|
};
|
|
241
231
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@principles/workbuddy-adapter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "WorkBuddy host adapter for Principles Disciple — implements the HostAdapter interface for WorkBuddy's Git Bash command-hook model (ADR-0020 third host, SPEC workbuddy-host-adapter v0.3.0).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|