@principles/workbuddy-adapter 0.4.1 → 0.5.1
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/dist/pd-hook.js
CHANGED
|
@@ -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
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@principles/workbuddy-adapter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
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",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"lint": "eslint \"src/**/*.ts\""
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@principles/core": "^
|
|
46
|
-
"@principles/host-runtime": "^0.
|
|
45
|
+
"@principles/core": "^4.0.0",
|
|
46
|
+
"@principles/host-runtime": "^2.0.0",
|
|
47
47
|
"@principles/install-layout": "^0.4.1"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
@@ -61,5 +61,5 @@
|
|
|
61
61
|
"publishConfig": {
|
|
62
62
|
"access": "public"
|
|
63
63
|
},
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "48ab9505979feb0cb13757e30d41d8567715efe1"
|
|
65
65
|
}
|