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.
Files changed (53) hide show
  1. package/_release/product-identity.json +1 -1
  2. package/codex-adapter/package.json +1 -1
  3. package/console/dist/server/index.js +8 -0
  4. package/console/dist/server/routes/examiner-executor.d.ts +254 -0
  5. package/console/dist/server/routes/examiner-executor.js +622 -0
  6. package/console/dist/server/routes/examiner.d.ts +46 -0
  7. package/console/dist/server/routes/examiner.js +296 -0
  8. package/console/dist/ui/App.js +6 -3
  9. package/console/dist/ui/api.d.ts +138 -0
  10. package/console/dist/ui/api.js +56 -0
  11. package/console/dist/ui/components/layout/app-sidebar.d.ts +11 -0
  12. package/console/dist/ui/components/layout/app-sidebar.js +12 -2
  13. package/console/dist/ui/i18n/en.json +63 -0
  14. package/console/dist/ui/i18n/zh-CN.json +63 -0
  15. package/console/dist/ui/pages/examiner/ExaminerPage.d.ts +15 -0
  16. package/console/dist/ui/pages/examiner/ExaminerPage.js +158 -0
  17. package/console/dist/ui/pages/principles/PrincipleDetailPage.js +2 -1
  18. package/console/dist/ui/utils/runtime-mode.d.ts +10 -0
  19. package/console/dist/ui/utils/runtime-mode.js +10 -0
  20. package/console/dist/web/assets/app.css +44 -0
  21. package/console/dist/web/assets/app.js +33 -31
  22. package/core/dist/host/host-installer.d.ts +13 -0
  23. package/core/dist/host/host-installer.d.ts.map +1 -1
  24. package/core/dist/host/host-installer.js.map +1 -1
  25. package/core/package.json +1 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +29 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/installer.js +1 -1
  30. package/dist/installer.js.map +1 -1
  31. package/dist/installers/workbuddy-host-installer.d.ts +39 -0
  32. package/dist/installers/workbuddy-host-installer.d.ts.map +1 -1
  33. package/dist/installers/workbuddy-host-installer.js +76 -27
  34. package/dist/installers/workbuddy-host-installer.js.map +1 -1
  35. package/package.json +2 -2
  36. package/pd-cli/dist/services/pd-config-loader.d.ts +1 -1
  37. package/pd-cli/dist/services/pd-config-loader.d.ts.map +1 -1
  38. package/pd-cli/dist/services/pd-config-loader.js +9 -0
  39. package/pd-cli/dist/services/pd-config-loader.js.map +1 -1
  40. package/pd-cli/package.json +1 -1
  41. package/plugin/openclaw.plugin.json +1 -1
  42. package/plugin/package.json +1 -1
  43. package/release-manager/dist/index.d.ts.map +1 -1
  44. package/release-manager/dist/index.js +29 -0
  45. package/release-manager/dist/index.js.map +1 -1
  46. package/release-manager/dist/installer.js +1 -1
  47. package/release-manager/dist/installer.js.map +1 -1
  48. package/release-manager/dist/installers/workbuddy-host-installer.d.ts +39 -0
  49. package/release-manager/dist/installers/workbuddy-host-installer.d.ts.map +1 -1
  50. package/release-manager/dist/installers/workbuddy-host-installer.js +76 -27
  51. package/release-manager/dist/installers/workbuddy-host-installer.js.map +1 -1
  52. package/release-manager/package.json +2 -2
  53. package/workbuddy-adapter/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "productVersion": "2.5.0",
4
- "sourceCommit": "1c787bf80015d10ab8cd06bcb949c329f3dce473"
4
+ "sourceCommit": "5ee57d2ce6030686a3e8b98c78a9dfb636eb21bd"
5
5
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principles/codex-adapter",
3
- "version": "0.6.1",
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
+ }>;