create-principles-disciple 1.145.29 → 1.145.32
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/index.d.ts +1 -1
- package/core/dist/index.d.ts.map +1 -1
- package/core/dist/prompt-builder/index.d.ts +1 -3
- package/core/dist/prompt-builder/index.d.ts.map +1 -1
- package/core/dist/prompt-builder/index.js +0 -1
- package/core/dist/prompt-builder/index.js.map +1 -1
- package/core/dist/prompt-builder/size-guard.d.ts +3 -4
- package/core/dist/prompt-builder/size-guard.d.ts.map +1 -1
- package/core/dist/prompt-builder/size-guard.js +7 -25
- package/core/dist/prompt-builder/size-guard.js.map +1 -1
- package/core/dist/prompt-builder/types.d.ts +1 -7
- package/core/dist/prompt-builder/types.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +0 -3
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +0 -4
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/runtime-v2/recovery-actions-log.d.ts.map +1 -1
- package/core/dist/runtime-v2/recovery-actions-log.js +2 -3
- package/core/dist/runtime-v2/recovery-actions-log.js.map +1 -1
- package/core/package.json +1 -1
- package/dist/installer.d.ts +16 -0
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +49 -13
- package/dist/installer.js.map +1 -1
- package/host-runtime/dist/active-principle-prompt.d.ts +1 -9
- package/host-runtime/dist/active-principle-prompt.js +10 -22
- package/host-runtime/dist/index.d.ts +0 -1
- package/host-runtime/dist/index.js +0 -1
- package/host-runtime/dist/prompt-injection-projection.d.ts +0 -7
- package/host-runtime/dist/prompt-injection-projection.js +0 -5
- package/host-runtime/package.json +1 -1
- package/package.json +2 -2
- package/pd-cli/dist/commands/health-codex-install.d.ts +0 -12
- package/pd-cli/dist/commands/health-codex-install.d.ts.map +1 -1
- package/pd-cli/dist/commands/health-codex-install.js +8 -90
- package/pd-cli/dist/commands/health-codex-install.js.map +1 -1
- package/pd-cli/dist/commands/runtime-pruning.d.ts +0 -18
- package/pd-cli/dist/commands/runtime-pruning.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-pruning.js +1 -117
- package/pd-cli/dist/commands/runtime-pruning.js.map +1 -1
- package/pd-cli/dist/commands/version.d.ts +5 -0
- package/pd-cli/dist/commands/version.d.ts.map +1 -1
- package/pd-cli/dist/commands/version.js +27 -5
- package/pd-cli/dist/commands/version.js.map +1 -1
- package/pd-cli/dist/index.js +1 -37
- package/pd-cli/dist/index.js.map +1 -1
- package/pd-cli/dist/services/codex-plugin-install.d.ts +66 -0
- package/pd-cli/dist/services/codex-plugin-install.d.ts.map +1 -0
- package/pd-cli/dist/services/codex-plugin-install.js +168 -0
- package/pd-cli/dist/services/codex-plugin-install.js.map +1 -0
- package/pd-cli/dist/services/delivery-surfaces.d.ts +48 -0
- package/pd-cli/dist/services/delivery-surfaces.d.ts.map +1 -0
- package/pd-cli/dist/services/delivery-surfaces.js +387 -0
- package/pd-cli/dist/services/delivery-surfaces.js.map +1 -0
- package/pd-cli/dist/services/pain-recall.d.ts +79 -0
- package/pd-cli/dist/services/pain-recall.d.ts.map +1 -1
- package/pd-cli/dist/services/pain-recall.js +295 -12
- package/pd-cli/dist/services/pain-recall.js.map +1 -1
- package/pd-cli/package.json +1 -1
- package/plugin/dist/bundle.js +439 -449
- package/plugin/dist/core/evolution-reducer.d.ts +0 -2
- package/plugin/dist/core/session-tracker.d.ts +0 -4
- package/plugin/dist/core/workspace-context.d.ts +0 -8
- package/plugin/dist/hooks/after-tool-call-helpers.d.ts +0 -7
- package/plugin/dist/hooks/pain.d.ts +3 -4
- package/plugin/dist/hooks/prompt-helpers.d.ts +2 -12
- package/plugin/dist/hooks/prompt-types.d.ts +0 -4
- package/plugin/dist/hooks/prompt.d.ts +1 -11
- 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 +4 -26
- package/release-manager/dist/installer.d.ts +16 -0
- package/release-manager/dist/installer.d.ts.map +1 -1
- package/release-manager/dist/installer.js +49 -13
- package/release-manager/dist/installer.js.map +1 -1
- package/release-manager/package.json +2 -2
- package/workbuddy-adapter/package.json +1 -1
- package/workbuddy-adapter/plugin/.codebuddy-plugin/plugin.json +1 -1
- package/workbuddy-adapter/plugin/hooks/hooks.json +1 -1
- package/workbuddy-adapter/plugin/scripts/wrapper.cjs +68 -4
- package/core/dist/prompt-builder/principle-selection.d.ts +0 -68
- package/core/dist/prompt-builder/principle-selection.d.ts.map +0 -1
- package/core/dist/prompt-builder/principle-selection.js +0 -140
- package/core/dist/prompt-builder/principle-selection.js.map +0 -1
- package/core/dist/runtime-v2/pruning-mask.d.ts +0 -27
- package/core/dist/runtime-v2/pruning-mask.d.ts.map +0 -1
- package/core/dist/runtime-v2/pruning-mask.js +0 -59
- package/core/dist/runtime-v2/pruning-mask.js.map +0 -1
- package/core/dist/runtime-v2/pruning-review-log.d.ts +0 -41
- package/core/dist/runtime-v2/pruning-review-log.d.ts.map +0 -1
- package/core/dist/runtime-v2/pruning-review-log.js +0 -106
- package/core/dist/runtime-v2/pruning-review-log.js.map +0 -1
- package/plugin/dist/core/principle-injection.d.ts +0 -10
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-principles-disciple",
|
|
3
|
-
"version": "1.145.
|
|
3
|
+
"version": "1.145.32",
|
|
4
4
|
"description": "Interactive CLI installer for Principles Disciple OpenClaw plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -89,6 +89,6 @@
|
|
|
89
89
|
"directory": "packages/create-principles-disciple"
|
|
90
90
|
},
|
|
91
91
|
"pd": {
|
|
92
|
-
"bundledPluginVersion": "2.2.
|
|
92
|
+
"bundledPluginVersion": "2.2.6"
|
|
93
93
|
}
|
|
94
94
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@principles/workbuddy-adapter",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.14",
|
|
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",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "principles-disciple",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Principles Disciple — Owner-governed behavior internalization for AI agents (WorkBuddy host adapter, ADR-0020 third host). Requires explicit setup and host.workbuddy feature enablement; inactive until then.",
|
|
5
5
|
"defaultEnabled": false
|
|
6
6
|
}
|
|
@@ -23,6 +23,25 @@
|
|
|
23
23
|
* 1 with a bounded stderr diagnostic: probe P02 established exit 1 is
|
|
24
24
|
* non-blocking on WorkBuddy, and the SPEC §4.4 startup-failure row forbids
|
|
25
25
|
* claiming self-blocking the wrapper cannot guarantee.
|
|
26
|
+
*
|
|
27
|
+
* SELF-DEADLINE (SPEC §4.4 timeout row): the adapter entry's own fail-open
|
|
28
|
+
* exits can never run when the HOST kills this wrapper on the hooks.json
|
|
29
|
+
* timeout — the process dies mid-flight, and the host's timeout semantics for
|
|
30
|
+
* a killed hook are undefined. So the wrapper arms a deadline STRICTLY BELOW
|
|
31
|
+
* the host budget and kills the child itself, degrading non-blocking
|
|
32
|
+
* (exit 1 + bounded stderr) instead of leaving the worst failure mode — a
|
|
33
|
+
* lost UserPromptSubmit prompt — to the host. The budget pairs are locked
|
|
34
|
+
* below the hooks.json timeouts by tests/plugin-skeleton.test.ts:
|
|
35
|
+
* UserPromptSubmit 12000ms < 15s (prompt loss is the costliest channel);
|
|
36
|
+
* every other channel 25000ms < 30s.
|
|
37
|
+
* PD_WORKBUDDY_HOOK_SELF_TIMEOUT_MS overrides the table (integer ms > 0, all
|
|
38
|
+
* events) for tests and field diagnostics; invalid values fall back to the
|
|
39
|
+
* table, and a valid one is CLAMPED strictly below the host budget so the
|
|
40
|
+
* override can never re-create the bug this deadline exists to fix.
|
|
41
|
+
*
|
|
42
|
+
* A killed child gets no chance to clean up (SIGTERM is TerminateProcess on
|
|
43
|
+
* Windows), so the deadline path deliberately does NOT promise adapter-side
|
|
44
|
+
* flush of evidence / SQLite locks — see SPEC §4.4.
|
|
26
45
|
*/
|
|
27
46
|
const { spawnSync } = require('node:child_process');
|
|
28
47
|
const fs = require('node:fs');
|
|
@@ -30,13 +49,42 @@ const path = require('node:path');
|
|
|
30
49
|
|
|
31
50
|
const eventName = process.argv[2];
|
|
32
51
|
|
|
33
|
-
|
|
52
|
+
// hooks.json host budgets in ms. Kept here ONLY so the override below can be
|
|
53
|
+
// clamped and so the guard test can prove the two tables agree with
|
|
54
|
+
// hooks.json; the host remains the authority for actually killing us.
|
|
55
|
+
const HOST_TIMEOUT_MS = { UserPromptSubmit: 15000, default: 30000 };
|
|
56
|
+
// Margin for this process's own startup plus the degradation write, so our
|
|
57
|
+
// timer always fires before the host's.
|
|
58
|
+
const SELF_DEADLINE_MARGIN_MS = 3000;
|
|
59
|
+
// Must stay strictly below the matching hooks.json timeout (seconds) — the
|
|
60
|
+
// guard test in tests/plugin-skeleton.test.ts locks every pair.
|
|
61
|
+
const SELF_TIMEOUT_MS = { UserPromptSubmit: 12000, default: 25000 };
|
|
62
|
+
|
|
63
|
+
function hostBudgetMs(event) {
|
|
64
|
+
return HOST_TIMEOUT_MS[event] ?? HOST_TIMEOUT_MS.default;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function resolveSelfDeadlineMs(event) {
|
|
68
|
+
const budget = SELF_TIMEOUT_MS[event] ?? SELF_TIMEOUT_MS.default;
|
|
69
|
+
const override = Number.parseInt(process.env.PD_WORKBUDDY_HOOK_SELF_TIMEOUT_MS ?? '', 10);
|
|
70
|
+
if (!Number.isInteger(override) || override <= 0) return budget;
|
|
71
|
+
// Clamp, never trust: a diagnostic setting of 60000 would otherwise leave
|
|
72
|
+
// the outcome to the host's undefined timeout semantics again.
|
|
73
|
+
return Math.max(1, Math.min(override, hostBudgetMs(event) - SELF_DEADLINE_MARGIN_MS));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function fail(message, nextAction = 'Reinstall PD (npx create-principles-disciple) or set PD_WORKBUDDY_ADAPTER_ENTRY to the built adapter entry.') {
|
|
34
77
|
try {
|
|
35
|
-
process.stderr.write(`[PD] status=degraded reason=workbuddy_wrapper:${message} nextAction
|
|
78
|
+
process.stderr.write(`[PD] status=degraded reason=workbuddy_wrapper:${message} nextAction=${nextAction}\n`);
|
|
36
79
|
} catch (_) { /* no channel left */ }
|
|
37
80
|
process.exit(1);
|
|
38
81
|
}
|
|
39
82
|
|
|
83
|
+
// The adapter child was killed at OUR deadline (before the host timeout):
|
|
84
|
+
// the hook result is a non-blocking degradation, so the user's prompt/tool
|
|
85
|
+
// call survives — the recovery action is diagnosis, not reinstall.
|
|
86
|
+
const DEADLINE_NEXT_ACTION = 'The hook degraded at its self-deadline before the host timeout (non-blocking: the prompt/tool call survived). If this repeats, inspect PD stderr and the governance workspace, and time one manual pd-hook run.';
|
|
87
|
+
|
|
40
88
|
function resolveEntry() {
|
|
41
89
|
const override = process.env.PD_WORKBUDDY_ADAPTER_ENTRY;
|
|
42
90
|
if (override && override.trim().length > 0) {
|
|
@@ -62,18 +110,34 @@ try {
|
|
|
62
110
|
} catch (_) {
|
|
63
111
|
fail('entry_not_found:' + entry.slice(0, 120));
|
|
64
112
|
}
|
|
113
|
+
const deadlineMs = resolveSelfDeadlineMs(eventName);
|
|
114
|
+
const startedAt = Date.now();
|
|
65
115
|
const child = spawnSync(process.execPath, [entry, eventName], {
|
|
66
116
|
stdio: ['inherit', 'inherit', 'inherit'],
|
|
67
117
|
windowsHide: true,
|
|
118
|
+
timeout: deadlineMs,
|
|
119
|
+
killSignal: 'SIGTERM',
|
|
68
120
|
});
|
|
69
121
|
|
|
70
122
|
if (child.error) {
|
|
123
|
+
// spawnSync surfaces its OWN timeout kill as error.code === 'ETIMEDOUT'
|
|
124
|
+
// (status null, no child exit code) — that is the self-deadline firing,
|
|
125
|
+
// not a spawn failure. Degrade non-blocking with the observable budget.
|
|
126
|
+
if (child.error.code === 'ETIMEDOUT') {
|
|
127
|
+
fail(`entry_deadline_exceeded:${Date.now() - startedAt}ms_budget_${deadlineMs}ms`, DEADLINE_NEXT_ACTION);
|
|
128
|
+
}
|
|
71
129
|
const code = child.error.code === 'ENOENT' ? 'entry_not_found' : 'spawn_failed';
|
|
72
130
|
fail(`${code}:${child.error.message.slice(0, 120)}`);
|
|
73
131
|
}
|
|
74
132
|
if (child.status === null) {
|
|
75
|
-
// Killed by signal
|
|
76
|
-
//
|
|
133
|
+
// Killed by signal. When our own deadline armed first, this is the
|
|
134
|
+
// self-timeout degradation (the host kills THIS wrapper, not the child);
|
|
135
|
+
// report it distinctly so field logs separate PD-side degradation from an
|
|
136
|
+
// externally killed adapter.
|
|
137
|
+
const elapsedMs = Date.now() - startedAt;
|
|
138
|
+
if (child.signal === 'SIGTERM' && elapsedMs >= deadlineMs - 500) {
|
|
139
|
+
fail(`entry_deadline_exceeded:${elapsedMs}ms_budget_${deadlineMs}ms`, DEADLINE_NEXT_ACTION);
|
|
140
|
+
}
|
|
77
141
|
fail(`entry_killed_signal:${String(child.signal).slice(0, 30)}`);
|
|
78
142
|
}
|
|
79
143
|
process.exit(child.status);
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Budget-Aware Principle Selection
|
|
3
|
-
*
|
|
4
|
-
* Phase: PRI-75 Prompt Injection SDK Migration Phase 2
|
|
5
|
-
*
|
|
6
|
-
* Pure functions for selecting and formatting principles within a character budget.
|
|
7
|
-
* No I/O dependencies — suitable for any host.
|
|
8
|
-
*/
|
|
9
|
-
import type { PrinciplePriority } from '../runtime-v2/types/principle-enums.js';
|
|
10
|
-
/**
|
|
11
|
-
* Minimal principle shape required for injection selection.
|
|
12
|
-
* Accepts both evolution-types.Principle and principle-tree-schema.Principle.
|
|
13
|
-
*/
|
|
14
|
-
export interface InjectablePrinciple {
|
|
15
|
-
id: string;
|
|
16
|
-
text: string;
|
|
17
|
-
/** Priority level. Defaults to 'P1' if not set by the source. */
|
|
18
|
-
priority?: PrinciplePriority;
|
|
19
|
-
/** ISO date string. Required for recency ordering in selectPrinciplesForInjection. */
|
|
20
|
-
createdAt: string;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Result of principle selection for injection.
|
|
24
|
-
*/
|
|
25
|
-
export interface PrincipleSelectionResult {
|
|
26
|
-
/** Selected principles in injection order (priority-first, then recency) */
|
|
27
|
-
selected: InjectablePrinciple[];
|
|
28
|
-
/** Total character count of selected principles' formatted output */
|
|
29
|
-
totalChars: number;
|
|
30
|
-
/** Number of principles by priority tier */
|
|
31
|
-
breakdown: {
|
|
32
|
-
p0: number;
|
|
33
|
-
p1: number;
|
|
34
|
-
p2: number;
|
|
35
|
-
};
|
|
36
|
-
/** Whether at least one P0 principle was included */
|
|
37
|
-
hasP0: boolean;
|
|
38
|
-
/** Whether the selection was truncated due to budget */
|
|
39
|
-
wasTruncated: boolean;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Format a single principle for injection.
|
|
43
|
-
* Returns the formatted string including ID and text.
|
|
44
|
-
*
|
|
45
|
-
* Format: "- [ID] text" (matches existing prompt.ts format)
|
|
46
|
-
*/
|
|
47
|
-
export declare function formatPrinciple(p: InjectablePrinciple): string;
|
|
48
|
-
/**
|
|
49
|
-
* Select principles for prompt injection within a character budget.
|
|
50
|
-
*
|
|
51
|
-
* Algorithm:
|
|
52
|
-
* 1. Sort all principles by priority (P0 > P1 > P2), then by recency
|
|
53
|
-
* 2. Iterate through sorted principles, accumulating character count
|
|
54
|
-
* 3. Stop when adding the next principle would exceed budgetChars
|
|
55
|
-
* 4. Ensure at least one P0 principle is included (even if it exceeds budget)
|
|
56
|
-
*
|
|
57
|
-
* @param principles - All available principles to select from
|
|
58
|
-
* @param budgetChars - Maximum character budget for formatted output
|
|
59
|
-
* @returns Selection result with chosen principles and metadata
|
|
60
|
-
*/
|
|
61
|
-
export declare function selectPrinciplesForInjection(principles: InjectablePrinciple[], budgetChars: number): PrincipleSelectionResult;
|
|
62
|
-
/**
|
|
63
|
-
* Default character budget for principle injection.
|
|
64
|
-
* 4000 characters is ~800 tokens, leaving ample room for other prompt sections
|
|
65
|
-
* within the 10K character injection limit.
|
|
66
|
-
*/
|
|
67
|
-
export declare const DEFAULT_PRINCIPLE_BUDGET = 4000;
|
|
68
|
-
//# sourceMappingURL=principle-selection.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"principle-selection.d.ts","sourceRoot":"","sources":["../../src/prompt-builder/principle-selection.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAMhF;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,sFAAsF;IACtF,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,4EAA4E;IAC5E,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,SAAS,EAAE;QACT,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,qDAAqD;IACrD,KAAK,EAAE,OAAO,CAAC;IACf,wDAAwD;IACxD,YAAY,EAAE,OAAO,CAAC;CACvB;AAmCD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,mBAAmB,GAAG,MAAM,CAE9D;AAaD;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,mBAAmB,EAAE,EACjC,WAAW,EAAE,MAAM,GAClB,wBAAwB,CAwE1B;AAMD;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,OAAO,CAAC"}
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Budget-Aware Principle Selection
|
|
3
|
-
*
|
|
4
|
-
* Phase: PRI-75 Prompt Injection SDK Migration Phase 2
|
|
5
|
-
*
|
|
6
|
-
* Pure functions for selecting and formatting principles within a character budget.
|
|
7
|
-
* No I/O dependencies — suitable for any host.
|
|
8
|
-
*/
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
|
-
// Priority Ordering
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
|
-
const PRIORITY_ORDER = {
|
|
13
|
-
P0: 0,
|
|
14
|
-
P1: 1,
|
|
15
|
-
P2: 2,
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* Compare two principles for sorting.
|
|
19
|
-
* Primary: priority (P0 < P1 < P2 — lower is higher priority).
|
|
20
|
-
* Secondary: recency (newer createdAt first).
|
|
21
|
-
*/
|
|
22
|
-
function comparePrinciples(a, b) {
|
|
23
|
-
const INVALID_PRIORITY_RANK = 99;
|
|
24
|
-
const priorityA = PRIORITY_ORDER[a.priority ?? 'P1'] ?? INVALID_PRIORITY_RANK;
|
|
25
|
-
const priorityB = PRIORITY_ORDER[b.priority ?? 'P1'] ?? INVALID_PRIORITY_RANK;
|
|
26
|
-
if (priorityA !== priorityB) {
|
|
27
|
-
return priorityA - priorityB;
|
|
28
|
-
}
|
|
29
|
-
// Same priority: sort by recency (newer first)
|
|
30
|
-
// Date.parse is robust to non-ISO-8601 formats unlike localeCompare on raw strings
|
|
31
|
-
return Date.parse(b.createdAt) - Date.parse(a.createdAt);
|
|
32
|
-
}
|
|
33
|
-
// ---------------------------------------------------------------------------
|
|
34
|
-
// Formatting
|
|
35
|
-
// ---------------------------------------------------------------------------
|
|
36
|
-
/**
|
|
37
|
-
* Format a single principle for injection.
|
|
38
|
-
* Returns the formatted string including ID and text.
|
|
39
|
-
*
|
|
40
|
-
* Format: "- [ID] text" (matches existing prompt.ts format)
|
|
41
|
-
*/
|
|
42
|
-
export function formatPrinciple(p) {
|
|
43
|
-
return `- [${p.id}] ${p.text}`;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Calculate the character length of a formatted principle, including newline.
|
|
47
|
-
*/
|
|
48
|
-
function formattedLength(p) {
|
|
49
|
-
return formatPrinciple(p).length + 1; // +1 for newline separator
|
|
50
|
-
}
|
|
51
|
-
// ---------------------------------------------------------------------------
|
|
52
|
-
// Selection Algorithm
|
|
53
|
-
// ---------------------------------------------------------------------------
|
|
54
|
-
/**
|
|
55
|
-
* Select principles for prompt injection within a character budget.
|
|
56
|
-
*
|
|
57
|
-
* Algorithm:
|
|
58
|
-
* 1. Sort all principles by priority (P0 > P1 > P2), then by recency
|
|
59
|
-
* 2. Iterate through sorted principles, accumulating character count
|
|
60
|
-
* 3. Stop when adding the next principle would exceed budgetChars
|
|
61
|
-
* 4. Ensure at least one P0 principle is included (even if it exceeds budget)
|
|
62
|
-
*
|
|
63
|
-
* @param principles - All available principles to select from
|
|
64
|
-
* @param budgetChars - Maximum character budget for formatted output
|
|
65
|
-
* @returns Selection result with chosen principles and metadata
|
|
66
|
-
*/
|
|
67
|
-
export function selectPrinciplesForInjection(principles, budgetChars) {
|
|
68
|
-
if (principles.length === 0) {
|
|
69
|
-
return {
|
|
70
|
-
selected: [],
|
|
71
|
-
totalChars: 0,
|
|
72
|
-
breakdown: { p0: 0, p1: 0, p2: 0 },
|
|
73
|
-
hasP0: false,
|
|
74
|
-
wasTruncated: false,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
// Sort by priority then recency
|
|
78
|
-
const sorted = [...principles].sort(comparePrinciples);
|
|
79
|
-
const selected = [];
|
|
80
|
-
let totalChars = 0;
|
|
81
|
-
let p0Included = false;
|
|
82
|
-
let wasTruncated = false;
|
|
83
|
-
for (const principle of sorted) {
|
|
84
|
-
const cost = formattedLength(principle);
|
|
85
|
-
// Check if adding this principle would exceed budget
|
|
86
|
-
if (totalChars + cost > budgetChars) {
|
|
87
|
-
// Special case: if no P0 has been included yet, force-include the first P0
|
|
88
|
-
// even if it exceeds the budget (P0 principles are critical)
|
|
89
|
-
if (!p0Included && principle.priority === 'P0') {
|
|
90
|
-
selected.push(principle);
|
|
91
|
-
totalChars += cost;
|
|
92
|
-
p0Included = true;
|
|
93
|
-
wasTruncated = true;
|
|
94
|
-
// Continue to try to fit more principles after this forced inclusion
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
wasTruncated = true;
|
|
98
|
-
// Continue evaluating remaining principles — a smaller one that fits may exist
|
|
99
|
-
continue;
|
|
100
|
-
}
|
|
101
|
-
selected.push(principle);
|
|
102
|
-
totalChars += cost;
|
|
103
|
-
if (principle.priority === 'P0') {
|
|
104
|
-
p0Included = true;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
// Safety net: if we went through all principles and still no P0 included
|
|
108
|
-
// (because P0 was beyond budget threshold), force-include the first P0
|
|
109
|
-
if (!p0Included) {
|
|
110
|
-
const firstP0 = sorted.find(p => p.priority === 'P0');
|
|
111
|
-
if (firstP0 && !selected.includes(firstP0)) {
|
|
112
|
-
// Insert P0 at the beginning of selected (highest priority)
|
|
113
|
-
selected.unshift(firstP0);
|
|
114
|
-
totalChars += formattedLength(firstP0);
|
|
115
|
-
p0Included = true;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
const breakdown = {
|
|
119
|
-
p0: selected.filter(p => (p.priority ?? 'P1') === 'P0').length,
|
|
120
|
-
p1: selected.filter(p => (p.priority ?? 'P1') === 'P1').length,
|
|
121
|
-
p2: selected.filter(p => (p.priority ?? 'P1') === 'P2').length,
|
|
122
|
-
};
|
|
123
|
-
return {
|
|
124
|
-
selected,
|
|
125
|
-
totalChars,
|
|
126
|
-
breakdown,
|
|
127
|
-
hasP0: p0Included,
|
|
128
|
-
wasTruncated,
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
// ---------------------------------------------------------------------------
|
|
132
|
-
// Default Budget
|
|
133
|
-
// ---------------------------------------------------------------------------
|
|
134
|
-
/**
|
|
135
|
-
* Default character budget for principle injection.
|
|
136
|
-
* 4000 characters is ~800 tokens, leaving ample room for other prompt sections
|
|
137
|
-
* within the 10K character injection limit.
|
|
138
|
-
*/
|
|
139
|
-
export const DEFAULT_PRINCIPLE_BUDGET = 4000;
|
|
140
|
-
//# sourceMappingURL=principle-selection.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"principle-selection.js","sourceRoot":"","sources":["../../src/prompt-builder/principle-selection.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAyCH,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,MAAM,cAAc,GAAsC;IACxD,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;CACN,CAAC;AAEF;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,CAAsB,EAAE,CAAsB;IACvE,MAAM,qBAAqB,GAAG,EAAE,CAAC;IACjC,MAAM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,qBAAqB,CAAC;IAC9E,MAAM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,qBAAqB,CAAC;IAE9E,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,SAAS,GAAG,SAAS,CAAC;IAC/B,CAAC;IAED,+CAA+C;IAC/C,mFAAmF;IACnF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAC3D,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,CAAsB;IACpD,OAAO,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,CAAsB;IAC7C,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,2BAA2B;AACnE,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,4BAA4B,CAC1C,UAAiC,EACjC,WAAmB;IAEnB,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO;YACL,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,CAAC;YACb,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;YAClC,KAAK,EAAE,KAAK;YACZ,YAAY,EAAE,KAAK;SACpB,CAAC;IACJ,CAAC;IAED,gCAAgC;IAChC,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAEvD,MAAM,QAAQ,GAA0B,EAAE,CAAC;IAC3C,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,KAAK,MAAM,SAAS,IAAI,MAAM,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QAExC,qDAAqD;QACrD,IAAI,UAAU,GAAG,IAAI,GAAG,WAAW,EAAE,CAAC;YACpC,2EAA2E;YAC3E,6DAA6D;YAC7D,IAAI,CAAC,UAAU,IAAI,SAAS,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;gBAC/C,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACzB,UAAU,IAAI,IAAI,CAAC;gBACnB,UAAU,GAAG,IAAI,CAAC;gBAClB,YAAY,GAAG,IAAI,CAAC;gBACpB,qEAAqE;gBACrE,SAAS;YACX,CAAC;YAED,YAAY,GAAG,IAAI,CAAC;YACpB,+EAA+E;YAC/E,SAAS;QACX,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzB,UAAU,IAAI,IAAI,CAAC;QACnB,IAAI,SAAS,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAChC,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;IACH,CAAC;IAED,yEAAyE;IACzE,uEAAuE;IACvE,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC;QACtD,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3C,4DAA4D;YAC5D,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC1B,UAAU,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;YACvC,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG;QAChB,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM;QAC9D,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM;QAC9D,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM;KAC/D,CAAC;IAEF,OAAO;QACL,QAAQ;QACR,UAAU;QACV,SAAS;QACT,KAAK,EAAE,UAAU;QACjB,YAAY;KACb,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pruning Mask — builds a set of principle IDs to exclude from prompt injection.
|
|
3
|
-
*
|
|
4
|
-
* Consumes PruningReviewRecord[] (from listPruningReviews) and applies LWW
|
|
5
|
-
* (Last Write Wins) semantics: for each principleId, only the latest decision
|
|
6
|
-
* matters. archive-candidate → masked, keep/defer → not masked.
|
|
7
|
-
*
|
|
8
|
-
* Pure function, zero I/O, zero side effects.
|
|
9
|
-
*/
|
|
10
|
-
import type { PruningReviewRecord } from './pruning-review-log.js';
|
|
11
|
-
export declare function buildMaskedPrincipleSet(reviews: PruningReviewRecord[]): Set<string>;
|
|
12
|
-
/**
|
|
13
|
-
* Returns a cached mask of principle IDs to exclude from injection.
|
|
14
|
-
* Reads the review log from disk only once per TTL window (default 60s).
|
|
15
|
-
*
|
|
16
|
-
* @param workspaceDir - Workspace root directory
|
|
17
|
-
* @param ttlMs - Time-to-live in milliseconds (default 60_000)
|
|
18
|
-
* @returns Set of principle IDs with latest decision = archive-candidate
|
|
19
|
-
* @throws Propagates I/O errors from listPruningReviews so callers can degrade safely
|
|
20
|
-
*/
|
|
21
|
-
export declare function getCachedMaskedPrincipleSet(workspaceDir: string, ttlMs?: number): Set<string>;
|
|
22
|
-
/**
|
|
23
|
-
* Clears the pruning mask cache.
|
|
24
|
-
* Primarily useful for tests that need deterministic I/O timing.
|
|
25
|
-
*/
|
|
26
|
-
export declare function clearPruningMaskCache(): void;
|
|
27
|
-
//# sourceMappingURL=pruning-mask.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pruning-mask.d.ts","sourceRoot":"","sources":["../../src/runtime-v2/pruning-mask.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAyB,MAAM,yBAAyB,CAAC;AAG1F,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,mBAAmB,EAAE,GAC7B,GAAG,CAAC,MAAM,CAAC,CAyBb;AAUD;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,MAAM,EACpB,KAAK,SAAiB,GACrB,GAAG,CAAC,MAAM,CAAC,CAUb;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAI5C"}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { listPruningReviews } from './pruning-review-log.js';
|
|
2
|
-
export function buildMaskedPrincipleSet(reviews) {
|
|
3
|
-
if (!reviews || reviews.length === 0) {
|
|
4
|
-
return new Set();
|
|
5
|
-
}
|
|
6
|
-
// LWW: track latest decision per principleId
|
|
7
|
-
const latest = new Map();
|
|
8
|
-
for (const r of reviews) {
|
|
9
|
-
if (!r?.principleId || !r?.decision || !r?.reviewedAt) {
|
|
10
|
-
continue; // skip corrupt records
|
|
11
|
-
}
|
|
12
|
-
const existing = latest.get(r.principleId);
|
|
13
|
-
if (!existing || r.reviewedAt >= existing.reviewedAt) {
|
|
14
|
-
latest.set(r.principleId, { decision: r.decision, reviewedAt: r.reviewedAt });
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
const masked = new Set();
|
|
18
|
-
for (const [principleId, { decision }] of latest) {
|
|
19
|
-
if (decision === 'archive-candidate') {
|
|
20
|
-
masked.add(principleId);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return masked;
|
|
24
|
-
}
|
|
25
|
-
// ── TTL cache ────────────────────────────────────────────────────────────────
|
|
26
|
-
const DEFAULT_TTL_MS = 60_000;
|
|
27
|
-
let cachedMask = null;
|
|
28
|
-
let cachedAt = 0;
|
|
29
|
-
let cachedWorkspaceDir = '';
|
|
30
|
-
/**
|
|
31
|
-
* Returns a cached mask of principle IDs to exclude from injection.
|
|
32
|
-
* Reads the review log from disk only once per TTL window (default 60s).
|
|
33
|
-
*
|
|
34
|
-
* @param workspaceDir - Workspace root directory
|
|
35
|
-
* @param ttlMs - Time-to-live in milliseconds (default 60_000)
|
|
36
|
-
* @returns Set of principle IDs with latest decision = archive-candidate
|
|
37
|
-
* @throws Propagates I/O errors from listPruningReviews so callers can degrade safely
|
|
38
|
-
*/
|
|
39
|
-
export function getCachedMaskedPrincipleSet(workspaceDir, ttlMs = DEFAULT_TTL_MS) {
|
|
40
|
-
const now = Date.now();
|
|
41
|
-
if (cachedMask !== null && cachedWorkspaceDir === workspaceDir && (now - cachedAt) < ttlMs) {
|
|
42
|
-
return cachedMask;
|
|
43
|
-
}
|
|
44
|
-
const reviews = listPruningReviews(workspaceDir);
|
|
45
|
-
cachedMask = buildMaskedPrincipleSet(reviews);
|
|
46
|
-
cachedAt = now;
|
|
47
|
-
cachedWorkspaceDir = workspaceDir;
|
|
48
|
-
return cachedMask;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Clears the pruning mask cache.
|
|
52
|
-
* Primarily useful for tests that need deterministic I/O timing.
|
|
53
|
-
*/
|
|
54
|
-
export function clearPruningMaskCache() {
|
|
55
|
-
cachedMask = null;
|
|
56
|
-
cachedAt = 0;
|
|
57
|
-
cachedWorkspaceDir = '';
|
|
58
|
-
}
|
|
59
|
-
//# sourceMappingURL=pruning-mask.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pruning-mask.js","sourceRoot":"","sources":["../../src/runtime-v2/pruning-mask.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,MAAM,UAAU,uBAAuB,CACrC,OAA8B;IAE9B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,OAAO,IAAI,GAAG,EAAE,CAAC;IACnB,CAAC;IAED,6CAA6C;IAC7C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAmE,CAAC;IAE1F,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,EAAE,WAAW,IAAI,CAAC,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;YACtD,SAAS,CAAC,uBAAuB;QACnC,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QAC3C,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;YACrD,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,KAAK,MAAM,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC;QACjD,IAAI,QAAQ,KAAK,mBAAmB,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gFAAgF;AAEhF,MAAM,cAAc,GAAG,MAAM,CAAC;AAE9B,IAAI,UAAU,GAAuB,IAAI,CAAC;AAC1C,IAAI,QAAQ,GAAG,CAAC,CAAC;AACjB,IAAI,kBAAkB,GAAG,EAAE,CAAC;AAE5B;;;;;;;;GAQG;AACH,MAAM,UAAU,2BAA2B,CACzC,YAAoB,EACpB,KAAK,GAAG,cAAc;IAEtB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,UAAU,KAAK,IAAI,IAAI,kBAAkB,KAAK,YAAY,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAK,EAAE,CAAC;QAC3F,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,MAAM,OAAO,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;IACjD,UAAU,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAC9C,QAAQ,GAAG,GAAG,CAAC;IACf,kBAAkB,GAAG,YAAY,CAAC;IAClC,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB;IACnC,UAAU,GAAG,IAAI,CAAC;IAClB,QAAQ,GAAG,CAAC,CAAC;IACb,kBAAkB,GAAG,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import type { PrinciplePruningSignal } from './pruning-read-model.js';
|
|
2
|
-
export type PruningReviewDecision = 'keep' | 'defer' | 'archive-candidate';
|
|
3
|
-
export interface PruningReviewRecord {
|
|
4
|
-
reviewId: string;
|
|
5
|
-
principleId: string;
|
|
6
|
-
decision: PruningReviewDecision;
|
|
7
|
-
note: string;
|
|
8
|
-
reviewer: string;
|
|
9
|
-
reviewedAt: string;
|
|
10
|
-
signalSnapshot: PrinciplePruningSignal;
|
|
11
|
-
}
|
|
12
|
-
export interface AppendPruningReviewInput {
|
|
13
|
-
principleId: string;
|
|
14
|
-
decision: PruningReviewDecision;
|
|
15
|
-
note?: string;
|
|
16
|
-
reviewer?: string;
|
|
17
|
-
/**
|
|
18
|
-
* Snapshot of the principle's pruning signal at the time of review.
|
|
19
|
-
* Optional — rollback operations may not have a live signal available.
|
|
20
|
-
*/
|
|
21
|
-
signalSnapshot?: PruningReviewRecord['signalSnapshot'];
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Append a pruning review record to the audit log.
|
|
25
|
-
*
|
|
26
|
-
* @param workspaceDir - The workspace root directory
|
|
27
|
-
* @param input - Review decision input
|
|
28
|
-
* @returns The full record that was written
|
|
29
|
-
*/
|
|
30
|
-
export declare function appendPruningReview(workspaceDir: string, input: AppendPruningReviewInput): PruningReviewRecord;
|
|
31
|
-
/**
|
|
32
|
-
* List pruning review records from the audit log.
|
|
33
|
-
*
|
|
34
|
-
* @param workspaceDir - The workspace root directory
|
|
35
|
-
* @param filter - Optional filter by principleId
|
|
36
|
-
* @returns Array of review records (oldest first)
|
|
37
|
-
*/
|
|
38
|
-
export declare function listPruningReviews(workspaceDir: string, filter?: {
|
|
39
|
-
principleId?: string;
|
|
40
|
-
}): PruningReviewRecord[];
|
|
41
|
-
//# sourceMappingURL=pruning-review-log.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pruning-review-log.d.ts","sourceRoot":"","sources":["../../src/runtime-v2/pruning-review-log.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAItE,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,OAAO,GAAG,mBAAmB,CAAC;AAE3E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,qBAAqB,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,sBAAsB,CAAC;CACxC;AAED,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,qBAAqB,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,cAAc,CAAC,EAAE,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;CACxD;AAyBD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,wBAAwB,GAC9B,mBAAmB,CAqCrB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAChC,mBAAmB,EAAE,CA0BvB"}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PruningReviewLog — append-only JSONL audit log for human pruning review decisions.
|
|
3
|
-
*
|
|
4
|
-
* PRI-24: Add pruning review audit log.
|
|
5
|
-
*
|
|
6
|
-
* Storage: <workspace>/.state/pruning_reviews.jsonl
|
|
7
|
-
* Each line is one complete JSON record.
|
|
8
|
-
*
|
|
9
|
-
* Non-goals:
|
|
10
|
-
* - Does not modify ledger or state.db
|
|
11
|
-
* - Does not implement automatic pruning
|
|
12
|
-
* - Does not provide CLI (that's PRI-25)
|
|
13
|
-
*/
|
|
14
|
-
import * as fs from 'fs';
|
|
15
|
-
import * as path from 'path';
|
|
16
|
-
import * as crypto from 'crypto';
|
|
17
|
-
// ── Validation ─────────────────────────────────────────────────────────────────
|
|
18
|
-
const VALID_DECISIONS = new Set(['keep', 'defer', 'archive-candidate']);
|
|
19
|
-
function validateDecision(decision) {
|
|
20
|
-
if (!VALID_DECISIONS.has(decision)) {
|
|
21
|
-
throw new Error(`Invalid decision: '${decision}'. Must be one of: keep, defer, archive-candidate`);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
// ── Core Functions ─────────────────────────────────────────────────────────────
|
|
25
|
-
function getLogPath(workspaceDir) {
|
|
26
|
-
return path.join(workspaceDir, '.state', 'pruning_reviews.jsonl');
|
|
27
|
-
}
|
|
28
|
-
function ensureStateDir(workspaceDir) {
|
|
29
|
-
const stateDir = path.join(workspaceDir, '.state');
|
|
30
|
-
if (!fs.existsSync(stateDir)) {
|
|
31
|
-
fs.mkdirSync(stateDir, { recursive: true });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Append a pruning review record to the audit log.
|
|
36
|
-
*
|
|
37
|
-
* @param workspaceDir - The workspace root directory
|
|
38
|
-
* @param input - Review decision input
|
|
39
|
-
* @returns The full record that was written
|
|
40
|
-
*/
|
|
41
|
-
export function appendPruningReview(workspaceDir, input) {
|
|
42
|
-
validateDecision(input.decision);
|
|
43
|
-
ensureStateDir(workspaceDir);
|
|
44
|
-
const reviewId = crypto.randomUUID();
|
|
45
|
-
const reviewedAt = new Date().toISOString();
|
|
46
|
-
const reviewer = input.reviewer ?? 'operator';
|
|
47
|
-
const record = {
|
|
48
|
-
reviewId,
|
|
49
|
-
principleId: input.principleId,
|
|
50
|
-
decision: input.decision,
|
|
51
|
-
note: input.note ?? '',
|
|
52
|
-
reviewer,
|
|
53
|
-
reviewedAt,
|
|
54
|
-
signalSnapshot: input.signalSnapshot ?? {
|
|
55
|
-
principleId: input.principleId,
|
|
56
|
-
status: 'active',
|
|
57
|
-
createdAt: reviewedAt,
|
|
58
|
-
updatedAt: reviewedAt,
|
|
59
|
-
derivedCandidateIds: [],
|
|
60
|
-
derivedPainCount: 0,
|
|
61
|
-
matchedCandidateCount: 0,
|
|
62
|
-
recentCandidateCount: 0,
|
|
63
|
-
orphanCandidateCount: 0,
|
|
64
|
-
ageDays: 0,
|
|
65
|
-
riskLevel: 'watch',
|
|
66
|
-
reasons: ['rollback: no signal snapshot available'],
|
|
67
|
-
},
|
|
68
|
-
};
|
|
69
|
-
const logPath = getLogPath(workspaceDir);
|
|
70
|
-
const line = JSON.stringify(record) + '\n';
|
|
71
|
-
fs.appendFileSync(logPath, line, 'utf-8');
|
|
72
|
-
return record;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* List pruning review records from the audit log.
|
|
76
|
-
*
|
|
77
|
-
* @param workspaceDir - The workspace root directory
|
|
78
|
-
* @param filter - Optional filter by principleId
|
|
79
|
-
* @returns Array of review records (oldest first)
|
|
80
|
-
*/
|
|
81
|
-
export function listPruningReviews(workspaceDir, filter) {
|
|
82
|
-
const logPath = getLogPath(workspaceDir);
|
|
83
|
-
if (!fs.existsSync(logPath)) {
|
|
84
|
-
return [];
|
|
85
|
-
}
|
|
86
|
-
const content = fs.readFileSync(logPath, 'utf-8');
|
|
87
|
-
const lines = content.split('\n');
|
|
88
|
-
const records = [];
|
|
89
|
-
for (const line of lines) {
|
|
90
|
-
const trimmed = line.trim();
|
|
91
|
-
if (!trimmed)
|
|
92
|
-
continue;
|
|
93
|
-
try {
|
|
94
|
-
const record = JSON.parse(trimmed);
|
|
95
|
-
if (filter?.principleId && record.principleId !== filter.principleId) {
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
records.push(record);
|
|
99
|
-
}
|
|
100
|
-
catch {
|
|
101
|
-
// Skip corrupt lines — continue processing
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
return records;
|
|
105
|
-
}
|
|
106
|
-
//# sourceMappingURL=pruning-review-log.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pruning-review-log.js","sourceRoot":"","sources":["../../src/runtime-v2/pruning-review-log.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Principle Injection — Budget-Aware Principle Selection
|
|
3
|
-
*
|
|
4
|
-
* Phase: PRI-75 Prompt Injection SDK Migration Phase 2
|
|
5
|
-
*
|
|
6
|
-
* This file is now a thin re-export layer.
|
|
7
|
-
* All pure logic lives in @principles/core/prompt-builder/principle-selection.ts.
|
|
8
|
-
*/
|
|
9
|
-
export { formatPrinciple, selectPrinciplesForInjection, DEFAULT_PRINCIPLE_BUDGET, } from '@principles/core/prompt-builder';
|
|
10
|
-
export type { InjectablePrinciple, PrincipleSelectionResult } from '@principles/core/prompt-builder';
|