create-principles-disciple 1.147.8 → 1.147.9
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 +2 -2
- package/core/dist/runtime-v2/activation/adaptive-delivery-record.d.ts +37 -0
- package/core/dist/runtime-v2/activation/adaptive-delivery-record.d.ts.map +1 -0
- package/core/dist/runtime-v2/activation/adaptive-delivery-record.js +126 -0
- package/core/dist/runtime-v2/activation/adaptive-delivery-record.js.map +1 -0
- package/core/dist/runtime-v2/activation/adaptive-principle-intervention.d.ts +46 -0
- package/core/dist/runtime-v2/activation/adaptive-principle-intervention.d.ts.map +1 -0
- package/core/dist/runtime-v2/activation/adaptive-principle-intervention.js +91 -0
- package/core/dist/runtime-v2/activation/adaptive-principle-intervention.js.map +1 -0
- package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.d.ts +2 -0
- package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.js +2 -0
- package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.js.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +3 -0
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +2 -0
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-connection.js +1 -1
- package/core/dist/runtime-v2/store/sqlite-connection.js.map +1 -1
- package/core/dist/runtime-v2/types/event-types.d.ts +6 -3
- package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/event-types.js +2 -0
- package/core/dist/runtime-v2/types/event-types.js.map +1 -1
- package/core/package.json +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/install-summary.d.ts +3 -0
- package/dist/install-summary.d.ts.map +1 -1
- package/dist/install-summary.js +17 -9
- package/dist/install-summary.js.map +1 -1
- package/dist/installers/workbuddy-host-installer.d.ts +20 -1
- package/dist/installers/workbuddy-host-installer.d.ts.map +1 -1
- package/dist/installers/workbuddy-host-installer.js +75 -14
- package/dist/installers/workbuddy-host-installer.js.map +1 -1
- package/host-runtime/dist/active-principle-prompt.d.ts +28 -0
- package/host-runtime/dist/active-principle-prompt.js +163 -50
- package/host-runtime/dist/adaptive-principle-revalidation.d.ts +8 -0
- package/host-runtime/dist/adaptive-principle-revalidation.js +52 -0
- package/host-runtime/dist/index.d.ts +16 -0
- package/host-runtime/dist/index.js +34 -0
- package/host-runtime/dist/prompt-activation-authority.d.ts +7 -0
- package/host-runtime/dist/prompt-activation-authority.js +16 -0
- package/package.json +2 -2
- package/pd-cli/package.json +1 -1
- package/plugin/dist/bundle.js +446 -446
- package/plugin/dist/core/event-log.d.ts +3 -0
- package/plugin/dist/governance-audit.js +3 -3
- package/plugin/dist/hooks/adaptive-activation-config.d.ts +8 -0
- package/plugin/dist/hooks/prompt-helpers.d.ts +5 -0
- package/plugin/dist/hooks/prompt-types.d.ts +1 -0
- package/plugin/dist/hooks/prompt.d.ts +8 -1
- package/plugin/dist/host-runtime/openclaw-host-runtime.d.ts +13 -0
- package/plugin/dist/openclaw-sdk.d.ts +4 -0
- package/plugin/dist/openclaw.plugin.json +33 -1
- package/plugin/openclaw.plugin.json +32 -0
- package/release-manager/dist/installers/workbuddy-host-installer.js +75 -14
- package/release-manager/package.json +1 -1
|
@@ -3,6 +3,8 @@ import fs from 'node:fs';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { escapeXml } from '@principles/core/prompt-builder';
|
|
5
5
|
import { loadPdConfigForPlugin } from './pd-config.js';
|
|
6
|
+
import { readPromptActivationAuthority } from './prompt-activation-authority.js';
|
|
7
|
+
import { revalidateAdaptivePrinciple } from './adaptive-principle-revalidation.js';
|
|
6
8
|
/** PRI-904 SPEC §10: bounded diagnostic id lists (mirrors the core selector's cap of 16). */
|
|
7
9
|
export const MAX_SHARED_DIAGNOSTIC_IDS = 16;
|
|
8
10
|
/**
|
|
@@ -34,7 +36,10 @@ export async function readPromptActivationCandidates(input) {
|
|
|
34
36
|
return { principles, warnings, aborted: true, selfReportEnabled, abstractionLayerEnabled };
|
|
35
37
|
}
|
|
36
38
|
try {
|
|
37
|
-
connection = new SqliteConnection({ workspaceDir: input.workspaceDir, readonly: true, bootstrapIfMissing: false
|
|
39
|
+
connection = new SqliteConnection({ workspaceDir: input.workspaceDir, readonly: true, bootstrapIfMissing: false,
|
|
40
|
+
// Additional adaptive reads must not hold the host behind SQLite's synchronous busy wait.
|
|
41
|
+
...(input.includeAuthority === true ? { busyTimeoutMs: 0 } : {}),
|
|
42
|
+
});
|
|
38
43
|
const activations = filterPromptActivations(await new SqliteActivationStateStore(connection).listPromptActivations());
|
|
39
44
|
const artifactStore = new SqlitePIArtifactStore(connection);
|
|
40
45
|
for (const activation of activations) {
|
|
@@ -61,6 +66,19 @@ export async function readPromptActivationCandidates(input) {
|
|
|
61
66
|
warnings.push(resolved.warning);
|
|
62
67
|
continue;
|
|
63
68
|
}
|
|
69
|
+
if (input.includeAuthority === true) {
|
|
70
|
+
try {
|
|
71
|
+
const authority = readPromptActivationAuthority(connection, artifact.artifactId, 'prompt');
|
|
72
|
+
if (authority.authority)
|
|
73
|
+
resolved.principle.authority = authority.authority;
|
|
74
|
+
if (authority.approvedBy)
|
|
75
|
+
resolved.principle.approvedBy = authority.approvedBy;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Approval lookup failure is unknown, never inferred as owner or policy.
|
|
79
|
+
warnings.push(`prompt_activation_authority_unavailable: artifactId=${artifact.artifactId}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
64
82
|
principles.push(resolved.principle);
|
|
65
83
|
}
|
|
66
84
|
}
|
|
@@ -84,6 +102,11 @@ export async function buildActivePrinciplePromptContext(input) {
|
|
|
84
102
|
additionalContext: '', principleIds: [], activationIds: [], artifactIds: [], warnings,
|
|
85
103
|
budget: budgetChars, truncated: false,
|
|
86
104
|
selectionPolicy: 'legacy_fifo_prefix_v1', eligibleCount: 0,
|
|
105
|
+
...(input.adaptivePriority ? { adaptivePacking: {
|
|
106
|
+
status: 'unavailable', reason: 'reader_aborted',
|
|
107
|
+
targetActivationId: input.adaptivePriority.activationId, targetArtifactId: input.adaptivePriority.artifactId,
|
|
108
|
+
displacedActivationIds: [], ...(input.hookInvocationId ? { hookInvocationId: input.hookInvocationId } : {}),
|
|
109
|
+
} } : {}),
|
|
87
110
|
budgetCapacitySource: promptBudget.capacitySource,
|
|
88
111
|
budgetCapacityStatus: promptBudget.capacityStatus,
|
|
89
112
|
budgetContextWindowTokens: promptBudget.contextWindowTokens,
|
|
@@ -92,9 +115,6 @@ export async function buildActivePrinciplePromptContext(input) {
|
|
|
92
115
|
...(promptBudget.fallbackDetail !== undefined ? { budgetFallbackDetail: promptBudget.fallbackDetail } : {}),
|
|
93
116
|
};
|
|
94
117
|
}
|
|
95
|
-
const included = [];
|
|
96
|
-
let additionalContext = '';
|
|
97
|
-
let truncated = false;
|
|
98
118
|
// PRI-904: same fair-rotation semantics as the plugin route's trimToBudget —
|
|
99
119
|
// deterministic rotating start over the base (ASC) candidate order, circular
|
|
100
120
|
// scan, continue-on-non-fit. Costs are measured with the REAL serializer
|
|
@@ -108,56 +128,149 @@ export async function buildActivePrinciplePromptContext(input) {
|
|
|
108
128
|
const rotationStartIndex = selectionPolicy === 'fair_rotation_v1' && roundKey !== undefined
|
|
109
129
|
? ((roundKey % n) + n) % n
|
|
110
130
|
: undefined;
|
|
111
|
-
const
|
|
112
|
-
const oversizedActivationIds = [];
|
|
113
|
-
const standaloneFits = (principle) => renderPrinciplesToDirectives([principle], new Set([principle.principleId]), { escapeFn: escapeXml, selfReportInstruction: selfReportEnabled }).length
|
|
114
|
-
<= budgetChars;
|
|
115
|
-
const scanOrder = rotationStartIndex === undefined
|
|
131
|
+
const nativeScanOrder = rotationStartIndex === undefined
|
|
116
132
|
? principles
|
|
117
133
|
: principles.slice(rotationStartIndex).concat(principles.slice(0, rotationStartIndex));
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
134
|
+
const pack = (scanOrder) => {
|
|
135
|
+
const included = [];
|
|
136
|
+
let additionalContext = '';
|
|
137
|
+
let truncated = false;
|
|
138
|
+
const dropped = [];
|
|
139
|
+
const oversized = [];
|
|
140
|
+
const standaloneFits = (principle) => renderPrinciplesToDirectives([principle], new Set([principle.principleId]), { escapeFn: escapeXml, selfReportInstruction: selfReportEnabled }).length
|
|
141
|
+
<= budgetChars;
|
|
142
|
+
for (const principle of scanOrder) {
|
|
143
|
+
const candidate = [...included, principle];
|
|
144
|
+
const candidateContext = renderPrinciplesToDirectives(candidate, new Set(candidate.map((entry) => entry.principleId)), { escapeFn: escapeXml, selfReportInstruction: selfReportEnabled });
|
|
145
|
+
if (candidateContext.length > budgetChars) {
|
|
146
|
+
if (standaloneFits(principle)) {
|
|
147
|
+
truncated = true;
|
|
148
|
+
if (dropped.length < MAX_SHARED_DIAGNOSTIC_IDS)
|
|
149
|
+
dropped.push(principle.activationId);
|
|
150
|
+
}
|
|
151
|
+
else if (oversized.length < MAX_SHARED_DIAGNOSTIC_IDS) {
|
|
152
|
+
oversized.push(principle.activationId);
|
|
153
|
+
}
|
|
154
|
+
if (selectionPolicy === 'legacy_fifo_prefix_v1')
|
|
155
|
+
break;
|
|
156
|
+
continue;
|
|
131
157
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
continue;
|
|
158
|
+
included.push(principle);
|
|
159
|
+
additionalContext = candidateContext;
|
|
135
160
|
}
|
|
136
|
-
included
|
|
137
|
-
|
|
161
|
+
return { included, additionalContext, truncated, dropped, oversized };
|
|
162
|
+
};
|
|
163
|
+
const makeResult = (packing, eligiblePrinciples, adaptivePacking) => {
|
|
164
|
+
const resultWarnings = [...warnings];
|
|
165
|
+
if (packing.truncated) {
|
|
166
|
+
resultWarnings.push('prompt_context_truncated: production_prompt_cap; nextAction=reduce_active_prompt_principles');
|
|
167
|
+
}
|
|
168
|
+
const injectedIds = new Set(packing.included.map((principle) => principle.principleId));
|
|
169
|
+
return {
|
|
170
|
+
additionalContext: packing.additionalContext,
|
|
171
|
+
principleIds: [...injectedIds],
|
|
172
|
+
activationIds: packing.included.map((principle) => principle.activationId),
|
|
173
|
+
artifactIds: packing.included.map((principle) => principle.artifactId),
|
|
174
|
+
warnings: resultWarnings,
|
|
175
|
+
budget: budgetChars,
|
|
176
|
+
truncated: packing.truncated,
|
|
177
|
+
selectionPolicy,
|
|
178
|
+
eligibleCount: eligiblePrinciples.length,
|
|
179
|
+
...(rotationStartIndex !== undefined ? { rotationStartIndex } : {}),
|
|
180
|
+
...(packing.dropped.length > 0 ? { droppedActivationIds: packing.dropped } : {}),
|
|
181
|
+
...(packing.oversized.length > 0 ? { oversizedActivationIds: packing.oversized } : {}),
|
|
182
|
+
budgetCapacitySource: promptBudget.capacitySource,
|
|
183
|
+
budgetCapacityStatus: promptBudget.capacityStatus,
|
|
184
|
+
budgetContextWindowTokens: promptBudget.contextWindowTokens,
|
|
185
|
+
budgetPolicyVersion: promptBudget.policyVersion,
|
|
186
|
+
...(promptBudget.fallbackReason !== undefined ? { budgetFallbackReason: promptBudget.fallbackReason } : {}),
|
|
187
|
+
...(promptBudget.fallbackDetail !== undefined ? { budgetFallbackDetail: promptBudget.fallbackDetail } : {}),
|
|
188
|
+
...(adaptivePacking ? { adaptivePacking } : {}),
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
const nativePacking = pack(nativeScanOrder);
|
|
192
|
+
const nativeResult = makeResult(nativePacking, principles);
|
|
193
|
+
const priority = input.adaptivePriority;
|
|
194
|
+
if (priority === undefined)
|
|
195
|
+
return nativeResult;
|
|
196
|
+
const report = (status, reason, displacedActivationIds = []) => ({
|
|
197
|
+
status,
|
|
198
|
+
...(reason ? { reason } : {}),
|
|
199
|
+
targetActivationId: typeof priority.activationId === 'string' ? priority.activationId : '',
|
|
200
|
+
targetArtifactId: typeof priority.artifactId === 'string' ? priority.artifactId : '',
|
|
201
|
+
...(input.hookInvocationId ? { hookInvocationId: input.hookInvocationId } : {}),
|
|
202
|
+
displacedActivationIds,
|
|
203
|
+
});
|
|
204
|
+
const nativeTargetMatches = principles.filter((principle) => principle.artifactId === priority.artifactId && principle.activationId === priority.activationId);
|
|
205
|
+
const [nativeTarget] = nativeTargetMatches;
|
|
206
|
+
const baselineHasTarget = nativePacking.included.some((principle) => principle.artifactId === priority.artifactId && principle.activationId === priority.activationId);
|
|
207
|
+
const withoutTarget = (reason) => {
|
|
208
|
+
if (nativeTargetMatches.length !== 1 || !nativeTarget)
|
|
209
|
+
return { ...nativeResult, adaptivePacking: report('unavailable', reason) };
|
|
210
|
+
const targetPrincipleId = nativeTarget.principleId;
|
|
211
|
+
const safePrinciples = principles.filter((principle) => principle.principleId !== targetPrincipleId);
|
|
212
|
+
const safeScanOrder = nativeScanOrder.filter((principle) => principle.principleId !== targetPrincipleId);
|
|
213
|
+
const safePacking = pack(safeScanOrder);
|
|
214
|
+
return makeResult(safePacking, safePrinciples, report('unavailable', reason, baselineHasTarget ? [nativeTarget.activationId] : []));
|
|
215
|
+
};
|
|
216
|
+
if (typeof priority.artifactId !== 'string' || !priority.artifactId.trim()
|
|
217
|
+
|| typeof priority.activationId !== 'string' || !priority.activationId.trim()) {
|
|
218
|
+
return { ...nativeResult, adaptivePacking: report('unavailable', 'invalid_target') };
|
|
138
219
|
}
|
|
139
|
-
if (
|
|
140
|
-
|
|
220
|
+
if (nativeTargetMatches.length === 0)
|
|
221
|
+
return { ...nativeResult, adaptivePacking: report('unavailable', 'target_unavailable') };
|
|
222
|
+
if (nativeTargetMatches.length !== 1)
|
|
223
|
+
return { ...nativeResult, adaptivePacking: report('unavailable', 'target_ambiguous') };
|
|
224
|
+
if (!nativeTarget)
|
|
225
|
+
return { ...nativeResult, adaptivePacking: report('unavailable', 'target_unavailable') };
|
|
226
|
+
if (principles.filter((principle) => principle.principleId === nativeTarget.principleId).length !== 1) {
|
|
227
|
+
return { ...nativeResult, adaptivePacking: report('unavailable', 'target_ambiguous') };
|
|
141
228
|
}
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
...(
|
|
161
|
-
|
|
162
|
-
|
|
229
|
+
const authorityRead = await readPromptActivationCandidates({ workspaceDir: input.workspaceDir, includeAuthority: true });
|
|
230
|
+
const authorizedMatches = authorityRead.principles.filter((principle) => principle.artifactId === priority.artifactId && principle.activationId === priority.activationId);
|
|
231
|
+
const [authorizedTarget] = authorizedMatches;
|
|
232
|
+
if (authorityRead.aborted || authorityRead.warnings.length > 0 || authorizedMatches.length !== 1 || !authorizedTarget
|
|
233
|
+
|| authorityRead.principles.filter((principle) => principle.principleId === authorizedTarget.principleId).length !== 1) {
|
|
234
|
+
return withoutTarget('authority_unavailable');
|
|
235
|
+
}
|
|
236
|
+
if (!authorizedTarget.authority
|
|
237
|
+
|| authorizedTarget.principleId !== nativeTarget.principleId
|
|
238
|
+
|| authorizedTarget.text !== nativeTarget.text
|
|
239
|
+
|| authorizedTarget.artifactContentSha256 !== nativeTarget.artifactContentSha256) {
|
|
240
|
+
return withoutTarget('target_changed');
|
|
241
|
+
}
|
|
242
|
+
const signal = input.signal ?? new AbortController().signal;
|
|
243
|
+
const targetRendered = renderPrinciplesToDirectives([nativeTarget], new Set([nativeTarget.principleId]), { escapeFn: escapeXml });
|
|
244
|
+
const targetBody = targetRendered.slice(targetRendered.indexOf('<directive '), targetRendered.indexOf('</directive>') + '</directive>'.length);
|
|
245
|
+
const prepared = (status, displaced = []) => ({
|
|
246
|
+
...report(status, undefined, displaced), targetSnapshot: authorizedTarget, targetBody,
|
|
247
|
+
nativeBaseline: nativeResult, ...(input.deadlineAt !== undefined ? { deadlineAt: input.deadlineAt } : {}),
|
|
248
|
+
});
|
|
249
|
+
if (baselineHasTarget) {
|
|
250
|
+
const stillValid = await revalidateAdaptivePrinciple(input.workspaceDir, authorizedTarget, signal);
|
|
251
|
+
if (!stillValid)
|
|
252
|
+
return withoutTarget('target_changed');
|
|
253
|
+
return { ...nativeResult, adaptivePacking: prepared('target_present') };
|
|
254
|
+
}
|
|
255
|
+
const targetIndex = nativeScanOrder.indexOf(nativeTarget);
|
|
256
|
+
const targetFirstScan = [nativeTarget, ...nativeScanOrder.filter((principle, index) => index !== targetIndex && principle.principleId !== nativeTarget.principleId)];
|
|
257
|
+
const prioritizedPacking = pack(targetFirstScan);
|
|
258
|
+
if (!prioritizedPacking.included.some((principle) => principle.principleId === nativeTarget.principleId)) {
|
|
259
|
+
return { ...nativeResult, adaptivePacking: report('unavailable', 'target_does_not_fit') };
|
|
260
|
+
}
|
|
261
|
+
const mandatoryIds = input.mandatoryPrincipleIds ?? [];
|
|
262
|
+
if (!Array.isArray(mandatoryIds) || mandatoryIds.some((id) => typeof id !== 'string')
|
|
263
|
+
|| mandatoryIds.some((id) => !prioritizedPacking.included.some((principle) => principle.principleId === id))) {
|
|
264
|
+
return { ...nativeResult, adaptivePacking: report('unavailable', 'mandatory_constraint_displaced') };
|
|
265
|
+
}
|
|
266
|
+
const stillValid = await revalidateAdaptivePrinciple(input.workspaceDir, authorizedTarget, signal);
|
|
267
|
+
if (!stillValid)
|
|
268
|
+
return { ...nativeResult, adaptivePacking: report('unavailable', 'target_changed') };
|
|
269
|
+
const prioritizedActivationIds = new Set(prioritizedPacking.included.map((principle) => principle.activationId));
|
|
270
|
+
const displacedActivationIds = nativePacking.included
|
|
271
|
+
.filter((principle) => !prioritizedActivationIds.has(principle.activationId))
|
|
272
|
+
.map((principle) => principle.activationId);
|
|
273
|
+
const result = makeResult(prioritizedPacking, principles, prepared('prioritized', displacedActivationIds));
|
|
274
|
+
// Adaptive assembly is deliberately limited to the existing renderer's Native budget cap.
|
|
275
|
+
return result;
|
|
163
276
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type PromptActivationCandidates } from './active-principle-prompt.js';
|
|
2
|
+
import type { ActivatedPrinciple } from '@principles/core/runtime-v2';
|
|
3
|
+
export type AdaptivePrincipleReader = (input: {
|
|
4
|
+
workspaceDir: string;
|
|
5
|
+
}) => Promise<PromptActivationCandidates>;
|
|
6
|
+
/** Bind a test or host-specific reader while keeping the production call signature minimal. */
|
|
7
|
+
export declare function createAdaptivePrincipleRevalidator(reader: AdaptivePrincipleReader): (workspaceDir: string, expected: ActivatedPrinciple, signal: AbortSignal) => Promise<boolean>;
|
|
8
|
+
export declare function revalidateAdaptivePrinciple(workspaceDir: string, expected: ActivatedPrinciple, signal: AbortSignal): Promise<boolean>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { readPromptActivationCandidates, } from './active-principle-prompt.js';
|
|
2
|
+
/**
|
|
3
|
+
* Rechecks the rendered principle's identity, body, and authorization at the
|
|
4
|
+
* adaptive-intervention return boundary. A full artifact digest is required;
|
|
5
|
+
* legacy snapshots without it cannot certify a stable artifact revision.
|
|
6
|
+
*/
|
|
7
|
+
async function revalidateWithReader(input, reader) {
|
|
8
|
+
const { workspaceDir, expected, signal } = input;
|
|
9
|
+
if (signal.aborted || !expected.artifactContentSha256 || !/^[a-f0-9]{64}$/.test(expected.artifactContentSha256))
|
|
10
|
+
return false;
|
|
11
|
+
let onAbort;
|
|
12
|
+
const aborted = new Promise((resolve) => {
|
|
13
|
+
onAbort = () => resolve(null);
|
|
14
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
15
|
+
if (signal.aborted)
|
|
16
|
+
onAbort();
|
|
17
|
+
});
|
|
18
|
+
try {
|
|
19
|
+
const result = await Promise.race([reader({ workspaceDir }), aborted]);
|
|
20
|
+
if (!result || signal.aborted || result.aborted || result.warnings.length > 0)
|
|
21
|
+
return false;
|
|
22
|
+
const matches = result.principles.filter((candidate) => candidate.artifactId === expected.artifactId && candidate.activationId === expected.activationId);
|
|
23
|
+
if (matches.length !== 1)
|
|
24
|
+
return false;
|
|
25
|
+
const [current] = matches;
|
|
26
|
+
if (!current)
|
|
27
|
+
return false;
|
|
28
|
+
// Duplicate principle identity is ambiguous even if one activation pair matches.
|
|
29
|
+
if (result.principles.filter((candidate) => candidate.principleId === expected.principleId).length !== 1)
|
|
30
|
+
return false;
|
|
31
|
+
return current.principleId === expected.principleId
|
|
32
|
+
&& current.artifactContentSha256 === expected.artifactContentSha256
|
|
33
|
+
&& current.text === expected.text
|
|
34
|
+
&& current.authority === expected.authority
|
|
35
|
+
&& current.approvedBy === expected.approvedBy;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
if (onAbort)
|
|
42
|
+
signal.removeEventListener('abort', onAbort);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Bind a test or host-specific reader while keeping the production call signature minimal. */
|
|
46
|
+
export function createAdaptivePrincipleRevalidator(reader) {
|
|
47
|
+
return (workspaceDir, expected, signal) => revalidateWithReader({ workspaceDir, expected, signal }, reader);
|
|
48
|
+
}
|
|
49
|
+
export function revalidateAdaptivePrinciple(workspaceDir, expected, signal) {
|
|
50
|
+
const readWithAuthority = ({ workspaceDir: currentWorkspaceDir }) => readPromptActivationCandidates({ workspaceDir: currentWorkspaceDir, includeAuthority: true });
|
|
51
|
+
return revalidateWithReader({ workspaceDir, expected, signal }, readWithAuthority);
|
|
52
|
+
}
|
|
@@ -5,6 +5,7 @@ import type { RuleImplementationRuntime } from './rule-implementation-runtime.js
|
|
|
5
5
|
import { type PainDatabaseFactory, type PainEnrichmentProvider } from './production-pain-evidence.js';
|
|
6
6
|
import type { GovernanceHostKind, ToolSemanticRegistry } from '@principles/core/runtime-v2';
|
|
7
7
|
export * from './active-principle-prompt.js';
|
|
8
|
+
export * from './prompt-activation-authority.js';
|
|
8
9
|
export * from './prompt-injection-projection.js';
|
|
9
10
|
export * from './prompt-activation-deliverability.js';
|
|
10
11
|
export * from './prompt-injection-status.js';
|
|
@@ -76,6 +77,20 @@ export declare function createProductionHostRuntime(options?: Partial<Pick<HostR
|
|
|
76
77
|
projectDir?: string;
|
|
77
78
|
/** PRI-634-F: host-declared tool semantics supplied by the constructing host adapter. */
|
|
78
79
|
toolSemantics?: ToolSemanticRegistry;
|
|
80
|
+
/** Optional, already-scoped single prompt target from the host adapter. Errors fail closed to Native. */
|
|
81
|
+
adaptivePriorityProvider?: (event: HostEvent) => {
|
|
82
|
+
artifactId: string;
|
|
83
|
+
activationId: string;
|
|
84
|
+
hookInvocationId?: string;
|
|
85
|
+
signal?: AbortSignal;
|
|
86
|
+
deadlineAt?: number;
|
|
87
|
+
} | undefined | Promise<{
|
|
88
|
+
artifactId: string;
|
|
89
|
+
activationId: string;
|
|
90
|
+
hookInvocationId?: string;
|
|
91
|
+
signal?: AbortSignal;
|
|
92
|
+
deadlineAt?: number;
|
|
93
|
+
} | undefined>;
|
|
79
94
|
/**
|
|
80
95
|
* PRI-750: optional event emission port. When present, the shared-path
|
|
81
96
|
* handlers record injection/tool events carrying the host's natural
|
|
@@ -96,3 +111,4 @@ export * from './explicit-owner-statement-prefix.js';
|
|
|
96
111
|
export { listObservedDesignGateSessions } from './workspace-behavior-evidence.js';
|
|
97
112
|
export { readDesignGateSpecSnapshot, describeCodexRuleContextFact } from './design-gate-facts.js';
|
|
98
113
|
export { createCodexArtificerTrustedFactsPort } from './codex-artificer-trusted-facts.js';
|
|
114
|
+
export { revalidateAdaptivePrinciple, createAdaptivePrincipleRevalidator, type AdaptivePrincipleReader } from './adaptive-principle-revalidation.js';
|
|
@@ -6,6 +6,7 @@ import { buildActivePrinciplePromptContext } from './active-principle-prompt.js'
|
|
|
6
6
|
import { createProductionRuleHostGate } from './production-rulehost-gate.js';
|
|
7
7
|
import { createProductionPainEvidenceHandler } from './production-pain-evidence.js';
|
|
8
8
|
export * from './active-principle-prompt.js';
|
|
9
|
+
export * from './prompt-activation-authority.js';
|
|
9
10
|
export * from './prompt-injection-projection.js';
|
|
10
11
|
// SPEC PD_PROMPT_CAPACITY_V1: route-aware single-artifact deliverability
|
|
11
12
|
// precheck (B1 write gate + A candidate fit) and the per-live-activation
|
|
@@ -225,8 +226,35 @@ export function createProductionHostRuntime(options = {}) {
|
|
|
225
226
|
const declaredWindow = promptBudgetHostKind === undefined
|
|
226
227
|
? undefined
|
|
227
228
|
: operatorDeclaredContextWindow(loadPdConfigForPlugin(event.context.workspaceDir).effective.config.promptBudget, promptBudgetHostKind);
|
|
229
|
+
let adaptivePriority;
|
|
230
|
+
let skippedPriority;
|
|
231
|
+
if (options.adaptivePriorityProvider) {
|
|
232
|
+
try {
|
|
233
|
+
adaptivePriority = await options.adaptivePriorityProvider(event);
|
|
234
|
+
if (adaptivePriority && (typeof adaptivePriority.artifactId !== 'string' || !adaptivePriority.artifactId.trim()
|
|
235
|
+
|| typeof adaptivePriority.activationId !== 'string' || !adaptivePriority.activationId.trim()
|
|
236
|
+
|| (adaptivePriority.deadlineAt !== undefined && !Number.isFinite(adaptivePriority.deadlineAt)))) {
|
|
237
|
+
adaptivePriority = undefined;
|
|
238
|
+
}
|
|
239
|
+
if (adaptivePriority?.signal?.aborted
|
|
240
|
+
|| (adaptivePriority?.deadlineAt !== undefined && Date.now() >= adaptivePriority.deadlineAt)) {
|
|
241
|
+
skippedPriority = adaptivePriority;
|
|
242
|
+
adaptivePriority = undefined;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
// An optional adaptive provider can never alter the ordinary Native path on failure.
|
|
247
|
+
adaptivePriority = undefined;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
228
250
|
const prompt = await buildActivePrinciplePromptContext({
|
|
229
251
|
workspaceDir: event.context.workspaceDir,
|
|
252
|
+
...(adaptivePriority ? {
|
|
253
|
+
adaptivePriority: { artifactId: adaptivePriority.artifactId, activationId: adaptivePriority.activationId },
|
|
254
|
+
...(adaptivePriority.signal ? { signal: adaptivePriority.signal } : {}),
|
|
255
|
+
...(adaptivePriority.deadlineAt !== undefined ? { deadlineAt: adaptivePriority.deadlineAt } : {}),
|
|
256
|
+
...(adaptivePriority.hookInvocationId ? { hookInvocationId: adaptivePriority.hookInvocationId } : {}),
|
|
257
|
+
} : {}),
|
|
230
258
|
promptBudget: resolvePromptBudget({
|
|
231
259
|
// SPEC-PD-MODEL-AWARE-PROMPT-BUDGET-001: resolve ONCE per request
|
|
232
260
|
// from the host's own hook facts (OpenClaw effective window /
|
|
@@ -250,6 +278,11 @@ export function createProductionHostRuntime(options = {}) {
|
|
|
250
278
|
catalog: getPromptModelCatalog(),
|
|
251
279
|
}),
|
|
252
280
|
});
|
|
281
|
+
if (skippedPriority?.hookInvocationId)
|
|
282
|
+
prompt.adaptivePacking = {
|
|
283
|
+
status: 'unavailable', reason: 'deadline', targetActivationId: skippedPriority.activationId,
|
|
284
|
+
targetArtifactId: skippedPriority.artifactId, hookInvocationId: skippedPriority.hookInvocationId, displacedActivationIds: [],
|
|
285
|
+
};
|
|
253
286
|
// PRI-750: record the injection event on the shared path with the host
|
|
254
287
|
// turn id (Codex turn_id → runId) so receipt events carry a turn-level
|
|
255
288
|
// anchor in the same events_*.jsonl format as the OpenClaw path. The
|
|
@@ -326,3 +359,4 @@ export * from './explicit-owner-statement-prefix.js';
|
|
|
326
359
|
export { listObservedDesignGateSessions } from './workspace-behavior-evidence.js';
|
|
327
360
|
export { readDesignGateSpecSnapshot, describeCodexRuleContextFact } from './design-gate-facts.js';
|
|
328
361
|
export { createCodexArtificerTrustedFactsPort } from './codex-artificer-trusted-facts.js';
|
|
362
|
+
export { revalidateAdaptivePrinciple, createAdaptivePrincipleRevalidator } from './adaptive-principle-revalidation.js';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SqliteConnection } from '@principles/core/runtime-v2';
|
|
2
|
+
export interface PromptActivationAuthority {
|
|
3
|
+
authority?: 'owner' | 'system_policy';
|
|
4
|
+
approvedBy?: string;
|
|
5
|
+
}
|
|
6
|
+
/** Read the existing approval row without changing how activation is granted. */
|
|
7
|
+
export declare function readPromptActivationAuthority(sqliteConn: Pick<SqliteConnection, 'getDb'>, artifactId: string, channel: string): PromptActivationAuthority;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Read the existing approval row without changing how activation is granted. */
|
|
2
|
+
export function readPromptActivationAuthority(sqliteConn, artifactId, channel) {
|
|
3
|
+
const row = sqliteConn.getDb().prepare(`
|
|
4
|
+
SELECT decided_by FROM approvals
|
|
5
|
+
WHERE artifact_id = ? AND channel = ? AND status = 'approved'
|
|
6
|
+
ORDER BY decided_at DESC LIMIT 1
|
|
7
|
+
`).get(artifactId, channel);
|
|
8
|
+
if (row !== null && typeof row === 'object' && Object.hasOwn(row, 'decided_by')) {
|
|
9
|
+
const decidedBy = row.decided_by;
|
|
10
|
+
return {
|
|
11
|
+
authority: 'owner',
|
|
12
|
+
approvedBy: typeof decidedBy === 'string' && decidedBy.length > 0 ? decidedBy : undefined,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
return { authority: 'system_policy' };
|
|
16
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-principles-disciple",
|
|
3
|
-
"version": "1.147.
|
|
3
|
+
"version": "1.147.9",
|
|
4
4
|
"description": "Interactive CLI installer for Principles Disciple OpenClaw plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -101,5 +101,5 @@
|
|
|
101
101
|
"pd": {
|
|
102
102
|
"bundledPluginVersion": "2.6.1"
|
|
103
103
|
},
|
|
104
|
-
"gitHead": "
|
|
104
|
+
"gitHead": "75c6765405cfb763e52c2b558e80a76deb96e3f6"
|
|
105
105
|
}
|