create-principles-disciple 1.95.0 → 1.97.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 (263) hide show
  1. package/console/dist/server/config/pd-config-store.js +49 -12
  2. package/console/dist/server/index.js +4 -3
  3. package/console/dist/server/models/IntentPageModel.d.ts +36 -2
  4. package/console/dist/server/models/IntentPageModel.js +213 -11
  5. package/console/dist/server/routes/intent.d.ts +5 -1
  6. package/console/dist/server/routes/intent.js +200 -12
  7. package/console/dist/types.d.ts +1 -0
  8. package/console/dist/ui/App.js +0 -53
  9. package/console/dist/ui/api.d.ts +18 -4
  10. package/console/dist/ui/api.js +38 -5
  11. package/console/dist/ui/components/layout/app-sidebar.js +12 -12
  12. package/console/dist/ui/components/ui/badge.d.ts +1 -1
  13. package/console/dist/ui/i18n/en.json +142 -3
  14. package/console/dist/ui/i18n/zh-CN.json +142 -3
  15. package/console/dist/ui/pages/control-center/AgentCard.d.ts +31 -0
  16. package/console/dist/ui/pages/control-center/AgentCard.js +156 -0
  17. package/console/dist/ui/pages/control-center/AgentGroup.d.ts +26 -0
  18. package/console/dist/ui/pages/control-center/AgentGroup.js +38 -0
  19. package/console/dist/ui/pages/control-center/ControlCenterPage.js +77 -41
  20. package/console/dist/ui/pages/control-center/WorkflowDiagram.d.ts +17 -0
  21. package/console/dist/ui/pages/control-center/WorkflowDiagram.js +55 -0
  22. package/console/dist/ui/pages/intent/IntentOnboarding.d.ts +67 -0
  23. package/console/dist/ui/pages/intent/IntentOnboarding.js +289 -0
  24. package/console/dist/ui/pages/intent/IntentPage.js +117 -6
  25. package/console/dist/ui/utils/agent-metadata.d.ts +58 -0
  26. package/console/dist/ui/utils/agent-metadata.js +275 -0
  27. package/console/dist/ui/utils/control-center-helpers.d.ts +19 -0
  28. package/console/dist/ui/utils/control-center-helpers.js +37 -0
  29. package/console/dist/ui/utils/validators.d.ts +37 -0
  30. package/console/dist/ui/utils/validators.js +130 -0
  31. package/console/dist/web/assets/app.css +360 -3
  32. package/console/dist/web/assets/app.js +2952 -1143
  33. package/console/package.json +1 -1
  34. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +27 -35
  35. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  36. package/core/dist/runtime-v2/__tests__/evaluator-runner-vslice-v2.test.js +85 -7
  37. package/core/dist/runtime-v2/__tests__/evaluator-runner-vslice-v2.test.js.map +1 -1
  38. package/core/dist/runtime-v2/__tests__/golden-trace-replay-validator.test.js +70 -0
  39. package/core/dist/runtime-v2/__tests__/golden-trace-replay-validator.test.js.map +1 -1
  40. package/core/dist/runtime-v2/__tests__/golden-trace.test.js +136 -1
  41. package/core/dist/runtime-v2/__tests__/golden-trace.test.js.map +1 -1
  42. package/core/dist/runtime-v2/__tests__/v2-adversarial-cases.test.d.ts +2 -0
  43. package/core/dist/runtime-v2/__tests__/v2-adversarial-cases.test.d.ts.map +1 -0
  44. package/core/dist/runtime-v2/__tests__/v2-adversarial-cases.test.js +211 -0
  45. package/core/dist/runtime-v2/__tests__/v2-adversarial-cases.test.js.map +1 -0
  46. package/core/dist/runtime-v2/activation/writers/__tests__/rule-host-writer.test.js +93 -0
  47. package/core/dist/runtime-v2/activation/writers/__tests__/rule-host-writer.test.js.map +1 -1
  48. package/core/dist/runtime-v2/activation/writers/rule-host-writer.d.ts +11 -0
  49. package/core/dist/runtime-v2/activation/writers/rule-host-writer.d.ts.map +1 -1
  50. package/core/dist/runtime-v2/activation/writers/rule-host-writer.js +22 -0
  51. package/core/dist/runtime-v2/activation/writers/rule-host-writer.js.map +1 -1
  52. package/core/dist/runtime-v2/feature-flags/__tests__/rulecode-context-v2-flag.test.d.ts +2 -0
  53. package/core/dist/runtime-v2/feature-flags/__tests__/rulecode-context-v2-flag.test.d.ts.map +1 -0
  54. package/core/dist/runtime-v2/feature-flags/__tests__/rulecode-context-v2-flag.test.js +74 -0
  55. package/core/dist/runtime-v2/feature-flags/__tests__/rulecode-context-v2-flag.test.js.map +1 -0
  56. package/core/dist/runtime-v2/feature-flags/__tests__/surface-guard-policy.test.d.ts +2 -0
  57. package/core/dist/runtime-v2/feature-flags/__tests__/surface-guard-policy.test.d.ts.map +1 -0
  58. package/core/dist/runtime-v2/feature-flags/__tests__/surface-guard-policy.test.js +246 -0
  59. package/core/dist/runtime-v2/feature-flags/__tests__/surface-guard-policy.test.js.map +1 -0
  60. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
  61. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +7 -0
  62. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
  63. package/core/dist/runtime-v2/feature-flags/index.d.ts +2 -0
  64. package/core/dist/runtime-v2/feature-flags/index.d.ts.map +1 -1
  65. package/core/dist/runtime-v2/feature-flags/index.js +2 -0
  66. package/core/dist/runtime-v2/feature-flags/index.js.map +1 -1
  67. package/{plugin/dist/core/surface-guard.d.ts → core/dist/runtime-v2/feature-flags/surface-guard-policy.d.ts} +15 -5
  68. package/core/dist/runtime-v2/feature-flags/surface-guard-policy.d.ts.map +1 -0
  69. package/{plugin/dist/core/surface-guard.js → core/dist/runtime-v2/feature-flags/surface-guard-policy.js} +14 -2
  70. package/core/dist/runtime-v2/feature-flags/surface-guard-policy.js.map +1 -0
  71. package/core/dist/runtime-v2/golden-trace-replay-validator.js +1 -1
  72. package/core/dist/runtime-v2/golden-trace-replay-validator.js.map +1 -1
  73. package/core/dist/runtime-v2/golden-trace.d.ts +19 -3
  74. package/core/dist/runtime-v2/golden-trace.d.ts.map +1 -1
  75. package/core/dist/runtime-v2/golden-trace.js +2 -0
  76. package/core/dist/runtime-v2/golden-trace.js.map +1 -1
  77. package/core/dist/runtime-v2/index.d.ts +15 -3
  78. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  79. package/core/dist/runtime-v2/index.js +11 -2
  80. package/core/dist/runtime-v2/index.js.map +1 -1
  81. package/core/dist/runtime-v2/intent/__tests__/intent-doc-version.test.d.ts +2 -0
  82. package/core/dist/runtime-v2/intent/__tests__/intent-doc-version.test.d.ts.map +1 -0
  83. package/core/dist/runtime-v2/intent/__tests__/intent-doc-version.test.js +88 -0
  84. package/core/dist/runtime-v2/intent/__tests__/intent-doc-version.test.js.map +1 -0
  85. package/core/dist/runtime-v2/intent/__tests__/intent-doc.test.js +91 -1
  86. package/core/dist/runtime-v2/intent/__tests__/intent-doc.test.js.map +1 -1
  87. package/core/dist/runtime-v2/intent/index.d.ts +2 -0
  88. package/core/dist/runtime-v2/intent/index.d.ts.map +1 -1
  89. package/core/dist/runtime-v2/intent/index.js +2 -0
  90. package/core/dist/runtime-v2/intent/index.js.map +1 -1
  91. package/core/dist/runtime-v2/intent/intent-browser.d.ts +23 -0
  92. package/core/dist/runtime-v2/intent/intent-browser.d.ts.map +1 -0
  93. package/core/dist/runtime-v2/intent/intent-browser.js +21 -0
  94. package/core/dist/runtime-v2/intent/intent-browser.js.map +1 -0
  95. package/core/dist/runtime-v2/intent/intent-doc-version.d.ts +28 -0
  96. package/core/dist/runtime-v2/intent/intent-doc-version.d.ts.map +1 -0
  97. package/core/dist/runtime-v2/intent/intent-doc-version.js +21 -0
  98. package/core/dist/runtime-v2/intent/intent-doc-version.js.map +1 -0
  99. package/core/dist/runtime-v2/intent/intent-doc.d.ts +17 -1
  100. package/core/dist/runtime-v2/intent/intent-doc.d.ts.map +1 -1
  101. package/core/dist/runtime-v2/intent/intent-doc.js +95 -7
  102. package/core/dist/runtime-v2/intent/intent-doc.js.map +1 -1
  103. package/core/dist/runtime-v2/intent/intent-hash.d.ts +2 -0
  104. package/core/dist/runtime-v2/intent/intent-hash.d.ts.map +1 -0
  105. package/core/dist/runtime-v2/intent/intent-hash.js +10 -0
  106. package/core/dist/runtime-v2/intent/intent-hash.js.map +1 -0
  107. package/core/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder.test.js +41 -1
  108. package/core/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder.test.js.map +1 -1
  109. package/core/dist/runtime-v2/internalization/__tests__/artificer-rule-output.test.js +130 -2
  110. package/core/dist/runtime-v2/internalization/__tests__/artificer-rule-output.test.js.map +1 -1
  111. package/core/dist/runtime-v2/internalization/__tests__/behavior-example-pack.test.d.ts +2 -0
  112. package/core/dist/runtime-v2/internalization/__tests__/behavior-example-pack.test.d.ts.map +1 -0
  113. package/core/dist/runtime-v2/internalization/__tests__/behavior-example-pack.test.js +228 -0
  114. package/core/dist/runtime-v2/internalization/__tests__/behavior-example-pack.test.js.map +1 -0
  115. package/core/dist/runtime-v2/internalization/__tests__/diag-chain-e2e.test.js +41 -11
  116. package/core/dist/runtime-v2/internalization/__tests__/diag-chain-e2e.test.js.map +1 -1
  117. package/core/dist/runtime-v2/internalization/__tests__/refiner-sandbox-wrapper.test.js +135 -0
  118. package/core/dist/runtime-v2/internalization/__tests__/refiner-sandbox-wrapper.test.js.map +1 -1
  119. package/core/dist/runtime-v2/internalization/__tests__/rule-context-v2.test.d.ts +2 -0
  120. package/core/dist/runtime-v2/internalization/__tests__/rule-context-v2.test.d.ts.map +1 -0
  121. package/core/dist/runtime-v2/internalization/__tests__/rule-context-v2.test.js +449 -0
  122. package/core/dist/runtime-v2/internalization/__tests__/rule-context-v2.test.js.map +1 -0
  123. package/core/dist/runtime-v2/internalization/adversarial-case.d.ts.map +1 -1
  124. package/core/dist/runtime-v2/internalization/adversarial-case.js +24 -0
  125. package/core/dist/runtime-v2/internalization/adversarial-case.js.map +1 -1
  126. package/core/dist/runtime-v2/internalization/artificer-output.d.ts +10 -0
  127. package/core/dist/runtime-v2/internalization/artificer-output.d.ts.map +1 -1
  128. package/core/dist/runtime-v2/internalization/artificer-output.js +45 -0
  129. package/core/dist/runtime-v2/internalization/artificer-output.js.map +1 -1
  130. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts +2 -2
  131. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts.map +1 -1
  132. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js +7 -2
  133. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js.map +1 -1
  134. package/core/dist/runtime-v2/internalization/behavior-example-pack.d.ts +66 -0
  135. package/core/dist/runtime-v2/internalization/behavior-example-pack.d.ts.map +1 -0
  136. package/core/dist/runtime-v2/internalization/behavior-example-pack.js +183 -0
  137. package/core/dist/runtime-v2/internalization/behavior-example-pack.js.map +1 -0
  138. package/core/dist/runtime-v2/internalization/evaluator-output.d.ts +8 -0
  139. package/core/dist/runtime-v2/internalization/evaluator-output.d.ts.map +1 -1
  140. package/core/dist/runtime-v2/internalization/evaluator-output.js +10 -0
  141. package/core/dist/runtime-v2/internalization/evaluator-output.js.map +1 -1
  142. package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts +17 -0
  143. package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
  144. package/core/dist/runtime-v2/internalization/evaluator-runner.js +118 -24
  145. package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
  146. package/core/dist/runtime-v2/internalization/refiner-sandbox-wrapper.d.ts.map +1 -1
  147. package/core/dist/runtime-v2/internalization/refiner-sandbox-wrapper.js +1 -1
  148. package/core/dist/runtime-v2/internalization/refiner-sandbox-wrapper.js.map +1 -1
  149. package/core/dist/runtime-v2/internalization/rule-context-v2.d.ts +61 -0
  150. package/core/dist/runtime-v2/internalization/rule-context-v2.d.ts.map +1 -0
  151. package/core/dist/runtime-v2/internalization/rule-context-v2.js +301 -0
  152. package/core/dist/runtime-v2/internalization/rule-context-v2.js.map +1 -0
  153. package/core/dist/runtime-v2/internalization/rule-host-contracts.d.ts +9 -0
  154. package/core/dist/runtime-v2/internalization/rule-host-contracts.d.ts.map +1 -1
  155. package/core/dist/runtime-v2/internalization/v2-adversarial-cases.d.ts +55 -0
  156. package/core/dist/runtime-v2/internalization/v2-adversarial-cases.d.ts.map +1 -0
  157. package/core/dist/runtime-v2/internalization/v2-adversarial-cases.js +131 -0
  158. package/core/dist/runtime-v2/internalization/v2-adversarial-cases.js.map +1 -0
  159. package/core/dist/runtime-v2/pain-signal-observability.d.ts.map +1 -1
  160. package/core/dist/runtime-v2/pain-signal-observability.js +24 -1
  161. package/core/dist/runtime-v2/pain-signal-observability.js.map +1 -1
  162. package/core/dist/runtime-v2/risk/__tests__/risk-calculator-policy.test.d.ts +2 -0
  163. package/core/dist/runtime-v2/risk/__tests__/risk-calculator-policy.test.d.ts.map +1 -0
  164. package/core/dist/runtime-v2/risk/__tests__/risk-calculator-policy.test.js +95 -0
  165. package/core/dist/runtime-v2/risk/__tests__/risk-calculator-policy.test.js.map +1 -0
  166. package/core/dist/runtime-v2/risk/index.d.ts +7 -0
  167. package/core/dist/runtime-v2/risk/index.d.ts.map +1 -0
  168. package/core/dist/runtime-v2/risk/index.js +6 -0
  169. package/core/dist/runtime-v2/risk/index.js.map +1 -0
  170. package/core/dist/runtime-v2/risk/risk-calculator-policy.d.ts +18 -0
  171. package/core/dist/runtime-v2/risk/risk-calculator-policy.d.ts.map +1 -0
  172. package/core/dist/runtime-v2/risk/risk-calculator-policy.js +47 -0
  173. package/core/dist/runtime-v2/risk/risk-calculator-policy.js.map +1 -0
  174. package/core/dist/runtime-v2/store/intent/__tests__/sqlite-intent-doc-version-store.test.d.ts +2 -0
  175. package/core/dist/runtime-v2/store/intent/__tests__/sqlite-intent-doc-version-store.test.d.ts.map +1 -0
  176. package/core/dist/runtime-v2/store/intent/__tests__/sqlite-intent-doc-version-store.test.js +83 -0
  177. package/core/dist/runtime-v2/store/intent/__tests__/sqlite-intent-doc-version-store.test.js.map +1 -0
  178. package/core/dist/runtime-v2/store/intent/index.d.ts +2 -1
  179. package/core/dist/runtime-v2/store/intent/index.d.ts.map +1 -1
  180. package/core/dist/runtime-v2/store/intent/index.js +2 -1
  181. package/core/dist/runtime-v2/store/intent/index.js.map +1 -1
  182. package/core/dist/runtime-v2/store/intent/sqlite-intent-doc-version-store.d.ts +28 -0
  183. package/core/dist/runtime-v2/store/intent/sqlite-intent-doc-version-store.d.ts.map +1 -0
  184. package/core/dist/runtime-v2/store/intent/sqlite-intent-doc-version-store.js +88 -0
  185. package/core/dist/runtime-v2/store/intent/sqlite-intent-doc-version-store.js.map +1 -0
  186. package/core/dist/runtime-v2/store/sqlite-connection.d.ts.map +1 -1
  187. package/core/dist/runtime-v2/store/sqlite-connection.js +14 -0
  188. package/core/dist/runtime-v2/store/sqlite-connection.js.map +1 -1
  189. package/core/dist/runtime-v2/thinking-models/__tests__/thinking-models-policy.test.d.ts +2 -0
  190. package/core/dist/runtime-v2/thinking-models/__tests__/thinking-models-policy.test.d.ts.map +1 -0
  191. package/core/dist/runtime-v2/thinking-models/__tests__/thinking-models-policy.test.js +149 -0
  192. package/core/dist/runtime-v2/thinking-models/__tests__/thinking-models-policy.test.js.map +1 -0
  193. package/core/dist/runtime-v2/thinking-models/index.d.ts +3 -0
  194. package/core/dist/runtime-v2/thinking-models/index.d.ts.map +1 -0
  195. package/core/dist/runtime-v2/thinking-models/index.js +3 -0
  196. package/core/dist/runtime-v2/thinking-models/index.js.map +1 -0
  197. package/core/dist/runtime-v2/thinking-models/thinking-models-policy.d.ts +73 -0
  198. package/core/dist/runtime-v2/thinking-models/thinking-models-policy.d.ts.map +1 -0
  199. package/core/dist/runtime-v2/thinking-models/thinking-models-policy.js +227 -0
  200. package/core/dist/runtime-v2/thinking-models/thinking-models-policy.js.map +1 -0
  201. package/core/dist/runtime-v2/tools/__tests__/artificer-l2-tool-contract.test.js +40 -1
  202. package/core/dist/runtime-v2/tools/__tests__/artificer-l2-tool-contract.test.js.map +1 -1
  203. package/core/dist/runtime-v2/tools/artificer-l2-tool-contract.d.ts.map +1 -1
  204. package/core/dist/runtime-v2/tools/artificer-l2-tool-contract.js +28 -1
  205. package/core/dist/runtime-v2/tools/artificer-l2-tool-contract.js.map +1 -1
  206. package/core/dist/runtime-v2/tools/artificer-output-typebox.d.ts +3 -0
  207. package/core/dist/runtime-v2/tools/artificer-output-typebox.d.ts.map +1 -1
  208. package/core/dist/runtime-v2/tools/artificer-output-typebox.js +3 -0
  209. package/core/dist/runtime-v2/tools/artificer-output-typebox.js.map +1 -1
  210. package/core/package.json +4 -0
  211. package/package.json +1 -1
  212. package/pd-cli/dist/commands/__tests__/intent-flag-wiring.test.js +74 -3
  213. package/pd-cli/dist/commands/__tests__/intent-flag-wiring.test.js.map +1 -1
  214. package/pd-cli/dist/commands/intent.d.ts +21 -4
  215. package/pd-cli/dist/commands/intent.d.ts.map +1 -1
  216. package/pd-cli/dist/commands/intent.js +88 -27
  217. package/pd-cli/dist/commands/intent.js.map +1 -1
  218. package/plugin/dist/commands/pain.js +2 -2
  219. package/plugin/dist/core/behavior-example-pack-assembler.d.ts +43 -0
  220. package/plugin/dist/core/behavior-example-pack-assembler.js +247 -0
  221. package/plugin/dist/core/intent-doc-reader-adapter.d.ts +13 -5
  222. package/plugin/dist/core/intent-doc-reader-adapter.js +25 -5
  223. package/plugin/dist/core/intent-doc-reader.d.ts +13 -4
  224. package/plugin/dist/core/intent-doc-reader.js +45 -24
  225. package/plugin/dist/core/rule-context-assembler.d.ts +45 -0
  226. package/plugin/dist/core/rule-context-assembler.js +148 -0
  227. package/plugin/dist/core/thinking-models.d.ts +12 -57
  228. package/plugin/dist/core/thinking-models.js +18 -224
  229. package/plugin/dist/core/trajectory-types.d.ts +18 -0
  230. package/plugin/dist/core/trajectory.d.ts +34 -2
  231. package/plugin/dist/core/trajectory.js +103 -0
  232. package/plugin/dist/hooks/gate.js +59 -2
  233. package/plugin/dist/hooks/pain.js +2 -2
  234. package/plugin/dist/hooks/prompt.js +2 -1
  235. package/plugin/dist/index.js +1 -1
  236. package/plugin/package.json +1 -1
  237. package/plugin/dist/core/evolution-migration.d.ts +0 -5
  238. package/plugin/dist/core/evolution-migration.js +0 -65
  239. package/plugin/dist/core/risk-calculator.d.ts +0 -22
  240. package/plugin/dist/core/risk-calculator.js +0 -88
  241. package/plugin/dist/core/rule-host-helpers.d.ts +0 -8
  242. package/plugin/dist/core/rule-host-helpers.js +0 -7
  243. package/plugin/dist/core/rule-host-types.d.ts +0 -7
  244. package/plugin/dist/core/rule-host-types.js +0 -7
  245. package/plugin/dist/core/schema/db-types.d.ts +0 -11
  246. package/plugin/dist/core/schema/db-types.js +0 -5
  247. package/plugin/dist/core/schema/index.d.ts +0 -17
  248. package/plugin/dist/core/schema/index.js +0 -15
  249. package/plugin/dist/core/schema/migration-runner.d.ts +0 -53
  250. package/plugin/dist/core/schema/migration-runner.js +0 -170
  251. package/plugin/dist/core/schema/migrations/001-init-trajectory.d.ts +0 -6
  252. package/plugin/dist/core/schema/migrations/001-init-trajectory.js +0 -190
  253. package/plugin/dist/core/schema/migrations/002-init-central.d.ts +0 -5
  254. package/plugin/dist/core/schema/migrations/002-init-central.js +0 -108
  255. package/plugin/dist/core/schema/migrations/003-init-workflow.d.ts +0 -5
  256. package/plugin/dist/core/schema/migrations/003-init-workflow.js +0 -50
  257. package/plugin/dist/core/schema/migrations/004-add-thinking-and-gfi.d.ts +0 -8
  258. package/plugin/dist/core/schema/migrations/004-add-thinking-and-gfi.js +0 -66
  259. package/plugin/dist/core/schema/migrations/index.d.ts +0 -16
  260. package/plugin/dist/core/schema/migrations/index.js +0 -27
  261. package/plugin/dist/core/schema/schema-definitions.d.ts +0 -46
  262. package/plugin/dist/core/schema/schema-definitions.js +0 -599
  263. package/plugin/scripts/db-migrate.mjs +0 -170
@@ -0,0 +1,301 @@
1
+ /**
2
+ * PRI-480 — Phase 1 Core ABI (rule-context-v2.ts)
3
+ *
4
+ * Pure logic: types + canonicalize + validators + behavior-facts computation.
5
+ * Zero I/O — this module MUST NOT import node:fs / node:path / better-sqlite3 /
6
+ * any network module. The runtime-v2 architecture-regression test enforces the
7
+ * file boundary.
8
+ *
9
+ * Err-prevention:
10
+ * - ERR-001 (validate-as-unknown): every public validator takes `unknown` and
11
+ * validates structurally. No `as` bypass on parsed input.
12
+ * - ERR-076 (prototype-pollution / host-realm independence): structural checks
13
+ * use Object.keys + a PROTO_KEYS set. We never touch the host realm's
14
+ * prototype chain (no `instanceof`, no `in`).
15
+ * - rc-2: no `as` casts on parsed input.
16
+ * - rc-5: Object.hasOwn / Object.keys over the `in` operator.
17
+ *
18
+ * Spec: docs/superpowers/specs/2026-06-27-rulecode-context-vision-design.md §4.
19
+ */
20
+ // ── internal constants ─────────────────────────────────────────────────────
21
+ const CANONICAL_KINDS = new Set([
22
+ 'read',
23
+ 'search',
24
+ 'write',
25
+ 'execute',
26
+ 'agent',
27
+ 'other',
28
+ ]);
29
+ const EVIDENCE_STATES = new Set(['yes', 'no', 'unknown']);
30
+ const TOOL_OUTCOMES = new Set(['success', 'failure', 'blocked']);
31
+ const HISTORY_STATUSES = new Set(['available', 'unavailable']);
32
+ const PROTO_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
33
+ const OK_RESULT = { valid: true, errors: [] };
34
+ function fail(errors) {
35
+ return errors.length === 0 ? OK_RESULT : { valid: false, errors };
36
+ }
37
+ function isPlainObjectLike(value) {
38
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
39
+ }
40
+ function hasNoProtoKeys(value) {
41
+ for (const key of Object.keys(value)) {
42
+ if (PROTO_KEYS.has(key))
43
+ return false;
44
+ }
45
+ return true;
46
+ }
47
+ function isFiniteNumber(value) {
48
+ return typeof value === 'number' && Number.isFinite(value);
49
+ }
50
+ function isNullOrNonNegativeFinite(value) {
51
+ return value === null || (typeof value === 'number' && Number.isFinite(value) && value >= 0);
52
+ }
53
+ // ── canonicalizeToolKind (static alias table, spec §4.4) ────────────────────
54
+ //
55
+ // NOTE: the authoritative source for canonical kinds SHOULD be a host declaration
56
+ // (spec §4.4 anti-drift note), so that `core` never owns a growing hardcoded
57
+ // tool list. The first version uses a static alias table (ticket-bounded); a
58
+ // later phase will let hosts declare `ruleCanonicalKind` overrides. core only
59
+ // owns the CLOSED CanonicalKind enum + this pure lookup function.
60
+ const TOOL_ALIAS = {
61
+ read: 'read',
62
+ read_file: 'read',
63
+ read_many_files: 'read',
64
+ grep: 'search',
65
+ grep_search: 'search',
66
+ search_file_content: 'search',
67
+ glob: 'search',
68
+ write: 'write',
69
+ write_file: 'write',
70
+ edit: 'write',
71
+ edit_file: 'write',
72
+ replace: 'write',
73
+ apply_patch: 'write',
74
+ bash: 'execute',
75
+ exec: 'execute',
76
+ execute: 'execute',
77
+ run_shell_command: 'execute',
78
+ sessions_spawn: 'agent',
79
+ };
80
+ export function canonicalizeToolKind(toolName) {
81
+ if (typeof toolName !== 'string')
82
+ return 'other';
83
+ // ERR-076: Object.hasOwn guards against inherited Object.prototype keys
84
+ // (__proto__, constructor, toString, hasOwnProperty, ...) that direct
85
+ // indexing would otherwise leak as non-CanonicalKind values (e.g. the
86
+ // Object.prototype object, the Object constructor function). Without this
87
+ // guard `TOOL_ALIAS['__proto__']` returns Object.prototype, not undefined.
88
+ if (!Object.hasOwn(TOOL_ALIAS, toolName))
89
+ return 'other';
90
+ const hit = TOOL_ALIAS[toolName];
91
+ return hit !== undefined ? hit : 'other';
92
+ }
93
+ // ── validators ─────────────────────────────────────────────────────────────
94
+ export function validateRuleToolCallRecord(value) {
95
+ if (!isPlainObjectLike(value)) {
96
+ return { valid: false, errors: ['record must be a plain object'] };
97
+ }
98
+ if (!hasNoProtoKeys(value)) {
99
+ return { valid: false, errors: ['record must not carry prototype-pollution keys'] };
100
+ }
101
+ const errors = [];
102
+ if (!isFiniteNumber(value.sequenceId)) {
103
+ errors.push('sequenceId must be a finite number');
104
+ }
105
+ const { toolName } = value;
106
+ if (typeof toolName !== 'string' || toolName.length === 0) {
107
+ errors.push('toolName must be a non-empty string');
108
+ }
109
+ const { canonicalKind } = value;
110
+ if (typeof canonicalKind !== 'string' || !CANONICAL_KINDS.has(canonicalKind)) {
111
+ errors.push('canonicalKind must be a valid CanonicalKind');
112
+ }
113
+ const { normalizedPath } = value;
114
+ if (normalizedPath !== null && typeof normalizedPath !== 'string') {
115
+ errors.push('normalizedPath must be a string or null');
116
+ }
117
+ if (!isPlainObjectLike(value.paramsSummary)) {
118
+ errors.push('paramsSummary must be a plain object');
119
+ }
120
+ const { outcome } = value;
121
+ if (typeof outcome !== 'string' || !TOOL_OUTCOMES.has(outcome)) {
122
+ errors.push('outcome must be success | failure | blocked');
123
+ }
124
+ return fail(errors);
125
+ }
126
+ export function validateRuleHistoryWindow(value) {
127
+ if (!isPlainObjectLike(value)) {
128
+ return { valid: false, errors: ['history window must be a plain object'] };
129
+ }
130
+ if (!hasNoProtoKeys(value)) {
131
+ return { valid: false, errors: ['history window must not carry prototype-pollution keys'] };
132
+ }
133
+ const errors = [];
134
+ const { status } = value;
135
+ if (typeof status !== 'string' || !HISTORY_STATUSES.has(status)) {
136
+ errors.push('status must be available | unavailable');
137
+ }
138
+ const { unavailableReason } = value;
139
+ if (unavailableReason !== undefined && typeof unavailableReason !== 'string') {
140
+ errors.push('unavailableReason must be a string or undefined');
141
+ }
142
+ if (typeof value.truncated !== 'boolean') {
143
+ errors.push('truncated must be a boolean');
144
+ }
145
+ const { calls } = value;
146
+ if (!Array.isArray(calls)) {
147
+ errors.push('calls must be an array');
148
+ }
149
+ else {
150
+ for (let i = 0; i < calls.length; i++) {
151
+ const recordResult = validateRuleToolCallRecord(calls[i]);
152
+ if (!recordResult.valid) {
153
+ errors.push(`calls[${i}] invalid: ${recordResult.errors.join('; ')}`);
154
+ }
155
+ }
156
+ }
157
+ return fail(errors);
158
+ }
159
+ export function validateRuleBehaviorFacts(value) {
160
+ if (!isPlainObjectLike(value)) {
161
+ return { valid: false, errors: ['facts must be a plain object'] };
162
+ }
163
+ if (!hasNoProtoKeys(value)) {
164
+ return { valid: false, errors: ['facts must not carry prototype-pollution keys'] };
165
+ }
166
+ const errors = [];
167
+ const { priorReadOfTarget } = value;
168
+ if (typeof priorReadOfTarget !== 'string' || !EVIDENCE_STATES.has(priorReadOfTarget)) {
169
+ errors.push('priorReadOfTarget must be yes | no | unknown');
170
+ }
171
+ if (!isNullOrNonNegativeFinite(value.readCount)) {
172
+ errors.push('readCount must be a non-negative finite number or null');
173
+ }
174
+ if (!isNullOrNonNegativeFinite(value.writeCount)) {
175
+ errors.push('writeCount must be a non-negative finite number or null');
176
+ }
177
+ if (!isNullOrNonNegativeFinite(value.uniqueWritePathCount)) {
178
+ errors.push('uniqueWritePathCount must be a non-negative finite number or null');
179
+ }
180
+ if (!isNullOrNonNegativeFinite(value.sameActionBlockCount)) {
181
+ errors.push('sameActionBlockCount must be a non-negative finite number or null');
182
+ }
183
+ return fail(errors);
184
+ }
185
+ export function validateRuleContextV2(value) {
186
+ if (!isPlainObjectLike(value)) {
187
+ return { valid: false, errors: ['context must be a plain object'] };
188
+ }
189
+ if (!hasNoProtoKeys(value)) {
190
+ return { valid: false, errors: ['context must not carry prototype-pollution keys'] };
191
+ }
192
+ const errors = [];
193
+ if (value.version !== 2) {
194
+ errors.push('version must be 2');
195
+ }
196
+ const historyResult = validateRuleHistoryWindow(value.history);
197
+ if (!historyResult.valid) {
198
+ errors.push(`history invalid: ${historyResult.errors.join('; ')}`);
199
+ }
200
+ const factsResult = validateRuleBehaviorFacts(value.facts);
201
+ if (!factsResult.valid) {
202
+ errors.push(`facts invalid: ${factsResult.errors.join('; ')}`);
203
+ }
204
+ // Unavailable invariant (acceptance C): when history.status === 'unavailable',
205
+ // facts MUST be the canonical unavailable posture — priorReadOfTarget='unknown'
206
+ // and every count null. Any drift is rejected so downstream gates can't be
207
+ // fooled by a host that fabricates numbers while claiming history is missing.
208
+ const { history } = value;
209
+ const { facts } = value;
210
+ if (historyResult.valid &&
211
+ factsResult.valid &&
212
+ isPlainObjectLike(history) &&
213
+ isPlainObjectLike(facts) &&
214
+ history.status === 'unavailable') {
215
+ if (facts.priorReadOfTarget !== 'unknown') {
216
+ errors.push('unavailable invariant: priorReadOfTarget must be "unknown" when history is unavailable');
217
+ }
218
+ if (facts.readCount !== null) {
219
+ errors.push('unavailable invariant: readCount must be null when history is unavailable');
220
+ }
221
+ if (facts.writeCount !== null) {
222
+ errors.push('unavailable invariant: writeCount must be null when history is unavailable');
223
+ }
224
+ if (facts.uniqueWritePathCount !== null) {
225
+ errors.push('unavailable invariant: uniqueWritePathCount must be null when history is unavailable');
226
+ }
227
+ if (facts.sameActionBlockCount !== null) {
228
+ errors.push('unavailable invariant: sameActionBlockCount must be null when history is unavailable');
229
+ }
230
+ }
231
+ return fail(errors);
232
+ }
233
+ // ── computeBehaviorFacts (pure) ────────────────────────────────────────────
234
+ export function computeBehaviorFacts(window, targetPath, sameActionBlockCount) {
235
+ if (window.status === 'unavailable') {
236
+ return {
237
+ priorReadOfTarget: 'unknown',
238
+ readCount: null,
239
+ writeCount: null,
240
+ uniqueWritePathCount: null,
241
+ sameActionBlockCount: null,
242
+ };
243
+ }
244
+ let readCount = 0;
245
+ let writeCount = 0;
246
+ const writePaths = new Set();
247
+ let priorReadOfTarget = targetPath === null ? 'unknown' : 'no';
248
+ const { calls } = window;
249
+ for (const call of calls) {
250
+ const kind = call.canonicalKind;
251
+ if (kind === 'read' || kind === 'search') {
252
+ readCount++;
253
+ if (targetPath !== null && call.normalizedPath === targetPath) {
254
+ priorReadOfTarget = 'yes';
255
+ }
256
+ }
257
+ else if (kind === 'write') {
258
+ writeCount++;
259
+ if (typeof call.normalizedPath === 'string') {
260
+ writePaths.add(call.normalizedPath);
261
+ }
262
+ }
263
+ }
264
+ return {
265
+ priorReadOfTarget,
266
+ readCount,
267
+ writeCount,
268
+ uniqueWritePathCount: writePaths.size,
269
+ sameActionBlockCount,
270
+ };
271
+ }
272
+ // ── UNAVAILABLE_RULE_CONTEXT sentinel (deep-frozen) ────────────────────────
273
+ //
274
+ // The canonical "host gave us no history" context. Downstream code compares
275
+ // against this (or checks history.status) instead of null-checking, so the
276
+ // unavailable posture is always well-typed. Deep-frozen so a buggy host cannot
277
+ // mutate the shared sentinel and poison every subsequent rule evaluation.
278
+ const _UNAVAILABLE_FACTS = {
279
+ priorReadOfTarget: 'unknown',
280
+ readCount: null,
281
+ writeCount: null,
282
+ uniqueWritePathCount: null,
283
+ sameActionBlockCount: null,
284
+ };
285
+ Object.freeze(_UNAVAILABLE_FACTS);
286
+ const _UNAVAILABLE_HISTORY = {
287
+ status: 'unavailable',
288
+ unavailableReason: 'host did not provide a history window',
289
+ truncated: false,
290
+ calls: [],
291
+ };
292
+ Object.freeze(_UNAVAILABLE_HISTORY.calls);
293
+ Object.freeze(_UNAVAILABLE_HISTORY);
294
+ const _UNAVAILABLE_VALUE = {
295
+ version: 2,
296
+ history: _UNAVAILABLE_HISTORY,
297
+ facts: _UNAVAILABLE_FACTS,
298
+ };
299
+ Object.freeze(_UNAVAILABLE_VALUE);
300
+ export const UNAVAILABLE_RULE_CONTEXT = _UNAVAILABLE_VALUE;
301
+ //# sourceMappingURL=rule-context-v2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule-context-v2.js","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/rule-context-v2.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@
11
11
  * - No filesystem, process, require, dynamic import, eval, or network access
12
12
  */
13
13
  import type { CorrectionProposal } from './correction-proposal.js';
14
+ import type { RuleContextV2 } from './rule-context-v2.js';
14
15
  export interface RuleHostInput {
15
16
  action: {
16
17
  toolName: string;
@@ -34,6 +35,14 @@ export interface RuleHostInput {
34
35
  estimatedLineChanges: number;
35
36
  bashRisk: 'safe' | 'normal' | 'dangerous' | 'unknown';
36
37
  };
38
+ /**
39
+ * PRI-480 (RuleContext v2 — Phase 1): optional structured context describing
40
+ * the recent tool-call history and derived behavior facts. Optional on purpose
41
+ * — v1 rule implementations that never read this field see `undefined` and
42
+ * behave exactly as before. Hosts opt in by populating the field; downstream
43
+ * phases will gate new rule behavior on `context?.history.status === 'available'`.
44
+ */
45
+ context?: RuleContextV2;
37
46
  }
38
47
  export type RuleHostDecision = 'allow' | 'block' | 'requireApproval' | 'auto_correct';
39
48
  export interface RuleHostMeta {
@@ -1 +1 @@
1
- {"version":3,"file":"rule-host-contracts.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/rule-host-contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAMnE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACxC,CAAC;IACF,SAAS,EAAE;QACT,UAAU,EAAE,OAAO,CAAC;QACpB,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;QACnD,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,OAAO,EAAE;QACP,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,SAAS,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,EAAE;QACP,oBAAoB,EAAE,MAAM,CAAC;QAC7B,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;KACvD,CAAC;CACH;AAMD,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,OAAO,GAAG,iBAAiB,GAAG,cAAc,CAAC;AAMtF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;CACzB;AAMD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uFAAuF;IACvF,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAMD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,cAAc,CAAC;CACrD"}
1
+ {"version":3,"file":"rule-host-contracts.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/rule-host-contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAM1D,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACxC,CAAC;IACF,SAAS,EAAE;QACT,UAAU,EAAE,OAAO,CAAC;QACpB,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;QACnD,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,OAAO,EAAE;QACP,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,SAAS,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,EAAE;QACP,oBAAoB,EAAE,MAAM,CAAC;QAC7B,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;KACvD,CAAC;IACF;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAMD,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,OAAO,GAAG,iBAAiB,GAAG,cAAc,CAAC;AAMtF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;CACzB;AAMD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uFAAuF;IACvF,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAMD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,cAAc,CAAC;CACrD"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * PRI-485 Phase 6 — v2 adversarial case generator (pure logic).
3
+ *
4
+ * Auto-generates 5 deterministic adversarial cases that defend against the
5
+ * most common false-positive patterns when a RuleCode consumes a v2
6
+ * RuleContext. Each case carries a fabricated `ruleContext` that exercises
7
+ * one spec-defined edge (spec §7.4, §10.1):
8
+ *
9
+ * 1. v2-unavailable — host provided no history; rule must allow.
10
+ * 2. v2-truncated — history was truncated; rule must define a
11
+ * conservative (fail-open) strategy.
12
+ * 3. v2-alias — write_file after read_file on the same path must
13
+ * be allowed (canonicalKind match, not toolName).
14
+ * 4. v2-path-boundary — targetPath.bak must NOT be treated as a prior
15
+ * read of targetPath (no substring matching).
16
+ * 5. v2-combination — v2 priorRead=yes must NOT override a v1
17
+ * action-only risk-path block.
18
+ *
19
+ * Pure logic: zero I/O. The generated cases flow through the existing
20
+ * adversarialCasesToGoldenTrace → evaluateRefinerRuleHostGate path.
21
+ *
22
+ * Err-prevention:
23
+ * - ERR-069: generated cases share the AdversarialCase schema; the caller
24
+ * (Evaluator runner) validates them via DefaultEvaluatorValidator.
25
+ * - ERR-001 / rc-1 / rc-2: every ruleContext is a real RuleContextV2 value
26
+ * (UNAVAILABLE_RULE_CONTEXT sentinel or a freshly-built object that
27
+ * satisfies validateRuleContextV2). No `as` casts.
28
+ * - rc-9: every case carries a non-empty rationale explaining the edge.
29
+ *
30
+ * Spec: docs/superpowers/specs/2026-06-27-rulecode-context-vision-design.md
31
+ * §7.4 Evaluator responsibilities, §10.1 acceptance scenarios.
32
+ */
33
+ import type { CanonicalKind } from './rule-context-v2.js';
34
+ import type { AdversarialCase } from './evaluator-output.js';
35
+ /**
36
+ * Inputs the generator needs to fabricate path-realistic cases.
37
+ * - `toolName` is the action tool the rule governs (e.g. 'write_file').
38
+ * - `targetPath` is the workspace path used in positive cases.
39
+ * - `canonicalKind` is the canonical kind of `toolName` (caller pre-computes
40
+ * via canonicalizeToolKind so this module stays pure and doesn't re-import
41
+ * the alias table).
42
+ */
43
+ export interface V2AdversarialCaseSpec {
44
+ readonly toolName: string;
45
+ readonly targetPath: string;
46
+ readonly canonicalKind: CanonicalKind;
47
+ }
48
+ /**
49
+ * Generate the 5 canonical v2 adversarial cases for the given spec.
50
+ *
51
+ * The output is deterministic and stable in caseId order:
52
+ * v2-unavailable, v2-truncated, v2-alias, v2-path-boundary, v2-combination.
53
+ */
54
+ export declare function generateV2ContextAdversarialCases(spec: V2AdversarialCaseSpec): readonly AdversarialCase[];
55
+ //# sourceMappingURL=v2-adversarial-cases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2-adversarial-cases.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/v2-adversarial-cases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAQ1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;CACvC;AA6DD;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,qBAAqB,GAAG,SAAS,eAAe,EAAE,CAmGzG"}
@@ -0,0 +1,131 @@
1
+ import { UNAVAILABLE_RULE_CONTEXT, } from './rule-context-v2.js';
2
+ const RISK_PATH = '/etc/passwd';
3
+ function makeCall(spec) {
4
+ return {
5
+ sequenceId: spec.sequenceId,
6
+ toolName: spec.toolName,
7
+ canonicalKind: spec.canonicalKind,
8
+ normalizedPath: spec.normalizedPath,
9
+ paramsSummary: spec.normalizedPath !== null ? { path: spec.normalizedPath } : {},
10
+ outcome: 'success',
11
+ };
12
+ }
13
+ function makeHistory(spec) {
14
+ return {
15
+ status: spec.status,
16
+ truncated: spec.truncated,
17
+ calls: spec.calls,
18
+ ...(spec.unavailableReason !== undefined ? { unavailableReason: spec.unavailableReason } : {}),
19
+ };
20
+ }
21
+ function makeFacts(spec) {
22
+ // sameActionBlockCount is informational only; null is the canonical
23
+ // "host did not provide" value per the unavailable invariant.
24
+ return {
25
+ priorReadOfTarget: spec.priorReadOfTarget,
26
+ readCount: spec.readCount,
27
+ writeCount: spec.writeCount,
28
+ uniqueWritePathCount: spec.uniqueWritePathCount,
29
+ sameActionBlockCount: null,
30
+ };
31
+ }
32
+ function makeContext(history, facts) {
33
+ return { version: 2, history, facts };
34
+ }
35
+ /**
36
+ * Generate the 5 canonical v2 adversarial cases for the given spec.
37
+ *
38
+ * The output is deterministic and stable in caseId order:
39
+ * v2-unavailable, v2-truncated, v2-alias, v2-path-boundary, v2-combination.
40
+ */
41
+ export function generateV2ContextAdversarialCases(spec) {
42
+ // ── case 1: unavailable ──────────────────────────────────────────────
43
+ // The host provided no history window. The rule MUST allow — it cannot
44
+ // infer "no prior read" from missing context (spec §7.4, §10.1 row 6).
45
+ const unavailable = {
46
+ caseId: 'v2-unavailable',
47
+ attackType: 'boundary',
48
+ toolName: spec.toolName,
49
+ params: { path: spec.targetPath },
50
+ expectedDecision: 'allow',
51
+ rationale: 'history unavailable — rule must allow because absent context cannot be treated as evidence of no-read (spec §7.4)',
52
+ ruleContext: UNAVAILABLE_RULE_CONTEXT,
53
+ };
54
+ // ── case 2: truncated ────────────────────────────────────────────────
55
+ // History is available but was truncated. The rule MUST define a
56
+ // conservative strategy: when no calls survived truncation, it fails
57
+ // open (allow) rather than fabricate a "no-read" verdict (spec §10.1
58
+ // row 7). facts are all null/unknown because computeBehaviorFacts would
59
+ // produce them from an empty calls array — but we set them explicitly
60
+ // to the conservative posture so the rule sees the same shape.
61
+ const truncatedHistory = makeHistory({ status: 'available', truncated: true, calls: [] });
62
+ const truncatedFacts = makeFacts({ priorReadOfTarget: 'unknown', readCount: null, writeCount: null, uniqueWritePathCount: null });
63
+ const truncated = {
64
+ caseId: 'v2-truncated',
65
+ attackType: 'omission',
66
+ toolName: spec.toolName,
67
+ params: { path: spec.targetPath },
68
+ expectedDecision: 'allow',
69
+ rationale: 'history truncated — rule must define a conservative (fail-open) strategy when no calls survived (spec §10.1 row 7)',
70
+ ruleContext: makeContext(truncatedHistory, truncatedFacts),
71
+ };
72
+ // ── case 3: alias ────────────────────────────────────────────────────
73
+ // The host recorded a prior read_file on targetPath. The action is now
74
+ // write_file (alias of write). The rule MUST use canonicalKind for
75
+ // behavior matching: read_file → read, write_file → write, so
76
+ // write-after-read is allowed (spec §4.4, §10.1 row 8).
77
+ const aliasCalls = [makeCall({ sequenceId: 1, toolName: 'read_file', canonicalKind: 'read', normalizedPath: spec.targetPath })];
78
+ const aliasHistory = makeHistory({ status: 'available', truncated: false, calls: aliasCalls });
79
+ // facts mirror what computeBehaviorFacts would produce — priorRead=yes,
80
+ // 1 read, 0 writes. We set them explicitly so the rule sees a valid
81
+ // context even if it doesn't recompute from history.
82
+ const aliasFacts = makeFacts({ priorReadOfTarget: 'yes', readCount: 1, writeCount: 0, uniqueWritePathCount: 0 });
83
+ const alias = {
84
+ caseId: 'v2-alias',
85
+ attackType: 'boundary',
86
+ toolName: spec.toolName,
87
+ params: { path: spec.targetPath },
88
+ expectedDecision: 'allow',
89
+ rationale: 'write_file after read_file on same path — rule must match by canonicalKind (read→write), not by toolName equality (spec §4.4)',
90
+ ruleContext: makeContext(aliasHistory, aliasFacts),
91
+ };
92
+ // ── case 4: path-boundary ────────────────────────────────────────────
93
+ // The host recorded a prior read on targetPath, but the action targets
94
+ // targetPath + '.bak'. The rule MUST NOT substring-match — these are
95
+ // different files (spec §10.1 row 9). priorReadOfTarget is 'no' because
96
+ // the action's path is targetPath.bak, not targetPath.
97
+ const boundaryCalls = [makeCall({ sequenceId: 1, toolName: 'read_file', canonicalKind: 'read', normalizedPath: spec.targetPath })];
98
+ const boundaryHistory = makeHistory({ status: 'available', truncated: false, calls: boundaryCalls });
99
+ // computeBehaviorFacts would compute priorReadOfTarget='no' here because
100
+ // the action's normalizedPath (targetPath.bak) ≠ targetPath. We set it
101
+ // explicitly to mirror that computation.
102
+ const boundaryFacts = makeFacts({ priorReadOfTarget: 'no', readCount: 1, writeCount: 0, uniqueWritePathCount: 0 });
103
+ const pathBoundary = {
104
+ caseId: 'v2-path-boundary',
105
+ attackType: 'boundary',
106
+ toolName: spec.toolName,
107
+ params: { path: `${spec.targetPath}.bak` },
108
+ expectedDecision: 'block',
109
+ rationale: 'targetPath.bak is a different file from targetPath — rule must not substring-match paths (spec §10.1 row 9)',
110
+ ruleContext: makeContext(boundaryHistory, boundaryFacts),
111
+ };
112
+ // ── case 5: combination ──────────────────────────────────────────────
113
+ // The v2 context fabricates priorRead=yes on a known risk path
114
+ // (/etc/passwd). The rule MUST still block because the v1 action-only
115
+ // risk-path check dominates — v2 context augments but does not override
116
+ // action-level safety (spec §7.4, §10.1 row 10).
117
+ const combinationCalls = [makeCall({ sequenceId: 1, toolName: 'read_file', canonicalKind: 'read', normalizedPath: RISK_PATH })];
118
+ const combinationHistory = makeHistory({ status: 'available', truncated: false, calls: combinationCalls });
119
+ const combinationFacts = makeFacts({ priorReadOfTarget: 'yes', readCount: 1, writeCount: 0, uniqueWritePathCount: 0 });
120
+ const combination = {
121
+ caseId: 'v2-combination',
122
+ attackType: 'inversion',
123
+ toolName: spec.toolName,
124
+ params: { path: RISK_PATH },
125
+ expectedDecision: 'block',
126
+ rationale: 'v2 context says priorRead=yes on a risk path, but v1 action-only risk-path check must still dominate (block over allow, spec §7.4)',
127
+ ruleContext: makeContext(combinationHistory, combinationFacts),
128
+ };
129
+ return [unavailable, truncated, alias, pathBoundary, combination];
130
+ }
131
+ //# sourceMappingURL=v2-adversarial-cases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v2-adversarial-cases.js","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/v2-adversarial-cases.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pain-signal-observability.d.ts","sourceRoot":"","sources":["../../src/runtime-v2/pain-signal-observability.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,MAAM,WAAW,6BAA6B;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,oCAAoC;IACnD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,gBAAgB,CAAC;IACvB,oFAAoF;IACpF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA4XD;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,oCAAoC,GACzC,6BAA6B,CAiE/B"}
1
+ {"version":3,"file":"pain-signal-observability.d.ts","sourceRoot":"","sources":["../../src/runtime-v2/pain-signal-observability.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,MAAM,WAAW,6BAA6B;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,oCAAoC;IACnD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,gBAAgB,CAAC;IACvB,oFAAoF;IACpF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAmZD;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,oCAAoC,GACzC,6BAA6B,CAiE/B"}
@@ -41,6 +41,13 @@ function getSessionsColumns(db) {
41
41
  const cols = db.prepare('PRAGMA table_info(sessions)').all();
42
42
  return cols.map((c) => c.name);
43
43
  }
44
+ /**
45
+ * Type guard: narrows `object` to `{ name: unknown }` without `as` casts.
46
+ * Used for PRAGMA table_info rows (rc-2-no-as-bypass).
47
+ */
48
+ function hasNameField(row) {
49
+ return Object.hasOwn(row, 'name');
50
+ }
44
51
  /**
45
52
  * Ensure trajectory.db has the full schema (all 16 tables + indexes + migrations).
46
53
  *
@@ -87,6 +94,8 @@ function ensureTrajectorySchema(db) {
87
94
  empathy_signal_json TEXT NOT NULL,
88
95
  blob_ref TEXT,
89
96
  raw_excerpt TEXT,
97
+ stop_reason TEXT,
98
+ thinking_blocks_count INTEGER,
90
99
  created_at TEXT NOT NULL
91
100
  );
92
101
  CREATE TABLE IF NOT EXISTS user_turns (
@@ -113,6 +122,7 @@ function ensureTrajectorySchema(db) {
113
122
  gfi_before REAL,
114
123
  gfi_after REAL,
115
124
  params_json TEXT NOT NULL,
125
+ result_preview TEXT,
116
126
  created_at TEXT NOT NULL
117
127
  );
118
128
  CREATE TABLE IF NOT EXISTS pain_events (
@@ -125,6 +135,8 @@ function ensureTrajectorySchema(db) {
125
135
  origin TEXT,
126
136
  confidence REAL,
127
137
  text TEXT,
138
+ canonical_pain_id TEXT,
139
+ runtime_task_id TEXT,
128
140
  created_at TEXT NOT NULL
129
141
  );
130
142
  CREATE TABLE IF NOT EXISTS gate_blocks (
@@ -203,6 +215,12 @@ function ensureTrajectorySchema(db) {
203
215
  started_at TEXT,
204
216
  completed_at TEXT,
205
217
  resolution TEXT,
218
+ task_kind TEXT,
219
+ priority TEXT,
220
+ retry_count INTEGER,
221
+ max_retries INTEGER,
222
+ last_error TEXT,
223
+ result_ref TEXT,
206
224
  created_at TEXT NOT NULL,
207
225
  updated_at TEXT NOT NULL
208
226
  );
@@ -279,7 +297,12 @@ function ensureTrajectorySchema(db) {
279
297
  ];
280
298
  for (const col of v2Columns) {
281
299
  const exists = db.prepare(`PRAGMA table_info(evolution_tasks)`).all()
282
- .some((row) => row.name === col.name);
300
+ .some((row) => {
301
+ if (typeof row !== 'object' || row === null)
302
+ return false;
303
+ // Use type guard predicate to narrow without `as` (rc-2-no-as-bypass)
304
+ return hasNameField(row) && row.name === col.name;
305
+ });
283
306
  if (!exists) {
284
307
  db.exec(`ALTER TABLE evolution_tasks ADD COLUMN ${col.name} ${col.type}`);
285
308
  }