create-principles-disciple 1.145.41 → 1.145.43
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/package.json +1 -1
- package/console/dist/server/index.js +8 -0
- package/console/dist/server/routes/examiner-executor.d.ts +254 -0
- package/console/dist/server/routes/examiner-executor.js +622 -0
- package/console/dist/server/routes/examiner.d.ts +46 -0
- package/console/dist/server/routes/examiner.js +296 -0
- package/console/dist/ui/App.js +6 -3
- package/console/dist/ui/api.d.ts +138 -0
- package/console/dist/ui/api.js +56 -0
- package/console/dist/ui/components/layout/app-sidebar.d.ts +11 -0
- package/console/dist/ui/components/layout/app-sidebar.js +12 -2
- package/console/dist/ui/i18n/en.json +63 -0
- package/console/dist/ui/i18n/zh-CN.json +63 -0
- package/console/dist/ui/pages/examiner/ExaminerPage.d.ts +15 -0
- package/console/dist/ui/pages/examiner/ExaminerPage.js +158 -0
- package/console/dist/ui/pages/principles/PrincipleDetailPage.js +2 -1
- package/console/dist/ui/utils/runtime-mode.d.ts +10 -0
- package/console/dist/ui/utils/runtime-mode.js +10 -0
- package/console/dist/web/assets/app.css +44 -0
- package/console/dist/web/assets/app.js +33 -31
- package/core/dist/host/host-installer.d.ts +13 -0
- package/core/dist/host/host-installer.d.ts.map +1 -1
- package/core/dist/host/host-installer.js.map +1 -1
- package/core/package.json +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -1
- package/dist/installer.js +1 -1
- package/dist/installer.js.map +1 -1
- package/dist/installers/workbuddy-host-installer.d.ts +39 -0
- package/dist/installers/workbuddy-host-installer.d.ts.map +1 -1
- package/dist/installers/workbuddy-host-installer.js +76 -27
- package/dist/installers/workbuddy-host-installer.js.map +1 -1
- package/package.json +2 -2
- package/pd-cli/dist/services/pd-config-loader.d.ts +1 -1
- package/pd-cli/dist/services/pd-config-loader.d.ts.map +1 -1
- package/pd-cli/dist/services/pd-config-loader.js +9 -0
- package/pd-cli/dist/services/pd-config-loader.js.map +1 -1
- package/pd-cli/package.json +1 -1
- package/plugin/openclaw.plugin.json +1 -1
- package/plugin/package.json +1 -1
- package/release-manager/dist/index.d.ts.map +1 -1
- package/release-manager/dist/index.js +29 -0
- package/release-manager/dist/index.js.map +1 -1
- package/release-manager/dist/installer.js +1 -1
- package/release-manager/dist/installer.js.map +1 -1
- package/release-manager/dist/installers/workbuddy-host-installer.d.ts +39 -0
- package/release-manager/dist/installers/workbuddy-host-installer.d.ts.map +1 -1
- package/release-manager/dist/installers/workbuddy-host-installer.js +76 -27
- package/release-manager/dist/installers/workbuddy-host-installer.js.map +1 -1
- package/release-manager/package.json +2 -2
- package/workbuddy-adapter/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@principles/codex-adapter",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "Codex CLI host adapter for Principles Disciple — implements HostAdapter interface for OpenAI Codex CLI's stdin/stdout JSON hook model (ADR-0020).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,6 +17,7 @@ import { handleApprovalsRoute, disposeApprovalsModels } from './routes/approvals
|
|
|
17
17
|
import { handleHealthRoute, disposeHealthModels } from './routes/health.js';
|
|
18
18
|
import { handlePrinciplesRoute, handleCorePrinciplesRoute, disposePrinciplesModels } from './routes/principles.js';
|
|
19
19
|
import { handleLifecycleRoute, disposeLifecycleModels } from './routes/lifecycle.js';
|
|
20
|
+
import { handleExaminerRoute } from './routes/examiner.js';
|
|
20
21
|
import { handleActivationsRoute, disposeActivationsModels } from './routes/activations.js';
|
|
21
22
|
import { handleReceiptsRoute, disposeReceiptsModels } from './routes/receipts.js';
|
|
22
23
|
import { handleApprovalsGroupedRoute, disposeApprovalsGroupedModels } from './routes/approvals-grouped.js';
|
|
@@ -456,6 +457,13 @@ function handleRequest(services) {
|
|
|
456
457
|
asyncHandler(() => handleLifecycleRoute(req, res, services.workspaceDir, subPath))(req, res);
|
|
457
458
|
return;
|
|
458
459
|
}
|
|
460
|
+
// SPEC-PD-EXAMINER-001 v0.9 §8: Examiner offline studies (local-dev
|
|
461
|
+
// scope — the route answers 503 when the lab tooling is not present).
|
|
462
|
+
if (urlPath === '/api/v1/examiner' || urlPath.startsWith('/api/v1/examiner/')) {
|
|
463
|
+
const subPath = urlPath.slice('/api/v1/examiner'.length);
|
|
464
|
+
asyncHandler(() => handleExaminerRoute(req, res, services.workspaceDir, subPath))(req, res);
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
459
467
|
// CR8: GET /api/v1/activations
|
|
460
468
|
if (urlPath === '/api/v1/activations' || urlPath.startsWith('/api/v1/activations/')) {
|
|
461
469
|
const subPath = urlPath.slice('/api/v1/activations'.length);
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
export type LabModules = {
|
|
2
|
+
study: Record<string, unknown> & {
|
|
3
|
+
runExaminerPreflight: (input: Record<string, unknown>) => {
|
|
4
|
+
ok: boolean;
|
|
5
|
+
status: string;
|
|
6
|
+
blockers: unknown[];
|
|
7
|
+
warnings: unknown[];
|
|
8
|
+
checks: unknown[];
|
|
9
|
+
};
|
|
10
|
+
definePrimaryEndpoint: (input: {
|
|
11
|
+
id: string;
|
|
12
|
+
}) => Record<string, unknown>;
|
|
13
|
+
buildHostEffectivePrincipleSet: (input: Record<string, unknown>) => Record<string, unknown>;
|
|
14
|
+
buildRuleCodePolicy: (input: Record<string, unknown>) => Record<string, unknown>;
|
|
15
|
+
verifyExaminerStudyBindings: (studyDir: string, options?: {
|
|
16
|
+
requireAnchor?: boolean;
|
|
17
|
+
}) => {
|
|
18
|
+
ok: boolean;
|
|
19
|
+
anchor: string;
|
|
20
|
+
problems: string[];
|
|
21
|
+
bindingHash?: string | null;
|
|
22
|
+
};
|
|
23
|
+
verifyRuleCodePolicy: (policy: Record<string, unknown>) => {
|
|
24
|
+
ok: boolean;
|
|
25
|
+
reason?: string;
|
|
26
|
+
};
|
|
27
|
+
verifyHostEffectivePrincipleSet: (heps: Record<string, unknown>) => {
|
|
28
|
+
ok: boolean;
|
|
29
|
+
reason?: string;
|
|
30
|
+
};
|
|
31
|
+
writeExaminerStudyArtifacts: (input: Record<string, unknown>) => {
|
|
32
|
+
manifest: Record<string, unknown>;
|
|
33
|
+
pairAssignment: Record<string, unknown>;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
runner: Record<string, unknown> & {
|
|
37
|
+
runChallengeStudy: (options: Record<string, unknown>) => Promise<{
|
|
38
|
+
units: Record<string, unknown>[];
|
|
39
|
+
}>;
|
|
40
|
+
verifyStudyRunReadiness: (studyDir: string) => unknown;
|
|
41
|
+
};
|
|
42
|
+
report: Record<string, unknown> & {
|
|
43
|
+
verifyBehaviorReportV2: (studyDir: string) => {
|
|
44
|
+
checks: {
|
|
45
|
+
ok: boolean;
|
|
46
|
+
}[];
|
|
47
|
+
};
|
|
48
|
+
writeBehaviorReportV2: (studyDir: string, options: {
|
|
49
|
+
now: string;
|
|
50
|
+
canWrite?: () => {
|
|
51
|
+
ok: boolean;
|
|
52
|
+
reason?: string;
|
|
53
|
+
};
|
|
54
|
+
}) => {
|
|
55
|
+
status: string;
|
|
56
|
+
written: boolean;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
actor: Record<string, unknown> & {
|
|
60
|
+
createScriptedStub: (options: {
|
|
61
|
+
actions: Record<string, unknown>[];
|
|
62
|
+
armPrompt?: string | null;
|
|
63
|
+
}) => {
|
|
64
|
+
nextAction: () => Record<string, unknown>;
|
|
65
|
+
loadArmPrompt?: (prompt: string) => unknown;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
/** Historical research-asset root — ALWAYS read-only, never a writable root. */
|
|
70
|
+
export type StudyRoots = {
|
|
71
|
+
writable: string;
|
|
72
|
+
historical: string;
|
|
73
|
+
};
|
|
74
|
+
export declare const CONSOLE_OWNERSHIP_MARKER = ".console-study-owner.json";
|
|
75
|
+
/** Stable, Owner-facing boundary reasons — never paths or exception text. */
|
|
76
|
+
export declare const STUDY_PATH_PROBLEM: {
|
|
77
|
+
readonly unresolved: 'the study path cannot be resolved to a canonical location (fail-closed)';
|
|
78
|
+
readonly notInside: 'the study directory resolves outside the writable console root';
|
|
79
|
+
readonly historical: 'the study directory resolves inside the historical research area';
|
|
80
|
+
readonly rootNotIsolated: 'the writable study root must be separate from the historical examiner-studies area';
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* P1-1 canonical resolution. An existing path goes through `realpath`, which
|
|
84
|
+
* follows symlinks AND Windows junctions. A path that does not exist yet is
|
|
85
|
+
* resolved through its deepest EXISTING ancestor (so a symlinked parent can
|
|
86
|
+
* never hide an escape) and the remaining lexically-safe segments are
|
|
87
|
+
* appended. Any resolution failure is fail-closed (null).
|
|
88
|
+
*/
|
|
89
|
+
export declare function canonicalPathSync(target: string): string | null;
|
|
90
|
+
export declare function isSamePath(a: string, b: string): boolean;
|
|
91
|
+
/** Strict containment: equal paths are NOT inside each other. */
|
|
92
|
+
export declare function isPathInside(root: string, candidate: string): boolean;
|
|
93
|
+
/** Resolve the two roots once. `PD_EXAMINER_STUDIES_ROOT` overrides the WRITABLE root only. */
|
|
94
|
+
export declare function resolveStudyRoots(labRoot: string): StudyRoots;
|
|
95
|
+
export declare function isJsonObject(value: unknown): value is Record<string, unknown>;
|
|
96
|
+
/** Boundary-checked study file reader (fails closed on missing/malformed). */
|
|
97
|
+
export declare function readStudyJson(studyDir: string, rel: string): Record<string, unknown>;
|
|
98
|
+
/**
|
|
99
|
+
* List the study directory names the server itself enumerated under the
|
|
100
|
+
* studies root (sorted). The route layer treats this list as the allowlist.
|
|
101
|
+
*/
|
|
102
|
+
export declare function listStudyNames(studiesRoot: string): string[];
|
|
103
|
+
export type StudyAccess = {
|
|
104
|
+
dir: string;
|
|
105
|
+
studyId: string;
|
|
106
|
+
readOnly: boolean;
|
|
107
|
+
reason: string;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* P1-1: verify that a directory under the WRITABLE root was really created by
|
|
111
|
+
* this server. Name membership is not enough and file existence is not enough:
|
|
112
|
+
* the directory must
|
|
113
|
+
* 1. resolve (realpath) strictly INSIDE the writable root,
|
|
114
|
+
* 2. be a real directory (not a symlink/junction),
|
|
115
|
+
* 3. carry the server ownership marker whose studyId matches BOTH the
|
|
116
|
+
* directory name and the frozen examiner manifest.
|
|
117
|
+
* A historical research asset can therefore never be written, even if a file
|
|
118
|
+
* named like the marker is dropped beside it.
|
|
119
|
+
*/
|
|
120
|
+
export declare function verifyConsoleOwnership(writableRoot: string, studyDir: string): {
|
|
121
|
+
ok: boolean;
|
|
122
|
+
reason: string;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Resolve a requested study by EXACT membership in the server's own
|
|
126
|
+
* enumeration of BOTH roots. The returned path is always built from an
|
|
127
|
+
* enumerated entry name; callers only select, never construct path segments.
|
|
128
|
+
* A writable entry that resolves outside the writable root (or into the
|
|
129
|
+
* historical area) is returned READ-ONLY with a stable boundary reason.
|
|
130
|
+
*/
|
|
131
|
+
export declare function resolveStudyAccess(roots: StudyRoots, requested: string): StudyAccess | null;
|
|
132
|
+
/**
|
|
133
|
+
* The writable root must never be, contain, or be contained by the historical
|
|
134
|
+
* research area. Both the LEXICAL pair and the CANONICAL pair are checked:
|
|
135
|
+
* lexical catches obvious aliases, canonical catches symlink/junction aliases
|
|
136
|
+
* and their not-yet-existing descendants. Unresolvable roots fail closed.
|
|
137
|
+
*/
|
|
138
|
+
export declare function writableRootProblem(roots: StudyRoots): string | null;
|
|
139
|
+
/**
|
|
140
|
+
* Unified write-boundary check for ONE study directory: inside the canonical
|
|
141
|
+
* writable root AND outside the canonical historical area. Used by every
|
|
142
|
+
* write path (creation, ownership marker, run, report) immediately before the
|
|
143
|
+
* mutation — a check done only at startup is not evidence about now.
|
|
144
|
+
*/
|
|
145
|
+
export declare function writableStudyDirProblem(roots: StudyRoots, studyDir: string): string | null;
|
|
146
|
+
/** Study status projection (manifest + ledger settlement counts + report status). */
|
|
147
|
+
export declare function studyStatusPayload(studyDir: string): Record<string, unknown>;
|
|
148
|
+
/** Read-only Report V2 payload + replay verification. */
|
|
149
|
+
export declare function studyReportPayload(modules: LabModules, studyDir: string): Record<string, unknown> | null;
|
|
150
|
+
export declare class ExaminerPreflightBlockedError extends Error {
|
|
151
|
+
readonly blockers: unknown[];
|
|
152
|
+
constructor(blockers: unknown[]);
|
|
153
|
+
}
|
|
154
|
+
export declare class ExaminerWriteRefusedError extends Error {
|
|
155
|
+
constructor(message: string);
|
|
156
|
+
}
|
|
157
|
+
/** The frozen study area + historical root this server must never write into. */
|
|
158
|
+
export type StudyDirContext = {
|
|
159
|
+
labRoot: string;
|
|
160
|
+
roots: StudyRoots;
|
|
161
|
+
};
|
|
162
|
+
export declare function preflightCheck(modules: LabModules, studyDir: string, context?: StudyDirContext): {
|
|
163
|
+
ok: boolean;
|
|
164
|
+
status: string;
|
|
165
|
+
blockers: unknown[];
|
|
166
|
+
warnings: unknown[];
|
|
167
|
+
checks: unknown[];
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* P1-4: POST /run can never reach the runner without passing the server gate.
|
|
171
|
+
* The readiness check below is evaluated first (a convenience projection), then
|
|
172
|
+
* the runner re-evaluates the same frozen facts UNDER the study write lock
|
|
173
|
+
* before RUN_STARTED — but a blocker here means the runner is not called at
|
|
174
|
+
* all, so no attempt is reserved and no actor is created.
|
|
175
|
+
*/
|
|
176
|
+
export declare function offlineStudyPass(modules: LabModules, studyDir: string, context?: StudyDirContext): Promise<{
|
|
177
|
+
units: Record<string, unknown>[];
|
|
178
|
+
}>;
|
|
179
|
+
export declare function reportMaterialize(modules: LabModules, studyDir: string, now: string, context: StudyDirContext | undefined, canWrite: () => {
|
|
180
|
+
ok: boolean;
|
|
181
|
+
reason?: string;
|
|
182
|
+
}): {
|
|
183
|
+
status: string;
|
|
184
|
+
written: boolean;
|
|
185
|
+
};
|
|
186
|
+
export declare function studyReportVerify(modules: LabModules, studyDir: string): {
|
|
187
|
+
checks: {
|
|
188
|
+
ok: boolean;
|
|
189
|
+
}[];
|
|
190
|
+
};
|
|
191
|
+
export declare function loadLabModules(labRoot: string): Promise<LabModules>;
|
|
192
|
+
/** Host injection-capability ceiling table (from examiner-injection-evidence.mjs). */
|
|
193
|
+
export declare function loadHostCapability(labRoot: string): Promise<Record<string, string>>;
|
|
194
|
+
export type CreateStudyInputs = {
|
|
195
|
+
studyId: string;
|
|
196
|
+
studyDir: string;
|
|
197
|
+
experimentMode: 'isolated_principle' | 'full_library_incremental';
|
|
198
|
+
target: {
|
|
199
|
+
id: string;
|
|
200
|
+
version: string;
|
|
201
|
+
text: string;
|
|
202
|
+
status: string;
|
|
203
|
+
ruleCount?: number;
|
|
204
|
+
};
|
|
205
|
+
ledgerPrinciples: {
|
|
206
|
+
id: string;
|
|
207
|
+
version: string;
|
|
208
|
+
text: string;
|
|
209
|
+
status: string;
|
|
210
|
+
ruleCount?: number;
|
|
211
|
+
}[];
|
|
212
|
+
repetitionsPerCase: number;
|
|
213
|
+
};
|
|
214
|
+
/** Server-minted study handle + directory (crypto-random; never request-derived). */
|
|
215
|
+
export declare function mintStudyHandle(roots: StudyRoots): {
|
|
216
|
+
studyId: string;
|
|
217
|
+
studyDir: string;
|
|
218
|
+
} | null;
|
|
219
|
+
/**
|
|
220
|
+
* Create one console-originated offline examiner study: mint the server-side
|
|
221
|
+
* identity, resolve the target from the SERVER-provided ledger list (the id
|
|
222
|
+
* is charset-validated by the caller and must match a ledger entry exactly),
|
|
223
|
+
* then materialize the study through the lab contract. Synthetic calibration
|
|
224
|
+
* cases with SYNTHETIC_OFFLINE gold provenance — offline contract validation,
|
|
225
|
+
* never real-host behavior.
|
|
226
|
+
*/
|
|
227
|
+
export declare function materializeConsoleStudy(modules: LabModules, labRoot: string, roots: StudyRoots, selection: {
|
|
228
|
+
isolatedMode: boolean;
|
|
229
|
+
targetIndex: number;
|
|
230
|
+
ledgerPrinciples: {
|
|
231
|
+
id: string;
|
|
232
|
+
version: string;
|
|
233
|
+
text: string;
|
|
234
|
+
status: string;
|
|
235
|
+
ruleCount?: number;
|
|
236
|
+
}[];
|
|
237
|
+
repetitionsPerCase: number;
|
|
238
|
+
}): Promise<{
|
|
239
|
+
studyId: string;
|
|
240
|
+
targetPrincipleId: string;
|
|
241
|
+
manifestHash: unknown;
|
|
242
|
+
plannedPairs: number | null;
|
|
243
|
+
}>;
|
|
244
|
+
/**
|
|
245
|
+
* Create one offline examiner study. The study identity and directory are
|
|
246
|
+
* ALWAYS server-minted by the caller (crypto-random handle); this function
|
|
247
|
+
* receives already-validated server data only. Synthetic calibration cases
|
|
248
|
+
* with SYNTHETIC_OFFLINE gold provenance — offline contract validation,
|
|
249
|
+
* never real-host behavior.
|
|
250
|
+
*/
|
|
251
|
+
export declare function materializeOfflineStudy(modules: LabModules, labRoot: string, inputs: CreateStudyInputs): Promise<{
|
|
252
|
+
manifest: Record<string, unknown>;
|
|
253
|
+
pairAssignment: Record<string, unknown>;
|
|
254
|
+
}>;
|