create-principles-disciple 1.134.1 → 1.134.3

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 (92) hide show
  1. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-runtime-adapter.test.js +157 -0
  2. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-runtime-adapter.test.js.map +1 -1
  3. package/core/dist/runtime-v2/adapter/__tests__/structured-output-repair.test.js +9 -0
  4. package/core/dist/runtime-v2/adapter/__tests__/structured-output-repair.test.js.map +1 -1
  5. package/core/dist/runtime-v2/adapter/output-repair-contract.d.ts +10 -0
  6. package/core/dist/runtime-v2/adapter/output-repair-contract.d.ts.map +1 -1
  7. package/core/dist/runtime-v2/adapter/output-repair-contract.js.map +1 -1
  8. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.d.ts.map +1 -1
  9. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js +53 -1
  10. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js.map +1 -1
  11. package/core/dist/runtime-v2/adapter/structured-output-repair.d.ts +9 -1
  12. package/core/dist/runtime-v2/adapter/structured-output-repair.d.ts.map +1 -1
  13. package/core/dist/runtime-v2/adapter/structured-output-repair.js +8 -0
  14. package/core/dist/runtime-v2/adapter/structured-output-repair.js.map +1 -1
  15. package/core/dist/runtime-v2/internalization/__tests__/evaluator-chinese-feedback-contract.test.d.ts +2 -0
  16. package/core/dist/runtime-v2/internalization/__tests__/evaluator-chinese-feedback-contract.test.d.ts.map +1 -0
  17. package/core/dist/runtime-v2/internalization/__tests__/evaluator-chinese-feedback-contract.test.js +295 -0
  18. package/core/dist/runtime-v2/internalization/__tests__/evaluator-chinese-feedback-contract.test.js.map +1 -0
  19. package/core/dist/runtime-v2/internalization/__tests__/peer-prompt-language.test.d.ts +17 -0
  20. package/core/dist/runtime-v2/internalization/__tests__/peer-prompt-language.test.d.ts.map +1 -0
  21. package/core/dist/runtime-v2/internalization/__tests__/peer-prompt-language.test.js +280 -0
  22. package/core/dist/runtime-v2/internalization/__tests__/peer-prompt-language.test.js.map +1 -0
  23. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts +9 -0
  24. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts.map +1 -1
  25. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js +5 -1
  26. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js.map +1 -1
  27. package/core/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
  28. package/core/dist/runtime-v2/internalization/artificer-runner.js +4 -0
  29. package/core/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
  30. package/core/dist/runtime-v2/internalization/dreamer-prompt-builder.d.ts +7 -0
  31. package/core/dist/runtime-v2/internalization/dreamer-prompt-builder.d.ts.map +1 -1
  32. package/core/dist/runtime-v2/internalization/dreamer-prompt-builder.js +12 -1
  33. package/core/dist/runtime-v2/internalization/dreamer-prompt-builder.js.map +1 -1
  34. package/core/dist/runtime-v2/internalization/dreamer-runner.d.ts +7 -0
  35. package/core/dist/runtime-v2/internalization/dreamer-runner.d.ts.map +1 -1
  36. package/core/dist/runtime-v2/internalization/dreamer-runner.js +4 -2
  37. package/core/dist/runtime-v2/internalization/dreamer-runner.js.map +1 -1
  38. package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts +9 -0
  39. package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts.map +1 -1
  40. package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.js +5 -1
  41. package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.js.map +1 -1
  42. package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts +14 -0
  43. package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
  44. package/core/dist/runtime-v2/internalization/evaluator-runner.js +10 -0
  45. package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
  46. package/core/dist/runtime-v2/internalization/philosopher-prompt-builder.d.ts +6 -0
  47. package/core/dist/runtime-v2/internalization/philosopher-prompt-builder.d.ts.map +1 -1
  48. package/core/dist/runtime-v2/internalization/philosopher-prompt-builder.js +11 -1
  49. package/core/dist/runtime-v2/internalization/philosopher-prompt-builder.js.map +1 -1
  50. package/core/dist/runtime-v2/internalization/philosopher-runner.d.ts +7 -0
  51. package/core/dist/runtime-v2/internalization/philosopher-runner.d.ts.map +1 -1
  52. package/core/dist/runtime-v2/internalization/philosopher-runner.js +4 -2
  53. package/core/dist/runtime-v2/internalization/philosopher-runner.js.map +1 -1
  54. package/core/dist/runtime-v2/internalization/rollout-reviewer-prompt-builder.d.ts +8 -0
  55. package/core/dist/runtime-v2/internalization/rollout-reviewer-prompt-builder.d.ts.map +1 -1
  56. package/core/dist/runtime-v2/internalization/rollout-reviewer-prompt-builder.js +7 -1
  57. package/core/dist/runtime-v2/internalization/rollout-reviewer-prompt-builder.js.map +1 -1
  58. package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.d.ts +10 -0
  59. package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.d.ts.map +1 -1
  60. package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.js +3 -0
  61. package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.js.map +1 -1
  62. package/core/dist/runtime-v2/language-directive.d.ts +20 -2
  63. package/core/dist/runtime-v2/language-directive.d.ts.map +1 -1
  64. package/core/dist/runtime-v2/language-directive.js +25 -13
  65. package/core/dist/runtime-v2/language-directive.js.map +1 -1
  66. package/core/dist/runtime-v2/runner/__tests__/base-peer-runner-failure-details.test.js +36 -0
  67. package/core/dist/runtime-v2/runner/__tests__/base-peer-runner-failure-details.test.js.map +1 -1
  68. package/core/package.json +1 -1
  69. package/dist/uninstaller.d.ts +8 -11
  70. package/dist/uninstaller.d.ts.map +1 -1
  71. package/dist/uninstaller.js +97 -19
  72. package/dist/uninstaller.js.map +1 -1
  73. package/host-runtime/dist/internalization-consumer-cycle.js +9 -1
  74. package/host-runtime/package.json +1 -1
  75. package/package.json +2 -2
  76. package/pd-cli/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
  77. package/pd-cli/dist/commands/runtime-internalization-run-once.js +28 -8
  78. package/pd-cli/dist/commands/runtime-internalization-run-once.js.map +1 -1
  79. package/pd-cli/dist/services/rulehost-pipeline-runner.d.ts.map +1 -1
  80. package/pd-cli/dist/services/rulehost-pipeline-runner.js +11 -2
  81. package/pd-cli/dist/services/rulehost-pipeline-runner.js.map +1 -1
  82. package/pd-cli/package.json +1 -1
  83. package/plugin/dist/bundle.js +410 -409
  84. package/plugin/dist/governance-audit.js +156 -156
  85. package/plugin/dist/rulehost-evidence.js +140 -140
  86. package/plugin/openclaw.plugin.json +1 -1
  87. package/plugin/package.json +1 -1
  88. package/release-manager/dist/uninstaller.d.ts +8 -11
  89. package/release-manager/dist/uninstaller.d.ts.map +1 -1
  90. package/release-manager/dist/uninstaller.js +97 -19
  91. package/release-manager/dist/uninstaller.js.map +1 -1
  92. package/release-manager/package.json +2 -2
@@ -0,0 +1,295 @@
1
+ /**
2
+ * PRI-714 (review fix #3): downstream contract — Chinese evaluator feedback
3
+ * survives the artificer repair round and the re-evaluation round.
4
+ *
5
+ * Proves, through REAL production components (real runners, real
6
+ * DefaultEvaluatorValidator with the PRI-630 convergence contract, real
7
+ * deterministic replay gate, real artifact store):
8
+ *
9
+ * Round 1 evaluator emits needs_revision with CHINESE summary/concerns/
10
+ * requiredChanges (as the zh-CN language directive asks) →
11
+ * repair task seeded carrying the Chinese feedback;
12
+ * Repair the artificer repair prompt carries the Chinese requiredChange
13
+ * verbatim (repairFeedback), and the code itself is unchanged;
14
+ * Round 2 the evaluator's startRun prompt carries the Chinese prior
15
+ * requirement statement verbatim (previousEvaluation context), and
16
+ * the Chinese requirementLedger echo PASSES the real validator's
17
+ * verbatim-equality convergence check → approved → pi-rule.
18
+ *
19
+ * Machine protocol invariants are asserted on every hop: decision enums,
20
+ * caseIds, lineage artifact ids, and the implementation code are never
21
+ * rewritten.
22
+ *
23
+ * Test-double scope note: the scripted LLM proves the CONTRACT AND WIRING
24
+ * (Chinese text is transported, parsed, validated and consumed). It does NOT
25
+ * prove a real LLM will follow the language directive — that remains
26
+ * probabilistic by nature.
27
+ */
28
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
29
+ import * as fs from 'node:fs';
30
+ import * as path from 'node:path';
31
+ import * as os from 'node:os';
32
+ import { RuntimeStateManager } from '../../store/runtime-state-manager.js';
33
+ import { EvaluatorRunner } from '../evaluator-runner.js';
34
+ import { ArtificerRunner } from '../artificer-runner.js';
35
+ import { DefaultEvaluatorValidator } from '../evaluator-output.js';
36
+ import { DefaultArtificerValidator } from '../artificer-output.js';
37
+ import { StoreEventEmitter } from '../../store/event-emitter.js';
38
+ import { SqliteConnection } from '../../store/sqlite-connection.js';
39
+ import { SqlitePIArtifactStore } from '../../store/artifact/sqlite-pi-artifact-store.js';
40
+ import { createPITaskDiagnosticJson } from '../pitask-metadata.js';
41
+ import { createProductionGateDeps } from '../../activation/production-gate-deps.js';
42
+ let workspaceDir;
43
+ let stateManager;
44
+ let emitter;
45
+ let store;
46
+ const SCRIBE_ID = 'scribe-lang';
47
+ const ART1_ID = 'artificer-lang-1';
48
+ const EVAL1_ID = 'evaluator-lang-1';
49
+ const REPAIR_ID = 'artificer-repair-lang-1';
50
+ const EVAL2_ID = 'evaluator-lang-2';
51
+ const SCRIBE_ART = 'pi-art-scribe-lang';
52
+ /** Round-1 RuleCode (buggy) and Round-2 RuleCode (fixed) — must reach the rule artifact byte-identical. */
53
+ const BAD_RULE_CODE = `function evaluate(input, helpers) {
54
+ if (input.action.paramsSummary.includes('/etc/passwd')) {
55
+ return { decision: 'block', matched: true, reason: 'risk path' };
56
+ }
57
+ return { decision: 'allow', matched: false, reason: 'safe path' };
58
+ }`;
59
+ const GOOD_RULE_CODE = `function evaluate(input, helpers) {
60
+ var rawPath = input.action.paramsSummary.path;
61
+ var p = (typeof rawPath === 'string') ? rawPath : (input.action.normalizedPath || '');
62
+ if (p.indexOf('/etc/') === 0 || p === '/etc/passwd') {
63
+ return { decision: 'block', matched: true, reason: 'risk path dominates prior context' };
64
+ }
65
+ var ctx = input.context;
66
+ if (ctx && ctx.facts && ctx.facts.priorReadOfTarget === 'no') {
67
+ return { decision: 'block', matched: true, reason: 'write target was not read first' };
68
+ }
69
+ return { decision: 'allow', matched: false, reason: 'no risk signal' };
70
+ }`;
71
+ const GOLDEN_TRACE_CASES = [
72
+ { caseId: 'neg-1', kind: 'negative', toolName: 'write_file', params: { path: '/etc/passwd' }, expectedDecision: 'block' },
73
+ { caseId: 'pos-1', kind: 'positive', toolName: 'write_file', params: { path: '/workspace/src/a.ts' }, expectedDecision: 'allow' },
74
+ ];
75
+ /** Chinese round-1 feedback (what the zh-CN language directive asks for). */
76
+ const ZH_SUMMARY = '规则实现与原则意图不一致:直接对 paramsSummary 调用字符串方法。';
77
+ const ZH_CONCERN = 'paramsSummary 可能为对象或数组,直接调用 includes 会崩溃。';
78
+ const ZH_REQUIRED_CHANGE = '修复 paramsSummary 字符串方法崩溃:先用 typeof 守卫取值,再做前缀匹配。';
79
+ function flagsOffConfig() {
80
+ return {
81
+ config: {
82
+ version: 1,
83
+ features: {
84
+ artifact_summary_redundancy: { category: 'quiet', enabled: false },
85
+ context_manifest_budget: { category: 'quiet', enabled: false },
86
+ progressive_evaluator: { category: 'quiet', enabled: false },
87
+ },
88
+ runtimeProfiles: {},
89
+ internalAgents: {},
90
+ ui: { diagnostics: { mode: 'simple' } },
91
+ },
92
+ source: 'user_config',
93
+ warnings: [],
94
+ resolvedContextInjection: {
95
+ thinkingOs: false,
96
+ projectFocus: 'off',
97
+ evolutionContext: { enabled: true, maxMessages: 4, maxCharsPerMessage: 200 },
98
+ },
99
+ };
100
+ }
101
+ function artificerOutput(implementationCode, scribeArtifactId, taskId) {
102
+ return {
103
+ taskId,
104
+ sourceScribeArtifactId: scribeArtifactId,
105
+ implementationSummary: 'read-before-write guard',
106
+ sourceTrace: { scribeArtifactId: scribeArtifactId },
107
+ risks: [],
108
+ implementationCode,
109
+ goldenTraceCases: GOLDEN_TRACE_CASES,
110
+ affectedTools: ['write_file'],
111
+ generatedAt: new Date().toISOString(),
112
+ };
113
+ }
114
+ function evaluatorOutput(taskId, artificerArtifactId, decision) {
115
+ return {
116
+ taskId,
117
+ sourceArtificerArtifactId: artificerArtifactId,
118
+ evaluation: {
119
+ decision,
120
+ summary: decision === 'needs_revision' ? ZH_SUMMARY : '中文反馈闭环回归:修复后的规则已通过全部用例。',
121
+ score: decision === 'approved' ? 0.9 : 0.6,
122
+ strengths: decision === 'approved' ? ['使用守卫取值替代字符串方法直接调用'] : [],
123
+ concerns: decision === 'needs_revision' ? [ZH_CONCERN] : [],
124
+ requiredChanges: decision === 'needs_revision' ? [ZH_REQUIRED_CHANGE] : [],
125
+ // PRI-630 convergence: round 2 must echo the round-1 Chinese requirement
126
+ // VERBATIM — the real validator enforces exact statement equality.
127
+ ...(taskId === EVAL2_ID
128
+ ? {
129
+ priorRequirementStatuses: [{ id: 'req-1', status: 'resolved' }],
130
+ requirementLedger: [{ id: 'req-1', statement: ZH_REQUIRED_CHANGE, status: 'resolved' }],
131
+ }
132
+ : {}),
133
+ },
134
+ sourceTrace: { artificerArtifactId, scribeArtifactId: SCRIBE_ART },
135
+ risks: [],
136
+ generatedAt: new Date().toISOString(),
137
+ };
138
+ }
139
+ /** Scripted LLM adapter that records every prompt it receives. */
140
+ function scriptedAdapter(payload, prompts, runId) {
141
+ return {
142
+ startRun: async (req) => {
143
+ prompts.push(String(req.inputPayload));
144
+ return { runId, runtimeKind: 'test-double', startedAt: new Date().toISOString() };
145
+ },
146
+ pollRun: async () => ({ status: 'succeeded', runId }),
147
+ fetchOutput: async () => ({ runId, payload }),
148
+ cancelRun: async () => undefined,
149
+ };
150
+ }
151
+ function meta(o = {}) {
152
+ return createPITaskDiagnosticJson({
153
+ dependencyTaskIds: [], channel: 'prompt', timeoutMs: 300_000,
154
+ inputArtifactRefs: [], outputArtifactRefs: [], ...o,
155
+ });
156
+ }
157
+ async function mkTask(spec) {
158
+ await stateManager.createTask({
159
+ taskId: spec.id, taskKind: spec.kind, status: 'pending', attemptCount: 0, maxAttempts: 3,
160
+ diagnosticJson: spec.diagnosticJson ?? meta({ dependencyTaskIds: spec.deps }),
161
+ });
162
+ }
163
+ async function succeed(id) {
164
+ await stateManager.acquireLease({ taskId: id, owner: 'lang-test', runtimeKind: 'test-double' });
165
+ await stateManager.markTaskSucceeded(id);
166
+ }
167
+ beforeEach(async () => {
168
+ workspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-lang-contract-'));
169
+ stateManager = new RuntimeStateManager({ workspaceDir });
170
+ await stateManager.initialize();
171
+ emitter = new StoreEventEmitter();
172
+ store = new SqlitePIArtifactStore(new SqliteConnection(workspaceDir));
173
+ });
174
+ afterEach(async () => {
175
+ await stateManager.close();
176
+ try {
177
+ fs.rmSync(workspaceDir, { recursive: true, force: true });
178
+ }
179
+ catch { /* temp */ }
180
+ });
181
+ describe('PRI-714 review fix: Chinese evaluator feedback through repair + re-evaluation (downstream contract)', () => {
182
+ it('Chinese feedback survives artificer repair and passes the PRI-630 verbatim ledger convergence', async () => {
183
+ // ── lineage: scribe task + artifact ──
184
+ await mkTask({ id: SCRIBE_ID, kind: 'scribe', deps: [] });
185
+ await succeed(SCRIBE_ID);
186
+ await store.upsertArtifact({
187
+ artifactId: SCRIBE_ART, artifactKind: 'principle', sourceTaskId: SCRIBE_ID,
188
+ lineageArtifactIds: [], validationStatus: 'validated',
189
+ contentJson: JSON.stringify({ principleId: 'pri-lang-read-before-write', principleDraft: { statement: '先读后写。' }, sourceTrace: {} }),
190
+ createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
191
+ });
192
+ // ── Round 1: artificer emits the buggy code ──
193
+ await mkTask({ id: ART1_ID, kind: 'artificer', deps: [SCRIBE_ID] });
194
+ const artificer1 = new ArtificerRunner({
195
+ stateManager,
196
+ runtimeAdapter: scriptedAdapter(artificerOutput(BAD_RULE_CODE, SCRIBE_ART, ART1_ID), [], 'run-art-1'),
197
+ eventEmitter: emitter,
198
+ artifactStore: store,
199
+ validator: new DefaultArtificerValidator(),
200
+ }, { owner: 'lang-test', runtimeKind: 'test-double', pollIntervalMs: 5, timeoutMs: 5_000, effectiveConfig: flagsOffConfig() });
201
+ expect((await artificer1.run(ART1_ID)).status).toBe('succeeded');
202
+ // ── Round 1: evaluator needs_revision with CHINESE feedback ──
203
+ await mkTask({ id: EVAL1_ID, kind: 'evaluator', deps: [ART1_ID] });
204
+ const eval1Prompts = [];
205
+ const evaluator1 = new EvaluatorRunner({
206
+ stateManager,
207
+ runtimeAdapter: scriptedAdapter(evaluatorOutput(EVAL1_ID, 'pi-art-artificer-lang-1-run-1', 'needs_revision'), eval1Prompts, 'run-eval-1'),
208
+ eventEmitter: emitter,
209
+ artifactStore: store,
210
+ validator: new DefaultEvaluatorValidator(),
211
+ isRepairLoopEnabled: () => true,
212
+ seedArtificerRepairTask: async (params) => {
213
+ await mkTask({ id: REPAIR_ID, kind: 'artificer', deps: params.inheritedDependencyTaskIds, diagnosticJson: meta({
214
+ dependencyTaskIds: params.inheritedDependencyTaskIds,
215
+ repairPayload: params.repairPayload,
216
+ }) });
217
+ return REPAIR_ID;
218
+ },
219
+ }, {
220
+ owner: 'lang-test', runtimeKind: 'test-double', pollIntervalMs: 5, timeoutMs: 5_000,
221
+ gateDeps: createProductionGateDeps(),
222
+ outputLanguage: 'zh-CN',
223
+ });
224
+ const eval1Result = await evaluator1.run(EVAL1_ID);
225
+ expect(eval1Result.status).toBe('succeeded');
226
+ // (1) The zh-CN language directive is on the round-1 evaluator prompt,
227
+ // with the review subject's nested field list and the PRI-630 ledger
228
+ // echo guard.
229
+ expect(eval1Prompts).toHaveLength(1);
230
+ const eval1Prompt = eval1Prompts[0] ?? '';
231
+ expect(eval1Prompt).toContain('LANGUAGE DIRECTIVE');
232
+ expect(eval1Prompt).toContain('Simplified Chinese');
233
+ expect(eval1Prompt).toContain('codeReview.traceCoverage.gaps');
234
+ expect(eval1Prompt).toContain('adversarialCases[].rationale');
235
+ expect(eval1Prompt).toContain('requirementLedger[].statement MUST be copied verbatim');
236
+ // (2) The repair task was seeded and carries the Chinese feedback.
237
+ const repairTask = await stateManager.getTask(REPAIR_ID);
238
+ expect(repairTask).toBeDefined();
239
+ // ── Repair round: the artificer prompt carries the Chinese requiredChange verbatim ──
240
+ const repairPrompts = [];
241
+ const artificerRepair = new ArtificerRunner({
242
+ stateManager,
243
+ runtimeAdapter: scriptedAdapter(artificerOutput(GOOD_RULE_CODE, SCRIBE_ART, REPAIR_ID), repairPrompts, 'run-repair-1'),
244
+ eventEmitter: emitter,
245
+ artifactStore: store,
246
+ validator: new DefaultArtificerValidator(),
247
+ }, { owner: 'lang-test', runtimeKind: 'test-double', pollIntervalMs: 5, timeoutMs: 5_000, effectiveConfig: flagsOffConfig() });
248
+ expect((await artificerRepair.run(REPAIR_ID)).status).toBe('succeeded');
249
+ expect(repairPrompts).toHaveLength(1);
250
+ expect(repairPrompts[0]).toContain(ZH_REQUIRED_CHANGE);
251
+ expect(repairPrompts[0]).toContain(ZH_CONCERN);
252
+ const repairArtifacts = await store.listBySourceTaskId(REPAIR_ID);
253
+ const repairArtifact = repairArtifacts.find((a) => a.artifactKind === 'principle');
254
+ expect(repairArtifact).toBeDefined();
255
+ if (!repairArtifact)
256
+ return;
257
+ // ── Round 2: evaluator approves; the Chinese prior requirement flows in
258
+ // via previousEvaluation and the verbatim Chinese ledger echo PASSES
259
+ // the real convergence validation ──
260
+ await mkTask({ id: EVAL2_ID, kind: 'evaluator', deps: [REPAIR_ID] });
261
+ const eval2Prompts = [];
262
+ const evaluator2 = new EvaluatorRunner({
263
+ stateManager,
264
+ runtimeAdapter: scriptedAdapter(evaluatorOutput(EVAL2_ID, repairArtifact.artifactId, 'approved'), eval2Prompts, 'run-eval-2'),
265
+ eventEmitter: emitter,
266
+ artifactStore: store,
267
+ validator: new DefaultEvaluatorValidator(),
268
+ }, {
269
+ owner: 'lang-test', runtimeKind: 'test-double', pollIntervalMs: 5, timeoutMs: 5_000,
270
+ gateDeps: createProductionGateDeps(),
271
+ outputLanguage: 'zh-CN',
272
+ });
273
+ const eval2Result = await evaluator2.run(EVAL2_ID);
274
+ // The real DefaultEvaluatorValidator (with expectedRequirements from the
275
+ // Chinese prior context) accepted the verbatim Chinese ledger echo.
276
+ expect(eval2Result.status).toBe('succeeded');
277
+ // (3) The round-2 evaluator prompt carried the Chinese prior requirement
278
+ // statement verbatim — Chinese text is consumed downstream, not mangled.
279
+ expect(eval2Prompts).toHaveLength(1);
280
+ expect(eval2Prompts[0]).toContain(ZH_REQUIRED_CHANGE);
281
+ // (4) The formal rule artifact assembles with machine fields intact.
282
+ const eval2Artifacts = await store.listBySourceTaskId(EVAL2_ID);
283
+ const ruleArtifact = eval2Artifacts.find((a) => a.artifactKind === 'rule');
284
+ expect(ruleArtifact).toBeDefined();
285
+ if (!ruleArtifact)
286
+ return;
287
+ expect(ruleArtifact.artifactId).toContain('pi-rule-');
288
+ expect(ruleArtifact.validationStatus).toBe('validated');
289
+ const ruleContent = JSON.parse(ruleArtifact.contentJson);
290
+ // The code is consumed BYTE-IDENTICAL — never translated or rewritten.
291
+ expect(ruleContent.implementationCode).toBe(GOOD_RULE_CODE);
292
+ expect(ruleContent.goldenTraceCases?.map((c) => c.caseId)).toEqual(['neg-1', 'pos-1']);
293
+ }, 60_000);
294
+ });
295
+ //# sourceMappingURL=evaluator-chinese-feedback-contract.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluator-chinese-feedback-contract.test.js","sourceRoot":"","sources":["../../../../src/runtime-v2/internalization/__tests__/evaluator-chinese-feedback-contract.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * PRI-714: outputLanguage coverage across ALL internalization peer agents.
3
+ *
4
+ * Owner-facing review/implementation artifacts (evaluator summary, rollout
5
+ * reviewer summary, artificer implementationSummary, dreamer candidates,
6
+ * philosopher thesis) must follow `principles.outputLanguage` exactly like
7
+ * scribe principle fields have since PRI-336.
8
+ *
9
+ * Validates per builder:
10
+ * - zh-CN: instruction carries the language directive
11
+ * - en: instruction carries the English directive
12
+ * - undefined: instruction is byte-identical to the base protocol (backward
13
+ * compatible — the pre-PRI-714 tests assert this identity too)
14
+ * - technical identifiers / JSON keys stay untranslated (directive content)
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=peer-prompt-language.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer-prompt-language.test.d.ts","sourceRoot":"","sources":["../../../../src/runtime-v2/internalization/__tests__/peer-prompt-language.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
@@ -0,0 +1,280 @@
1
+ /**
2
+ * PRI-714: outputLanguage coverage across ALL internalization peer agents.
3
+ *
4
+ * Owner-facing review/implementation artifacts (evaluator summary, rollout
5
+ * reviewer summary, artificer implementationSummary, dreamer candidates,
6
+ * philosopher thesis) must follow `principles.outputLanguage` exactly like
7
+ * scribe principle fields have since PRI-336.
8
+ *
9
+ * Validates per builder:
10
+ * - zh-CN: instruction carries the language directive
11
+ * - en: instruction carries the English directive
12
+ * - undefined: instruction is byte-identical to the base protocol (backward
13
+ * compatible — the pre-PRI-714 tests assert this identity too)
14
+ * - technical identifiers / JSON keys stay untranslated (directive content)
15
+ */
16
+ import { describe, it, expect } from 'vitest';
17
+ import { EvaluatorPromptBuilder, EVALUATOR_PROTOCOL_INSTRUCTION } from '../evaluator-prompt-builder.js';
18
+ import { RolloutReviewerPromptBuilder, ROLLOUT_REVIEWER_PROTOCOL_INSTRUCTION } from '../rollout-reviewer-prompt-builder.js';
19
+ import { ArtificerPromptBuilder, ARTIFICER_PROTOCOL_INSTRUCTION } from '../artificer-prompt-builder.js';
20
+ import { DreamerPromptBuilder, buildDreamerProtocolInstruction } from '../dreamer-prompt-builder.js';
21
+ import { PhilosopherPromptBuilder, buildPhilosopherProtocolInstruction } from '../philosopher-prompt-builder.js';
22
+ import { buildLanguageDirective } from '../../language-directive.js';
23
+ /** Trust-boundary helper: validate parsed prompt JSON before property access. */
24
+ function parsePromptJson(raw) {
25
+ const parsed = JSON.parse(raw);
26
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
27
+ throw new Error(`parsePromptJson: expected object, got ${typeof parsed}`);
28
+ }
29
+ return parsed;
30
+ }
31
+ // ── Evaluator ────────────────────────────────────────────────────────────────
32
+ describe('EvaluatorPromptBuilder — outputLanguage (PRI-714)', () => {
33
+ const builder = new EvaluatorPromptBuilder();
34
+ const input = {
35
+ taskId: 'evaluator-task-001',
36
+ contextHash: 'ctx-abc123',
37
+ sourceArtificerArtifactId: 'pi-art-artificer-001',
38
+ artificerArtifact: { taskId: 'artificer-task-001' },
39
+ };
40
+ it('includes Chinese language directive naming review fields when zh-CN', () => {
41
+ const { promptInput } = builder.buildPrompt({ ...input, outputLanguage: 'zh-CN' });
42
+ expect(promptInput.evaluatorInstruction).toContain('LANGUAGE DIRECTIVE');
43
+ expect(promptInput.evaluatorInstruction).toContain('Simplified Chinese');
44
+ // review-subject field list present as EXPLICIT NESTED PATHS (PRI-714
45
+ // review fix: the previously shared flat list missed two free-text fields
46
+ // and left `explanation` ambiguous across three codeReview sub-objects).
47
+ expect(promptInput.evaluatorInstruction).toContain('(evaluation.summary, evaluation.strengths, evaluation.concerns, evaluation.requiredChanges, '
48
+ + 'codeReview.intentConsistency.explanation, codeReview.scopePrecision.explanation, '
49
+ + 'codeReview.traceCoverage.explanation, codeReview.traceCoverage.gaps, '
50
+ + 'adversarialCases[].rationale, painCoverage.explanation, compressionFidelity.explanation, risks)');
51
+ // …not the principle-subject list (the base instruction mentions
52
+ // antiPatterns for code review, so assert the directive's own field list
53
+ // string rather than global absence).
54
+ expect(promptInput.evaluatorInstruction).not.toContain('(title, statement, rationale, applicability, antiPatterns, description)');
55
+ // PRI-630 guard: the requirementLedger statement echo rule is part of the
56
+ // directive so the language instruction cannot override the convergence
57
+ // contract (statement must be a verbatim echo, never translated).
58
+ expect(promptInput.evaluatorInstruction).toContain('requirementLedger[].statement MUST be copied verbatim');
59
+ });
60
+ it('includes English language directive when en', () => {
61
+ const { promptInput } = builder.buildPrompt({ ...input, outputLanguage: 'en' });
62
+ expect(promptInput.evaluatorInstruction).toContain('English');
63
+ expect(promptInput.evaluatorInstruction).toContain('MUST NOT be translated');
64
+ });
65
+ it('instruction is byte-identical to base protocol when outputLanguage is undefined', () => {
66
+ const { promptInput } = builder.buildPrompt(input);
67
+ expect(promptInput.evaluatorInstruction).toBe(EVALUATOR_PROTOCOL_INSTRUCTION);
68
+ });
69
+ it('directive keeps technical identifiers and JSON keys untranslated', () => {
70
+ const { promptInput } = builder.buildPrompt({ ...input, outputLanguage: 'zh-CN' });
71
+ expect(promptInput.evaluatorInstruction).toContain('JSON field names (keys) MUST remain in English');
72
+ expect(promptInput.evaluatorInstruction).toContain('Lineage and evidence fields MUST NOT be translated');
73
+ });
74
+ });
75
+ // ── Dreamer ──────────────────────────────────────────────────────────────────
76
+ describe('DreamerPromptBuilder — outputLanguage (PRI-714 review fix)', () => {
77
+ const input = {
78
+ taskId: 'dreamer-task-001',
79
+ contextHash: 'ctx-abc123',
80
+ contextRefs: ['pi-art-diag-001'],
81
+ predecessorOutput: { diagnosis: 'null crash' },
82
+ };
83
+ it('appends the dreamer-subject directive to the REAL generated prompt message when zh-CN', () => {
84
+ // The real message the runner hands to adapter.startRun — not a helper.
85
+ const { message, promptInput } = new DreamerPromptBuilder().buildPrompt({ ...input, outputLanguage: 'zh-CN' });
86
+ expect(promptInput.dreamerInstruction).toContain('LANGUAGE DIRECTIVE');
87
+ expect(promptInput.dreamerInstruction).toContain('Simplified Chinese');
88
+ // Field list matches the actual DreamerCandidate schema (riskLevel is an
89
+ // enum — absent from the translatable list).
90
+ expect(promptInput.dreamerInstruction).toContain('(candidates[].badDecision, candidates[].betterDecision, candidates[].rationale, candidates[].strategicPerspective)');
91
+ // The directive survives JSON serialization into the actual message.
92
+ const parsed = parsePromptJson(message);
93
+ expect(parsed.dreamerInstruction).toBe(promptInput.dreamerInstruction);
94
+ });
95
+ it('directive works with coreGrounding ON (axiom block + directive coexist)', () => {
96
+ const { promptInput } = new DreamerPromptBuilder({ coreGrounding: true }).buildPrompt({ ...input, outputLanguage: 'zh-CN' });
97
+ expect(promptInput.dreamerInstruction).toContain('CORE AXIOMS:');
98
+ expect(promptInput.dreamerInstruction).toContain('LANGUAGE DIRECTIVE');
99
+ });
100
+ it('directive also works with coreGrounding OFF (review bug: only the axiom block used the language)', () => {
101
+ const { promptInput } = new DreamerPromptBuilder({ coreGrounding: false }).buildPrompt({ ...input, outputLanguage: 'en' });
102
+ expect(promptInput.dreamerInstruction).not.toContain('CORE AXIOMS:');
103
+ expect(promptInput.dreamerInstruction).toContain('LANGUAGE DIRECTIVE');
104
+ expect(promptInput.dreamerInstruction).toContain('English');
105
+ });
106
+ it('instruction is byte-identical to the base protocol when outputLanguage is undefined', () => {
107
+ const withLang = new DreamerPromptBuilder().buildPrompt({ ...input, outputLanguage: undefined });
108
+ const base = buildDreamerProtocolInstruction({ coreGrounding: false });
109
+ expect(withLang.promptInput.dreamerInstruction).toBe(base);
110
+ // And the class-level constructor default behaves identically.
111
+ const implicit = new DreamerPromptBuilder().buildPrompt(input);
112
+ expect(implicit.promptInput.dreamerInstruction).toBe(base);
113
+ });
114
+ });
115
+ // ── Philosopher ──────────────────────────────────────────────────────────────
116
+ describe('PhilosopherPromptBuilder — outputLanguage (PRI-714 review fix)', () => {
117
+ const input = {
118
+ taskId: 'philosopher-task-001',
119
+ contextHash: 'ctx-abc123',
120
+ dreamerArtifact: { taskId: 'dreamer-task-001' },
121
+ sourceDreamerArtifactId: 'pi-art-dreamer-001',
122
+ };
123
+ it('appends the philosopher-subject directive to the REAL generated prompt message when zh-CN', () => {
124
+ const { message, promptInput } = new PhilosopherPromptBuilder().buildPrompt({ ...input, outputLanguage: 'zh-CN' });
125
+ expect(promptInput.philosopherInstruction).toContain('LANGUAGE DIRECTIVE');
126
+ expect(promptInput.philosopherInstruction).toContain('Simplified Chinese');
127
+ // Field list matches the actual PhilosopherOutputV1 schema (confidence is
128
+ // numeric — absent from the translatable list).
129
+ expect(promptInput.philosopherInstruction).toContain('(thesis, principleCandidate.title, principleCandidate.rationale, principleCandidate.scope, risks[])');
130
+ const parsed = parsePromptJson(message);
131
+ expect(parsed.philosopherInstruction).toBe(promptInput.philosopherInstruction);
132
+ });
133
+ it('directive works with coreGrounding ON and OFF', () => {
134
+ const on = new PhilosopherPromptBuilder({ coreGrounding: true }).buildPrompt({ ...input, outputLanguage: 'zh-CN' });
135
+ expect(on.promptInput.philosopherInstruction).toContain('CORE AXIOMS:');
136
+ expect(on.promptInput.philosopherInstruction).toContain('LANGUAGE DIRECTIVE');
137
+ const off = new PhilosopherPromptBuilder({ coreGrounding: false }).buildPrompt({ ...input, outputLanguage: 'en' });
138
+ expect(off.promptInput.philosopherInstruction).not.toContain('CORE AXIOMS:');
139
+ expect(off.promptInput.philosopherInstruction).toContain('LANGUAGE DIRECTIVE');
140
+ expect(off.promptInput.philosopherInstruction).toContain('English');
141
+ });
142
+ it('instruction is byte-identical to the base protocol when outputLanguage is undefined', () => {
143
+ const withLang = new PhilosopherPromptBuilder().buildPrompt({ ...input, outputLanguage: undefined });
144
+ const base = buildPhilosopherProtocolInstruction({ coreGrounding: false });
145
+ expect(withLang.promptInput.philosopherInstruction).toBe(base);
146
+ });
147
+ });
148
+ // ── Rollout Reviewer ─────────────────────────────────────────────────────────
149
+ describe('RolloutReviewerPromptBuilder — outputLanguage (PRI-714)', () => {
150
+ const builder = new RolloutReviewerPromptBuilder();
151
+ const input = {
152
+ taskId: 'task-rr-001',
153
+ contextHash: 'ctx-abc123',
154
+ sourceEvaluatorArtifactId: 'pi-art-evaluator-001',
155
+ evaluatorArtifact: { taskId: 'eval-001' },
156
+ };
157
+ it('includes Chinese language directive naming review fields when zh-CN', () => {
158
+ const result = builder.buildPrompt({ ...input, outputLanguage: 'zh-CN' });
159
+ expect(result.promptInput.rolloutReviewerInstruction).toContain('LANGUAGE DIRECTIVE');
160
+ expect(result.promptInput.rolloutReviewerInstruction).toContain('Simplified Chinese');
161
+ // PRI-714 review fix: the rollout reviewer names its OWN schema fields
162
+ // (review.*) — not the evaluator's evaluation.*/codeReview.* paths.
163
+ expect(result.promptInput.rolloutReviewerInstruction).toContain('(review.summary, review.requiredChanges, review.rolloutRisks, review.safetyChecks, risks)');
164
+ expect(result.promptInput.rolloutReviewerInstruction).not.toContain('codeReview.traceCoverage');
165
+ expect(result.promptInput.rolloutReviewerInstruction).not.toContain('requirementLedger');
166
+ });
167
+ it('includes English language directive when en', () => {
168
+ const result = builder.buildPrompt({ ...input, outputLanguage: 'en' });
169
+ expect(result.promptInput.rolloutReviewerInstruction).toContain('English');
170
+ expect(result.promptInput.rolloutReviewerInstruction).toContain('MUST NOT be translated');
171
+ });
172
+ it('instruction is byte-identical to base protocol when outputLanguage is undefined', () => {
173
+ const result = builder.buildPrompt(input);
174
+ expect(result.promptInput.rolloutReviewerInstruction).toBe(ROLLOUT_REVIEWER_PROTOCOL_INSTRUCTION);
175
+ expect(result.message).toBeDefined();
176
+ const parsed = parsePromptJson(result.message);
177
+ expect(parsed.rolloutReviewerInstruction).toBe(ROLLOUT_REVIEWER_PROTOCOL_INSTRUCTION);
178
+ });
179
+ });
180
+ // ── Artificer ────────────────────────────────────────────────────────────────
181
+ describe('ArtificerPromptBuilder — outputLanguage (PRI-714)', () => {
182
+ const builder = new ArtificerPromptBuilder();
183
+ const input = {
184
+ contextMode: 'v1',
185
+ taskId: 'artificer-task-001',
186
+ contextHash: 'ctx-abc123',
187
+ sourceScribeArtifactId: 'pi-art-scribe-001',
188
+ scribeArtifact: { taskId: 'scribe-001' },
189
+ };
190
+ it('includes Chinese language directive naming implementation fields when zh-CN', () => {
191
+ const result = builder.buildPrompt({ ...input, outputLanguage: 'zh-CN' });
192
+ expect(result.promptInput.artificerInstruction).toContain('LANGUAGE DIRECTIVE');
193
+ expect(result.promptInput.artificerInstruction).toContain('Simplified Chinese');
194
+ // implementation-subject field list
195
+ expect(result.promptInput.artificerInstruction).toContain('implementationSummary');
196
+ expect(result.promptInput.artificerInstruction).not.toContain('requiredChanges');
197
+ });
198
+ it('directive appears after the context-mode block in v2 mode too', () => {
199
+ const ruleContext = {
200
+ version: 2,
201
+ history: { status: 'available', truncated: false, calls: [] },
202
+ facts: { priorReadOfTarget: 'unknown', readCount: 0, writeCount: 0, uniqueWritePathCount: 0, sameActionBlockCount: null },
203
+ };
204
+ const result = builder.buildPrompt({
205
+ ...input,
206
+ contextMode: 'v2',
207
+ behaviorExamplePack: {
208
+ sourceNegativeCase: { caseId: 'negative-1', kind: 'negative', toolName: 'write_file', params: { path: 'unread' }, expectedDecision: 'block', ruleContext },
209
+ ownerDesiredOutcome: 'Block unread writes.',
210
+ positiveCounterexamples: [{ caseId: 'positive-1', kind: 'positive', toolName: 'write_file', params: { path: 'read' }, expectedDecision: 'allow', ruleContext }],
211
+ evidenceRefs: ['pain:1'],
212
+ redactionNotes: [],
213
+ },
214
+ outputLanguage: 'zh-CN',
215
+ });
216
+ expect(result.promptInput.artificerInstruction).toContain('CONTEXT MODE: v2');
217
+ expect(result.promptInput.artificerInstruction).toContain('LANGUAGE DIRECTIVE');
218
+ });
219
+ it('instruction is byte-identical to base protocol + v1 context block when outputLanguage is undefined', () => {
220
+ const result = builder.buildPrompt(input);
221
+ const base = ARTIFICER_PROTOCOL_INSTRUCTION
222
+ + '\nCONTEXT MODE: v1\n- You MUST NOT read input.context.\n'
223
+ + '- You MUST NOT output requiresContextVersion or case-level ruleContext.\n'
224
+ + '- Generate an action-only rule from the Scribe principle.\n';
225
+ expect(result.promptInput.artificerInstruction).toBe(base);
226
+ });
227
+ });
228
+ // ── buildLanguageDirective subject variants ─────────────────────────────────
229
+ describe('buildLanguageDirective — subject field lists (PRI-714)', () => {
230
+ it('principle subject keeps the PRI-336 field list (backward compatible default)', () => {
231
+ const directive = buildLanguageDirective('zh-CN');
232
+ expect(directive).toContain('(title, statement, rationale, applicability, antiPatterns, description)');
233
+ });
234
+ it('review subject enumerates the evaluator schema with explicit nested paths', () => {
235
+ const directive = buildLanguageDirective('zh-CN', 'review');
236
+ expect(directive).toContain('(evaluation.summary, evaluation.strengths, evaluation.concerns, evaluation.requiredChanges, codeReview.intentConsistency.explanation, codeReview.scopePrecision.explanation, codeReview.traceCoverage.explanation, codeReview.traceCoverage.gaps, adversarialCases[].rationale, painCoverage.explanation, compressionFidelity.explanation, risks)');
237
+ // The review subject carries the PRI-630 requirementLedger verbatim-echo
238
+ // rule; no other subject does.
239
+ expect(directive).toContain('requirementLedger[].statement MUST be copied verbatim');
240
+ for (const other of ['principle', 'dreamer', 'philosopher', 'rollout-review', 'implementation']) {
241
+ expect(buildLanguageDirective('zh-CN', other)).not.toContain('requirementLedger');
242
+ }
243
+ });
244
+ it('dreamer subject enumerates the dreamer candidate fields', () => {
245
+ const directive = buildLanguageDirective('en', 'dreamer');
246
+ expect(directive).toContain('(candidates[].badDecision, candidates[].betterDecision, candidates[].rationale, candidates[].strategicPerspective)');
247
+ });
248
+ it('philosopher subject enumerates the philosopher output fields', () => {
249
+ const directive = buildLanguageDirective('en', 'philosopher');
250
+ expect(directive).toContain('(thesis, principleCandidate.title, principleCandidate.rationale, principleCandidate.scope, risks[])');
251
+ });
252
+ it('rollout-review subject enumerates the rollout reviewer schema (not the evaluator schema)', () => {
253
+ const directive = buildLanguageDirective('en', 'rollout-review');
254
+ expect(directive).toContain('(review.summary, review.requiredChanges, review.rolloutRisks, review.safetyChecks, risks)');
255
+ expect(directive).not.toContain('codeReview');
256
+ });
257
+ it('implementation subject enumerates implementation fields', () => {
258
+ const directive = buildLanguageDirective('zh-CN', 'implementation');
259
+ expect(directive).toContain('(implementationSummary, risks)');
260
+ });
261
+ it('all subjects share the no-translate rules', () => {
262
+ for (const directive of [
263
+ buildLanguageDirective('zh-CN'),
264
+ buildLanguageDirective('zh-CN', 'dreamer'),
265
+ buildLanguageDirective('zh-CN', 'philosopher'),
266
+ buildLanguageDirective('zh-CN', 'review'),
267
+ buildLanguageDirective('zh-CN', 'rollout-review'),
268
+ buildLanguageDirective('zh-CN', 'implementation'),
269
+ ]) {
270
+ expect(directive).toContain('MUST NOT be translated');
271
+ expect(directive).toContain('JSON field names (keys) MUST remain in English');
272
+ }
273
+ });
274
+ it('undefined outputLanguage yields empty directive for every subject', () => {
275
+ for (const subject of ['principle', 'dreamer', 'philosopher', 'review', 'rollout-review', 'implementation']) {
276
+ expect(buildLanguageDirective(undefined, subject)).toBe('');
277
+ }
278
+ });
279
+ });
280
+ //# sourceMappingURL=peer-prompt-language.test.js.map