create-principles-disciple 1.121.8 → 1.121.10

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 (462) hide show
  1. package/README.md +13 -1
  2. package/console/dist/server/config/pd-config-store.d.ts +1 -3
  3. package/console/dist/server/config/pd-config-store.js +4 -4
  4. package/console/dist/server/feedback/channels.d.ts +2 -8
  5. package/console/dist/server/feedback/channels.js +0 -11
  6. package/console/dist/server/index.js +34 -5
  7. package/console/dist/server/models/ActivationsConsoleModel.d.ts +28 -1
  8. package/console/dist/server/models/ActivationsConsoleModel.js +72 -30
  9. package/console/dist/server/models/GovernanceExperienceCollector.d.ts +28 -0
  10. package/console/dist/server/models/GovernanceExperienceCollector.js +305 -0
  11. package/console/dist/server/models/GovernanceProjectionCollector.d.ts +60 -2
  12. package/console/dist/server/models/GovernanceProjectionCollector.js +323 -285
  13. package/console/dist/server/models/PrincipleClassifier.d.ts +1 -1
  14. package/console/dist/server/models/PrincipleClassifier.js +7 -4
  15. package/console/dist/server/models/PrinciplesConsoleModel.d.ts +2 -1
  16. package/console/dist/server/models/ReceiptsConsoleModel.d.ts +5 -0
  17. package/console/dist/server/models/ReceiptsConsoleModel.js +140 -13
  18. package/console/dist/server/routes/activations.js +1 -1
  19. package/console/dist/server/routes/failed-tasks.js +28 -11
  20. package/console/dist/server/routes/governance.d.ts +26 -0
  21. package/console/dist/server/routes/governance.js +51 -0
  22. package/console/dist/server/routes/owner-identity.d.ts +31 -0
  23. package/console/dist/server/routes/owner-identity.js +76 -0
  24. package/console/dist/server/routes/update-history.d.ts +5 -0
  25. package/console/dist/server/routes/update-history.js +50 -4
  26. package/console/dist/server/routes/update.js +263 -41
  27. package/console/dist/server/utils/update-links.d.ts +38 -0
  28. package/console/dist/server/utils/update-links.js +71 -0
  29. package/console/dist/shared/feedback-channel-ids.d.ts +13 -0
  30. package/console/dist/shared/feedback-channel-ids.js +12 -0
  31. package/console/dist/shared/feedback-contract.d.ts +46 -0
  32. package/console/dist/shared/feedback-contract.js +45 -0
  33. package/console/dist/ui/App.js +1 -1
  34. package/console/dist/ui/api.d.ts +22 -3
  35. package/console/dist/ui/api.js +63 -3
  36. package/console/dist/ui/components/receipts/ReceiptCoverageDisclosure.d.ts +6 -0
  37. package/console/dist/ui/components/receipts/ReceiptCoverageDisclosure.js +66 -0
  38. package/console/dist/ui/i18n/en.json +198 -2
  39. package/console/dist/ui/i18n/zh-CN.json +196 -0
  40. package/console/dist/ui/pages/activation/ActivationPage.js +14 -2
  41. package/console/dist/ui/pages/failed-tasks/FailedTasksPage.js +25 -5
  42. package/console/dist/ui/pages/focus/FocusPage.d.ts +28 -1
  43. package/console/dist/ui/pages/focus/FocusPage.js +128 -15
  44. package/console/dist/ui/pages/principles/PrincipleDetailPage.d.ts +30 -0
  45. package/console/dist/ui/pages/principles/PrincipleDetailPage.js +49 -6
  46. package/console/dist/ui/pages/settings/SettingsPage.js +67 -2
  47. package/console/dist/ui/pages/settings/UpdatePage.js +7 -7
  48. package/console/dist/ui/utils/enum-labels.js +0 -1
  49. package/console/dist/ui/utils/validators.d.ts +53 -21
  50. package/console/dist/ui/utils/validators.js +248 -21
  51. package/console/dist/web/assets/app.css +6 -0
  52. package/console/dist/web/assets/app.js +2721 -1664
  53. package/console/package.json +3 -1
  54. package/core/dist/host/host-adapter.d.ts +1 -1
  55. package/core/dist/host/host-adapter.d.ts.map +1 -1
  56. package/core/dist/host/host-adapter.js +1 -0
  57. package/core/dist/host/host-adapter.js.map +1 -1
  58. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +12 -2
  59. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  60. package/core/dist/runtime-v2/__tests__/attack-e2e-pipeline-smoke.test.js +1 -1
  61. package/core/dist/runtime-v2/__tests__/attack-e2e-pipeline-smoke.test.js.map +1 -1
  62. package/core/dist/runtime-v2/__tests__/governance-experience.test.d.ts +2 -0
  63. package/core/dist/runtime-v2/__tests__/governance-experience.test.d.ts.map +1 -0
  64. package/core/dist/runtime-v2/__tests__/governance-experience.test.js +300 -0
  65. package/core/dist/runtime-v2/__tests__/governance-experience.test.js.map +1 -0
  66. package/core/dist/runtime-v2/__tests__/owner-identity.test.d.ts +2 -0
  67. package/core/dist/runtime-v2/__tests__/owner-identity.test.d.ts.map +1 -0
  68. package/core/dist/runtime-v2/__tests__/owner-identity.test.js +147 -0
  69. package/core/dist/runtime-v2/__tests__/owner-identity.test.js.map +1 -0
  70. package/core/dist/runtime-v2/__tests__/product-telemetry-contract.test.d.ts +18 -0
  71. package/core/dist/runtime-v2/__tests__/product-telemetry-contract.test.d.ts.map +1 -0
  72. package/core/dist/runtime-v2/__tests__/product-telemetry-contract.test.js +303 -0
  73. package/core/dist/runtime-v2/__tests__/product-telemetry-contract.test.js.map +1 -0
  74. package/core/dist/runtime-v2/__tests__/recovery-actions-log.test.js +40 -0
  75. package/core/dist/runtime-v2/__tests__/recovery-actions-log.test.js.map +1 -1
  76. package/core/dist/runtime-v2/__tests__/status-contract.test.d.ts +2 -0
  77. package/core/dist/runtime-v2/__tests__/status-contract.test.d.ts.map +1 -0
  78. package/core/dist/runtime-v2/__tests__/status-contract.test.js +107 -0
  79. package/core/dist/runtime-v2/__tests__/status-contract.test.js.map +1 -0
  80. package/core/dist/runtime-v2/activation/__tests__/promotion-evidence-snapshot.test.d.ts +2 -0
  81. package/core/dist/runtime-v2/activation/__tests__/promotion-evidence-snapshot.test.d.ts.map +1 -0
  82. package/core/dist/runtime-v2/activation/__tests__/promotion-evidence-snapshot.test.js +104 -0
  83. package/core/dist/runtime-v2/activation/__tests__/promotion-evidence-snapshot.test.js.map +1 -0
  84. package/core/dist/runtime-v2/activation/__tests__/promotion-readiness-evaluator.test.js +19 -0
  85. package/core/dist/runtime-v2/activation/__tests__/promotion-readiness-evaluator.test.js.map +1 -1
  86. package/core/dist/runtime-v2/activation/__tests__/rulecode-owner-decision-service.test.js +20 -0
  87. package/core/dist/runtime-v2/activation/__tests__/rulecode-owner-decision-service.test.js.map +1 -1
  88. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-safety-store.test.js +40 -0
  89. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-safety-store.test.js.map +1 -1
  90. package/core/dist/runtime-v2/activation/index.d.ts +2 -0
  91. package/core/dist/runtime-v2/activation/index.d.ts.map +1 -1
  92. package/core/dist/runtime-v2/activation/index.js +1 -0
  93. package/core/dist/runtime-v2/activation/index.js.map +1 -1
  94. package/core/dist/runtime-v2/activation/promotion-evidence-snapshot.d.ts +30 -0
  95. package/core/dist/runtime-v2/activation/promotion-evidence-snapshot.d.ts.map +1 -0
  96. package/core/dist/runtime-v2/activation/promotion-evidence-snapshot.js +87 -0
  97. package/core/dist/runtime-v2/activation/promotion-evidence-snapshot.js.map +1 -0
  98. package/core/dist/runtime-v2/activation/promotion-readiness-evaluator.d.ts.map +1 -1
  99. package/core/dist/runtime-v2/activation/promotion-readiness-evaluator.js +3 -0
  100. package/core/dist/runtime-v2/activation/promotion-readiness-evaluator.js.map +1 -1
  101. package/core/dist/runtime-v2/activation/promotion-readiness-reader.d.ts +1 -1
  102. package/core/dist/runtime-v2/activation/promotion-readiness-reader.d.ts.map +1 -1
  103. package/core/dist/runtime-v2/activation/promotion-readiness-reader.js +2 -2
  104. package/core/dist/runtime-v2/activation/promotion-readiness-reader.js.map +1 -1
  105. package/core/dist/runtime-v2/activation/rulecode-owner-decision-service.d.ts.map +1 -1
  106. package/core/dist/runtime-v2/activation/rulecode-owner-decision-service.js +18 -9
  107. package/core/dist/runtime-v2/activation/rulecode-owner-decision-service.js.map +1 -1
  108. package/core/dist/runtime-v2/adapter/__tests__/chaos-json-repair.test.js +1 -1
  109. package/core/dist/runtime-v2/adapter/__tests__/chaos-json-repair.test.js.map +1 -1
  110. package/core/dist/runtime-v2/adapter/__tests__/json-extractor.test.js +91 -1
  111. package/core/dist/runtime-v2/adapter/__tests__/json-extractor.test.js.map +1 -1
  112. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-runtime-adapter.test.js +59 -12
  113. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-runtime-adapter.test.js.map +1 -1
  114. package/core/dist/runtime-v2/adapter/__tests__/runtime-config-contract.test.js +10 -9
  115. package/core/dist/runtime-v2/adapter/__tests__/runtime-config-contract.test.js.map +1 -1
  116. package/core/dist/runtime-v2/adapter/__tests__/structured-output-repair.test.js +42 -1
  117. package/core/dist/runtime-v2/adapter/__tests__/structured-output-repair.test.js.map +1 -1
  118. package/core/dist/runtime-v2/adapter/json-extractor.d.ts +25 -0
  119. package/core/dist/runtime-v2/adapter/json-extractor.d.ts.map +1 -1
  120. package/core/dist/runtime-v2/adapter/json-extractor.js +126 -0
  121. package/core/dist/runtime-v2/adapter/json-extractor.js.map +1 -1
  122. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.d.ts +9 -4
  123. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.d.ts.map +1 -1
  124. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.js +9 -4
  125. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.js.map +1 -1
  126. package/core/dist/runtime-v2/adapter/output-repair-contract.d.ts +5 -1
  127. package/core/dist/runtime-v2/adapter/output-repair-contract.d.ts.map +1 -1
  128. package/core/dist/runtime-v2/adapter/output-repair-contract.js +4 -1
  129. package/core/dist/runtime-v2/adapter/output-repair-contract.js.map +1 -1
  130. package/core/dist/runtime-v2/adapter/pi-ai-catalog.d.ts +7 -0
  131. package/core/dist/runtime-v2/adapter/pi-ai-catalog.d.ts.map +1 -0
  132. package/core/dist/runtime-v2/adapter/pi-ai-catalog.js +19 -0
  133. package/core/dist/runtime-v2/adapter/pi-ai-catalog.js.map +1 -0
  134. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.d.ts +13 -15
  135. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.d.ts.map +1 -1
  136. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js +104 -37
  137. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js.map +1 -1
  138. package/core/dist/runtime-v2/adapter/structured-output-repair.d.ts +16 -1
  139. package/core/dist/runtime-v2/adapter/structured-output-repair.d.ts.map +1 -1
  140. package/core/dist/runtime-v2/adapter/structured-output-repair.js +38 -6
  141. package/core/dist/runtime-v2/adapter/structured-output-repair.js.map +1 -1
  142. package/core/dist/runtime-v2/adapter/tools/diagnostician-tool.d.ts +1 -1
  143. package/core/dist/runtime-v2/adapter/tools/diagnostician-tool.d.ts.map +1 -1
  144. package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.js +8 -9
  145. package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.js.map +1 -1
  146. package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js +27 -3
  147. package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js.map +1 -1
  148. package/core/dist/runtime-v2/config/__tests__/pd-config-principles.test.d.ts +11 -0
  149. package/core/dist/runtime-v2/config/__tests__/pd-config-principles.test.d.ts.map +1 -0
  150. package/core/dist/runtime-v2/config/__tests__/pd-config-principles.test.js +93 -0
  151. package/core/dist/runtime-v2/config/__tests__/pd-config-principles.test.js.map +1 -0
  152. package/core/dist/runtime-v2/config/__tests__/pd-config-workspace.test.js +41 -0
  153. package/core/dist/runtime-v2/config/__tests__/pd-config-workspace.test.js.map +1 -1
  154. package/core/dist/runtime-v2/config/index.d.ts +2 -2
  155. package/core/dist/runtime-v2/config/index.d.ts.map +1 -1
  156. package/core/dist/runtime-v2/config/index.js +2 -0
  157. package/core/dist/runtime-v2/config/index.js.map +1 -1
  158. package/core/dist/runtime-v2/config/pd-config-agent-binding.d.ts.map +1 -1
  159. package/core/dist/runtime-v2/config/pd-config-agent-binding.js +4 -13
  160. package/core/dist/runtime-v2/config/pd-config-agent-binding.js.map +1 -1
  161. package/core/dist/runtime-v2/config/pd-config-effective.d.ts.map +1 -1
  162. package/core/dist/runtime-v2/config/pd-config-effective.js +14 -7
  163. package/core/dist/runtime-v2/config/pd-config-effective.js.map +1 -1
  164. package/core/dist/runtime-v2/config/pd-config-feature-flags.d.ts.map +1 -1
  165. package/core/dist/runtime-v2/config/pd-config-feature-flags.js +5 -12
  166. package/core/dist/runtime-v2/config/pd-config-feature-flags.js.map +1 -1
  167. package/core/dist/runtime-v2/config/pd-config-types.d.ts +8 -0
  168. package/core/dist/runtime-v2/config/pd-config-types.d.ts.map +1 -1
  169. package/core/dist/runtime-v2/config/pd-config-types.js +2 -0
  170. package/core/dist/runtime-v2/config/pd-config-types.js.map +1 -1
  171. package/core/dist/runtime-v2/config/pd-config-validate.d.ts.map +1 -1
  172. package/core/dist/runtime-v2/config/pd-config-validate.js +48 -3
  173. package/core/dist/runtime-v2/config/pd-config-validate.js.map +1 -1
  174. package/core/dist/runtime-v2/core-principles/__tests__/core-axiom-block.test.js +36 -8
  175. package/core/dist/runtime-v2/core-principles/__tests__/core-axiom-block.test.js.map +1 -1
  176. package/core/dist/runtime-v2/core-principles/__tests__/core-principle-registry.test.js +36 -12
  177. package/core/dist/runtime-v2/core-principles/__tests__/core-principle-registry.test.js.map +1 -1
  178. package/core/dist/runtime-v2/core-principles/core-axiom-block.d.ts +22 -8
  179. package/core/dist/runtime-v2/core-principles/core-axiom-block.d.ts.map +1 -1
  180. package/core/dist/runtime-v2/core-principles/core-axiom-block.js +28 -13
  181. package/core/dist/runtime-v2/core-principles/core-axiom-block.js.map +1 -1
  182. package/core/dist/runtime-v2/core-principles/core-principle-registry.d.ts +29 -4
  183. package/core/dist/runtime-v2/core-principles/core-principle-registry.d.ts.map +1 -1
  184. package/core/dist/runtime-v2/core-principles/core-principle-registry.js +68 -33
  185. package/core/dist/runtime-v2/core-principles/core-principle-registry.js.map +1 -1
  186. package/core/dist/runtime-v2/core-principles/index.d.ts +3 -3
  187. package/core/dist/runtime-v2/core-principles/index.d.ts.map +1 -1
  188. package/core/dist/runtime-v2/core-principles/index.js +1 -1
  189. package/core/dist/runtime-v2/core-principles/index.js.map +1 -1
  190. package/core/dist/runtime-v2/evolution/evolution-types.d.ts +2 -1
  191. package/core/dist/runtime-v2/evolution/evolution-types.d.ts.map +1 -1
  192. package/core/dist/runtime-v2/evolution/evolution-types.js.map +1 -1
  193. package/core/dist/runtime-v2/feature-flags/__tests__/anonymous-product-telemetry-flag.test.d.ts +2 -0
  194. package/core/dist/runtime-v2/feature-flags/__tests__/anonymous-product-telemetry-flag.test.d.ts.map +1 -0
  195. package/core/dist/runtime-v2/feature-flags/__tests__/anonymous-product-telemetry-flag.test.js +48 -0
  196. package/core/dist/runtime-v2/feature-flags/__tests__/anonymous-product-telemetry-flag.test.js.map +1 -0
  197. package/core/dist/runtime-v2/feature-flags/__tests__/codex-conversation-ingestion-flag.test.d.ts +2 -0
  198. package/core/dist/runtime-v2/feature-flags/__tests__/codex-conversation-ingestion-flag.test.d.ts.map +1 -0
  199. package/core/dist/runtime-v2/feature-flags/__tests__/codex-conversation-ingestion-flag.test.js +46 -0
  200. package/core/dist/runtime-v2/feature-flags/__tests__/codex-conversation-ingestion-flag.test.js.map +1 -0
  201. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +86 -31
  202. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
  203. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-lifecycle.test.d.ts +2 -0
  204. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-lifecycle.test.d.ts.map +1 -0
  205. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-lifecycle.test.js +83 -0
  206. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-lifecycle.test.js.map +1 -0
  207. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts +19 -1
  208. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
  209. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +128 -10
  210. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
  211. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.d.ts +37 -0
  212. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.d.ts.map +1 -0
  213. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js +304 -0
  214. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js.map +1 -0
  215. package/core/dist/runtime-v2/feature-flags/index.d.ts +4 -2
  216. package/core/dist/runtime-v2/feature-flags/index.d.ts.map +1 -1
  217. package/core/dist/runtime-v2/feature-flags/index.js +3 -1
  218. package/core/dist/runtime-v2/feature-flags/index.js.map +1 -1
  219. package/core/dist/runtime-v2/governance-experience-contract.d.ts +468 -0
  220. package/core/dist/runtime-v2/governance-experience-contract.d.ts.map +1 -0
  221. package/core/dist/runtime-v2/governance-experience-contract.js +208 -0
  222. package/core/dist/runtime-v2/governance-experience-contract.js.map +1 -0
  223. package/core/dist/runtime-v2/governance-experience.d.ts +11 -0
  224. package/core/dist/runtime-v2/governance-experience.d.ts.map +1 -0
  225. package/core/dist/runtime-v2/governance-experience.js +276 -0
  226. package/core/dist/runtime-v2/governance-experience.js.map +1 -0
  227. package/core/dist/runtime-v2/index.d.ts +20 -8
  228. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  229. package/core/dist/runtime-v2/index.js +20 -6
  230. package/core/dist/runtime-v2/index.js.map +1 -1
  231. package/core/dist/runtime-v2/internalization/__tests__/artificer-output-retry-flag.test.js +29 -10
  232. package/core/dist/runtime-v2/internalization/__tests__/artificer-output-retry-flag.test.js.map +1 -1
  233. package/core/dist/runtime-v2/owner-identity.d.ts +69 -0
  234. package/core/dist/runtime-v2/owner-identity.d.ts.map +1 -0
  235. package/core/dist/runtime-v2/owner-identity.js +179 -0
  236. package/core/dist/runtime-v2/owner-identity.js.map +1 -0
  237. package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
  238. package/core/dist/runtime-v2/pain-signal-runtime-factory.js +2 -3
  239. package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
  240. package/core/dist/runtime-v2/product-telemetry/daily-identity.d.ts +70 -0
  241. package/core/dist/runtime-v2/product-telemetry/daily-identity.d.ts.map +1 -0
  242. package/core/dist/runtime-v2/product-telemetry/daily-identity.js +89 -0
  243. package/core/dist/runtime-v2/product-telemetry/daily-identity.js.map +1 -0
  244. package/core/dist/runtime-v2/product-telemetry/snapshot-contract.d.ts +110 -0
  245. package/core/dist/runtime-v2/product-telemetry/snapshot-contract.d.ts.map +1 -0
  246. package/core/dist/runtime-v2/product-telemetry/snapshot-contract.js +250 -0
  247. package/core/dist/runtime-v2/product-telemetry/snapshot-contract.js.map +1 -0
  248. package/core/dist/runtime-v2/pruning-read-model.d.ts +2 -1
  249. package/core/dist/runtime-v2/pruning-read-model.d.ts.map +1 -1
  250. package/core/dist/runtime-v2/pruning-read-model.js.map +1 -1
  251. package/core/dist/runtime-v2/receipt-coverage.d.ts +63 -0
  252. package/core/dist/runtime-v2/receipt-coverage.d.ts.map +1 -0
  253. package/core/dist/runtime-v2/receipt-coverage.js +19 -0
  254. package/core/dist/runtime-v2/receipt-coverage.js.map +1 -0
  255. package/core/dist/runtime-v2/recovery-actions-log.d.ts +7 -0
  256. package/core/dist/runtime-v2/recovery-actions-log.d.ts.map +1 -1
  257. package/core/dist/runtime-v2/recovery-actions-log.js +6 -0
  258. package/core/dist/runtime-v2/recovery-actions-log.js.map +1 -1
  259. package/core/dist/runtime-v2/runtime-protocol.js +1 -1
  260. package/core/dist/runtime-v2/runtime-protocol.js.map +1 -1
  261. package/core/dist/runtime-v2/store/task/__tests__/sqlite-task-store.failed-tasks.test.js +17 -1
  262. package/core/dist/runtime-v2/store/task/__tests__/sqlite-task-store.failed-tasks.test.js.map +1 -1
  263. package/core/dist/runtime-v2/store/task/sqlite-task-store.d.ts.map +1 -1
  264. package/core/dist/runtime-v2/store/task/sqlite-task-store.js +10 -0
  265. package/core/dist/runtime-v2/store/task/sqlite-task-store.js.map +1 -1
  266. package/core/dist/runtime-v2/store/task/task-types.d.ts +2 -0
  267. package/core/dist/runtime-v2/store/task/task-types.d.ts.map +1 -1
  268. package/core/dist/runtime-v2/task-status.d.ts +9 -5
  269. package/core/dist/runtime-v2/task-status.d.ts.map +1 -1
  270. package/core/dist/runtime-v2/task-status.js +15 -7
  271. package/core/dist/runtime-v2/task-status.js.map +1 -1
  272. package/core/dist/runtime-v2/types/event-types.d.ts +4 -0
  273. package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
  274. package/core/dist/runtime-v2/types/event-types.js.map +1 -1
  275. package/core/dist/runtime-v2/types/index.d.ts +1 -1
  276. package/core/dist/runtime-v2/types/index.d.ts.map +1 -1
  277. package/core/dist/runtime-v2/types/index.js +1 -1
  278. package/core/dist/runtime-v2/types/index.js.map +1 -1
  279. package/core/dist/runtime-v2/types/principle-enums.d.ts +3 -2
  280. package/core/dist/runtime-v2/types/principle-enums.d.ts.map +1 -1
  281. package/core/dist/runtime-v2/types/principle-enums.js +11 -5
  282. package/core/dist/runtime-v2/types/principle-enums.js.map +1 -1
  283. package/core/dist/runtime-v2/types/principle-schema.d.ts +1 -1
  284. package/core/dist/runtime-v2/types/principle-tree-store.d.ts +1 -1
  285. package/core/dist/runtime-v2/utils/cli-process-runner.d.ts.map +1 -1
  286. package/core/dist/runtime-v2/utils/cli-process-runner.js +3 -2
  287. package/core/dist/runtime-v2/utils/cli-process-runner.js.map +1 -1
  288. package/core/package.json +1 -2
  289. package/dist/i18n.d.ts.map +1 -1
  290. package/dist/i18n.js +4 -2
  291. package/dist/i18n.js.map +1 -1
  292. package/dist/index.d.ts +2 -0
  293. package/dist/index.d.ts.map +1 -1
  294. package/dist/index.js +47 -11
  295. package/dist/index.js.map +1 -1
  296. package/dist/installer.d.ts +31 -5
  297. package/dist/installer.d.ts.map +1 -1
  298. package/dist/installer.js +472 -161
  299. package/dist/installer.js.map +1 -1
  300. package/dist/installers/codex-host-installer.d.ts.map +1 -1
  301. package/dist/installers/codex-host-installer.js +4 -0
  302. package/dist/installers/codex-host-installer.js.map +1 -1
  303. package/dist/mvp-config.d.ts +10 -0
  304. package/dist/mvp-config.d.ts.map +1 -1
  305. package/dist/mvp-config.js +30 -3
  306. package/dist/mvp-config.js.map +1 -1
  307. package/dist/uninstaller.d.ts +9 -1
  308. package/dist/uninstaller.d.ts.map +1 -1
  309. package/dist/uninstaller.js +103 -23
  310. package/dist/uninstaller.js.map +1 -1
  311. package/dist/update/atomic-file.d.ts +35 -0
  312. package/dist/update/atomic-file.d.ts.map +1 -0
  313. package/dist/update/atomic-file.js +120 -0
  314. package/dist/update/atomic-file.js.map +1 -0
  315. package/dist/update/bootstrap-protocol.d.ts +55 -0
  316. package/dist/update/bootstrap-protocol.d.ts.map +1 -0
  317. package/dist/update/bootstrap-protocol.js +132 -0
  318. package/dist/update/bootstrap-protocol.js.map +1 -0
  319. package/dist/update/channel-metadata.d.ts +28 -0
  320. package/dist/update/channel-metadata.d.ts.map +1 -0
  321. package/dist/update/channel-metadata.js +90 -0
  322. package/dist/update/channel-metadata.js.map +1 -0
  323. package/dist/update/channel-promotion.d.ts +39 -0
  324. package/dist/update/channel-promotion.d.ts.map +1 -0
  325. package/dist/update/channel-promotion.js +55 -0
  326. package/dist/update/channel-promotion.js.map +1 -0
  327. package/dist/update/data-compatibility.d.ts +35 -0
  328. package/dist/update/data-compatibility.d.ts.map +1 -0
  329. package/dist/update/data-compatibility.js +45 -0
  330. package/dist/update/data-compatibility.js.map +1 -0
  331. package/dist/update/install-layout.d.ts +59 -0
  332. package/dist/update/install-layout.d.ts.map +1 -0
  333. package/dist/update/install-layout.js +127 -0
  334. package/dist/update/install-layout.js.map +1 -0
  335. package/dist/update/legacy-migration.d.ts +56 -0
  336. package/dist/update/legacy-migration.d.ts.map +1 -0
  337. package/dist/update/legacy-migration.js +254 -0
  338. package/dist/update/legacy-migration.js.map +1 -0
  339. package/dist/update/product-identity.d.ts +50 -0
  340. package/dist/update/product-identity.d.ts.map +1 -0
  341. package/dist/update/product-identity.js +63 -0
  342. package/dist/update/product-identity.js.map +1 -0
  343. package/dist/update/release-asset-manifest.d.ts +31 -0
  344. package/dist/update/release-asset-manifest.d.ts.map +1 -0
  345. package/dist/update/release-asset-manifest.js +161 -0
  346. package/dist/update/release-asset-manifest.js.map +1 -0
  347. package/dist/update/release-identity.d.ts +33 -0
  348. package/dist/update/release-identity.d.ts.map +1 -0
  349. package/dist/update/release-identity.js +108 -0
  350. package/dist/update/release-identity.js.map +1 -0
  351. package/dist/update/release-manager.d.ts +96 -0
  352. package/dist/update/release-manager.d.ts.map +1 -0
  353. package/dist/update/release-manager.js +253 -0
  354. package/dist/update/release-manager.js.map +1 -0
  355. package/dist/update/release-metadata.d.ts +57 -0
  356. package/dist/update/release-metadata.d.ts.map +1 -0
  357. package/dist/update/release-metadata.js +200 -0
  358. package/dist/update/release-metadata.js.map +1 -0
  359. package/dist/update/release-policy.d.ts +51 -0
  360. package/dist/update/release-policy.d.ts.map +1 -0
  361. package/dist/update/release-policy.js +103 -0
  362. package/dist/update/release-policy.js.map +1 -0
  363. package/dist/update/rollback-policy.d.ts +56 -0
  364. package/dist/update/rollback-policy.d.ts.map +1 -0
  365. package/dist/update/rollback-policy.js +61 -0
  366. package/dist/update/rollback-policy.js.map +1 -0
  367. package/dist/update/transaction-journal.d.ts +121 -0
  368. package/dist/update/transaction-journal.d.ts.map +1 -0
  369. package/dist/update/transaction-journal.js +333 -0
  370. package/dist/update/transaction-journal.js.map +1 -0
  371. package/dist/update/trust-metadata.d.ts +55 -0
  372. package/dist/update/trust-metadata.d.ts.map +1 -0
  373. package/dist/update/trust-metadata.js +170 -0
  374. package/dist/update/trust-metadata.js.map +1 -0
  375. package/dist/update/update-history.d.ts +46 -0
  376. package/dist/update/update-history.d.ts.map +1 -0
  377. package/dist/update/update-history.js +123 -0
  378. package/dist/update/update-history.js.map +1 -0
  379. package/dist/utils/env.d.ts +7 -0
  380. package/dist/utils/env.d.ts.map +1 -1
  381. package/dist/utils/env.js +134 -44
  382. package/dist/utils/env.js.map +1 -1
  383. package/host-runtime/dist/governance-observation-store.d.ts +172 -0
  384. package/host-runtime/dist/governance-observation-store.js +649 -0
  385. package/host-runtime/dist/index.d.ts +6 -0
  386. package/host-runtime/dist/index.js +8 -0
  387. package/host-runtime/dist/product-telemetry/consent-store.d.ts +107 -0
  388. package/host-runtime/dist/product-telemetry/consent-store.js +329 -0
  389. package/host-runtime/dist/product-telemetry/eligibility.d.ts +53 -0
  390. package/host-runtime/dist/product-telemetry/eligibility.js +69 -0
  391. package/host-runtime/dist/product-telemetry/exporter.d.ts +46 -0
  392. package/host-runtime/dist/product-telemetry/exporter.js +71 -0
  393. package/host-runtime/dist/product-telemetry/milestone-readers.d.ts +61 -0
  394. package/host-runtime/dist/product-telemetry/milestone-readers.js +234 -0
  395. package/host-runtime/dist/product-telemetry/service.d.ts +142 -0
  396. package/host-runtime/dist/product-telemetry/service.js +532 -0
  397. package/host-runtime/dist/product-telemetry/workspace-scope.d.ts +38 -0
  398. package/host-runtime/dist/product-telemetry/workspace-scope.js +64 -0
  399. package/host-runtime/package.json +5 -0
  400. package/install-layout/dist/index.d.ts +48 -0
  401. package/install-layout/dist/index.js +81 -0
  402. package/install-layout/dist/index.test.d.ts +1 -0
  403. package/install-layout/dist/index.test.js +34 -0
  404. package/install-layout/package.json +29 -0
  405. package/package.json +16 -6
  406. package/pd-cli/dist/commands/__tests__/telemetry-flag-wiring.test.d.ts +9 -0
  407. package/pd-cli/dist/commands/__tests__/telemetry-flag-wiring.test.d.ts.map +1 -0
  408. package/pd-cli/dist/commands/__tests__/telemetry-flag-wiring.test.js +76 -0
  409. package/pd-cli/dist/commands/__tests__/telemetry-flag-wiring.test.js.map +1 -0
  410. package/pd-cli/dist/commands/__tests__/version.test.d.ts +2 -0
  411. package/pd-cli/dist/commands/__tests__/version.test.d.ts.map +1 -0
  412. package/pd-cli/dist/commands/__tests__/version.test.js +134 -0
  413. package/pd-cli/dist/commands/__tests__/version.test.js.map +1 -0
  414. package/pd-cli/dist/commands/console.d.ts.map +1 -1
  415. package/pd-cli/dist/commands/console.js +29 -10
  416. package/pd-cli/dist/commands/console.js.map +1 -1
  417. package/pd-cli/dist/commands/pain-record.d.ts.map +1 -1
  418. package/pd-cli/dist/commands/pain-record.js +6 -15
  419. package/pd-cli/dist/commands/pain-record.js.map +1 -1
  420. package/pd-cli/dist/commands/runtime-activation.d.ts +29 -0
  421. package/pd-cli/dist/commands/runtime-activation.d.ts.map +1 -1
  422. package/pd-cli/dist/commands/runtime-activation.js +70 -31
  423. package/pd-cli/dist/commands/runtime-activation.js.map +1 -1
  424. package/pd-cli/dist/commands/runtime-internalization-enqueue-successors.d.ts.map +1 -1
  425. package/pd-cli/dist/commands/runtime-internalization-enqueue-successors.js +2 -2
  426. package/pd-cli/dist/commands/runtime-internalization-enqueue-successors.js.map +1 -1
  427. package/pd-cli/dist/commands/telemetry.d.ts +82 -0
  428. package/pd-cli/dist/commands/telemetry.d.ts.map +1 -0
  429. package/pd-cli/dist/commands/telemetry.js +268 -0
  430. package/pd-cli/dist/commands/telemetry.js.map +1 -0
  431. package/pd-cli/dist/commands/version.d.ts +11 -0
  432. package/pd-cli/dist/commands/version.d.ts.map +1 -0
  433. package/pd-cli/dist/commands/version.js +48 -0
  434. package/pd-cli/dist/commands/version.js.map +1 -0
  435. package/pd-cli/dist/index.js +35 -2
  436. package/pd-cli/dist/index.js.map +1 -1
  437. package/pd-cli/dist/services/version-report.d.ts +44 -0
  438. package/pd-cli/dist/services/version-report.d.ts.map +1 -0
  439. package/pd-cli/dist/services/version-report.js +152 -0
  440. package/pd-cli/dist/services/version-report.js.map +1 -0
  441. package/pd-cli/package.json +1 -0
  442. package/plugin/dist/bundle.js +868 -936
  443. package/plugin/dist/core/init.d.ts +2 -1
  444. package/plugin/dist/core/principle-application-ledger.d.ts +10 -0
  445. package/plugin/dist/core/product-telemetry-trigger.d.ts +14 -0
  446. package/plugin/dist/core/thinking-os-parser.d.ts +5 -2
  447. package/plugin/dist/governance-audit.js +386 -0
  448. package/plugin/dist/hooks/gate-block-helper.d.ts +25 -1
  449. package/plugin/dist/hooks/gate.d.ts +22 -0
  450. package/plugin/dist/rulehost-evidence.js +832 -0
  451. package/plugin/dist/templates/langs/en/principles/THINKING_OS.md +53 -45
  452. package/plugin/dist/templates/langs/en/skills/pd-mentor/SKILL.md +1 -1
  453. package/plugin/dist/templates/langs/zh/principles/THINKING_OS.md +62 -46
  454. package/plugin/dist/templates/langs/zh/skills/pd-mentor/SKILL.md +1 -1
  455. package/plugin/dist/templates/workspace/.principles/THINKING_OS.md +66 -38
  456. package/plugin/openclaw.plugin.json +1 -1
  457. package/plugin/package.json +1 -1
  458. package/plugin/templates/langs/en/principles/THINKING_OS.md +53 -45
  459. package/plugin/templates/langs/en/skills/pd-mentor/SKILL.md +1 -1
  460. package/plugin/templates/langs/zh/principles/THINKING_OS.md +62 -46
  461. package/plugin/templates/langs/zh/skills/pd-mentor/SKILL.md +1 -1
  462. package/plugin/templates/workspace/.principles/THINKING_OS.md +66 -38
@@ -9,6 +9,7 @@ import { SectionTitle } from "../../components/layout/section-title.js";
9
9
  import { ShinyText } from "../../components/ui/shiny-text.js";
10
10
  import { Button } from "../../components/ui/button.js";
11
11
  import { fetchAllActivations, disableActivation, fetchLifecycleMetrics, fetchReceiptCounts, fetchRuleCodeOwnerReview, ruleCodeDecision, pauseAllRuleCode, releaseRuleCodePause, } from "../../api.js";
12
+ import { ReceiptCoverageDisclosure, getReceiptSourceStatusLabelKey } from "../../components/receipts/ReceiptCoverageDisclosure.js";
12
13
  import { validateActivationsData, validateLifecycleMetricsData, isReversibleChannel, } from "./ActivationValidators.js";
13
14
  import { enumLabel } from "../../utils/enum-labels.js";
14
15
  import { formatDate } from "../../utils/format-date.js";
@@ -86,7 +87,7 @@ function RuleCodeOwnerPanel({ record, onChanged }) {
86
87
  const value = (number) => number === null ? t('pages.activation.notCollected') : String(number);
87
88
  const affectedTools = Array.isArray(review.artifact.content?.affectedTools) ? review.artifact.content.affectedTools.filter((item) => typeof item === 'string') : [];
88
89
  const renderWindow = (title, window) => _jsxs("div", { className: "rounded border border-line p-2", children: [_jsx("div", { className: "font-medium text-ink", children: title }), _jsxs("div", { className: "mt-1 grid grid-cols-2 gap-1 md:grid-cols-5", children: [_jsxs("span", { children: [t('pages.activation.eligibleEvaluations'), ": ", value(window.eligible)] }), _jsxs("span", { children: [t('pages.activation.matched'), ": ", value(window.matched)] }), _jsxs("span", { children: [t('pages.activation.blocked'), ": ", value(window.blocked)] }), _jsxs("span", { children: [t('pages.activation.unhealthy'), ": ", value(window.unhealthy)] }), _jsxs("span", { children: [t('pages.activation.circuitTrips'), ": ", window.circuitTrips] })] }), _jsxs("div", { className: "mt-1 text-ink-4", children: [t('pages.activation.toolDistribution'), ": ", window.toolDistribution === null ? t('pages.activation.notCollected') : Object.entries(window.toolDistribution).map(([tool, count]) => `${tool} ${count}`).join(', ') || '—'] })] });
89
- return _jsxs("div", { className: "mt-4 rounded-[5px] border border-gov/25 bg-surface/70 p-4", "data-testid": `owner-review-${record.activationId}`, children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("strong", { className: "text-[13px] text-ink", children: t('pages.activation.ownerDecisionTitle') }), _jsx("span", { className: "font-mono text-[11px] text-gov", children: review.readiness.status }), review.controlState?.enforcement === 'safety_isolated' && _jsx("span", { className: "text-danger text-[11px]", children: t('pages.activation.safetyIsolation') })] }), _jsxs("div", { className: "mt-2 grid grid-cols-2 gap-2 text-[12px] text-ink-3 md:grid-cols-4", children: [_jsxs("span", { children: [t('pages.activation.eligibleEvaluations'), ": ", value(summary.observed)] }), _jsxs("span", { children: [t('pages.activation.matched'), ": ", value(summary.matched)] }), _jsxs("span", { children: [t('pages.activation.wouldBlock'), ": ", value(summary.wouldBlock)] }), _jsxs("span", { children: [t('pages.activation.wouldAllow'), ": ", value(summary.wouldAllow)] }), _jsxs("span", { children: [t('pages.activation.requireApproval'), ": ", value(summary.requireApproval)] }), _jsxs("span", { children: [t('pages.activation.autoCorrect'), ": ", value(summary.autoCorrect)] }), _jsxs("span", { children: [t('pages.activation.neutralControl'), ": ", value(summary.neutralControl)] }), _jsxs("span", { children: [t('pages.activation.evaluationErrors'), ": ", value(summary.errors)] })] }), _jsx("div", { className: "mt-2 text-[11px] text-ink-4", children: t('pages.activation.shadowWindow', { first: summary.firstObservedAt ?? t('pages.activation.notCollected'), last: summary.lastObservedAt ?? t('pages.activation.notCollected') }) }), _jsx("div", { className: "mt-2 text-[12px] text-ink-3", children: t('pages.activation.runtimeCapability', { version: review.runtimeCapability.hostRuntimeVersion, supported: t(review.runtimeCapability.shadowEvidence ? 'pages.activation.supported' : 'pages.activation.unsupported') }) }), _jsx("div", { className: "mt-2 text-[12px] text-amber", children: t('pages.activation.worstImpact', { tools: affectedTools.join(', ') || t('pages.activation.notCollected') }) }), _jsxs("div", { className: "mt-3 text-[12px] text-ink-3", children: [_jsx("div", { className: "mb-1 font-medium text-ink", children: t('pages.activation.hardSafetyChecks') }), review.readiness.evidenceSnapshot.safetyGateResults.map(check => _jsxs("div", { className: check.status === 'passed' ? 'text-green' : 'text-danger', children: [check.checkId, ": ", check.status, check.reasonCode ? ` · ${check.reasonCode}` : ''] }, check.checkId))] }), review.readiness.failedChecks.length > 0 && _jsx("ul", { className: "mt-2 text-[12px] text-danger", children: review.readiness.failedChecks.map(check => _jsxs("li", { children: [check.checkId, ": ", check.reasonCode] }, check.checkId)) }), _jsxs("details", { className: "mt-2 text-[12px]", children: [_jsx("summary", { className: "cursor-pointer text-gov", children: t('pages.activation.scopeArtifactCode') }), _jsx("pre", { className: "mt-2 max-h-64 overflow-auto whitespace-pre-wrap text-ink-3", children: JSON.stringify(review.artifact.content, null, 2) })] }), _jsxs("div", { className: "mt-3 grid gap-2 text-[11px] text-ink-3 md:grid-cols-2", children: [renderWindow(t('pages.activation.live24Hours'), review.liveMetrics.last24Hours), renderWindow(t('pages.activation.live7Days'), review.liveMetrics.last7Days)] }), _jsx("div", { className: "mt-2 text-[11px] text-ink-3", children: t('pages.activation.behaviorDrift', { approved: value(review.behaviorDrift.approvedBlockRate), live: value(review.behaviorDrift.liveBlockRate), delta: value(review.behaviorDrift.delta) }) }), review.liveMetrics.representativeSamples.length > 0 && _jsxs("details", { className: "mt-2 text-[12px]", children: [_jsx("summary", { className: "cursor-pointer text-gov", children: t('pages.activation.representativeSamples') }), review.liveMetrics.representativeSamples.map((sample, index) => _jsxs("div", { className: "font-mono text-ink-3", children: [sample.toolName, " \u00B7 ", sample.decision, " \u00B7 ", sample.pathCategory] }, `${sample.toolName}-${index}`))] }), review.decisions.length > 0 && _jsxs("details", { className: "mt-2 text-[12px]", children: [_jsx("summary", { className: "cursor-pointer text-gov", children: t('pages.activation.ownerDecisionHistory') }), review.decisions.map(decision => _jsxs("div", { className: "mt-1 border-l border-line pl-2 text-ink-3", children: [_jsx("span", { className: "font-mono", children: decision.decidedAt }), " \u00B7 ", decision.decision, " \u00B7 ", decision.principalKind, ":", decision.actorId, " \u00B7 ", decision.authenticationMethod, " \u00B7 ", decision.reasonCode, decision.note ? ` · ${decision.note}` : ''] }, decision.decisionId))] }), _jsx("div", { className: "mt-2 text-[11px] text-ink-4", children: t('pages.activation.circuitConditions') }), review.readiness.status === 'evidence_insufficient' && _jsxs("label", { className: "mt-3 block text-[12px] text-ink-3", children: [t('pages.activation.overrideReason'), _jsxs("select", { value: overrideReason, onChange: event => setOverrideReason(event.target.value), className: "mt-1 w-full rounded border border-line bg-panel px-3 py-2 text-ink", children: [_jsx("option", { value: "rare_behavior", children: t('pages.activation.overrideRareBehavior') }), _jsx("option", { value: "controlled_rollout", children: t('pages.activation.overrideControlledRollout') }), _jsx("option", { value: "owner_accepts_limited_evidence", children: t('pages.activation.overrideOwnerAccepts') })] })] }), _jsx("input", { value: note, onChange: event => setNote(event.target.value), placeholder: t('pages.activation.ownerReviewNote'), className: "mt-3 w-full rounded border border-line bg-panel px-3 py-2 text-[12px] text-ink" }), _jsxs("div", { className: "mt-3 flex flex-wrap gap-2", children: [review.globalPause?.status === 'paused' && _jsx(Button, { disabled: busy || !review.ownerDecisionEnabled, variant: "outline", onClick: () => void releasePause(), children: t('pages.activation.releaseGlobalPause') }), record.action === 'code_tool_hook_shadow_activate' && _jsxs(_Fragment, { children: [_jsx(Button, { disabled: busy || !review.ownerDecisionEnabled, onClick: () => void decide('continue-observing'), children: t('pages.activation.continueObserving') }), _jsx(Button, { disabled: busy || !review.ownerDecisionEnabled, variant: "outline", onClick: () => void decide('reject-after-shadow'), children: t('pages.activation.rejectAfterShadow') }), _jsx(Button, { disabled: busy || !review.ownerDecisionEnabled || (review.readiness.status !== 'ready' && review.readiness.status !== 'evidence_insufficient') || (review.readiness.status === 'evidence_insufficient' && note.trim().length === 0), onClick: () => void decide('promote'), children: t('pages.activation.confirmLive') })] }), (record.action === 'code_tool_hook_live_activate' || review.controlState?.enforcement === 'safety_isolated') && _jsx(Button, { disabled: busy, variant: "destructive", onClick: () => void decide('emergency-deactivate'), children: t('pages.activation.emergencyDeactivate') }), review.controlState?.enforcement === 'safety_isolated' && _jsx(Button, { disabled: busy || !review.ownerDecisionEnabled, variant: "outline", onClick: () => void decide('recover-to-shadow'), children: t('pages.activation.recoverToShadow') })] }), !review.ownerDecisionEnabled && _jsx("div", { className: "mt-2 text-[11px] text-amber", children: t('pages.activation.rolloutDisabled') })] });
90
+ return _jsxs("div", { className: "mt-4 rounded-[5px] border border-gov/25 bg-surface/70 p-4", "data-testid": `owner-review-${record.activationId}`, children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("strong", { className: "text-[13px] text-ink", children: t('pages.activation.ownerDecisionTitle') }), _jsx("span", { className: "font-mono text-[11px] text-gov", children: review.readiness.status }), review.controlState?.enforcement === 'safety_isolated' && _jsx("span", { className: "text-danger text-[11px]", children: t('pages.activation.safetyIsolation') })] }), _jsxs("div", { className: "mt-2 grid grid-cols-2 gap-2 text-[12px] text-ink-3 md:grid-cols-4", children: [_jsxs("span", { children: [t('pages.activation.eligibleEvaluations'), ": ", value(summary.observed)] }), _jsxs("span", { children: [t('pages.activation.matched'), ": ", value(summary.matched)] }), _jsxs("span", { children: [t('pages.activation.wouldBlock'), ": ", value(summary.wouldBlock)] }), _jsxs("span", { children: [t('pages.activation.wouldAllow'), ": ", value(summary.wouldAllow)] }), _jsxs("span", { children: [t('pages.activation.requireApproval'), ": ", value(summary.requireApproval)] }), _jsxs("span", { children: [t('pages.activation.autoCorrect'), ": ", value(summary.autoCorrect)] }), _jsxs("span", { children: [t('pages.activation.neutralControl'), ": ", value(summary.neutralControl)] }), _jsxs("span", { children: [t('pages.activation.evaluationErrors'), ": ", value(summary.errors)] })] }), _jsx("div", { className: "mt-2 text-[11px] text-ink-4", children: t('pages.activation.shadowWindow', { first: summary.firstObservedAt ?? t('pages.activation.notCollected'), last: summary.lastObservedAt ?? t('pages.activation.notCollected') }) }), _jsx("div", { className: "mt-2 text-[12px] text-ink-3", children: t('pages.activation.runtimeCapability', { version: review.runtimeCapability.hostRuntimeVersion, supported: t(review.runtimeCapability.shadowEvidence ? 'pages.activation.supported' : 'pages.activation.unsupported') }) }), _jsx("div", { className: "mt-2 text-[12px] text-amber", children: t('pages.activation.worstImpact', { tools: affectedTools.join(', ') || t('pages.activation.notCollected') }) }), _jsxs("div", { className: "mt-3 text-[12px] text-ink-3", children: [_jsx("div", { className: "mb-1 font-medium text-ink", children: t('pages.activation.hardSafetyChecks') }), review.readiness.evidenceSnapshot.safetyGateResults.map(check => _jsxs("div", { className: check.status === 'passed' ? 'text-green' : 'text-danger', children: [t(`pages.activation.checks.${check.checkId}`, { defaultValue: check.checkId }), ": ", t(`pages.activation.checkStatus.${check.status}`, { defaultValue: check.status }), check.reasonCode ? ` · ${t(`pages.activation.reasonCodes.${check.reasonCode}`, { defaultValue: check.reasonCode })}` : ''] }, check.checkId))] }), review.readiness.failedChecks.length > 0 && _jsx("ul", { className: "mt-2 text-[12px] text-danger", children: review.readiness.failedChecks.map(check => _jsxs("li", { children: [t(`pages.activation.checks.${check.checkId}`, { defaultValue: check.checkId }), ": ", t(`pages.activation.reasonCodes.${check.reasonCode}`, { defaultValue: check.reasonCode })] }, check.checkId)) }), _jsxs("details", { className: "mt-2 text-[12px]", children: [_jsx("summary", { className: "cursor-pointer text-gov", children: t('pages.activation.scopeArtifactCode') }), _jsx("pre", { className: "mt-2 max-h-64 overflow-auto whitespace-pre-wrap text-ink-3", children: JSON.stringify(review.artifact.content, null, 2) })] }), _jsxs("div", { className: "mt-3 grid gap-2 text-[11px] text-ink-3 md:grid-cols-2", children: [renderWindow(t('pages.activation.live24Hours'), review.liveMetrics.last24Hours), renderWindow(t('pages.activation.live7Days'), review.liveMetrics.last7Days)] }), _jsx("div", { className: "mt-2 text-[11px] text-ink-3", children: t('pages.activation.behaviorDrift', { approved: value(review.behaviorDrift.approvedBlockRate), live: value(review.behaviorDrift.liveBlockRate), delta: value(review.behaviorDrift.delta) }) }), review.liveMetrics.representativeSamples.length > 0 && _jsxs("details", { className: "mt-2 text-[12px]", children: [_jsx("summary", { className: "cursor-pointer text-gov", children: t('pages.activation.representativeSamples') }), review.liveMetrics.representativeSamples.map((sample, index) => _jsxs("div", { className: "font-mono text-ink-3", children: [sample.toolName, " \u00B7 ", sample.decision, " \u00B7 ", sample.pathCategory] }, `${sample.toolName}-${index}`))] }), review.decisions.length > 0 && _jsxs("details", { className: "mt-2 text-[12px]", children: [_jsx("summary", { className: "cursor-pointer text-gov", children: t('pages.activation.ownerDecisionHistory') }), review.decisions.map(decision => _jsxs("div", { className: "mt-1 border-l border-line pl-2 text-ink-3", children: [_jsx("span", { className: "font-mono", children: decision.decidedAt }), " \u00B7 ", decision.decision, " \u00B7 ", decision.principalKind, ":", decision.actorId, " \u00B7 ", decision.authenticationMethod, " \u00B7 ", decision.reasonCode, decision.note ? ` · ${decision.note}` : ''] }, decision.decisionId))] }), _jsx("div", { className: "mt-2 text-[11px] text-ink-4", children: t('pages.activation.circuitConditions') }), review.readiness.status === 'evidence_insufficient' && _jsxs("label", { className: "mt-3 block text-[12px] text-ink-3", children: [t('pages.activation.overrideReason'), _jsxs("select", { value: overrideReason, onChange: event => setOverrideReason(event.target.value), className: "mt-1 w-full rounded border border-line bg-panel px-3 py-2 text-ink", children: [_jsx("option", { value: "rare_behavior", children: t('pages.activation.overrideRareBehavior') }), _jsx("option", { value: "controlled_rollout", children: t('pages.activation.overrideControlledRollout') }), _jsx("option", { value: "owner_accepts_limited_evidence", children: t('pages.activation.overrideOwnerAccepts') })] })] }), _jsx("input", { value: note, onChange: event => setNote(event.target.value), placeholder: t('pages.activation.ownerReviewNote'), className: "mt-3 w-full rounded border border-line bg-panel px-3 py-2 text-[12px] text-ink" }), _jsxs("div", { className: "mt-3 flex flex-wrap gap-2", children: [review.globalPause?.status === 'paused' && _jsx(Button, { disabled: busy || !review.ownerDecisionEnabled, variant: "outline", onClick: () => void releasePause(), children: t('pages.activation.releaseGlobalPause') }), record.action === 'code_tool_hook_shadow_activate' && _jsxs(_Fragment, { children: [_jsx(Button, { disabled: busy || !review.ownerDecisionEnabled, onClick: () => void decide('continue-observing'), children: t('pages.activation.continueObserving') }), _jsx(Button, { disabled: busy || !review.ownerDecisionEnabled, variant: "outline", onClick: () => void decide('reject-after-shadow'), children: t('pages.activation.rejectAfterShadow') }), _jsx(Button, { disabled: busy || !review.ownerDecisionEnabled || (review.readiness.status !== 'ready' && review.readiness.status !== 'evidence_insufficient') || (review.readiness.status === 'evidence_insufficient' && note.trim().length === 0), onClick: () => void decide('promote'), children: t('pages.activation.confirmLive') })] }), (record.action === 'code_tool_hook_live_activate' || review.controlState?.enforcement === 'safety_isolated') && _jsx(Button, { disabled: busy, variant: "destructive", onClick: () => void decide('emergency-deactivate'), children: t('pages.activation.emergencyDeactivate') }), review.controlState?.enforcement === 'safety_isolated' && _jsx(Button, { disabled: busy || !review.ownerDecisionEnabled, variant: "outline", onClick: () => void decide('recover-to-shadow'), children: t('pages.activation.recoverToShadow') })] }), !review.ownerDecisionEnabled && _jsx("div", { className: "mt-2 text-[11px] text-amber", children: t('pages.activation.rolloutDisabled') })] });
90
91
  }
91
92
  function ActivationFactCard({ record, lifecycleData, receiptCount, onDisable, disabling, onChanged, }) {
92
93
  const { t, i18n } = useTranslation();
@@ -122,6 +123,12 @@ export function ActivationPage() {
122
123
  const [lifecycleCache, setLifecycleCache] = useState({});
123
124
  const [receiptCounts, setReceiptCounts] = useState(null);
124
125
  const [receiptDegraded, setReceiptDegraded] = useState(null);
126
+ // PRI-590: page-level coverage disclosure for the receipt counts.
127
+ const [receiptCoverage, setReceiptCoverage] = useState(null);
128
+ // PRI-594: unknown is never presented as a trustworthy zero — when the ledger
129
+ // is malformed the per-card count rows are omitted and the page-level
130
+ // coverage block carries the "requires recovery" verdict instead.
131
+ const receiptCountsUntrustworthy = receiptCoverage !== null && receiptCoverage.validationStatus === "malformed";
125
132
  const [loadingState, setLoadingState] = useState("loading");
126
133
  const [errorMessage, setErrorMessage] = useState(null);
127
134
  const [disablingIds, setDisablingIds] = useState(new Set());
@@ -132,6 +139,7 @@ export function ActivationPage() {
132
139
  setDegradedNote(null);
133
140
  setReceiptCounts(null);
134
141
  setReceiptDegraded(null);
142
+ setReceiptCoverage(null);
135
143
  const result = await fetchAllActivations();
136
144
  if (!result.success) {
137
145
  setLoadingState("error");
@@ -166,12 +174,16 @@ export function ActivationPage() {
166
174
  byId[entry.principleId] = entry;
167
175
  }
168
176
  setReceiptCounts(byId);
177
+ setReceiptCoverage(rResult.data.coverage);
169
178
  }
170
179
  else {
171
180
  setReceiptDegraded({
172
181
  reason: rResult.data.reason ?? "unknown",
173
182
  ...(rResult.data.nextAction === undefined ? {} : { nextAction: rResult.data.nextAction }),
174
183
  });
184
+ // Degraded responses still carry coverage — it names the state
185
+ // (disabled vs unavailable) for the localized headline.
186
+ setReceiptCoverage(rResult.data.coverage);
175
187
  }
176
188
  }
177
189
  catch (err) {
@@ -269,7 +281,7 @@ export function ActivationPage() {
269
281
  const ordinaryActive = activeActivations.filter(record => !pendingRuleCode.includes(record) && !safetyAlerts.includes(record));
270
282
  const inactiveActivations = activations.filter((a) => a.status === "inactive");
271
283
  const neverActivatedCount = activations.filter((a) => a.activatedAt === null).length;
272
- return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.activation.eyebrow") }), _jsx(ShinyText, { as: "h1", className: "text-[29px] font-semibold tracking-tight text-ink mb-2", duration: 4.5, brightness: 0.5, disabled: activeActivations.length === 0, children: t("pages.activation.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.activation.subtitle") }), _jsxs("div", { className: "text-sm leading-relaxed text-ink-2 mb-7 px-[18px] py-[14px] bg-panel border border-line rounded-[6px]", role: "status", "aria-live": "polite", children: [_jsx("span", { className: "font-mono font-semibold text-ink tabular-nums", children: activeActivations.length }), " ", _jsx("span", { className: "text-ink-3", children: t("pages.activation.summaryActive") }), " ", "/", " ", _jsx("span", { className: "font-mono font-semibold text-ink tabular-nums", children: inactiveActivations.length }), " ", _jsx("span", { className: "text-ink-3", children: t("pages.activation.summaryInactive") }), neverActivatedCount > 0 && (_jsxs(_Fragment, { children: [" ", "/", " ", _jsx("span", { className: "font-mono font-semibold text-amber tabular-nums", children: neverActivatedCount }), " ", _jsx("span", { className: "text-amber", children: t("pages.activation.summaryNeverActivated") })] }))] }), _jsx(CapabilityBoundaryDeclaration, {}), activeActivations.some(record => record.action === 'code_tool_hook_live_activate') && _jsx("div", { className: "mt-4 flex justify-end", children: _jsx(Button, { variant: "destructive", onClick: () => void handleEmergencyPause(), children: t('pages.activation.pauseAll') }) }), degradedNote && (_jsx("div", { className: "mt-4 text-ink-4 text-[13px] bg-surface/60 border-l-2 border-amber px-3 py-2", children: degradedNote })), receiptDegraded && (_jsxs("div", { className: "mt-4 text-ink-4 text-[13px] bg-surface/60 border-l-2 border-amber px-3 py-2", "data-testid": "receipt-counts-degraded", children: [t("pages.activation.receiptsUnavailable", { reason: receiptDegraded.reason }), receiptDegraded.nextAction && (_jsx("span", { className: "mt-1 block font-mono text-[12px]", children: receiptDegraded.nextAction }))] })), pendingRuleCode.length > 0 && _jsxs("section", { className: "mt-8", "aria-labelledby": "section-pending-rulecode", children: [_jsx(SectionTitle, { id: "section-pending-rulecode", children: t('pages.activation.pendingRules') }), _jsx("p", { className: "mb-3 text-[12px] text-ink-3", children: t('pages.activation.pendingRulesDescription') }), _jsx("div", { className: "space-y-[14px]", children: pendingRuleCode.map(record => _jsx(ActivationFactCard, { record: record, lifecycleData: lifecycleCache[record.principleId], receiptCount: undefined, onDisable: handleDisable, disabling: disablingIds.has(record.activationId), onChanged: () => void loadData() }, record.activationId)) })] }), safetyAlerts.length > 0 && _jsxs("section", { className: "mt-8", "aria-labelledby": "section-safety-alerts", children: [_jsx(SectionTitle, { id: "section-safety-alerts", children: t('pages.activation.safetyAlerts') }), _jsx("p", { className: "mb-3 text-[12px] text-danger", children: t('pages.activation.safetyAlertsDescription') }), _jsx("div", { className: "space-y-[14px]", children: safetyAlerts.map(record => _jsx(ActivationFactCard, { record: record, lifecycleData: lifecycleCache[record.principleId], receiptCount: undefined, onDisable: handleDisable, disabling: disablingIds.has(record.activationId), onChanged: () => void loadData() }, record.activationId)) })] }), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-active", children: [_jsx(SectionTitle, { id: "section-active", children: t("pages.activation.sectionActive") }), ordinaryActive.length > 0 ? (_jsx("div", { className: "space-y-[14px]", children: ordinaryActive.map((record) => (_jsx(ActivationFactCard, { record: record, lifecycleData: lifecycleCache[record.principleId], receiptCount: receiptCounts !== null ? (Object.hasOwn(receiptCounts, record.principleId) ? receiptCounts[record.principleId] : null) : undefined, onDisable: handleDisable, disabling: disablingIds.has(record.activationId), onChanged: () => void loadData() }, record.activationId))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.activation.emptyActive") }))] }), inactiveActivations.length > 0 && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-inactive", children: [_jsx(SectionTitle, { id: "section-inactive", children: t("pages.activation.sectionInactive") }), _jsx("div", { className: "space-y-[14px]", children: inactiveActivations.map((record) => (_jsx(ActivationFactCard, { record: record, lifecycleData: lifecycleCache[record.principleId], receiptCount: receiptCounts !== null ? (Object.hasOwn(receiptCounts, record.principleId) ? receiptCounts[record.principleId] : null) : undefined, onDisable: handleDisable, disabling: disablingIds.has(record.activationId), onChanged: () => void loadData() }, record.activationId))) })] })), neverActivatedCount > 0 && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-never-activated", children: [_jsx(SectionTitle, { id: "section-never-activated", children: t("pages.activation.sectionNeverActivated") }), _jsx("div", { className: "space-y-[10px]", children: activations
284
+ return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.activation.eyebrow") }), _jsx(ShinyText, { as: "h1", className: "text-[29px] font-semibold tracking-tight text-ink mb-2", duration: 4.5, brightness: 0.5, disabled: activeActivations.length === 0, children: t("pages.activation.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.activation.subtitle") }), _jsxs("div", { className: "text-sm leading-relaxed text-ink-2 mb-7 px-[18px] py-[14px] bg-panel border border-line rounded-[6px]", role: "status", "aria-live": "polite", children: [_jsx("span", { className: "font-mono font-semibold text-ink tabular-nums", children: activeActivations.length }), " ", _jsx("span", { className: "text-ink-3", children: t("pages.activation.summaryActive") }), " ", "/", " ", _jsx("span", { className: "font-mono font-semibold text-ink tabular-nums", children: inactiveActivations.length }), " ", _jsx("span", { className: "text-ink-3", children: t("pages.activation.summaryInactive") }), neverActivatedCount > 0 && (_jsxs(_Fragment, { children: [" ", "/", " ", _jsx("span", { className: "font-mono font-semibold text-amber tabular-nums", children: neverActivatedCount }), " ", _jsx("span", { className: "text-amber", children: t("pages.activation.summaryNeverActivated") })] }))] }), _jsx(CapabilityBoundaryDeclaration, {}), activeActivations.some(record => record.action === 'code_tool_hook_live_activate') && _jsx("div", { className: "mt-4 flex justify-end", children: _jsx(Button, { variant: "destructive", onClick: () => void handleEmergencyPause(), children: t('pages.activation.pauseAll') }) }), degradedNote && (_jsx("div", { className: "mt-4 text-ink-4 text-[13px] bg-surface/60 border-l-2 border-amber px-3 py-2", children: degradedNote })), receiptDegraded && (_jsxs("div", { className: "mt-4 text-ink-4 text-[13px] bg-surface/60 border-l-2 border-amber px-3 py-2", "data-testid": "receipt-counts-degraded", children: [receiptCoverage !== null && (_jsx("span", { className: "block font-medium text-ink-3", children: t(getReceiptSourceStatusLabelKey(receiptCoverage.sourceStatus)) })), t("pages.activation.receiptsUnavailable", { reason: receiptDegraded.reason }), receiptDegraded.nextAction && (_jsx("span", { className: "mt-1 block font-mono text-[12px]", children: receiptDegraded.nextAction }))] })), receiptCounts !== null && receiptCoverage !== null && (_jsx("div", { className: "mt-4 bg-surface/60 border-l-2 border-line px-3 py-2", "data-testid": "receipt-counts-coverage", children: _jsx(ReceiptCoverageDisclosure, { coverage: receiptCoverage }) })), pendingRuleCode.length > 0 && _jsxs("section", { className: "mt-8", "aria-labelledby": "section-pending-rulecode", children: [_jsx(SectionTitle, { id: "section-pending-rulecode", children: t('pages.activation.pendingRules') }), _jsx("p", { className: "mb-3 text-[12px] text-ink-3", children: t('pages.activation.pendingRulesDescription') }), _jsx("div", { className: "space-y-[14px]", children: pendingRuleCode.map(record => _jsx(ActivationFactCard, { record: record, lifecycleData: lifecycleCache[record.principleId], receiptCount: undefined, onDisable: handleDisable, disabling: disablingIds.has(record.activationId), onChanged: () => void loadData() }, record.activationId)) })] }), safetyAlerts.length > 0 && _jsxs("section", { className: "mt-8", "aria-labelledby": "section-safety-alerts", children: [_jsx(SectionTitle, { id: "section-safety-alerts", children: t('pages.activation.safetyAlerts') }), _jsx("p", { className: "mb-3 text-[12px] text-danger", children: t('pages.activation.safetyAlertsDescription') }), _jsx("div", { className: "space-y-[14px]", children: safetyAlerts.map(record => _jsx(ActivationFactCard, { record: record, lifecycleData: lifecycleCache[record.principleId], receiptCount: undefined, onDisable: handleDisable, disabling: disablingIds.has(record.activationId), onChanged: () => void loadData() }, record.activationId)) })] }), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-active", children: [_jsx(SectionTitle, { id: "section-active", children: t("pages.activation.sectionActive") }), ordinaryActive.length > 0 ? (_jsx("div", { className: "space-y-[14px]", children: ordinaryActive.map((record) => (_jsx(ActivationFactCard, { record: record, lifecycleData: lifecycleCache[record.principleId], receiptCount: receiptCounts !== null && !receiptCountsUntrustworthy ? (Object.hasOwn(receiptCounts, record.principleId) ? receiptCounts[record.principleId] : null) : undefined, onDisable: handleDisable, disabling: disablingIds.has(record.activationId), onChanged: () => void loadData() }, record.activationId))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.activation.emptyActive") }))] }), inactiveActivations.length > 0 && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-inactive", children: [_jsx(SectionTitle, { id: "section-inactive", children: t("pages.activation.sectionInactive") }), _jsx("div", { className: "space-y-[14px]", children: inactiveActivations.map((record) => (_jsx(ActivationFactCard, { record: record, lifecycleData: lifecycleCache[record.principleId], receiptCount: receiptCounts !== null && !receiptCountsUntrustworthy ? (Object.hasOwn(receiptCounts, record.principleId) ? receiptCounts[record.principleId] : null) : undefined, onDisable: handleDisable, disabling: disablingIds.has(record.activationId), onChanged: () => void loadData() }, record.activationId))) })] })), neverActivatedCount > 0 && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-never-activated", children: [_jsx(SectionTitle, { id: "section-never-activated", children: t("pages.activation.sectionNeverActivated") }), _jsx("div", { className: "space-y-[10px]", children: activations
273
285
  .filter((a) => a.activatedAt === null)
274
286
  .map((record) => (_jsxs("article", { className: "relative pl-[22px] py-[14px] pr-[18px] bg-panel border border-amber/20 border-l-[3px] border-l-amber rounded-[6px]", children: [_jsxs("div", { className: "text-ink-2 text-sm leading-relaxed", children: [_jsx("span", { className: "font-medium text-ink", children: t("pages.activation.neverActivatedCard") }), " ", "\u2014 ", record.action, " \u00B7 ", getChannelLabel(record.channel, t), _jsx("span", { className: "ml-2 font-mono text-[11px] text-ink-4", children: record.principleId })] }), _jsxs(Link, { to: "/debt", className: "inline-flex items-center mt-2 text-gov text-[13px] hover:underline focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: [t("pages.activation.viewDebt"), " \u2192"] })] }, record.activationId))) })] })), _jsx("footer", { className: "mt-12 pt-6 border-t border-line text-ink-3 text-[13px]", children: t("pages.activation.footer") })] }) }));
275
287
  }
@@ -74,12 +74,14 @@ function validateTask(v) {
74
74
  const taskKind = readString(v, "taskKind");
75
75
  const status = readString(v, "status");
76
76
  const attemptCount = readNumber(v, "attemptCount");
77
+ const maxAttempts = readNumber(v, "maxAttempts");
77
78
  const createdAt = readString(v, "createdAt");
78
79
  // Required fields — fail loud when missing or wrong type (rc-3)
79
80
  if (taskId === null ||
80
81
  taskKind === null ||
81
82
  status === null ||
82
83
  attemptCount === null ||
84
+ maxAttempts === null ||
83
85
  createdAt === null) {
84
86
  return null;
85
87
  }
@@ -93,6 +95,7 @@ function validateTask(v) {
93
95
  status,
94
96
  lastError,
95
97
  attemptCount,
98
+ maxAttempts,
96
99
  createdAt,
97
100
  lastAttemptAt,
98
101
  };
@@ -129,6 +132,10 @@ function statusToVariant(status) {
129
132
  return "amber";
130
133
  return "default";
131
134
  }
135
+ /** A failed task whose retry budget is spent — only a force recovery can requeue it. */
136
+ function isAttemptBudgetExhausted(task) {
137
+ return task.status === "failed" && task.attemptCount >= task.maxAttempts;
138
+ }
132
139
  function groupTasksByKind(tasks) {
133
140
  const grouped = new Map();
134
141
  for (const task of tasks) {
@@ -148,6 +155,16 @@ export function FailedTasksPage() {
148
155
  const [recoveryEnabled, setRecoveryEnabled] = useState(false);
149
156
  const [recoverTarget, setRecoverTarget] = useState(null);
150
157
  const [recoverLoading, setRecoverLoading] = useState(false);
158
+ // Exhausted targets recover with force: the dialog warns first and the
159
+ // action button becomes 强制恢复 (server refuses force=false for these).
160
+ const recoverExhausted = recoverTarget !== null && isAttemptBudgetExhausted(recoverTarget);
161
+ let recoverConfirmLabel = t("pages.failedTasks.recoverConfirmButton");
162
+ if (recoverLoading) {
163
+ recoverConfirmLabel = t("common.loading");
164
+ }
165
+ else if (recoverExhausted) {
166
+ recoverConfirmLabel = t("pages.failedTasks.recoverConfirmForceButton");
167
+ }
151
168
  useEffect(() => {
152
169
  let cancelled = false;
153
170
  fetchConfigSummary()
@@ -246,7 +263,7 @@ export function FailedTasksPage() {
246
263
  return;
247
264
  setRecoverLoading(true);
248
265
  try {
249
- const result = await recoverFailedTask(recoverTarget.taskId);
266
+ const result = await recoverFailedTask(recoverTarget.taskId, undefined, recoverExhausted);
250
267
  if (result.success) {
251
268
  toast.success(t("pages.failedTasks.recoverSuccess"));
252
269
  setRecoverTarget(null);
@@ -271,14 +288,17 @@ export function FailedTasksPage() {
271
288
  if (!open && !recoverLoading) {
272
289
  setRecoverTarget(null);
273
290
  }
274
- }, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: t("pages.failedTasks.recoverConfirmTitle") }), _jsx(AlertDialogDescription, { asChild: true, children: _jsxs("div", { className: "space-y-2 text-[13px] leading-relaxed", children: [_jsxs("div", { children: [_jsxs("span", { className: "font-medium", children: [t("pages.failedTasks.recoverConfirmStatus"), ":"] }), " ", _jsx("span", { className: "font-mono", children: recoverTarget?.status ?? "—" })] }), _jsxs("div", { children: [_jsxs("span", { className: "font-medium", children: [t("pages.failedTasks.recoverConfirmActionLabel"), ":"] }), " ", t("pages.failedTasks.recoverConfirmActionDesc")] }), _jsxs("div", { children: [_jsxs("span", { className: "font-medium", children: [t("pages.failedTasks.recoverConfirmImpactLabel"), ":"] }), " ", t("pages.failedTasks.recoverConfirmImpactDesc")] })] }) })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: recoverLoading, children: t("common.cancel") }), _jsx(AlertDialogAction, { disabled: recoverLoading, onClick: (event) => {
291
+ }, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: t("pages.failedTasks.recoverConfirmTitle") }), _jsx(AlertDialogDescription, { asChild: true, children: _jsxs("div", { className: "space-y-2 text-[13px] leading-relaxed", children: [_jsxs("div", { children: [_jsxs("span", { className: "font-medium", children: [t("pages.failedTasks.recoverConfirmStatus"), ":"] }), " ", _jsx("span", { className: "font-mono", children: recoverTarget?.status ?? "—" })] }), recoverExhausted && (_jsxs(_Fragment, { children: [_jsxs("div", { children: [_jsxs("span", { className: "font-medium", children: [t("pages.failedTasks.recoverConfirmAttempts"), ":"] }), " ", _jsxs("span", { className: "font-mono", children: [recoverTarget?.attemptCount, " / ", recoverTarget?.maxAttempts] })] }), _jsx("div", { className: "text-danger", children: t("pages.failedTasks.recoverExhaustedWarning", {
292
+ attempt: recoverTarget?.attemptCount ?? 0,
293
+ max: recoverTarget?.maxAttempts ?? 0,
294
+ }) })] })), _jsxs("div", { children: [_jsxs("span", { className: "font-medium", children: [t("pages.failedTasks.recoverConfirmActionLabel"), ":"] }), " ", t("pages.failedTasks.recoverConfirmActionDesc")] }), _jsxs("div", { children: [_jsxs("span", { className: "font-medium", children: [t("pages.failedTasks.recoverConfirmImpactLabel"), ":"] }), " ", recoverExhausted
295
+ ? t("pages.failedTasks.recoverConfirmForceImpactDesc")
296
+ : t("pages.failedTasks.recoverConfirmImpactDesc")] })] }) })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: recoverLoading, children: t("common.cancel") }), _jsx(AlertDialogAction, { disabled: recoverLoading, onClick: (event) => {
275
297
  // Prevent Radix from auto-closing before the async POST
276
298
  // resolves; handleRecoverConfirmed closes on success.
277
299
  event.preventDefault();
278
300
  void handleRecoverConfirmed();
279
- }, children: recoverLoading
280
- ? t("common.loading")
281
- : t("pages.failedTasks.recoverConfirmButton") })] })] }) })] }));
301
+ }, children: recoverConfirmLabel })] })] }) })] }));
282
302
  }
283
303
  function LoadedContent({ data, onCreateDraft, onRecover, t }) {
284
304
  const hasTasks = data.tasks.length > 0;
@@ -1,3 +1,4 @@
1
+ import type { GovernanceExperienceReasonCode, GovernanceExperienceNextActionCode, GovernancePrimaryAttention } from "@principles/core/runtime-v2";
1
2
  type DecisionResult = {
2
3
  success: true;
3
4
  } | {
@@ -10,5 +11,31 @@ export declare function summarizeDecisionResults(results: readonly DecisionResul
10
11
  failedCount: number;
11
12
  failureReason?: string;
12
13
  };
13
- export declare function FocusPage(): import("react").JSX.Element;
14
+ export interface OwnerConfigureCommand {
15
+ /** i18n key for the shell label, e.g. "pages.focus.experience.ownerGuide.cmdPowerShell". */
16
+ labelKey: string;
17
+ /** Exact multi-line command to set both variables in that shell. */
18
+ command: string;
19
+ }
20
+ export interface OwnerConfigureGuide {
21
+ docUrl: string;
22
+ commands: readonly OwnerConfigureCommand[];
23
+ }
24
+ export declare const OWNER_CONFIGURE_DOC_URL = "https://github.com/csuzngjh/principles/blob/main/docs/runbooks/ops/owner-identity-configuration.md";
25
+ export declare const OWNER_CONFIGURE_COMMANDS: readonly OwnerConfigureCommand[];
26
+ /** Returns the configure guide when the Owner identity is missing, else null. */
27
+ export declare function deriveOwnerConfigureGuide(ownerIdentityConfiguration: string | undefined): OwnerConfigureGuide | null;
28
+ export declare const EXPERIENCE_ATTENTION: Record<GovernancePrimaryAttention, {
29
+ labelKey: string;
30
+ badgeClass: string;
31
+ }>;
32
+ export declare const EXPERIENCE_REASON: Record<GovernanceExperienceReasonCode, string>;
33
+ export declare const EXPERIENCE_NEXT_ACTION: Record<GovernanceExperienceNextActionCode, string>;
34
+ export interface FocusPageProps {
35
+ /** Feature flags from /api/v1/config/summary — gates the experience snapshot path. */
36
+ featureFlags?: Record<string, {
37
+ enabled: boolean;
38
+ } | undefined>;
39
+ }
40
+ export declare function FocusPage({ featureFlags }: FocusPageProps): import("react").JSX.Element;
14
41
  export {};
@@ -9,6 +9,7 @@ import { SectionTitle } from "../../components/layout/section-title.js";
9
9
  import { DailyThoughtCard } from "../../components/focus/daily-thought-card.js";
10
10
  import { ShinyText } from "../../components/ui/shiny-text.js";
11
11
  import { fetchGovernanceQueue, fetchApprovalsGrouped, approveApproval, rejectApproval, editApproval, fetchAllActivations, } from "../../api.js";
12
+ import { fetchGovernanceExperience } from "../../api.js";
12
13
  export function summarizeDecisionResults(results) {
13
14
  const failures = results.filter((result) => !result.success);
14
15
  const first = failures[0];
@@ -137,6 +138,23 @@ function getDegradedNextActionText(code, t) {
137
138
  const text = t(i18nKey);
138
139
  return text === i18nKey ? code : text;
139
140
  }
141
+ export const OWNER_CONFIGURE_DOC_URL = "https://github.com/csuzngjh/principles/blob/main/docs/runbooks/ops/owner-identity-configuration.md";
142
+ export const OWNER_CONFIGURE_COMMANDS = [
143
+ {
144
+ labelKey: "pages.focus.experience.ownerGuide.cmdPowerShell",
145
+ command: "[Environment]::SetEnvironmentVariable('PD_OWNER_ID', '<owner-id>', 'User')\n[Environment]::SetEnvironmentVariable('PD_OWNER_CREDENTIAL_ID', '<credential-id>', 'User')",
146
+ },
147
+ {
148
+ labelKey: "pages.focus.experience.ownerGuide.cmdBash",
149
+ command: "echo 'export PD_OWNER_ID=\"<owner-id>\"' >> ~/.bashrc\necho 'export PD_OWNER_CREDENTIAL_ID=\"<credential-id>\"' >> ~/.bashrc\nsource ~/.bashrc",
150
+ },
151
+ ];
152
+ /** Returns the configure guide when the Owner identity is missing, else null. */
153
+ export function deriveOwnerConfigureGuide(ownerIdentityConfiguration) {
154
+ if (ownerIdentityConfiguration !== "missing")
155
+ return null;
156
+ return { docUrl: OWNER_CONFIGURE_DOC_URL, commands: OWNER_CONFIGURE_COMMANDS };
157
+ }
140
158
  // ── Channel label helper ─────────────────────────────────────────────────────
141
159
  function getChannelLabel(channel, t) {
142
160
  switch (channel) {
@@ -351,9 +369,89 @@ function DegradedSummary({ signals }) {
351
369
  const { t } = useTranslation();
352
370
  return (_jsxs("div", { className: "bg-panel border border-amber/20 border-l-[3px] border-l-amber rounded-[6px] p-5", children: [_jsx(SectionTitle, { children: t("pages.focus.degradedTitle") }), _jsx("p", { className: "text-ink-2 text-sm leading-relaxed mt-2", children: t("pages.focus.degradedStateReason") }), _jsx("div", { className: "mt-4 space-y-[10px]", children: signals.map((signal, i) => (_jsx(DegradedSignalCard, { signal: signal }, `${signal.source}-${i}`))) })] }));
353
371
  }
354
- export function FocusPage() {
372
+ // ── PRI-586: Governance Experience Snapshot display ─────────────────────────
373
+ // Exhaustive Record maps over the snapshot enums (ERR-106: no binary ternaries
374
+ // folding union members into a default branch). Exported for the i18n parity
375
+ // test; keys must exist in BOTH en.json and zh-CN.json (cr10).
376
+ export const EXPERIENCE_ATTENTION = {
377
+ setup_required: { labelKey: "pages.focus.experience.attention.setupRequired", badgeClass: "bg-amber/10 text-amber border border-amber/20" },
378
+ owner_decision_required: { labelKey: "pages.focus.experience.attention.ownerDecisionRequired", badgeClass: "bg-gov/10 text-gov border border-gov/20" },
379
+ recovery_required: { labelKey: "pages.focus.experience.attention.recoveryRequired", badgeClass: "bg-amber/10 text-amber border border-amber/20" },
380
+ degraded: { labelKey: "pages.focus.experience.attention.degraded", badgeClass: "bg-amber/10 text-amber border border-amber/20" },
381
+ background_processing: { labelKey: "pages.focus.experience.attention.backgroundProcessing", badgeClass: "bg-green/10 text-green border border-green/20" },
382
+ all_clear: { labelKey: "pages.focus.experience.attention.allClear", badgeClass: "text-ink-4 border border-line bg-surface/80" },
383
+ };
384
+ export const EXPERIENCE_REASON = {
385
+ "governance.exp.reason.owner_identity_missing": "pages.focus.experience.reason.ownerIdentityMissing",
386
+ "governance.exp.reason.approval_pending": "pages.focus.experience.reason.approvalPending",
387
+ "governance.exp.reason.rulecode_owner_decision": "pages.focus.experience.reason.rulecodeOwnerDecision",
388
+ "governance.exp.reason.no_pending_decision": "pages.focus.experience.reason.noPendingDecision",
389
+ "governance.exp.reason.owner_decision_available": "pages.focus.experience.reason.ownerDecisionAvailable",
390
+ "governance.exp.reason.break_glass_entry": "pages.focus.experience.reason.breakGlassEntry",
391
+ "governance.exp.reason.recovery_required": "pages.focus.experience.reason.recoveryRequired",
392
+ "governance.exp.reason.source_unavailable": "pages.focus.experience.reason.sourceUnavailable",
393
+ "governance.exp.reason.config_invalid": "pages.focus.experience.reason.configInvalid",
394
+ "governance.exp.reason.processing": "pages.focus.experience.reason.processing",
395
+ "governance.exp.reason.workspace_clear": "pages.focus.experience.reason.workspaceClear",
396
+ "governance.exp.reason.workspace_empty": "pages.focus.experience.reason.workspaceEmpty",
397
+ };
398
+ export const EXPERIENCE_NEXT_ACTION = {
399
+ "governance.exp.next.configure_owner": "pages.focus.experience.next.configureOwner",
400
+ "governance.exp.next.review_approvals": "pages.focus.experience.next.reviewApprovals",
401
+ "governance.exp.next.inspect_recovery": "pages.focus.experience.next.inspectRecovery",
402
+ "governance.exp.next.inspect_sources": "pages.focus.experience.next.inspectSources",
403
+ "governance.exp.next.fix_config": "pages.focus.experience.next.fixConfig",
404
+ "governance.exp.next.monitor": "pages.focus.experience.next.monitor",
405
+ "governance.exp.next.none": "pages.focus.experience.next.none",
406
+ };
407
+ const EXPERIENCE_ENVIRONMENT = {
408
+ production: "pages.focus.experience.trust.environment.production",
409
+ development: "pages.focus.experience.trust.environment.development",
410
+ demo: "pages.focus.experience.trust.environment.demo",
411
+ test: "pages.focus.experience.trust.environment.test",
412
+ unknown: "pages.focus.experience.trust.environment.unknown",
413
+ };
414
+ function ExperienceSummaryCard({ snapshot }) {
355
415
  const { t } = useTranslation();
416
+ const [copiedCommandIdx, setCopiedCommandIdx] = useState(null);
417
+ const attention = EXPERIENCE_ATTENTION[snapshot.summary.primaryAttention];
418
+ const categoryOf = (category) => snapshot.activity.categories.find(entry => entry.category === category);
419
+ const decision = categoryOf("needs_decision");
420
+ const recovery = categoryOf("needs_recovery");
421
+ const blocked = categoryOf("blocked");
422
+ const processing = categoryOf("processing");
423
+ const actionOf = (kind) => snapshot.readiness.governanceActions.find(action => action.kind === kind);
424
+ const rulecodeAction = actionOf("rulecode_owner_decision");
425
+ const pauseAction = actionOf("emergency_pause");
426
+ const firstIssue = snapshot.dataQuality.issueGroups[0];
427
+ const ownerGuide = deriveOwnerConfigureGuide(snapshot.readiness.ownerIdentityConfiguration);
428
+ return (_jsxs("div", { className: "mb-7 px-[18px] py-[14px] bg-panel border border-line rounded-[6px]", "data-testid": "experience-summary", children: [_jsx("div", { className: "flex items-center gap-2 mb-1", children: _jsx("span", { className: `inline-flex items-center rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${attention.badgeClass}`, role: "status", children: t(attention.labelKey) }) }), _jsx("div", { className: "text-ink-2 text-[13px] leading-relaxed mt-1", "data-testid": "experience-reason", children: t(EXPERIENCE_REASON[snapshot.summary.reasonCode]) }), _jsxs("div", { className: "text-ink-4 text-[13px] leading-relaxed mt-1", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.nextActionLabel") }), " ", t(EXPERIENCE_NEXT_ACTION[snapshot.summary.nextActionCode])] }), (decision !== undefined || recovery !== undefined || blocked !== undefined || processing !== undefined) && (_jsxs("div", { className: "text-[13px] text-ink-3 mt-2 leading-relaxed", "data-testid": "experience-activity", children: [decision !== undefined && (_jsx("span", { className: "mr-4", children: t("pages.focus.experience.activity.needsDecision", { count: decision.count }) })), recovery !== undefined && (_jsx("span", { className: "mr-4", children: t("pages.focus.experience.activity.needsRecovery", { count: recovery.count }) })), blocked !== undefined && _jsx("span", { className: "mr-4", children: t("pages.focus.experience.activity.blocked") }), processing !== undefined && (_jsx("span", { children: t("pages.focus.experience.activity.processing", { count: processing.count }) }))] })), _jsxs("div", { className: "mt-2 text-[12px] text-ink-4 leading-relaxed", "data-testid": "experience-readiness", children: [t(`pages.focus.experience.readiness.identity.${snapshot.readiness.ownerIdentityConfiguration}`), " · ", t("pages.focus.experience.readiness.principleApproval"), t(`pages.focus.experience.readiness.rulecode.${rulecodeAction?.status === "blocked" ? "blocked" : "ready"}`), t(`pages.focus.experience.readiness.pause.${pauseAction?.observedAuthority === "break_glass" ? "breakGlass" : "owner"}`)] }), ownerGuide !== null && (_jsxs("div", { className: "mt-3 border border-line rounded-[6px] bg-panel px-3 py-2.5", "data-testid": "owner-configure-guide", children: [_jsx("div", { className: "text-[13px] font-medium", children: t("pages.focus.experience.ownerGuide.title") }), _jsx("div", { className: "mt-0.5 text-[12px] text-ink-3 leading-relaxed", children: t("pages.focus.experience.ownerGuide.intro") }), _jsx("div", { className: "mt-2 space-y-2", children: ownerGuide.commands.map((cmd, idx) => (_jsxs("div", { className: "border border-line rounded-[4px] overflow-hidden bg-surface", children: [_jsxs("div", { className: "flex items-center justify-between px-2.5 py-1", children: [_jsx("span", { className: "font-mono text-[11px] uppercase text-ink-3", children: t(cmd.labelKey) }), _jsx("button", { type: "button", onClick: async () => {
429
+ try {
430
+ await navigator.clipboard.writeText(cmd.command);
431
+ setCopiedCommandIdx(idx);
432
+ setTimeout(() => setCopiedCommandIdx(null), 2000);
433
+ }
434
+ catch (error) {
435
+ // clipboard unavailable — keep the command visible as fallback
436
+ console.warn("Owner configure command copy failed.", error);
437
+ }
438
+ }, className: "font-mono text-[11px] text-gov hover:text-gov-2", children: copiedCommandIdx === idx
439
+ ? t("pages.focus.experience.ownerGuide.copied")
440
+ : t("pages.focus.experience.ownerGuide.copy") })] }), _jsx("pre", { className: "px-2.5 pb-2 pt-0.5 text-[11px] font-mono text-ink-2 leading-relaxed overflow-x-auto whitespace-pre-wrap", children: cmd.command })] }, cmd.labelKey))) }), _jsx("p", { className: "mt-2 text-[12px] text-amber leading-relaxed", "data-testid": "owner-guide-token-auth-hint", children: t("pages.focus.experience.ownerGuide.tokenAuthHint") }), _jsx("a", { href: ownerGuide.docUrl, target: "_blank", rel: "noreferrer", className: "mt-2 inline-block text-[12px] text-gov underline hover:text-gov-2", children: t("pages.focus.experience.ownerGuide.docLink") })] })), _jsxs("div", { className: "mt-1 text-[12px] text-ink-4", "data-testid": "experience-trust", children: [t(EXPERIENCE_ENVIRONMENT[snapshot.trustContext.environmentContext.environment]), " · ", t(`pages.focus.experience.trust.lineage.${snapshot.trustContext.lineageTransparency.confidence}`)] }), snapshot.dataQuality.degraded && (_jsx("div", { className: "mt-2 text-[12px] text-amber leading-relaxed", "data-testid": "experience-data-quality", children: t("pages.focus.experience.dataQuality.degraded", { count: firstIssue?.count ?? 0, reasonCode: firstIssue?.reasonCode ?? "" }) }))] }));
441
+ }
442
+ export function FocusPage({ featureFlags }) {
443
+ const { t } = useTranslation();
444
+ // PRI-586: when governance_experience_v1 is enabled the governance summary
445
+ // comes ONLY from the experience snapshot — the legacy queue endpoint is not
446
+ // consulted (SPEC §14.2 no old-queue + snapshot merge). Approvals and
447
+ // activations remain the MUTATION surface (action cards), not a status source.
448
+ const experienceMode = featureFlags?.governance_experience_v1?.enabled === true;
449
+ // Flags still loading (undefined): fire NEITHER governance status endpoint —
450
+ // otherwise a transient legacy queue request goes out before the flag turns
451
+ // experience mode on (wasted call + legacy-panel flash). Hold in `loading`.
452
+ const flagsResolved = featureFlags !== undefined;
356
453
  const [queueData, setQueueData] = useState(null);
454
+ const [experienceData, setExperienceData] = useState(null);
357
455
  const [groupedData, setGroupedData] = useState(null);
358
456
  const [loadingState, setLoadingState] = useState("loading");
359
457
  const [errorMessage, setErrorMessage] = useState(null);
@@ -365,18 +463,31 @@ export function FocusPage() {
365
463
  setErrorMessage(null);
366
464
  setGroupedErrorReason(null);
367
465
  setRuleCodeErrorReason(null);
368
- const [queueResult, groupedResult, activationsResult] = await Promise.all([
369
- fetchGovernanceQueue(),
466
+ const [experienceResult, queueResult, groupedResult, activationsResult] = await Promise.all([
467
+ experienceMode ? fetchGovernanceExperience() : Promise.resolve(null),
468
+ experienceMode ? Promise.resolve(null) : fetchGovernanceQueue(),
370
469
  fetchApprovalsGrouped(),
371
470
  fetchAllActivations(),
372
471
  ]);
373
- // Queue data is already validated by the API layer (validateGovernanceQueue)
374
- if (!queueResult.success) {
375
- setLoadingState("error");
376
- setErrorMessage(queueResult.error);
377
- return;
472
+ if (experienceMode) {
473
+ if (experienceResult === null || !experienceResult.success) {
474
+ setLoadingState("error");
475
+ setErrorMessage(experienceResult === null ? t("pages.focus.experience.error.snapshotUnavailable") : experienceResult.error);
476
+ return;
477
+ }
478
+ setExperienceData(experienceResult.data);
479
+ setQueueData(null);
480
+ }
481
+ else {
482
+ // Queue data is already validated by the API layer (validateGovernanceQueue)
483
+ if (queueResult === null || !queueResult.success) {
484
+ setLoadingState("error");
485
+ setErrorMessage(queueResult === null ? t("pages.focus.loadError") : queueResult.error);
486
+ return;
487
+ }
488
+ setQueueData(queueResult.data);
489
+ setExperienceData(null);
378
490
  }
379
- setQueueData(queueResult.data);
380
491
  // Validate grouped data (ERR-002: degradation with reason)
381
492
  if (!groupedResult.success) {
382
493
  setGroupedData(null);
@@ -397,10 +508,12 @@ export function FocusPage() {
397
508
  setRuleCodeErrorReason(activationsResult.error);
398
509
  }
399
510
  setLoadingState("loaded");
400
- }, []);
511
+ }, [experienceMode, t]);
401
512
  useEffect(() => {
513
+ if (!flagsResolved)
514
+ return;
402
515
  loadData();
403
- }, [loadData]);
516
+ }, [flagsResolved, loadData]);
404
517
  // ── Loading state ────────────────────────────────────────────────────────
405
518
  if (loadingState === "loading") {
406
519
  return (_jsx(PageShell, { children: _jsx(PageLoading, { cardCount: 3, label: t("common.loading") }) }));
@@ -432,17 +545,17 @@ export function FocusPage() {
432
545
  const stateReasonCount = stateReasonCode === "tasks_need_human_review" ? humanReviewCount : pendingCount;
433
546
  const stateReason = getStateReasonText(stateReasonCode, t, stateReasonCount);
434
547
  const nextAction = getNextActionText(nextActionCode, t);
435
- return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.focus.eyebrow") }), _jsx(ShinyText, { as: "h1", className: "text-[29px] font-semibold tracking-tight text-ink mb-2", duration: 4.5, brightness: 0.5, disabled: pendingCount === 0, children: t("pages.focus.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.focus.subtitle") }), _jsxs("div", { className: "mb-7 px-[18px] py-[14px] bg-panel border border-line rounded-[6px]", children: [_jsx("div", { className: "flex items-center gap-2 mb-1", children: _jsx("span", { className: `inline-flex items-center rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${governanceState === "owner_review_ready"
548
+ return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.focus.eyebrow") }), _jsx(ShinyText, { as: "h1", className: "text-[29px] font-semibold tracking-tight text-ink mb-2", duration: 4.5, brightness: 0.5, disabled: pendingCount === 0, children: t("pages.focus.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.focus.subtitle") }), experienceMode && experienceData !== null ? (_jsx(ExperienceSummaryCard, { snapshot: experienceData })) : !experienceMode ? (_jsxs("div", { className: "mb-7 px-[18px] py-[14px] bg-panel border border-line rounded-[6px]", children: [_jsx("div", { className: "flex items-center gap-2 mb-1", children: _jsx("span", { className: `inline-flex items-center rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${governanceState === "owner_review_ready"
436
549
  ? "bg-gov/10 text-gov border border-gov/20"
437
550
  : governanceState === "degraded"
438
551
  ? "bg-amber/10 text-amber border border-amber/20"
439
552
  : governanceState === "in_progress"
440
553
  ? "bg-green/10 text-green border border-green/20"
441
- : "text-ink-4 border border-line bg-surface/80"}`, role: "status", children: t(`pages.focus.stateLabel.${governanceState}`) }) }), _jsx("div", { className: "text-ink-2 text-[13px] leading-relaxed mt-1", children: stateReason }), _jsxs("div", { className: "text-ink-4 text-[13px] leading-relaxed mt-1", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.nextActionLabel") }), " ", nextAction] })] }), _jsx(ProseSummary, { pendingCount: pendingCount, deviationCount: deviationCount, stagnationCount: stagnationCount, evidenceCount: evidenceCount }), _jsx(DailyThoughtCard, {}), _jsx(FeedbackStratification, { gateBlocksToday: gateBlocksToday, inProgressCount: evidenceCount, pendingCount: pendingCount }), governanceState === "none" && pendingCount === 0 && deviationCount === 0 && stagnationCount === 0 && (stateReasonCode === "state_db_missing" ? (_jsx(ZeroStateDbMissing, {})) : (_jsxs(_Fragment, { children: [_jsx(ZeroStateHealthy, {}), _jsx("div", { className: "mt-4", children: _jsx(OnboardingGuide, {}) })] }))), governanceState === "in_progress" && inProgressSummary && (_jsx(InProgressGuide, { summary: inProgressSummary })), degradedSignals && degradedSignals.length > 0 && (_jsx(DegradedSummary, { signals: degradedSignals })), (ruleCodeErrorReason || ruleCodePending.length > 0 || ruleCodeAlerts.length > 0) && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-rulecode-owner", children: [_jsx(SectionTitle, { id: "section-rulecode-owner", children: t("pages.focus.ruleCodeOwnerQueue") }), ruleCodeErrorReason && (_jsxs("div", { className: "mb-3 rounded border border-amber/30 bg-panel p-4 text-[12px] text-ink-3", children: [_jsx("div", { className: "font-medium text-amber", children: t("pages.focus.ruleCodeUnavailable") }), _jsx("div", { className: "mt-1 font-mono", children: ruleCodeErrorReason }), _jsx("div", { className: "mt-1", children: t("pages.focus.ruleCodeUnavailableNextAction") })] })), _jsxs("div", { className: "grid gap-3 md:grid-cols-2", children: [ruleCodePending.length > 0 && (_jsxs(Link, { to: "/activation", className: "rounded border border-gov/30 bg-panel p-4 hover:border-gov", children: [_jsx("div", { className: "font-medium text-ink", children: t("pages.focus.ruleCodePending") }), _jsx("div", { className: "mt-1 text-[12px] text-ink-3", children: t("pages.focus.ruleCodePendingCount", { count: ruleCodePending.length }) })] })), ruleCodeAlerts.length > 0 && (_jsxs(Link, { to: "/activation", className: "rounded border border-danger/30 bg-panel p-4 hover:border-danger", children: [_jsx("div", { className: "font-medium text-danger", children: t("pages.focus.ruleCodeAlerts") }), _jsx("div", { className: "mt-1 text-[12px] text-ink-3", children: t("pages.focus.ruleCodeAlertCount", { count: ruleCodeAlerts.length }) })] }))] })] })), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-pending", children: [_jsx(SectionTitle, { id: "section-pending", children: t("pages.focus.sectionPending") }), pendingGroups.length > 0 ? (_jsx("div", { className: "space-y-[14px]", children: pendingGroups.map((group) => (_jsx(PendingReviewCard, { group: group, onDecisionApplied: loadData }, group.principleId))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: approvalDataUnavailable
554
+ : "text-ink-4 border border-line bg-surface/80"}`, role: "status", children: t(`pages.focus.stateLabel.${governanceState}`) }) }), _jsx("div", { className: "text-ink-2 text-[13px] leading-relaxed mt-1", children: stateReason }), _jsxs("div", { className: "text-ink-4 text-[13px] leading-relaxed mt-1", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.nextActionLabel") }), " ", nextAction] })] })) : null, !experienceMode && (_jsxs(_Fragment, { children: [_jsx(ProseSummary, { pendingCount: pendingCount, deviationCount: deviationCount, stagnationCount: stagnationCount, evidenceCount: evidenceCount }), _jsx(FeedbackStratification, { gateBlocksToday: gateBlocksToday, inProgressCount: evidenceCount, pendingCount: pendingCount }), !experienceMode && governanceState === "none" && pendingCount === 0 && deviationCount === 0 && stagnationCount === 0 && (stateReasonCode === "state_db_missing" ? (_jsx(ZeroStateDbMissing, {})) : (_jsxs(_Fragment, { children: [_jsx(ZeroStateHealthy, {}), _jsx("div", { className: "mt-4", children: _jsx(OnboardingGuide, {}) })] }))), governanceState === "in_progress" && inProgressSummary && (_jsx(InProgressGuide, { summary: inProgressSummary })), degradedSignals && degradedSignals.length > 0 && (_jsx(DegradedSummary, { signals: degradedSignals }))] })), _jsx(DailyThoughtCard, {}), experienceMode && experienceData !== null && experienceData.summary.primaryAttention === "all_clear" && pendingGroups.length === 0 && (_jsx("div", { className: "mt-4", children: _jsx(OnboardingGuide, {}) })), (ruleCodeErrorReason || ruleCodePending.length > 0 || ruleCodeAlerts.length > 0) && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-rulecode-owner", children: [_jsx(SectionTitle, { id: "section-rulecode-owner", children: t("pages.focus.ruleCodeOwnerQueue") }), ruleCodeErrorReason && (_jsxs("div", { className: "mb-3 rounded border border-amber/30 bg-panel p-4 text-[12px] text-ink-3", children: [_jsx("div", { className: "font-medium text-amber", children: t("pages.focus.ruleCodeUnavailable") }), _jsx("div", { className: "mt-1 font-mono", children: ruleCodeErrorReason }), _jsx("div", { className: "mt-1", children: t("pages.focus.ruleCodeUnavailableNextAction") })] })), _jsxs("div", { className: "grid gap-3 md:grid-cols-2", children: [ruleCodePending.length > 0 && (_jsxs(Link, { to: "/activation", className: "rounded border border-gov/30 bg-panel p-4 hover:border-gov", children: [_jsx("div", { className: "font-medium text-ink", children: t("pages.focus.ruleCodePending") }), _jsx("div", { className: "mt-1 text-[12px] text-ink-3", children: t("pages.focus.ruleCodePendingCount", { count: ruleCodePending.length }) })] })), ruleCodeAlerts.length > 0 && (_jsxs(Link, { to: "/activation", className: "rounded border border-danger/30 bg-panel p-4 hover:border-danger", children: [_jsx("div", { className: "font-medium text-danger", children: t("pages.focus.ruleCodeAlerts") }), _jsx("div", { className: "mt-1 text-[12px] text-ink-3", children: t("pages.focus.ruleCodeAlertCount", { count: ruleCodeAlerts.length }) })] }))] })] })), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-pending", children: [_jsx(SectionTitle, { id: "section-pending", children: t("pages.focus.sectionPending") }), pendingGroups.length > 0 ? (_jsx("div", { className: "space-y-[14px]", children: pendingGroups.map((group) => (_jsx(PendingReviewCard, { group: group, onDecisionApplied: loadData }, group.principleId))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: approvalDataUnavailable
442
555
  ? (groupedErrorReason
443
556
  ? `${t("pages.focus.loadError")} (${groupedErrorReason})`
444
557
  : t("pages.focus.loadError"))
445
- : t("pages.focus.emptyPending") }))] }), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-deviation", children: [_jsx(SectionTitle, { id: "section-deviation", children: evidenceCount > 0
558
+ : t("pages.focus.emptyPending") }))] }), !experienceMode && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-deviation", children: [_jsx(SectionTitle, { id: "section-deviation", children: evidenceCount > 0
446
559
  ? t("pages.focus.sectionEvidenceInProgress")
447
- : t("pages.focus.sectionDeviation") }), deviationCount > 0 ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-ink-2 text-sm mb-3", children: [_jsx("span", { className: "font-mono font-semibold text-ink", children: deviationCount }), " ", t("pages.focus.deviationCount", { count: deviationCount })] }), _jsx("div", { className: "text-ink-4 text-[13px] bg-surface/60 border-l-2 border-amber px-3 py-2 mb-4", children: t("pages.focus.deviationDisclaimer") }), _jsxs("details", { className: "group", children: [_jsx("summary", { className: "text-gov text-[13px] cursor-pointer hover:underline focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.focus.viewFullChain") }), _jsx("div", { className: "mt-2 pl-4 border-l-2 border-line text-ink-3 text-[13px]", children: t("pages.focus.deviationDetailPending") })] })] })) : evidenceCount > 0 ? (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.evidenceInProgress", { count: evidenceCount }) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.emptyDeviation") }))] }), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-signals", children: [_jsx(SectionTitle, { id: "section-signals", children: t("pages.focus.sectionSignals") }), stagnationSignals.length > 0 ? (_jsx("div", { className: "space-y-[10px]", children: stagnationSignals.map((signal) => (_jsx(StagnationSignalCard, { signal: signal }, signal.principleId))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.emptySignals") }))] }), _jsx("footer", { className: "mt-12 pt-6 border-t border-line text-ink-3 text-[13px]", children: t("pages.focus.footer") })] }) }));
560
+ : t("pages.focus.sectionDeviation") }), deviationCount > 0 ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-ink-2 text-sm mb-3", children: [_jsx("span", { className: "font-mono font-semibold text-ink", children: deviationCount }), " ", t("pages.focus.deviationCount", { count: deviationCount })] }), _jsx("div", { className: "text-ink-4 text-[13px] bg-surface/60 border-l-2 border-amber px-3 py-2 mb-4", children: t("pages.focus.deviationDisclaimer") }), _jsxs("details", { className: "group", children: [_jsx("summary", { className: "text-gov text-[13px] cursor-pointer hover:underline focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.focus.viewFullChain") }), _jsx("div", { className: "mt-2 pl-4 border-l-2 border-line text-ink-3 text-[13px]", children: t("pages.focus.deviationDetailPending") })] })] })) : evidenceCount > 0 ? (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.evidenceInProgress", { count: evidenceCount }) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.emptyDeviation") }))] })), !experienceMode && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-signals", children: [_jsx(SectionTitle, { id: "section-signals", children: t("pages.focus.sectionSignals") }), stagnationSignals.length > 0 ? (_jsx("div", { className: "space-y-[10px]", children: stagnationSignals.map((signal) => (_jsx(StagnationSignalCard, { signal: signal }, signal.principleId))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.emptySignals") }))] })), _jsx("footer", { className: "mt-12 pt-6 border-t border-line text-ink-3 text-[13px]", children: t("pages.focus.footer") })] }) }));
448
561
  }
@@ -2,4 +2,34 @@ export declare function getReceiptPresentation(effectCount: number): {
2
2
  headlineKey: 'principles.detail.receipts.headline' | 'principles.detail.receipts.headlinePresence';
3
3
  showZeroEffectExplanation: boolean;
4
4
  };
5
+ export type GovernanceControlBlock = {
6
+ source: 'server';
7
+ reason: string;
8
+ nextAction?: string;
9
+ } | {
10
+ source: 'i18n';
11
+ reasonKey: string;
12
+ nextActionKey?: string;
13
+ };
14
+ export declare const GOVERNANCE_BLOCK_I18N_KEYS: {
15
+ readonly recoveryReason: 'principles.detail.governance.reason.recovery_required';
16
+ readonly recoveryNextAction: 'principles.detail.governance.next.inspect_recovery';
17
+ readonly noDecisionReason: 'principles.detail.governance.actionsNotAuthorized';
18
+ readonly nextActionLabel: 'principles.detail.governance.nextActionLabel';
19
+ };
20
+ /**
21
+ * Returns `null` when decision controls may render; otherwise the reason they
22
+ * must stay hidden.
23
+ */
24
+ export declare function deriveGovernanceControlBlock(input: {
25
+ governance: {
26
+ attention: {
27
+ primary: 'none' | 'owner_required' | 'recovery_required';
28
+ };
29
+ } | null;
30
+ governanceUnavailable: {
31
+ reason: string;
32
+ nextAction?: string;
33
+ } | null;
34
+ }): GovernanceControlBlock | null;
5
35
  export declare function PrincipleDetailPage(): import("react").JSX.Element;