@principles/core 1.270.5 → 1.272.0

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 (188) hide show
  1. package/dist/runtime-v2/__tests__/admission-gate.test.js +23 -6
  2. package/dist/runtime-v2/__tests__/admission-gate.test.js.map +1 -1
  3. package/dist/runtime-v2/__tests__/adversarial-loop.test.js +22 -0
  4. package/dist/runtime-v2/__tests__/adversarial-loop.test.js.map +1 -1
  5. package/dist/runtime-v2/__tests__/context-payload-validation.test.js +1 -1
  6. package/dist/runtime-v2/__tests__/context-payload-validation.test.js.map +1 -1
  7. package/dist/runtime-v2/__tests__/evaluator-repair-loop.test.js +20 -0
  8. package/dist/runtime-v2/__tests__/evaluator-repair-loop.test.js.map +1 -1
  9. package/dist/runtime-v2/__tests__/evidence-guards.test.js +2 -2
  10. package/dist/runtime-v2/__tests__/evidence-guards.test.js.map +1 -1
  11. package/dist/runtime-v2/__tests__/golden-path-diagnostician-e2e.test.js +1 -1
  12. package/dist/runtime-v2/__tests__/golden-path-diagnostician-e2e.test.js.map +1 -1
  13. package/dist/runtime-v2/__tests__/governance-experience.test.js +19 -0
  14. package/dist/runtime-v2/__tests__/governance-experience.test.js.map +1 -1
  15. package/dist/runtime-v2/__tests__/pain-evidence-contract.test.js +3 -3
  16. package/dist/runtime-v2/__tests__/pain-evidence-contract.test.js.map +1 -1
  17. package/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.js +1 -1
  18. package/dist/runtime-v2/__tests__/pain-signal-bridge-result-shaping.test.js.map +1 -1
  19. package/dist/runtime-v2/__tests__/rollout-reviewer-verdict-paths.test.js +26 -5
  20. package/dist/runtime-v2/__tests__/rollout-reviewer-verdict-paths.test.js.map +1 -1
  21. package/dist/runtime-v2/__tests__/rollout-rule-candidate-contract.test.d.ts +2 -0
  22. package/dist/runtime-v2/__tests__/rollout-rule-candidate-contract.test.d.ts.map +1 -0
  23. package/dist/runtime-v2/__tests__/rollout-rule-candidate-contract.test.js +243 -0
  24. package/dist/runtime-v2/__tests__/rollout-rule-candidate-contract.test.js.map +1 -0
  25. package/dist/runtime-v2/admission-gate.d.ts +8 -1
  26. package/dist/runtime-v2/admission-gate.d.ts.map +1 -1
  27. package/dist/runtime-v2/admission-gate.js +14 -0
  28. package/dist/runtime-v2/admission-gate.js.map +1 -1
  29. package/dist/runtime-v2/context-payload.d.ts +9 -3
  30. package/dist/runtime-v2/context-payload.d.ts.map +1 -1
  31. package/dist/runtime-v2/context-payload.js +3 -1
  32. package/dist/runtime-v2/context-payload.js.map +1 -1
  33. package/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.js +2 -2
  34. package/dist/runtime-v2/evidence-triage/__tests__/observation-resolver.test.js.map +1 -1
  35. package/dist/runtime-v2/evidence-triage/observation-resolver.d.ts +1 -1
  36. package/dist/runtime-v2/evidence-triage/observation-resolver.d.ts.map +1 -1
  37. package/dist/runtime-v2/evidence-triage/observation-resolver.js +2 -2
  38. package/dist/runtime-v2/evidence-triage/observation-resolver.js.map +1 -1
  39. package/dist/runtime-v2/evidence-triage/types.d.ts +1 -1
  40. package/dist/runtime-v2/evidence-triage/types.d.ts.map +1 -1
  41. package/dist/runtime-v2/evolution/evolution-types.d.ts +8 -4
  42. package/dist/runtime-v2/evolution/evolution-types.d.ts.map +1 -1
  43. package/dist/runtime-v2/evolution/evolution-types.js +3 -1
  44. package/dist/runtime-v2/evolution/evolution-types.js.map +1 -1
  45. package/dist/runtime-v2/governance-experience-contract.d.ts +16 -16
  46. package/dist/runtime-v2/governance-experience-contract.d.ts.map +1 -1
  47. package/dist/runtime-v2/governance-experience-contract.js +4 -1
  48. package/dist/runtime-v2/governance-experience-contract.js.map +1 -1
  49. package/dist/runtime-v2/governance-experience.d.ts.map +1 -1
  50. package/dist/runtime-v2/governance-experience.js +30 -8
  51. package/dist/runtime-v2/governance-experience.js.map +1 -1
  52. package/dist/runtime-v2/index.d.ts +11 -1
  53. package/dist/runtime-v2/index.d.ts.map +1 -1
  54. package/dist/runtime-v2/index.js +7 -0
  55. package/dist/runtime-v2/index.js.map +1 -1
  56. package/dist/runtime-v2/internalization/__tests__/artificer-code-bearing.test.d.ts +2 -0
  57. package/dist/runtime-v2/internalization/__tests__/artificer-code-bearing.test.d.ts.map +1 -0
  58. package/dist/runtime-v2/internalization/__tests__/artificer-code-bearing.test.js +114 -0
  59. package/dist/runtime-v2/internalization/__tests__/artificer-code-bearing.test.js.map +1 -0
  60. package/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.d.ts +2 -0
  61. package/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.d.ts.map +1 -0
  62. package/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.js +256 -0
  63. package/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.js.map +1 -0
  64. package/dist/runtime-v2/internalization/__tests__/evaluator-prompt-builder.test.js +1 -1
  65. package/dist/runtime-v2/internalization/__tests__/internalization-transition-decision.test.js +15 -14
  66. package/dist/runtime-v2/internalization/__tests__/internalization-transition-decision.test.js.map +1 -1
  67. package/dist/runtime-v2/internalization/__tests__/owner-decision-architecture.test.d.ts +2 -0
  68. package/dist/runtime-v2/internalization/__tests__/owner-decision-architecture.test.d.ts.map +1 -0
  69. package/dist/runtime-v2/internalization/__tests__/owner-decision-architecture.test.js +56 -0
  70. package/dist/runtime-v2/internalization/__tests__/owner-decision-architecture.test.js.map +1 -0
  71. package/dist/runtime-v2/internalization/__tests__/owner-decision-review.test.d.ts +2 -0
  72. package/dist/runtime-v2/internalization/__tests__/owner-decision-review.test.d.ts.map +1 -0
  73. package/dist/runtime-v2/internalization/__tests__/owner-decision-review.test.js +229 -0
  74. package/dist/runtime-v2/internalization/__tests__/owner-decision-review.test.js.map +1 -0
  75. package/dist/runtime-v2/internalization/__tests__/owner-decision.test.d.ts +2 -0
  76. package/dist/runtime-v2/internalization/__tests__/owner-decision.test.d.ts.map +1 -0
  77. package/dist/runtime-v2/internalization/__tests__/owner-decision.test.js +1054 -0
  78. package/dist/runtime-v2/internalization/__tests__/owner-decision.test.js.map +1 -0
  79. package/dist/runtime-v2/internalization/__tests__/owner-override-resume.test.d.ts +2 -0
  80. package/dist/runtime-v2/internalization/__tests__/owner-override-resume.test.d.ts.map +1 -0
  81. package/dist/runtime-v2/internalization/__tests__/owner-override-resume.test.js +328 -0
  82. package/dist/runtime-v2/internalization/__tests__/owner-override-resume.test.js.map +1 -0
  83. package/dist/runtime-v2/internalization/__tests__/rule-activation-contract.test.d.ts +2 -0
  84. package/dist/runtime-v2/internalization/__tests__/rule-activation-contract.test.d.ts.map +1 -0
  85. package/dist/runtime-v2/internalization/__tests__/rule-activation-contract.test.js +187 -0
  86. package/dist/runtime-v2/internalization/__tests__/rule-activation-contract.test.js.map +1 -0
  87. package/dist/runtime-v2/internalization/artificer-code-bearing.d.ts +39 -0
  88. package/dist/runtime-v2/internalization/artificer-code-bearing.d.ts.map +1 -0
  89. package/dist/runtime-v2/internalization/artificer-code-bearing.js +33 -0
  90. package/dist/runtime-v2/internalization/artificer-code-bearing.js.map +1 -0
  91. package/dist/runtime-v2/internalization/evaluator-output.d.ts +63 -2
  92. package/dist/runtime-v2/internalization/evaluator-output.d.ts.map +1 -1
  93. package/dist/runtime-v2/internalization/evaluator-output.js +139 -2
  94. package/dist/runtime-v2/internalization/evaluator-output.js.map +1 -1
  95. package/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts +54 -2
  96. package/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts.map +1 -1
  97. package/dist/runtime-v2/internalization/evaluator-prompt-builder.js +49 -2
  98. package/dist/runtime-v2/internalization/evaluator-prompt-builder.js.map +1 -1
  99. package/dist/runtime-v2/internalization/evaluator-runner.d.ts +45 -8
  100. package/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
  101. package/dist/runtime-v2/internalization/evaluator-runner.js +465 -43
  102. package/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
  103. package/dist/runtime-v2/internalization/index.d.ts +2 -0
  104. package/dist/runtime-v2/internalization/index.d.ts.map +1 -1
  105. package/dist/runtime-v2/internalization/index.js +1 -0
  106. package/dist/runtime-v2/internalization/index.js.map +1 -1
  107. package/dist/runtime-v2/internalization/internalization-orchestrator.d.ts.map +1 -1
  108. package/dist/runtime-v2/internalization/internalization-orchestrator.js +10 -54
  109. package/dist/runtime-v2/internalization/internalization-orchestrator.js.map +1 -1
  110. package/dist/runtime-v2/internalization/internalization-transition-decision.d.ts +7 -1
  111. package/dist/runtime-v2/internalization/internalization-transition-decision.d.ts.map +1 -1
  112. package/dist/runtime-v2/internalization/internalization-transition-decision.js +9 -2
  113. package/dist/runtime-v2/internalization/internalization-transition-decision.js.map +1 -1
  114. package/dist/runtime-v2/internalization/owner-decision-review.d.ts +98 -0
  115. package/dist/runtime-v2/internalization/owner-decision-review.d.ts.map +1 -0
  116. package/dist/runtime-v2/internalization/owner-decision-review.js +287 -0
  117. package/dist/runtime-v2/internalization/owner-decision-review.js.map +1 -0
  118. package/dist/runtime-v2/internalization/owner-resolution-service.d.ts +100 -0
  119. package/dist/runtime-v2/internalization/owner-resolution-service.d.ts.map +1 -0
  120. package/dist/runtime-v2/internalization/owner-resolution-service.js +385 -0
  121. package/dist/runtime-v2/internalization/owner-resolution-service.js.map +1 -0
  122. package/dist/runtime-v2/internalization/owner-retry.d.ts +12 -0
  123. package/dist/runtime-v2/internalization/owner-retry.d.ts.map +1 -1
  124. package/dist/runtime-v2/internalization/owner-retry.js +23 -0
  125. package/dist/runtime-v2/internalization/owner-retry.js.map +1 -1
  126. package/dist/runtime-v2/internalization/owner-review.d.ts +199 -0
  127. package/dist/runtime-v2/internalization/owner-review.d.ts.map +1 -0
  128. package/dist/runtime-v2/internalization/owner-review.js +470 -0
  129. package/dist/runtime-v2/internalization/owner-review.js.map +1 -0
  130. package/dist/runtime-v2/internalization/peer-runner-contracts.d.ts +5 -1
  131. package/dist/runtime-v2/internalization/peer-runner-contracts.d.ts.map +1 -1
  132. package/dist/runtime-v2/internalization/peer-runner-contracts.js.map +1 -1
  133. package/dist/runtime-v2/internalization/pitask-metadata.d.ts +84 -0
  134. package/dist/runtime-v2/internalization/pitask-metadata.d.ts.map +1 -1
  135. package/dist/runtime-v2/internalization/pitask-metadata.js +166 -0
  136. package/dist/runtime-v2/internalization/pitask-metadata.js.map +1 -1
  137. package/dist/runtime-v2/internalization/revision-reopen.d.ts +56 -0
  138. package/dist/runtime-v2/internalization/revision-reopen.d.ts.map +1 -0
  139. package/dist/runtime-v2/internalization/revision-reopen.js +144 -0
  140. package/dist/runtime-v2/internalization/revision-reopen.js.map +1 -0
  141. package/dist/runtime-v2/internalization/rollout-reviewer-runner.d.ts +25 -0
  142. package/dist/runtime-v2/internalization/rollout-reviewer-runner.d.ts.map +1 -1
  143. package/dist/runtime-v2/internalization/rollout-reviewer-runner.js +202 -23
  144. package/dist/runtime-v2/internalization/rollout-reviewer-runner.js.map +1 -1
  145. package/dist/runtime-v2/internalization/rule-activation-contract.d.ts +35 -0
  146. package/dist/runtime-v2/internalization/rule-activation-contract.d.ts.map +1 -0
  147. package/dist/runtime-v2/internalization/rule-activation-contract.js +36 -0
  148. package/dist/runtime-v2/internalization/rule-activation-contract.js.map +1 -0
  149. package/dist/runtime-v2/pain-signal-bridge.d.ts +2 -0
  150. package/dist/runtime-v2/pain-signal-bridge.d.ts.map +1 -1
  151. package/dist/runtime-v2/pain-signal-bridge.js +4 -3
  152. package/dist/runtime-v2/pain-signal-bridge.js.map +1 -1
  153. package/dist/runtime-v2/pain-to-principle-service.d.ts +1 -0
  154. package/dist/runtime-v2/pain-to-principle-service.d.ts.map +1 -1
  155. package/dist/runtime-v2/pain-to-principle-service.js +1 -0
  156. package/dist/runtime-v2/pain-to-principle-service.js.map +1 -1
  157. package/dist/runtime-v2/runner/__tests__/pain-signal-bridge-admission.test.js +6 -6
  158. package/dist/runtime-v2/runner/__tests__/pain-signal-bridge-admission.test.js.map +1 -1
  159. package/dist/runtime-v2/store/context/sqlite-context-assembler.d.ts.map +1 -1
  160. package/dist/runtime-v2/store/context/sqlite-context-assembler.js +25 -5
  161. package/dist/runtime-v2/store/context/sqlite-context-assembler.js.map +1 -1
  162. package/dist/runtime-v2/store/context/sqlite-context-assembler.test.js +39 -9
  163. package/dist/runtime-v2/store/context/sqlite-context-assembler.test.js.map +1 -1
  164. package/dist/runtime-v2/store/runtime-state-manager.d.ts +12 -0
  165. package/dist/runtime-v2/store/runtime-state-manager.d.ts.map +1 -1
  166. package/dist/runtime-v2/store/runtime-state-manager.js +17 -0
  167. package/dist/runtime-v2/store/runtime-state-manager.js.map +1 -1
  168. package/dist/runtime-v2/store/task/__tests__/sqlite-task-store-cas.test.d.ts +2 -0
  169. package/dist/runtime-v2/store/task/__tests__/sqlite-task-store-cas.test.d.ts.map +1 -0
  170. package/dist/runtime-v2/store/task/__tests__/sqlite-task-store-cas.test.js +114 -0
  171. package/dist/runtime-v2/store/task/__tests__/sqlite-task-store-cas.test.js.map +1 -0
  172. package/dist/runtime-v2/store/task/memory-task-store.d.ts +1 -0
  173. package/dist/runtime-v2/store/task/memory-task-store.d.ts.map +1 -1
  174. package/dist/runtime-v2/store/task/memory-task-store.js +8 -0
  175. package/dist/runtime-v2/store/task/memory-task-store.js.map +1 -1
  176. package/dist/runtime-v2/store/task/sqlite-task-store.d.ts +20 -0
  177. package/dist/runtime-v2/store/task/sqlite-task-store.d.ts.map +1 -1
  178. package/dist/runtime-v2/store/task/sqlite-task-store.js +81 -0
  179. package/dist/runtime-v2/store/task/sqlite-task-store.js.map +1 -1
  180. package/dist/runtime-v2/store/task/task-store.d.ts +9 -0
  181. package/dist/runtime-v2/store/task/task-store.d.ts.map +1 -1
  182. package/dist/runtime-v2/store/workspace-isolation.test.js +1 -0
  183. package/dist/runtime-v2/store/workspace-isolation.test.js.map +1 -1
  184. package/dist/runtime-v2/task-status.d.ts +2 -1
  185. package/dist/runtime-v2/task-status.d.ts.map +1 -1
  186. package/dist/runtime-v2/task-status.js +5 -1
  187. package/dist/runtime-v2/task-status.js.map +1 -1
  188. package/package.json +1 -1
@@ -0,0 +1,187 @@
1
+ /**
2
+ * PRI-634 — 可激活 rule 产物内容契约测试。
3
+ *
4
+ * 背景(PRI-634 取证结论):PRI-629 的数据修复把 artificer 原始产物改标成
5
+ * kind='rule' + validated,造出一个 kind/validated 全匹配、内容却是 artificer
6
+ * schema(goldenTraceCases,无 goldenTrace / ruleHostGateDecision)的伪候选。
7
+ * 修复前 resolveActivationCandidate 只按 kind+validated 过滤,伪候选被放行到
8
+ * RuleHostWriter.canActivate,直到那里才以 no_golden_trace 爆炸 —— Owner 侧
9
+ * 只剩一个无解释力的 rollout_dispatch_refused。
10
+ *
11
+ * 本测试锁定两件事:
12
+ * 1. 契约函数能区分「evaluator assemble 产物」与「伪候选」;
13
+ * 2. 契约函数的判定与 RuleHostWriter.canActivate 的静态检查一致(防漂移)。
14
+ */
15
+ import { describe, it, expect } from 'vitest';
16
+ import { checkRuleActivationContent } from '../rule-activation-contract.js';
17
+ import { buildGoldenTraceFromArtificer } from '../../golden-trace.js';
18
+ import { RuleHostWriter } from '../../activation/writers/rule-host-writer.js';
19
+ /** 构造一条结构合法的 goldenTrace(走生产同款 builder,避免手搓 schema 漂移)。 */
20
+ function buildValidTrace() {
21
+ const built = buildGoldenTraceFromArtificer({
22
+ cases: [
23
+ {
24
+ caseId: 'case-positive',
25
+ kind: 'positive',
26
+ toolName: 'edit',
27
+ params: { path: 'src/a.ts' },
28
+ expectedDecision: 'allow',
29
+ },
30
+ {
31
+ caseId: 'case-negative',
32
+ kind: 'negative',
33
+ toolName: 'bash',
34
+ params: { command: 'rm -rf /' },
35
+ expectedDecision: 'block',
36
+ },
37
+ ],
38
+ sourceArtifactId: 'pi-art-artificer-1',
39
+ });
40
+ if (!built.ok)
41
+ throw new Error(`fixture goldenTrace build failed: ${built.reason}`);
42
+ return built.trace;
43
+ }
44
+ /** evaluator assembleRuleArtifact 产出的合法可激活产物。 */
45
+ function validRuleContent() {
46
+ return JSON.stringify({
47
+ implementationCode: 'export function evaluate() { return { decision: "allow" }; }',
48
+ goldenTrace: buildValidTrace(),
49
+ goldenTraceCases: buildValidTrace().cases,
50
+ affectedTools: ['edit'],
51
+ ruleHostGateDecision: 'accepted_shadow',
52
+ sourceArtificerArtifactId: 'pi-art-artificer-1',
53
+ });
54
+ }
55
+ /**
56
+ * PRI-634 真实伪候选:artificer 原始产物被改标 kind='rule' + validated。
57
+ * 关键特征(与 state.db 取证记录一致)—— artificer schema 全字段都在
58
+ * (implementationCode / goldenTraceCases / affectedTools),**只缺 evaluator
59
+ * assemble 才会写入的 goldenTrace 与 ruleHostGateDecision**。回归失败原因
60
+ * 因此精确锁定这两个缺口,而不是顺便靠 implementationCode 缺失把测试打红。
61
+ */
62
+ function pseudoCandidateContent() {
63
+ return JSON.stringify({
64
+ implementationCode: 'export function evaluate() { return { decision: "allow" }; }',
65
+ goldenTraceCases: buildValidTrace().cases,
66
+ affectedTools: ['edit'],
67
+ sourceArtifactId: 'pi-art-artificer-1',
68
+ });
69
+ }
70
+ function snapshot(contentJson) {
71
+ return {
72
+ artifactId: 'pi-art-under-test',
73
+ artifactKind: 'rule',
74
+ sourceTaskId: 'task-under-test',
75
+ validationStatus: 'validated',
76
+ contentJson,
77
+ createdAt: new Date().toISOString(),
78
+ };
79
+ }
80
+ /**
81
+ * 沙箱永不该被调用:契约函数判定失败的产物,writer 的静态检查必然先返回。
82
+ * 因此这里用一个会抛错的 stub 来证明「没走到沙箱」。
83
+ */
84
+ const neverCalledSandbox = (_code, _trace, _opts) => {
85
+ throw new Error('sandbox must not be reached for contract-rejected artifacts');
86
+ };
87
+ describe('checkRuleActivationContent (PRI-634)', () => {
88
+ it('接受 evaluator assemble 的合法 rule 产物', () => {
89
+ expect(checkRuleActivationContent(validRuleContent())).toEqual({ ok: true });
90
+ });
91
+ it('拒绝 PRI-634 伪候选 (artificer schema 被改标 rule+validated)', () => {
92
+ const result = checkRuleActivationContent(pseudoCandidateContent());
93
+ expect(result.ok).toBe(false);
94
+ if (result.ok)
95
+ return;
96
+ // 真实形态(取证记录): artificer 产物自带 implementationCode,缺口精确
97
+ // 锁定为 evaluator assemble 未写入的两项 —— goldenTrace 与 gate decision。
98
+ expect(result.missingFields).toEqual(['goldenTrace', 'ruleHostGateDecision:accepted_shadow']);
99
+ });
100
+ it('goldenTrace 结构非法时拒绝 (即使字段存在)', () => {
101
+ const result = checkRuleActivationContent(JSON.stringify({
102
+ implementationCode: 'export function evaluate() {}',
103
+ goldenTrace: { traceId: 'x' }, // 缺 cases / version / createdAt
104
+ ruleHostGateDecision: 'accepted_shadow',
105
+ }));
106
+ expect(result.ok).toBe(false);
107
+ if (result.ok)
108
+ return;
109
+ expect(result.missingFields).toEqual(['goldenTrace']);
110
+ });
111
+ it('gate decision 非 accepted_shadow 时拒绝', () => {
112
+ const result = checkRuleActivationContent(JSON.stringify({
113
+ implementationCode: 'export function evaluate() {}',
114
+ goldenTrace: buildValidTrace(),
115
+ ruleHostGateDecision: 'rejected_validation_failed',
116
+ }));
117
+ expect(result.ok).toBe(false);
118
+ if (result.ok)
119
+ return;
120
+ expect(result.missingFields).toEqual(['ruleHostGateDecision:accepted_shadow']);
121
+ });
122
+ it('implementationCode 为空串时拒绝', () => {
123
+ const result = checkRuleActivationContent(JSON.stringify({
124
+ implementationCode: ' ',
125
+ goldenTrace: buildValidTrace(),
126
+ ruleHostGateDecision: 'accepted_shadow',
127
+ }));
128
+ expect(result.ok).toBe(false);
129
+ if (result.ok)
130
+ return;
131
+ expect(result.missingFields).toEqual(['implementationCode']);
132
+ });
133
+ it('contentJson 不可解析 / 非对象时不抛异常,返回 content_json_unparseable', () => {
134
+ expect(checkRuleActivationContent('not-json')).toEqual({
135
+ ok: false,
136
+ missingFields: ['content_json_unparseable'],
137
+ });
138
+ expect(checkRuleActivationContent(JSON.stringify([1, 2, 3]))).toEqual({
139
+ ok: false,
140
+ missingFields: ['content_json_unparseable'],
141
+ });
142
+ expect(checkRuleActivationContent(JSON.stringify(null))).toEqual({
143
+ ok: false,
144
+ missingFields: ['content_json_unparseable'],
145
+ });
146
+ });
147
+ });
148
+ /**
149
+ * 契约一致性 (防漂移):
150
+ * 契约函数放行的产物,writer 的静态检查必须也放行(不因缺字段在沙箱前被拒);
151
+ * 契约函数拒绝的产物,writer 必须在沙箱调用之前就拒绝。
152
+ */
153
+ describe('与 RuleHostWriter.canActivate 静态检查一致 (防漂移)', () => {
154
+ const writer = new RuleHostWriter({ gateDeps: { evaluateInSandbox: neverCalledSandbox } });
155
+ it('伪候选:契约拒绝 ⇒ writer 也在沙箱前拒绝,且不触碰沙箱', async () => {
156
+ const contentJson = pseudoCandidateContent();
157
+ expect(checkRuleActivationContent(contentJson).ok).toBe(false);
158
+ const result = await writer.canActivate(snapshot(contentJson));
159
+ expect(result.ok).toBe(false);
160
+ if (result.ok)
161
+ return;
162
+ // 真实形态下 implementationCode 存在,writer 的静态检查走到 goldenTrace
163
+ // 提取处失败 —— 与 PRI-634 生产事故的原始失败 reason 完全一致,证明
164
+ // 回归复现的就是那条真实失败链,而非另一个缺字段变体。
165
+ expect(result.reason).toBe('no_golden_trace');
166
+ });
167
+ it('合法产物:契约接受 ⇒ writer 不因缺字段拒绝 (进入沙箱/门禁阶段)', async () => {
168
+ const contentJson = validRuleContent();
169
+ expect(checkRuleActivationContent(contentJson)).toEqual({ ok: true });
170
+ // 用会在被调用时返回 rejected_no_cases 的沙箱,把「走到了门禁」与
171
+ // 「静态检查拒绝」区分开:静态拒绝的 reason 集合不含 gate_* 前缀。
172
+ const sandboxWriter = new RuleHostWriter({
173
+ gateDeps: {
174
+ evaluateInSandbox: () => ({
175
+ success: false,
176
+ failedCases: [],
177
+ executionTimeMs: 0,
178
+ forbiddenPatternViolations: [],
179
+ }),
180
+ },
181
+ });
182
+ const result = await sandboxWriter.canActivate(snapshot(contentJson));
183
+ expect(result.ok).toBe(false);
184
+ expect(String(result.ok ? '' : result.reason).startsWith('gate_decision_not_accepted_shadow')).toBe(true);
185
+ });
186
+ });
187
+ //# sourceMappingURL=rule-activation-contract.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule-activation-contract.test.js","sourceRoot":"","sources":["../../../../src/runtime-v2/internalization/__tests__/rule-activation-contract.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * PRI-634 A2(authority migration)— code-bearing Artificer artifact 判定。
3
+ *
4
+ * 设计裁决(Owner 评审 2026-08-31 冻结):`这条链是否需要 deterministic
5
+ * RuleHost gate` 的 authority 是 **durable Artificer artifact 是否
6
+ * code-bearing**,而不是 evaluator LLM 是否恰好输出了 optional 的 V2 字段
7
+ * (`isEvaluatorOutputV2()`)。原控制流把 optional LLM output shape 当作
8
+ * gate 前置 —— V2 字段全部 optional 且 validator 明确允许 V1 缺失
9
+ * (evaluator-output.ts),导致一个完整 code-bearing 的 Artificer 产物可以在
10
+ * evaluator 只返回 V1 shape 时结构性跳过安全门(48371236 链 attempt 17)。
11
+ *
12
+ * 评审实现约束:**不得**把「字段碰巧存在」当成新的弱 heuristic authority。
13
+ * 本函数逐项镜像 `assembleRuleArtifact()`(evaluator-runner.ts)的静态前置
14
+ * 验证 —— 返回 codeBearing=true 严格等价于「rule assembly 的全部静态检查
15
+ * 将通过」。这样 authority 定义收敛到唯一的、机器可验证的语义:
16
+ * 经 runtime validation 的 durable Artificer capability。
17
+ *
18
+ * 验证序列(与 assemble 的 rule_assembly_failed reasons 一一对应):
19
+ * 1. contentJson 缺失 → no_artificer_artifact
20
+ * 2. JSON 解析失败 / 非 object → artificer_artifact_unparseable
21
+ * 3. implementationCode 非空串 → artificer_artifact_has_no_implementation_code
22
+ * 4. goldenTraceCases 非数组 → artificer_golden_trace_cases_not_array
23
+ * 5. buildGoldenTraceFromArtificer 失败(结构非法 / 无 positive+negative)
24
+ * → golden_trace_build_failed:<reason>
25
+ *
26
+ * affectedTools 刻意**不**作为硬条件:assemble 的真实语义是 tolerant
27
+ * (optional 数组、元素 filter string、缺省 [])。把它收紧成硬失败会造出
28
+ * 比 assemble 更严的假 authority,违反 One Source of Truth。
29
+ *
30
+ * 纯函数:无 I/O、无注入依赖,可直接单测。
31
+ */
32
+ export type ArtificerCodeBearingAssessment = {
33
+ readonly codeBearing: true;
34
+ } | {
35
+ readonly codeBearing: false;
36
+ readonly reason: string;
37
+ };
38
+ export declare function assessArtificerCodeBearing(contentJson: string | null | undefined): ArtificerCodeBearingAssessment;
39
+ //# sourceMappingURL=artificer-code-bearing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artificer-code-bearing.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/artificer-code-bearing.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,MAAM,8BAA8B,GACtC;IAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,8BAA8B,CAqCjH"}
@@ -0,0 +1,33 @@
1
+ import { buildGoldenTraceFromArtificer } from '../golden-trace.js';
2
+ export function assessArtificerCodeBearing(contentJson) {
3
+ if (typeof contentJson !== 'string' || contentJson.trim() === '') {
4
+ return { codeBearing: false, reason: 'no_artificer_artifact' };
5
+ }
6
+ let parsed;
7
+ try {
8
+ parsed = JSON.parse(contentJson);
9
+ }
10
+ catch {
11
+ return { codeBearing: false, reason: 'artificer_artifact_unparseable' };
12
+ }
13
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
14
+ return { codeBearing: false, reason: 'artificer_artifact_unparseable' };
15
+ }
16
+ // runtime-contract-exempt: ERR-001 object-guarded unknown property extraction;
17
+ // values are typeof-checked / structurally validated immediately below.
18
+ const { implementationCode, goldenTraceCases } = parsed;
19
+ if (typeof implementationCode !== 'string' || implementationCode.trim() === '') {
20
+ return { codeBearing: false, reason: 'artificer_artifact_has_no_implementation_code' };
21
+ }
22
+ if (!Array.isArray(goldenTraceCases)) {
23
+ return { codeBearing: false, reason: 'artificer_golden_trace_cases_not_array' };
24
+ }
25
+ // assemble 要求 ≥1 positive + ≥1 negative 且逐 case 结构合法
26
+ // (buildGoldenTraceFromArtificer 内部对每项做 validateGoldenTraceCase)。
27
+ const traceBuild = buildGoldenTraceFromArtificer({ cases: goldenTraceCases });
28
+ if (!traceBuild.ok) {
29
+ return { codeBearing: false, reason: `golden_trace_build_failed: ${traceBuild.reason}` };
30
+ }
31
+ return { codeBearing: true };
32
+ }
33
+ //# sourceMappingURL=artificer-code-bearing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artificer-code-bearing.js","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/artificer-code-bearing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oBAAoB,CAAC;AAqCnE,MAAM,UAAU,0BAA0B,CAAC,WAAsC;IAC/E,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACjE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IACjE,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,gCAAgC,EAAE,CAAC;IAC1E,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,gCAAgC,EAAE,CAAC;IAC1E,CAAC;IAED,+EAA+E;IAC/E,wEAAwE;IACxE,MAAM,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,GAAG,MAGhD,CAAC;IAEF,IAAI,OAAO,kBAAkB,KAAK,QAAQ,IAAI,kBAAkB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC/E,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,+CAA+C,EAAE,CAAC;IACzF,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,wCAAwC,EAAE,CAAC;IAClF,CAAC;IAED,qDAAqD;IACrD,kEAAkE;IAClE,MAAM,UAAU,GAAG,6BAA6B,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC9E,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;QACnB,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;IAC3F,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AAC/B,CAAC"}
@@ -50,6 +50,15 @@ export interface EvaluatorAdversarialResult {
50
50
  readonly passed: boolean;
51
51
  readonly failedCases: readonly AdversarialFailedCase[];
52
52
  }
53
+ /**
54
+ * PRI-630 收敛契约: 第二轮及之后,评估器必须对上轮 review contract 的每个
55
+ * 稳定需求 id 裁定 resolved / still_open / regressed。
56
+ */
57
+ export type PriorRequirementStatus = 'resolved' | 'still_open' | 'regressed';
58
+ export interface PriorRequirementStatusEntry {
59
+ readonly id: string;
60
+ readonly status: PriorRequirementStatus;
61
+ }
53
62
  export interface EvaluatorEvaluation {
54
63
  readonly decision: 'approved' | 'needs_revision' | 'rejected';
55
64
  readonly summary: string;
@@ -57,6 +66,17 @@ export interface EvaluatorEvaluation {
57
66
  readonly strengths: readonly string[];
58
67
  readonly concerns: readonly string[];
59
68
  readonly requiredChanges: readonly string[];
69
+ /** PRI-630: 上轮需求的逐条核销 (仅有上轮上下文时合法;首轮省略) */
70
+ readonly priorRequirementStatuses?: readonly PriorRequirementStatusEntry[];
71
+ /**
72
+ * PRI-630 P1 评审修复: 输入需求的 ledger echo ({id, statement, status}) —
73
+ * 下一轮上下文的身份载体,保证 requirement id 跨轮稳定。
74
+ */
75
+ readonly requirementLedger?: readonly {
76
+ readonly id: string;
77
+ readonly statement: string;
78
+ readonly status: PriorRequirementStatus;
79
+ }[];
60
80
  }
61
81
  export interface EvaluatorSourceTrace {
62
82
  readonly artificerArtifactId: string;
@@ -113,6 +133,15 @@ export interface EvaluatorOutputV2 extends EvaluatorOutputV1 {
113
133
  readonly compressionFidelity?: EvaluatorCompressionFidelity;
114
134
  }
115
135
  export declare const EVALUATOR_DECISIONS: readonly ['approved', 'needs_revision', 'rejected'];
136
+ export declare const PriorRequirementStatusEntrySchema: import("@sinclair/typebox").TObject<{
137
+ id: import("@sinclair/typebox").TString;
138
+ status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"resolved">, import("@sinclair/typebox").TLiteral<"still_open">, import("@sinclair/typebox").TLiteral<"regressed">]>;
139
+ }>;
140
+ export declare const RequirementLedgerEntrySchema: import("@sinclair/typebox").TObject<{
141
+ id: import("@sinclair/typebox").TString;
142
+ statement: import("@sinclair/typebox").TString;
143
+ status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"resolved">, import("@sinclair/typebox").TLiteral<"still_open">, import("@sinclair/typebox").TLiteral<"regressed">]>;
144
+ }>;
116
145
  export declare const EvaluatorEvaluationSchema: import("@sinclair/typebox").TObject<{
117
146
  decision: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"approved">, import("@sinclair/typebox").TLiteral<"needs_revision">, import("@sinclair/typebox").TLiteral<"rejected">]>;
118
147
  summary: import("@sinclair/typebox").TString;
@@ -120,6 +149,15 @@ export declare const EvaluatorEvaluationSchema: import("@sinclair/typebox").TObj
120
149
  strengths: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
121
150
  concerns: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
122
151
  requiredChanges: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
152
+ priorRequirementStatuses: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
153
+ id: import("@sinclair/typebox").TString;
154
+ status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"resolved">, import("@sinclair/typebox").TLiteral<"still_open">, import("@sinclair/typebox").TLiteral<"regressed">]>;
155
+ }>>>;
156
+ requirementLedger: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
157
+ id: import("@sinclair/typebox").TString;
158
+ statement: import("@sinclair/typebox").TString;
159
+ status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"resolved">, import("@sinclair/typebox").TLiteral<"still_open">, import("@sinclair/typebox").TLiteral<"regressed">]>;
160
+ }>>>;
123
161
  }>;
124
162
  export declare const EvaluatorSourceTraceSchema: import("@sinclair/typebox").TObject<{
125
163
  artificerArtifactId: import("@sinclair/typebox").TString;
@@ -137,6 +175,15 @@ export declare const EvaluatorOutputV1Schema: import("@sinclair/typebox").TObjec
137
175
  strengths: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
138
176
  concerns: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
139
177
  requiredChanges: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
178
+ priorRequirementStatuses: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
179
+ id: import("@sinclair/typebox").TString;
180
+ status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"resolved">, import("@sinclair/typebox").TLiteral<"still_open">, import("@sinclair/typebox").TLiteral<"regressed">]>;
181
+ }>>>;
182
+ requirementLedger: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
183
+ id: import("@sinclair/typebox").TString;
184
+ statement: import("@sinclair/typebox").TString;
185
+ status: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"resolved">, import("@sinclair/typebox").TLiteral<"still_open">, import("@sinclair/typebox").TLiteral<"regressed">]>;
186
+ }>>>;
140
187
  }>;
141
188
  sourceTrace: import("@sinclair/typebox").TObject<{
142
189
  artificerArtifactId: import("@sinclair/typebox").TString;
@@ -160,9 +207,23 @@ export interface EvaluatorValidationResult {
160
207
  */
161
208
  export declare function isEvaluatorOutputV2(output: unknown): output is EvaluatorOutputV2;
162
209
  export interface EvaluatorValidator {
163
- validate(output: unknown, taskId: string, expectedSourceArtificerArtifactId?: string): Promise<EvaluatorValidationResult>;
210
+ validate(output: unknown, taskId: string, expectedSourceArtificerArtifactId?: string, convergence?: EvaluatorConvergenceContext): Promise<EvaluatorValidationResult>;
211
+ }
212
+ export interface EvaluatorExpectedRequirement {
213
+ /** 上轮分配的稳定 id (req-N) */
214
+ readonly id: string;
215
+ /** 上轮注入上下文的陈述原文 — ledger 必须 verbatim echo */
216
+ readonly statement: string;
217
+ }
218
+ export interface EvaluatorConvergenceContext {
219
+ /**
220
+ * 评审轮 2 P1: authoritative 修复轮契约 — runner 从上一轮上下文原样传入。
221
+ * repair round 的 priorRequirementStatuses 与 requirementLedger 都以此为准
222
+ * 做机器校验 (存在/完整/不重复/不重编号/statement 原文/status 互洽)。
223
+ */
224
+ readonly expectedRequirements?: readonly EvaluatorExpectedRequirement[];
164
225
  }
165
226
  export declare class DefaultEvaluatorValidator implements EvaluatorValidator {
166
- validate(output: unknown, taskId: string, expectedSourceArtificerArtifactId?: string): Promise<EvaluatorValidationResult>;
227
+ validate(output: unknown, taskId: string, expectedSourceArtificerArtifactId?: string, convergence?: EvaluatorConvergenceContext): Promise<EvaluatorValidationResult>;
167
228
  }
168
229
  //# sourceMappingURL=evaluator-output.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"evaluator-output.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/evaluator-output.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"evaluator-output.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/evaluator-output.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,23 @@
1
1
  import { Type } from '@sinclair/typebox';
2
2
  import { validateRuleContextV2 } from './rule-context-v2.js';
3
3
  export const EVALUATOR_DECISIONS = ['approved', 'needs_revision', 'rejected'];
4
+ export const PriorRequirementStatusEntrySchema = Type.Object({
5
+ id: Type.String({ minLength: 1 }),
6
+ status: Type.Union([
7
+ Type.Literal('resolved'),
8
+ Type.Literal('still_open'),
9
+ Type.Literal('regressed'),
10
+ ]),
11
+ });
12
+ export const RequirementLedgerEntrySchema = Type.Object({
13
+ id: Type.String({ minLength: 1 }),
14
+ statement: Type.String({ minLength: 1 }),
15
+ status: Type.Union([
16
+ Type.Literal('resolved'),
17
+ Type.Literal('still_open'),
18
+ Type.Literal('regressed'),
19
+ ]),
20
+ });
4
21
  export const EvaluatorEvaluationSchema = Type.Object({
5
22
  decision: Type.Union([
6
23
  Type.Literal('approved'),
@@ -12,6 +29,8 @@ export const EvaluatorEvaluationSchema = Type.Object({
12
29
  strengths: Type.Array(Type.String()),
13
30
  concerns: Type.Array(Type.String()),
14
31
  requiredChanges: Type.Array(Type.String()),
32
+ priorRequirementStatuses: Type.Optional(Type.Array(PriorRequirementStatusEntrySchema)),
33
+ requirementLedger: Type.Optional(Type.Array(RequirementLedgerEntrySchema)),
15
34
  });
16
35
  export const EvaluatorSourceTraceSchema = Type.Object({
17
36
  artificerArtifactId: Type.String({ minLength: 1 }),
@@ -192,8 +211,8 @@ export function isEvaluatorOutputV2(output) {
192
211
  && (!hasResult || validateAdversarialResult(output.adversarialResult).length === 0);
193
212
  }
194
213
  export class DefaultEvaluatorValidator {
195
- // eslint-disable-next-line @typescript-eslint/class-methods-use-this
196
- async validate(output, taskId, expectedSourceArtificerArtifactId) {
214
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this, @typescript-eslint/max-params -- 4th param is the PRI-630 convergence context (mirrors EvaluatorValidator interface); a params object would break existing call sites
215
+ async validate(output, taskId, expectedSourceArtificerArtifactId, convergence) {
197
216
  const errors = [];
198
217
  if (!isRecord(output)) {
199
218
  return { valid: false, errors: ['Output is not an object'], errorCategory: 'output_invalid' };
@@ -236,6 +255,55 @@ export class DefaultEvaluatorValidator {
236
255
  errors.push('evaluation.requiredChanges must be an array');
237
256
  else if (!ev.requiredChanges.every((e) => typeof e === 'string'))
238
257
  errors.push('evaluation.requiredChanges must be an array of strings');
258
+ // PRI-630 (SPEC §18.4) schema invariant: needs_revision 必须携带至少一条
259
+ // 可执行修改 — 空清单的 revision 判定是裁决与依据脱节 (链 48371236 轮3)。
260
+ else if (ev.decision === 'needs_revision' && ev.requiredChanges.length === 0) {
261
+ errors.push('evaluation.requiredChanges must be non-empty when decision is needs_revision (PRI-630 convergence invariant)');
262
+ }
263
+ // PRI-630 (SPEC §18.2): 上轮需求核销 — 结构校验 + id/status 枚举
264
+ if (Object.hasOwn(ev, 'priorRequirementStatuses') && ev.priorRequirementStatuses !== undefined) {
265
+ if (!Array.isArray(ev.priorRequirementStatuses)) {
266
+ errors.push('evaluation.priorRequirementStatuses must be an array');
267
+ }
268
+ else {
269
+ for (const entry of ev.priorRequirementStatuses) {
270
+ if (!isRecord(entry)) {
271
+ errors.push('evaluation.priorRequirementStatuses entries must be objects');
272
+ break;
273
+ }
274
+ if (typeof entry.id !== 'string' || entry.id.trim() === '') {
275
+ errors.push('evaluation.priorRequirementStatuses entries must have non-empty id');
276
+ }
277
+ if (entry.status !== 'resolved' && entry.status !== 'still_open' && entry.status !== 'regressed') {
278
+ errors.push(`evaluation.priorRequirementStatuses status must be resolved/still_open/regressed, got ${String(entry.status)}`);
279
+ }
280
+ }
281
+ }
282
+ }
283
+ // PRI-630 P1 评审修复: requirementLedger 结构校验 (id/statement 非空,
284
+ // status 枚举;『new』是上下文构建侧的状态,evaluator 输出不含)
285
+ if (Object.hasOwn(ev, 'requirementLedger') && ev.requirementLedger !== undefined) {
286
+ if (!Array.isArray(ev.requirementLedger)) {
287
+ errors.push('evaluation.requirementLedger must be an array');
288
+ }
289
+ else {
290
+ for (const entry of ev.requirementLedger) {
291
+ if (!isRecord(entry)) {
292
+ errors.push('evaluation.requirementLedger entries must be objects');
293
+ break;
294
+ }
295
+ if (typeof entry.id !== 'string' || entry.id.trim() === '') {
296
+ errors.push('evaluation.requirementLedger entries must have non-empty id');
297
+ }
298
+ if (typeof entry.statement !== 'string' || entry.statement.trim() === '') {
299
+ errors.push('evaluation.requirementLedger entries must have non-empty statement');
300
+ }
301
+ if (entry.status !== 'resolved' && entry.status !== 'still_open' && entry.status !== 'regressed') {
302
+ errors.push(`evaluation.requirementLedger status must be resolved/still_open/regressed, got ${String(entry.status)}`);
303
+ }
304
+ }
305
+ }
306
+ }
239
307
  }
240
308
  if (!Object.hasOwn(output, 'sourceTrace') || !isRecord(output.sourceTrace)) {
241
309
  errors.push('sourceTrace must be an object');
@@ -285,6 +353,75 @@ export class DefaultEvaluatorValidator {
285
353
  if (Object.hasOwn(output, 'adversarialResult')) {
286
354
  errors.push(...validateAdversarialResult(output.adversarialResult));
287
355
  }
356
+ // 评审轮 2 P1: requirementLedger 从 prompt-only echo 收紧为
357
+ // validator-enforced authoritative contract (机器可验证,不再依赖模型自觉):
358
+ // statuses — 每个 expected id 恰好一次 (不缺、不重复、无幻觉 id)
359
+ // ledger — 必须存在;每个 expected id 恰好一次;不重编号 (额外 id 拒绝);
360
+ // statement 与上下文原文一致;status 与 statuses 同 id 一致
361
+ const expectedReqs = convergence?.expectedRequirements;
362
+ if (expectedReqs && expectedReqs.length > 0) {
363
+ const ev = (isRecord(output) && isRecord(output.evaluation)) ? output.evaluation : undefined;
364
+ const statuses = ev && Array.isArray(ev.priorRequirementStatuses) ? ev.priorRequirementStatuses : undefined;
365
+ const ledger = ev && Array.isArray(ev.requirementLedger) ? ev.requirementLedger : undefined;
366
+ if (!statuses) {
367
+ errors.push('evaluation.priorRequirementStatuses is required in a repair round (previous evaluation context was provided)');
368
+ }
369
+ if (!ledger) {
370
+ errors.push('evaluation.requirementLedger is required in a repair round (previous evaluation context was provided)');
371
+ }
372
+ if (statuses && ledger) {
373
+ const statusById = new Map();
374
+ for (const entry of statuses) {
375
+ if (!isRecord(entry) || typeof entry.id !== 'string')
376
+ continue;
377
+ const prev = statusById.get(entry.id) ?? { count: 0, status: entry.status };
378
+ statusById.set(entry.id, { count: prev.count + 1, status: entry.status });
379
+ }
380
+ const ledgerById = new Map();
381
+ for (const entry of ledger) {
382
+ if (!isRecord(entry) || typeof entry.id !== 'string')
383
+ continue;
384
+ const prev = ledgerById.get(entry.id) ?? { count: 0, statement: entry.statement, status: entry.status };
385
+ ledgerById.set(entry.id, { count: prev.count + 1, statement: entry.statement, status: entry.status });
386
+ }
387
+ for (const expected of expectedReqs) {
388
+ const st = statusById.get(expected.id);
389
+ if (st === undefined || st.count === 0) {
390
+ errors.push(`evaluation.priorRequirementStatuses must cover prior requirement id ${expected.id} (missing)`);
391
+ }
392
+ else if (st.count > 1) {
393
+ errors.push(`evaluation.priorRequirementStatuses id ${expected.id} must appear exactly once (got ${st.count})`);
394
+ }
395
+ const lg = ledgerById.get(expected.id);
396
+ if (lg === undefined || lg.count === 0) {
397
+ errors.push(`evaluation.requirementLedger must cover prior requirement id ${expected.id} (missing or renumbered)`);
398
+ }
399
+ else if (lg.count > 1) {
400
+ errors.push(`evaluation.requirementLedger id ${expected.id} must appear exactly once (got ${lg.count})`);
401
+ }
402
+ else {
403
+ if (lg.statement !== expected.statement) {
404
+ errors.push(`evaluation.requirementLedger statement for ${expected.id} must match the authoritative context verbatim (got ${String(lg.statement)})`);
405
+ }
406
+ if (st !== undefined && st.count === 1 && lg.status !== st.status) {
407
+ errors.push(`evaluation.requirementLedger status for ${expected.id} (${String(lg.status)}) must match priorRequirementStatuses (${String(st.status)})`);
408
+ }
409
+ }
410
+ }
411
+ // 幻觉/重编号 id: expected 之外的任何 id 都不允许 (echo 契约)
412
+ const expectedIdSet = new Set(expectedReqs.map((e) => e.id));
413
+ for (const [id] of statusById) {
414
+ if (!expectedIdSet.has(id)) {
415
+ errors.push(`evaluation.priorRequirementStatuses has unexpected id ${id} (not in prior context — renumbering/fabrication)`);
416
+ }
417
+ }
418
+ for (const [id] of ledgerById) {
419
+ if (!expectedIdSet.has(id)) {
420
+ errors.push(`evaluation.requirementLedger has unexpected id ${id} (not in prior context — renumbering/fabrication)`);
421
+ }
422
+ }
423
+ }
424
+ }
288
425
  return errors.length > 0
289
426
  ? { valid: false, errors, errorCategory: 'output_invalid' }
290
427
  : { valid: true, errors: [] };