create-principles-disciple 1.141.0 → 1.142.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/codex-adapter/dist/pd-hook.d.ts +1 -0
  2. package/codex-adapter/dist/pd-hook.js +24 -1
  3. package/codex-adapter/package.json +1 -1
  4. package/console/dist/server/config/pd-config-store.d.ts +5 -0
  5. package/console/dist/server/config/pd-config-store.js +25 -1
  6. package/console/dist/ui/api.js +6 -3
  7. package/console/dist/ui/utils/__tests__/token-storage.test.d.ts +1 -0
  8. package/console/dist/ui/utils/__tests__/token-storage.test.js +64 -0
  9. package/console/dist/ui/utils/token-storage.d.ts +22 -0
  10. package/console/dist/ui/utils/token-storage.js +47 -0
  11. package/console/dist/web/assets/app.js +34 -4
  12. package/core/dist/runtime-v2/__tests__/adversarial-loop.test.js +27 -3
  13. package/core/dist/runtime-v2/__tests__/adversarial-loop.test.js.map +1 -1
  14. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +144 -0
  15. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  16. package/core/dist/runtime-v2/__tests__/artificer-runner-vslice.test.js +73 -12
  17. package/core/dist/runtime-v2/__tests__/artificer-runner-vslice.test.js.map +1 -1
  18. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +5 -0
  19. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
  20. package/core/dist/runtime-v2/feature-flags/__tests__/rulecode-context-v2-flag.test.js +11 -11
  21. package/core/dist/runtime-v2/feature-flags/__tests__/rulecode-context-v2-flag.test.js.map +1 -1
  22. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +5 -5
  23. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
  24. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js +6 -6
  25. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js.map +1 -1
  26. package/core/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder-v2.test.js +18 -27
  27. package/core/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder-v2.test.js.map +1 -1
  28. package/core/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder.test.js +40 -33
  29. package/core/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder.test.js.map +1 -1
  30. package/core/dist/runtime-v2/internalization/__tests__/evaluator-artificer-repair-replay.test.js +22 -4
  31. package/core/dist/runtime-v2/internalization/__tests__/evaluator-artificer-repair-replay.test.js.map +1 -1
  32. package/core/dist/runtime-v2/internalization/__tests__/evaluator-chinese-feedback-contract.test.js +20 -4
  33. package/core/dist/runtime-v2/internalization/__tests__/evaluator-chinese-feedback-contract.test.js.map +1 -1
  34. package/core/dist/runtime-v2/internalization/__tests__/evaluator-out-of-scope-governance.test.js +20 -14
  35. package/core/dist/runtime-v2/internalization/__tests__/evaluator-out-of-scope-governance.test.js.map +1 -1
  36. package/core/dist/runtime-v2/internalization/__tests__/evolution-alignment-contract.test.js +17 -4
  37. package/core/dist/runtime-v2/internalization/__tests__/evolution-alignment-contract.test.js.map +1 -1
  38. package/core/dist/runtime-v2/internalization/__tests__/external-review-p0-regressions.test.js +24 -0
  39. package/core/dist/runtime-v2/internalization/__tests__/external-review-p0-regressions.test.js.map +1 -1
  40. package/core/dist/runtime-v2/internalization/__tests__/peer-prompt-language.test.js +18 -21
  41. package/core/dist/runtime-v2/internalization/__tests__/peer-prompt-language.test.js.map +1 -1
  42. package/core/dist/runtime-v2/internalization/__tests__/shared-information-plane-runner.test.js +19 -4
  43. package/core/dist/runtime-v2/internalization/__tests__/shared-information-plane-runner.test.js.map +1 -1
  44. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts +17 -6
  45. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts.map +1 -1
  46. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js +23 -22
  47. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js.map +1 -1
  48. package/core/dist/runtime-v2/internalization/artificer-runner.d.ts +6 -2
  49. package/core/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
  50. package/core/dist/runtime-v2/internalization/artificer-runner.js +19 -14
  51. package/core/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
  52. package/core/dist/telemetry-event.d.ts +19 -36
  53. package/core/dist/telemetry-event.d.ts.map +1 -1
  54. package/core/dist/telemetry-event.js +253 -59
  55. package/core/dist/telemetry-event.js.map +1 -1
  56. package/core/package.json +1 -1
  57. package/package.json +2 -2
  58. package/pd-cli/dist/commands/console.d.ts.map +1 -1
  59. package/pd-cli/dist/commands/console.js +15 -3
  60. package/pd-cli/dist/commands/console.js.map +1 -1
  61. package/pd-cli/dist/commands/runtime-internalization-run-rulehost.d.ts.map +1 -1
  62. package/pd-cli/dist/commands/runtime-internalization-run-rulehost.js +42 -21
  63. package/pd-cli/dist/commands/runtime-internalization-run-rulehost.js.map +1 -1
  64. package/pd-cli/dist/services/console-launcher.d.ts +9 -0
  65. package/pd-cli/dist/services/console-launcher.d.ts.map +1 -1
  66. package/pd-cli/dist/services/console-launcher.js +47 -4
  67. package/pd-cli/dist/services/console-launcher.js.map +1 -1
  68. package/pd-cli/dist/services/pd-config-loader.d.ts +5 -0
  69. package/pd-cli/dist/services/pd-config-loader.d.ts.map +1 -1
  70. package/pd-cli/dist/services/pd-config-loader.js +25 -1
  71. package/pd-cli/dist/services/pd-config-loader.js.map +1 -1
  72. package/pd-cli/dist/services/rulehost-pipeline-runner.d.ts +5 -3
  73. package/pd-cli/dist/services/rulehost-pipeline-runner.d.ts.map +1 -1
  74. package/pd-cli/dist/services/rulehost-pipeline-runner.js +10 -1
  75. package/pd-cli/dist/services/rulehost-pipeline-runner.js.map +1 -1
  76. package/pd-cli/package.json +1 -1
  77. package/plugin/dist/bundle.js +290 -294
  78. package/plugin/dist/governance-audit.js +149 -149
  79. package/plugin/dist/rulehost-evidence.js +169 -169
  80. package/plugin/openclaw.plugin.json +1 -1
  81. package/plugin/package.json +1 -1
  82. package/release-manager/package.json +2 -2
@@ -5,5 +5,6 @@ export interface PdHookResult {
5
5
  exitCode: number;
6
6
  stderr: string[];
7
7
  }
8
+ export declare function annotateContextWarnings(warnings: readonly string[]): string[];
8
9
  export declare function processHookInvocation(rawStdin: string, _env?: EnvMap, cwd?: string): Promise<PdHookResult>;
9
10
  export {};
@@ -54,6 +54,26 @@ function diagnostic(reason, nextAction) {
54
54
  function errorMessage(error) {
55
55
  return error instanceof Error ? error.message.slice(0, MAX_DIAGNOSTIC) : 'unknown_error';
56
56
  }
57
+ /**
58
+ * PRI-780 Codex capability declaration (structured UNSUPPORTED — suspension
59
+ * semantics, revised after Codex review round 2 P1): the Codex host has no
60
+ * runtime context provider, and the "unavailable → allow" contract is
61
+ * generation-time prompt discipline, NOT a runtime-enforced invariant. Handing
62
+ * v2 rules a truthy unavailable-posture context would let a persisted rule
63
+ * evaluate context-blind and DENY tool calls that were previously suspended —
64
+ * a silent governance behavior change. Codex therefore passes NO context
65
+ * provider: the shared gate skips v2 rules with its structured
66
+ * `rule_context_v2_unavailable` warning, and this hook annotates that warning
67
+ * with the explicit host-unsupported reason before it reaches Codex stderr
68
+ * (see annotateContextWarnings — ticket option B: 明确 unsupported + 结构化
69
+ * warning, never a silent skip).
70
+ */
71
+ const CODEX_CONTEXT_UNSUPPORTED_NOTE = 'codex_runtime_context_unsupported: the Codex host provides no runtime context provider; v2 rules stay suspended on this host';
72
+ export function annotateContextWarnings(warnings) {
73
+ return warnings.map((warning) => warning.startsWith('rule_context_v2_unavailable')
74
+ ? `${warning}; ${CODEX_CONTEXT_UNSUPPORTED_NOTE}`
75
+ : warning);
76
+ }
57
77
  // Bounded governance-observation ingestion (Codex Governance Closure Slice
58
78
  // A) followed by the Slice B signal-admission pass (SPEC §12/§13): detection
59
79
  // → canonical pain → evidence promotion → one pending Diagnostician task.
@@ -163,8 +183,11 @@ export async function processHookInvocation(rawStdin, _env = process.env, cwd =
163
183
  hostKind: 'codex',
164
184
  toolSemantics: CODEX_TOOL_SEMANTICS,
165
185
  events: codexEventEmitter(path.join(resolution.workspaceDir, '.state')),
186
+ // PRI-780 (revised after Codex review round 2 P1): NO context provider —
187
+ // v2 rules stay SUSPENDED on Codex (never loaded context-blind). See
188
+ // annotateContextWarnings for the structured unsupported declaration.
166
189
  }).dispatch(event);
167
- const stderr = [...(result.warnings ?? []).slice(0, 16).map((warning) => diagnostic(warning, 'Inspect PD Workspace state and retry; the hook failed open.')), ...ingestionDiagnostics];
190
+ const stderr = [...annotateContextWarnings(result.warnings ?? []).slice(0, 16).map((warning) => diagnostic(warning, 'Inspect PD Workspace state and retry; the hook failed open.')), ...ingestionDiagnostics];
168
191
  return { stdout: adapter.encodeOutput(result, event.kind), exitCode: 0, stderr };
169
192
  }
170
193
  catch (error) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principles/codex-adapter",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
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",
@@ -86,6 +86,11 @@ export declare function loadPdConfig(workspaceDir: string): ConfigLoadResult;
86
86
  * Compute feature flags from the loaded PD config (PRI-460).
87
87
  * Works with both ok and error results (uses defaults for errors).
88
88
  * Replaces the legacy `loadWorkspaceFeatureFlags` + `buildFeedbackChannelFlags` path.
89
+ *
90
+ * On a failed load, flags whose gate fail-closes on config errors are forced
91
+ * disabled with an observable warning — the registry default (ON for a
92
+ * graduated flag) must never be displayed as enforcing when the workspace
93
+ * config is unreadable.
89
94
  */
90
95
  export declare function computeFlagsFromLoadResult(result: ConfigLoadResult): FeatureFlagsResult;
91
96
  export declare function getConfigSummary(workspaceDir: string): {
@@ -212,14 +212,38 @@ export function loadPdConfig(workspaceDir) {
212
212
  };
213
213
  }
214
214
  // ── Feature Flags from Config ────────────────────────────────────────────────
215
+ /**
216
+ * Flags whose production gate FAILS CLOSED when the workspace config cannot
217
+ * be loaded: the gate cannot know the flag state, so the gated capability is
218
+ * suspended (OpenClaw `buildRuleContextIfEnabled` returns undefined context on
219
+ * config failure → v2 rules skip). Status derivation must mirror that posture
220
+ * or the Console would display "active" for rules that are actually not
221
+ * enforcing (PRI-780 review B3).
222
+ */
223
+ const CONFIG_FAILURE_FAIL_CLOSED_FLAGS = new Set(['rulecode_context_v2']);
215
224
  /**
216
225
  * Compute feature flags from the loaded PD config (PRI-460).
217
226
  * Works with both ok and error results (uses defaults for errors).
218
227
  * Replaces the legacy `loadWorkspaceFeatureFlags` + `buildFeedbackChannelFlags` path.
228
+ *
229
+ * On a failed load, flags whose gate fail-closes on config errors are forced
230
+ * disabled with an observable warning — the registry default (ON for a
231
+ * graduated flag) must never be displayed as enforcing when the workspace
232
+ * config is unreadable.
219
233
  */
220
234
  export function computeFlagsFromLoadResult(result) {
221
235
  const effective = result.ok ? result.effective : result.defaults;
222
- return computeFeatureFlagsFromConfig(effective);
236
+ const flags = computeFeatureFlagsFromConfig(effective);
237
+ if (!result.ok) {
238
+ for (const flagId of CONFIG_FAILURE_FAIL_CLOSED_FLAGS) {
239
+ const flag = flags.flags[flagId];
240
+ if (flag?.enabled) {
241
+ flags.flags[flagId] = { ...flag, enabled: false };
242
+ flags.warnings.push(`${flagId}: config load failed — flag displayed as disabled (fail-closed, matches the gate's config-failure suspension)`);
243
+ }
244
+ }
245
+ }
246
+ return flags;
223
247
  }
224
248
  // ── Get Redacted Summary ─────────────────────────────────────────────────────
225
249
  export function getConfigSummary(workspaceDir) {
@@ -1,14 +1,17 @@
1
+ import { clearStoredToken, loadStoredToken, storeToken } from "./utils/token-storage.js";
1
2
  import { listActiveSignalKeywords, listPendingSignalTerms, fetchKeywordStore, fetchPendingTerms, updateKeywordStore, admitPendingTerm, rejectPendingTerm, } from "./utils/signal-keywords-api.js";
2
3
  import { validateErrorResponse, validateHeaders, validateFeedbackReport, validateFeedbackDraftsList, validateFeedbackDraftEnvelope, validateFeedbackChannels, validateFeedbackSubmitResult, validateDeleteEnvelope, validateWorkspaceEntry, validateWorkspaceList, validateRemovedEnvelope, validateSyncResult, validateConfigSummary, validateConfigCatalog, validateAgentBindingUpdate, validateDefaultRuntimeUpdate, validateRuntimeProfileMutation, validateReadinessCheck, validateFeatureFlagUpdate, validateOutputLanguage, validateGovernanceQueue, validateRecoveryResult, validateFailedTaskDetail, validateOwnerDecisionsData, validateOwnerResolutionResult, validateActivations, validateDisableActivation, validateLifecycleMetrics, validateUpdateStatus, validateUpdateHistory, validateApplyUpdateResult, validateRollbackResult, validateApprovalRecordDirect, validatePrinciplesList, validateCorePrinciples, validateApprovalsGrouped, validateEvidenceChain, validateTrajectoryData, validateIntentSummary, validateIntentDecisionList, validateIntentDecisionResult, validateIntentDecisionSummary, validateFollowUpResponse, validateIntentInitResult, validateIntentSaveResult, validateIntentRawContent, validateIntentVersions, validateOwnerGovernanceView, validateGovernanceExperienceSnapshot, validateRuleCodeOwnerReview, validateRuleCodeMutation, validateOwnerIdentityView, validateOwnerIdentityRegister, validateOwnerIdentityUnregister, } from "./utils/validators.js";
3
4
  // ── Auth ──────────────────────────────────────────────────────────────────────
4
5
  function getToken() {
5
- return sessionStorage.getItem("pd_token");
6
+ // PRI-793: localStorage-backed (with one-time migration from the legacy
7
+ // sessionStorage copy) so the token survives browser restarts.
8
+ return loadStoredToken();
6
9
  }
7
10
  function setToken(token) {
8
- sessionStorage.setItem("pd_token", token);
11
+ storeToken(token);
9
12
  }
10
13
  function clearToken() {
11
- sessionStorage.removeItem("pd_token");
14
+ clearStoredToken();
12
15
  }
13
16
  /**
14
17
  * True when an unauthorized response should route the UI to the login route.
@@ -0,0 +1,64 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { clearStoredToken, loadStoredToken, storeToken } from "../token-storage.js";
3
+ /** Minimal in-memory Storage double (no window dependency). */
4
+ function fakeStorage() {
5
+ const map = new Map();
6
+ return {
7
+ get length() {
8
+ return map.size;
9
+ },
10
+ clear: () => map.clear(),
11
+ getItem: (k) => (map.has(k) ? map.get(k) : null),
12
+ key: (i) => Array.from(map.keys())[i] ?? null,
13
+ removeItem: (k) => void map.delete(k),
14
+ setItem: (k, v) => void map.set(k, v),
15
+ };
16
+ }
17
+ describe("token-storage (PRI-793)", () => {
18
+ it("stores into localStorage and leaves no sessionStorage copy", () => {
19
+ const main = fakeStorage();
20
+ const legacy = fakeStorage();
21
+ storeToken("tok-1", main, legacy);
22
+ expect(main.getItem("pd_token")).toBe("tok-1");
23
+ expect(legacy.getItem("pd_token")).toBe(null);
24
+ });
25
+ it("loads the persisted token across 'browser restarts'", () => {
26
+ const main = fakeStorage();
27
+ const legacy = fakeStorage();
28
+ storeToken("tok-2", main, legacy);
29
+ expect(loadStoredToken(main, legacy)).toBe("tok-2");
30
+ });
31
+ it("migrates a legacy sessionStorage token once, then owns it in localStorage only", () => {
32
+ const main = fakeStorage();
33
+ const legacy = fakeStorage();
34
+ legacy.setItem("pd_token", "legacy-tok");
35
+ expect(loadStoredToken(main, legacy)).toBe("legacy-tok");
36
+ expect(main.getItem("pd_token")).toBe("legacy-tok");
37
+ expect(legacy.getItem("pd_token")).toBe(null);
38
+ });
39
+ it("returns null when nothing is stored anywhere", () => {
40
+ expect(loadStoredToken(fakeStorage(), fakeStorage())).toBe(null);
41
+ });
42
+ it("clear removes both storage copies so a stale token cannot resurrect", () => {
43
+ const main = fakeStorage();
44
+ const legacy = fakeStorage();
45
+ storeToken("tok-3", main, legacy);
46
+ legacy.setItem("pd_token", "stale");
47
+ clearStoredToken(main, legacy);
48
+ expect(main.getItem("pd_token")).toBe(null);
49
+ expect(legacy.getItem("pd_token")).toBe(null);
50
+ expect(loadStoredToken(main, legacy)).toBe(null);
51
+ });
52
+ it("re-login overwrites the persisted token", () => {
53
+ const main = fakeStorage();
54
+ const legacy = fakeStorage();
55
+ storeToken("old", main, legacy);
56
+ storeToken("new", main, legacy);
57
+ expect(loadStoredToken(main, legacy)).toBe("new");
58
+ });
59
+ it("degrades gracefully when no Storage exists (non-DOM environment)", () => {
60
+ expect(loadStoredToken(null, null)).toBe(null);
61
+ expect(() => storeToken("tok", null, null)).not.toThrow();
62
+ expect(() => clearStoredToken(null, null)).not.toThrow();
63
+ });
64
+ });
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Browser-side persistence for the Console login token (PRI-793).
3
+ *
4
+ * The token lives in localStorage so the Owner is not re-prompted on every
5
+ * browser start. sessionStorage is only a migration source: a token left
6
+ * there by older builds is promoted to localStorage once and then removed —
7
+ * localStorage is the single source of truth afterwards (P4).
8
+ *
9
+ * Clearing (logout / Settings "清除凭证") removes both keys so a stale copy
10
+ * can never resurrect the session.
11
+ *
12
+ * Storages are resolved from globalThis (browsers expose localStorage /
13
+ * sessionStorage there) and may be absent — non-DOM test environments run
14
+ * the same code path with null storages, where persistence degrades to
15
+ * "no stored token" instead of crashing. Explicit arguments override the
16
+ * builtins for tests.
17
+ */
18
+ type TokenStorage = Storage | null | undefined;
19
+ export declare function loadStoredToken(storage?: TokenStorage, legacy?: TokenStorage): string | null;
20
+ export declare function storeToken(token: string, storage?: TokenStorage, legacy?: TokenStorage): void;
21
+ export declare function clearStoredToken(storage?: TokenStorage, legacy?: TokenStorage): void;
22
+ export {};
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Browser-side persistence for the Console login token (PRI-793).
3
+ *
4
+ * The token lives in localStorage so the Owner is not re-prompted on every
5
+ * browser start. sessionStorage is only a migration source: a token left
6
+ * there by older builds is promoted to localStorage once and then removed —
7
+ * localStorage is the single source of truth afterwards (P4).
8
+ *
9
+ * Clearing (logout / Settings "清除凭证") removes both keys so a stale copy
10
+ * can never resurrect the session.
11
+ *
12
+ * Storages are resolved from globalThis (browsers expose localStorage /
13
+ * sessionStorage there) and may be absent — non-DOM test environments run
14
+ * the same code path with null storages, where persistence degrades to
15
+ * "no stored token" instead of crashing. Explicit arguments override the
16
+ * builtins for tests.
17
+ */
18
+ const TOKEN_KEY = "pd_token";
19
+ function builtin(kind) {
20
+ const g = globalThis;
21
+ return (kind === "local" ? g.localStorage : g.sessionStorage) ?? null;
22
+ }
23
+ export function loadStoredToken(storage, legacy) {
24
+ const main = storage ?? builtin("local");
25
+ const old = legacy ?? builtin("session");
26
+ const current = main?.getItem(TOKEN_KEY) ?? null;
27
+ if (current !== null)
28
+ return current;
29
+ const legacyToken = old?.getItem(TOKEN_KEY) ?? null;
30
+ if (legacyToken === null)
31
+ return null;
32
+ main?.setItem(TOKEN_KEY, legacyToken);
33
+ old?.removeItem(TOKEN_KEY);
34
+ return legacyToken;
35
+ }
36
+ export function storeToken(token, storage, legacy) {
37
+ const main = storage ?? builtin("local");
38
+ const old = legacy ?? builtin("session");
39
+ main?.setItem(TOKEN_KEY, token);
40
+ old?.removeItem(TOKEN_KEY);
41
+ }
42
+ export function clearStoredToken(storage, legacy) {
43
+ const main = storage ?? builtin("local");
44
+ const old = legacy ?? builtin("session");
45
+ main?.removeItem(TOKEN_KEY);
46
+ old?.removeItem(TOKEN_KEY);
47
+ }