create-principles-disciple 1.121.7 → 1.121.9

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 (461) 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 +186 -32
  27. package/console/dist/shared/feedback-channel-ids.d.ts +13 -0
  28. package/console/dist/shared/feedback-channel-ids.js +12 -0
  29. package/console/dist/shared/feedback-contract.d.ts +46 -0
  30. package/console/dist/shared/feedback-contract.js +45 -0
  31. package/console/dist/ui/App.js +1 -1
  32. package/console/dist/ui/api.d.ts +22 -3
  33. package/console/dist/ui/api.js +63 -3
  34. package/console/dist/ui/components/receipts/ReceiptCoverageDisclosure.d.ts +6 -0
  35. package/console/dist/ui/components/receipts/ReceiptCoverageDisclosure.js +66 -0
  36. package/console/dist/ui/i18n/en.json +198 -2
  37. package/console/dist/ui/i18n/zh-CN.json +196 -0
  38. package/console/dist/ui/pages/activation/ActivationPage.js +14 -2
  39. package/console/dist/ui/pages/failed-tasks/FailedTasksPage.js +25 -5
  40. package/console/dist/ui/pages/focus/FocusPage.d.ts +28 -1
  41. package/console/dist/ui/pages/focus/FocusPage.js +128 -15
  42. package/console/dist/ui/pages/principles/PrincipleDetailPage.d.ts +30 -0
  43. package/console/dist/ui/pages/principles/PrincipleDetailPage.js +49 -6
  44. package/console/dist/ui/pages/settings/SettingsPage.js +67 -2
  45. package/console/dist/ui/pages/settings/UpdatePage.js +7 -7
  46. package/console/dist/ui/utils/enum-labels.js +0 -1
  47. package/console/dist/ui/utils/validators.d.ts +53 -21
  48. package/console/dist/ui/utils/validators.js +248 -21
  49. package/console/dist/web/assets/app.css +6 -0
  50. package/console/dist/web/assets/app.js +2721 -1664
  51. package/console/package.json +4 -2
  52. package/core/dist/host/host-adapter.d.ts +1 -1
  53. package/core/dist/host/host-adapter.d.ts.map +1 -1
  54. package/core/dist/host/host-adapter.js +1 -0
  55. package/core/dist/host/host-adapter.js.map +1 -1
  56. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +12 -2
  57. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  58. package/core/dist/runtime-v2/__tests__/attack-e2e-pipeline-smoke.test.js +1 -1
  59. package/core/dist/runtime-v2/__tests__/attack-e2e-pipeline-smoke.test.js.map +1 -1
  60. package/core/dist/runtime-v2/__tests__/governance-experience.test.d.ts +2 -0
  61. package/core/dist/runtime-v2/__tests__/governance-experience.test.d.ts.map +1 -0
  62. package/core/dist/runtime-v2/__tests__/governance-experience.test.js +300 -0
  63. package/core/dist/runtime-v2/__tests__/governance-experience.test.js.map +1 -0
  64. package/core/dist/runtime-v2/__tests__/owner-identity.test.d.ts +2 -0
  65. package/core/dist/runtime-v2/__tests__/owner-identity.test.d.ts.map +1 -0
  66. package/core/dist/runtime-v2/__tests__/owner-identity.test.js +147 -0
  67. package/core/dist/runtime-v2/__tests__/owner-identity.test.js.map +1 -0
  68. package/core/dist/runtime-v2/__tests__/product-telemetry-contract.test.d.ts +18 -0
  69. package/core/dist/runtime-v2/__tests__/product-telemetry-contract.test.d.ts.map +1 -0
  70. package/core/dist/runtime-v2/__tests__/product-telemetry-contract.test.js +303 -0
  71. package/core/dist/runtime-v2/__tests__/product-telemetry-contract.test.js.map +1 -0
  72. package/core/dist/runtime-v2/__tests__/recovery-actions-log.test.js +40 -0
  73. package/core/dist/runtime-v2/__tests__/recovery-actions-log.test.js.map +1 -1
  74. package/core/dist/runtime-v2/__tests__/status-contract.test.d.ts +2 -0
  75. package/core/dist/runtime-v2/__tests__/status-contract.test.d.ts.map +1 -0
  76. package/core/dist/runtime-v2/__tests__/status-contract.test.js +107 -0
  77. package/core/dist/runtime-v2/__tests__/status-contract.test.js.map +1 -0
  78. package/core/dist/runtime-v2/activation/__tests__/promotion-evidence-snapshot.test.d.ts +2 -0
  79. package/core/dist/runtime-v2/activation/__tests__/promotion-evidence-snapshot.test.d.ts.map +1 -0
  80. package/core/dist/runtime-v2/activation/__tests__/promotion-evidence-snapshot.test.js +104 -0
  81. package/core/dist/runtime-v2/activation/__tests__/promotion-evidence-snapshot.test.js.map +1 -0
  82. package/core/dist/runtime-v2/activation/__tests__/promotion-readiness-evaluator.test.js +19 -0
  83. package/core/dist/runtime-v2/activation/__tests__/promotion-readiness-evaluator.test.js.map +1 -1
  84. package/core/dist/runtime-v2/activation/__tests__/rulecode-owner-decision-service.test.js +20 -0
  85. package/core/dist/runtime-v2/activation/__tests__/rulecode-owner-decision-service.test.js.map +1 -1
  86. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-safety-store.test.js +40 -0
  87. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-safety-store.test.js.map +1 -1
  88. package/core/dist/runtime-v2/activation/index.d.ts +2 -0
  89. package/core/dist/runtime-v2/activation/index.d.ts.map +1 -1
  90. package/core/dist/runtime-v2/activation/index.js +1 -0
  91. package/core/dist/runtime-v2/activation/index.js.map +1 -1
  92. package/core/dist/runtime-v2/activation/promotion-evidence-snapshot.d.ts +30 -0
  93. package/core/dist/runtime-v2/activation/promotion-evidence-snapshot.d.ts.map +1 -0
  94. package/core/dist/runtime-v2/activation/promotion-evidence-snapshot.js +87 -0
  95. package/core/dist/runtime-v2/activation/promotion-evidence-snapshot.js.map +1 -0
  96. package/core/dist/runtime-v2/activation/promotion-readiness-evaluator.d.ts.map +1 -1
  97. package/core/dist/runtime-v2/activation/promotion-readiness-evaluator.js +3 -0
  98. package/core/dist/runtime-v2/activation/promotion-readiness-evaluator.js.map +1 -1
  99. package/core/dist/runtime-v2/activation/promotion-readiness-reader.d.ts +1 -1
  100. package/core/dist/runtime-v2/activation/promotion-readiness-reader.d.ts.map +1 -1
  101. package/core/dist/runtime-v2/activation/promotion-readiness-reader.js +2 -2
  102. package/core/dist/runtime-v2/activation/promotion-readiness-reader.js.map +1 -1
  103. package/core/dist/runtime-v2/activation/rulecode-owner-decision-service.d.ts.map +1 -1
  104. package/core/dist/runtime-v2/activation/rulecode-owner-decision-service.js +18 -9
  105. package/core/dist/runtime-v2/activation/rulecode-owner-decision-service.js.map +1 -1
  106. package/core/dist/runtime-v2/adapter/__tests__/chaos-json-repair.test.js +1 -1
  107. package/core/dist/runtime-v2/adapter/__tests__/chaos-json-repair.test.js.map +1 -1
  108. package/core/dist/runtime-v2/adapter/__tests__/json-extractor.test.js +91 -1
  109. package/core/dist/runtime-v2/adapter/__tests__/json-extractor.test.js.map +1 -1
  110. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-runtime-adapter.test.js +59 -12
  111. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-runtime-adapter.test.js.map +1 -1
  112. package/core/dist/runtime-v2/adapter/__tests__/runtime-config-contract.test.js +10 -9
  113. package/core/dist/runtime-v2/adapter/__tests__/runtime-config-contract.test.js.map +1 -1
  114. package/core/dist/runtime-v2/adapter/__tests__/structured-output-repair.test.js +42 -1
  115. package/core/dist/runtime-v2/adapter/__tests__/structured-output-repair.test.js.map +1 -1
  116. package/core/dist/runtime-v2/adapter/json-extractor.d.ts +25 -0
  117. package/core/dist/runtime-v2/adapter/json-extractor.d.ts.map +1 -1
  118. package/core/dist/runtime-v2/adapter/json-extractor.js +126 -0
  119. package/core/dist/runtime-v2/adapter/json-extractor.js.map +1 -1
  120. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.d.ts +9 -4
  121. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.d.ts.map +1 -1
  122. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.js +9 -4
  123. package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.js.map +1 -1
  124. package/core/dist/runtime-v2/adapter/output-repair-contract.d.ts +5 -1
  125. package/core/dist/runtime-v2/adapter/output-repair-contract.d.ts.map +1 -1
  126. package/core/dist/runtime-v2/adapter/output-repair-contract.js +4 -1
  127. package/core/dist/runtime-v2/adapter/output-repair-contract.js.map +1 -1
  128. package/core/dist/runtime-v2/adapter/pi-ai-catalog.d.ts +7 -0
  129. package/core/dist/runtime-v2/adapter/pi-ai-catalog.d.ts.map +1 -0
  130. package/core/dist/runtime-v2/adapter/pi-ai-catalog.js +19 -0
  131. package/core/dist/runtime-v2/adapter/pi-ai-catalog.js.map +1 -0
  132. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.d.ts +13 -15
  133. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.d.ts.map +1 -1
  134. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js +104 -37
  135. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js.map +1 -1
  136. package/core/dist/runtime-v2/adapter/structured-output-repair.d.ts +16 -1
  137. package/core/dist/runtime-v2/adapter/structured-output-repair.d.ts.map +1 -1
  138. package/core/dist/runtime-v2/adapter/structured-output-repair.js +38 -6
  139. package/core/dist/runtime-v2/adapter/structured-output-repair.js.map +1 -1
  140. package/core/dist/runtime-v2/adapter/tools/diagnostician-tool.d.ts +1 -1
  141. package/core/dist/runtime-v2/adapter/tools/diagnostician-tool.d.ts.map +1 -1
  142. package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.js +8 -9
  143. package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.js.map +1 -1
  144. package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js +27 -3
  145. package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js.map +1 -1
  146. package/core/dist/runtime-v2/config/__tests__/pd-config-principles.test.d.ts +11 -0
  147. package/core/dist/runtime-v2/config/__tests__/pd-config-principles.test.d.ts.map +1 -0
  148. package/core/dist/runtime-v2/config/__tests__/pd-config-principles.test.js +93 -0
  149. package/core/dist/runtime-v2/config/__tests__/pd-config-principles.test.js.map +1 -0
  150. package/core/dist/runtime-v2/config/__tests__/pd-config-workspace.test.js +41 -0
  151. package/core/dist/runtime-v2/config/__tests__/pd-config-workspace.test.js.map +1 -1
  152. package/core/dist/runtime-v2/config/index.d.ts +2 -2
  153. package/core/dist/runtime-v2/config/index.d.ts.map +1 -1
  154. package/core/dist/runtime-v2/config/index.js +2 -0
  155. package/core/dist/runtime-v2/config/index.js.map +1 -1
  156. package/core/dist/runtime-v2/config/pd-config-agent-binding.d.ts.map +1 -1
  157. package/core/dist/runtime-v2/config/pd-config-agent-binding.js +4 -13
  158. package/core/dist/runtime-v2/config/pd-config-agent-binding.js.map +1 -1
  159. package/core/dist/runtime-v2/config/pd-config-effective.d.ts.map +1 -1
  160. package/core/dist/runtime-v2/config/pd-config-effective.js +14 -7
  161. package/core/dist/runtime-v2/config/pd-config-effective.js.map +1 -1
  162. package/core/dist/runtime-v2/config/pd-config-feature-flags.d.ts.map +1 -1
  163. package/core/dist/runtime-v2/config/pd-config-feature-flags.js +5 -12
  164. package/core/dist/runtime-v2/config/pd-config-feature-flags.js.map +1 -1
  165. package/core/dist/runtime-v2/config/pd-config-types.d.ts +8 -0
  166. package/core/dist/runtime-v2/config/pd-config-types.d.ts.map +1 -1
  167. package/core/dist/runtime-v2/config/pd-config-types.js +2 -0
  168. package/core/dist/runtime-v2/config/pd-config-types.js.map +1 -1
  169. package/core/dist/runtime-v2/config/pd-config-validate.d.ts.map +1 -1
  170. package/core/dist/runtime-v2/config/pd-config-validate.js +48 -3
  171. package/core/dist/runtime-v2/config/pd-config-validate.js.map +1 -1
  172. package/core/dist/runtime-v2/core-principles/__tests__/core-axiom-block.test.js +36 -8
  173. package/core/dist/runtime-v2/core-principles/__tests__/core-axiom-block.test.js.map +1 -1
  174. package/core/dist/runtime-v2/core-principles/__tests__/core-principle-registry.test.js +36 -12
  175. package/core/dist/runtime-v2/core-principles/__tests__/core-principle-registry.test.js.map +1 -1
  176. package/core/dist/runtime-v2/core-principles/core-axiom-block.d.ts +22 -8
  177. package/core/dist/runtime-v2/core-principles/core-axiom-block.d.ts.map +1 -1
  178. package/core/dist/runtime-v2/core-principles/core-axiom-block.js +28 -13
  179. package/core/dist/runtime-v2/core-principles/core-axiom-block.js.map +1 -1
  180. package/core/dist/runtime-v2/core-principles/core-principle-registry.d.ts +29 -4
  181. package/core/dist/runtime-v2/core-principles/core-principle-registry.d.ts.map +1 -1
  182. package/core/dist/runtime-v2/core-principles/core-principle-registry.js +68 -33
  183. package/core/dist/runtime-v2/core-principles/core-principle-registry.js.map +1 -1
  184. package/core/dist/runtime-v2/core-principles/index.d.ts +3 -3
  185. package/core/dist/runtime-v2/core-principles/index.d.ts.map +1 -1
  186. package/core/dist/runtime-v2/core-principles/index.js +1 -1
  187. package/core/dist/runtime-v2/core-principles/index.js.map +1 -1
  188. package/core/dist/runtime-v2/evolution/evolution-types.d.ts +2 -1
  189. package/core/dist/runtime-v2/evolution/evolution-types.d.ts.map +1 -1
  190. package/core/dist/runtime-v2/evolution/evolution-types.js.map +1 -1
  191. package/core/dist/runtime-v2/feature-flags/__tests__/anonymous-product-telemetry-flag.test.d.ts +2 -0
  192. package/core/dist/runtime-v2/feature-flags/__tests__/anonymous-product-telemetry-flag.test.d.ts.map +1 -0
  193. package/core/dist/runtime-v2/feature-flags/__tests__/anonymous-product-telemetry-flag.test.js +48 -0
  194. package/core/dist/runtime-v2/feature-flags/__tests__/anonymous-product-telemetry-flag.test.js.map +1 -0
  195. package/core/dist/runtime-v2/feature-flags/__tests__/codex-conversation-ingestion-flag.test.d.ts +2 -0
  196. package/core/dist/runtime-v2/feature-flags/__tests__/codex-conversation-ingestion-flag.test.d.ts.map +1 -0
  197. package/core/dist/runtime-v2/feature-flags/__tests__/codex-conversation-ingestion-flag.test.js +46 -0
  198. package/core/dist/runtime-v2/feature-flags/__tests__/codex-conversation-ingestion-flag.test.js.map +1 -0
  199. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +86 -31
  200. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
  201. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-lifecycle.test.d.ts +2 -0
  202. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-lifecycle.test.d.ts.map +1 -0
  203. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-lifecycle.test.js +83 -0
  204. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-lifecycle.test.js.map +1 -0
  205. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts +19 -1
  206. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
  207. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +128 -10
  208. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
  209. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.d.ts +37 -0
  210. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.d.ts.map +1 -0
  211. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js +304 -0
  212. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js.map +1 -0
  213. package/core/dist/runtime-v2/feature-flags/index.d.ts +4 -2
  214. package/core/dist/runtime-v2/feature-flags/index.d.ts.map +1 -1
  215. package/core/dist/runtime-v2/feature-flags/index.js +3 -1
  216. package/core/dist/runtime-v2/feature-flags/index.js.map +1 -1
  217. package/core/dist/runtime-v2/governance-experience-contract.d.ts +468 -0
  218. package/core/dist/runtime-v2/governance-experience-contract.d.ts.map +1 -0
  219. package/core/dist/runtime-v2/governance-experience-contract.js +208 -0
  220. package/core/dist/runtime-v2/governance-experience-contract.js.map +1 -0
  221. package/core/dist/runtime-v2/governance-experience.d.ts +11 -0
  222. package/core/dist/runtime-v2/governance-experience.d.ts.map +1 -0
  223. package/core/dist/runtime-v2/governance-experience.js +276 -0
  224. package/core/dist/runtime-v2/governance-experience.js.map +1 -0
  225. package/core/dist/runtime-v2/index.d.ts +20 -8
  226. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  227. package/core/dist/runtime-v2/index.js +20 -6
  228. package/core/dist/runtime-v2/index.js.map +1 -1
  229. package/core/dist/runtime-v2/internalization/__tests__/artificer-output-retry-flag.test.js +29 -10
  230. package/core/dist/runtime-v2/internalization/__tests__/artificer-output-retry-flag.test.js.map +1 -1
  231. package/core/dist/runtime-v2/owner-identity.d.ts +69 -0
  232. package/core/dist/runtime-v2/owner-identity.d.ts.map +1 -0
  233. package/core/dist/runtime-v2/owner-identity.js +179 -0
  234. package/core/dist/runtime-v2/owner-identity.js.map +1 -0
  235. package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
  236. package/core/dist/runtime-v2/pain-signal-runtime-factory.js +2 -3
  237. package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
  238. package/core/dist/runtime-v2/product-telemetry/daily-identity.d.ts +70 -0
  239. package/core/dist/runtime-v2/product-telemetry/daily-identity.d.ts.map +1 -0
  240. package/core/dist/runtime-v2/product-telemetry/daily-identity.js +89 -0
  241. package/core/dist/runtime-v2/product-telemetry/daily-identity.js.map +1 -0
  242. package/core/dist/runtime-v2/product-telemetry/snapshot-contract.d.ts +110 -0
  243. package/core/dist/runtime-v2/product-telemetry/snapshot-contract.d.ts.map +1 -0
  244. package/core/dist/runtime-v2/product-telemetry/snapshot-contract.js +250 -0
  245. package/core/dist/runtime-v2/product-telemetry/snapshot-contract.js.map +1 -0
  246. package/core/dist/runtime-v2/pruning-read-model.d.ts +2 -1
  247. package/core/dist/runtime-v2/pruning-read-model.d.ts.map +1 -1
  248. package/core/dist/runtime-v2/pruning-read-model.js.map +1 -1
  249. package/core/dist/runtime-v2/receipt-coverage.d.ts +63 -0
  250. package/core/dist/runtime-v2/receipt-coverage.d.ts.map +1 -0
  251. package/core/dist/runtime-v2/receipt-coverage.js +19 -0
  252. package/core/dist/runtime-v2/receipt-coverage.js.map +1 -0
  253. package/core/dist/runtime-v2/recovery-actions-log.d.ts +7 -0
  254. package/core/dist/runtime-v2/recovery-actions-log.d.ts.map +1 -1
  255. package/core/dist/runtime-v2/recovery-actions-log.js +6 -0
  256. package/core/dist/runtime-v2/recovery-actions-log.js.map +1 -1
  257. package/core/dist/runtime-v2/runtime-protocol.js +1 -1
  258. package/core/dist/runtime-v2/runtime-protocol.js.map +1 -1
  259. package/core/dist/runtime-v2/store/task/__tests__/sqlite-task-store.failed-tasks.test.js +17 -1
  260. package/core/dist/runtime-v2/store/task/__tests__/sqlite-task-store.failed-tasks.test.js.map +1 -1
  261. package/core/dist/runtime-v2/store/task/sqlite-task-store.d.ts.map +1 -1
  262. package/core/dist/runtime-v2/store/task/sqlite-task-store.js +10 -0
  263. package/core/dist/runtime-v2/store/task/sqlite-task-store.js.map +1 -1
  264. package/core/dist/runtime-v2/store/task/task-types.d.ts +2 -0
  265. package/core/dist/runtime-v2/store/task/task-types.d.ts.map +1 -1
  266. package/core/dist/runtime-v2/task-status.d.ts +9 -5
  267. package/core/dist/runtime-v2/task-status.d.ts.map +1 -1
  268. package/core/dist/runtime-v2/task-status.js +15 -7
  269. package/core/dist/runtime-v2/task-status.js.map +1 -1
  270. package/core/dist/runtime-v2/types/event-types.d.ts +4 -0
  271. package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
  272. package/core/dist/runtime-v2/types/event-types.js.map +1 -1
  273. package/core/dist/runtime-v2/types/index.d.ts +1 -1
  274. package/core/dist/runtime-v2/types/index.d.ts.map +1 -1
  275. package/core/dist/runtime-v2/types/index.js +1 -1
  276. package/core/dist/runtime-v2/types/index.js.map +1 -1
  277. package/core/dist/runtime-v2/types/principle-enums.d.ts +3 -2
  278. package/core/dist/runtime-v2/types/principle-enums.d.ts.map +1 -1
  279. package/core/dist/runtime-v2/types/principle-enums.js +11 -5
  280. package/core/dist/runtime-v2/types/principle-enums.js.map +1 -1
  281. package/core/dist/runtime-v2/types/principle-schema.d.ts +1 -1
  282. package/core/dist/runtime-v2/types/principle-tree-store.d.ts +1 -1
  283. package/core/dist/runtime-v2/utils/cli-process-runner.d.ts.map +1 -1
  284. package/core/dist/runtime-v2/utils/cli-process-runner.js +3 -2
  285. package/core/dist/runtime-v2/utils/cli-process-runner.js.map +1 -1
  286. package/core/package.json +4 -5
  287. package/dist/i18n.d.ts.map +1 -1
  288. package/dist/i18n.js +4 -2
  289. package/dist/i18n.js.map +1 -1
  290. package/dist/index.d.ts +2 -0
  291. package/dist/index.d.ts.map +1 -1
  292. package/dist/index.js +47 -11
  293. package/dist/index.js.map +1 -1
  294. package/dist/installer.d.ts +31 -5
  295. package/dist/installer.d.ts.map +1 -1
  296. package/dist/installer.js +472 -161
  297. package/dist/installer.js.map +1 -1
  298. package/dist/installers/codex-host-installer.d.ts.map +1 -1
  299. package/dist/installers/codex-host-installer.js +4 -0
  300. package/dist/installers/codex-host-installer.js.map +1 -1
  301. package/dist/mvp-config.d.ts +10 -0
  302. package/dist/mvp-config.d.ts.map +1 -1
  303. package/dist/mvp-config.js +30 -3
  304. package/dist/mvp-config.js.map +1 -1
  305. package/dist/uninstaller.d.ts +9 -1
  306. package/dist/uninstaller.d.ts.map +1 -1
  307. package/dist/uninstaller.js +103 -23
  308. package/dist/uninstaller.js.map +1 -1
  309. package/dist/update/atomic-file.d.ts +35 -0
  310. package/dist/update/atomic-file.d.ts.map +1 -0
  311. package/dist/update/atomic-file.js +120 -0
  312. package/dist/update/atomic-file.js.map +1 -0
  313. package/dist/update/bootstrap-protocol.d.ts +55 -0
  314. package/dist/update/bootstrap-protocol.d.ts.map +1 -0
  315. package/dist/update/bootstrap-protocol.js +132 -0
  316. package/dist/update/bootstrap-protocol.js.map +1 -0
  317. package/dist/update/channel-metadata.d.ts +28 -0
  318. package/dist/update/channel-metadata.d.ts.map +1 -0
  319. package/dist/update/channel-metadata.js +90 -0
  320. package/dist/update/channel-metadata.js.map +1 -0
  321. package/dist/update/channel-promotion.d.ts +39 -0
  322. package/dist/update/channel-promotion.d.ts.map +1 -0
  323. package/dist/update/channel-promotion.js +55 -0
  324. package/dist/update/channel-promotion.js.map +1 -0
  325. package/dist/update/data-compatibility.d.ts +35 -0
  326. package/dist/update/data-compatibility.d.ts.map +1 -0
  327. package/dist/update/data-compatibility.js +45 -0
  328. package/dist/update/data-compatibility.js.map +1 -0
  329. package/dist/update/install-layout.d.ts +59 -0
  330. package/dist/update/install-layout.d.ts.map +1 -0
  331. package/dist/update/install-layout.js +127 -0
  332. package/dist/update/install-layout.js.map +1 -0
  333. package/dist/update/legacy-migration.d.ts +56 -0
  334. package/dist/update/legacy-migration.d.ts.map +1 -0
  335. package/dist/update/legacy-migration.js +254 -0
  336. package/dist/update/legacy-migration.js.map +1 -0
  337. package/dist/update/product-identity.d.ts +50 -0
  338. package/dist/update/product-identity.d.ts.map +1 -0
  339. package/dist/update/product-identity.js +63 -0
  340. package/dist/update/product-identity.js.map +1 -0
  341. package/dist/update/release-asset-manifest.d.ts +31 -0
  342. package/dist/update/release-asset-manifest.d.ts.map +1 -0
  343. package/dist/update/release-asset-manifest.js +161 -0
  344. package/dist/update/release-asset-manifest.js.map +1 -0
  345. package/dist/update/release-identity.d.ts +33 -0
  346. package/dist/update/release-identity.d.ts.map +1 -0
  347. package/dist/update/release-identity.js +108 -0
  348. package/dist/update/release-identity.js.map +1 -0
  349. package/dist/update/release-manager.d.ts +96 -0
  350. package/dist/update/release-manager.d.ts.map +1 -0
  351. package/dist/update/release-manager.js +253 -0
  352. package/dist/update/release-manager.js.map +1 -0
  353. package/dist/update/release-metadata.d.ts +57 -0
  354. package/dist/update/release-metadata.d.ts.map +1 -0
  355. package/dist/update/release-metadata.js +200 -0
  356. package/dist/update/release-metadata.js.map +1 -0
  357. package/dist/update/release-policy.d.ts +51 -0
  358. package/dist/update/release-policy.d.ts.map +1 -0
  359. package/dist/update/release-policy.js +103 -0
  360. package/dist/update/release-policy.js.map +1 -0
  361. package/dist/update/rollback-policy.d.ts +56 -0
  362. package/dist/update/rollback-policy.d.ts.map +1 -0
  363. package/dist/update/rollback-policy.js +61 -0
  364. package/dist/update/rollback-policy.js.map +1 -0
  365. package/dist/update/transaction-journal.d.ts +121 -0
  366. package/dist/update/transaction-journal.d.ts.map +1 -0
  367. package/dist/update/transaction-journal.js +333 -0
  368. package/dist/update/transaction-journal.js.map +1 -0
  369. package/dist/update/trust-metadata.d.ts +55 -0
  370. package/dist/update/trust-metadata.d.ts.map +1 -0
  371. package/dist/update/trust-metadata.js +170 -0
  372. package/dist/update/trust-metadata.js.map +1 -0
  373. package/dist/update/update-history.d.ts +46 -0
  374. package/dist/update/update-history.d.ts.map +1 -0
  375. package/dist/update/update-history.js +123 -0
  376. package/dist/update/update-history.js.map +1 -0
  377. package/dist/utils/env.d.ts +7 -0
  378. package/dist/utils/env.d.ts.map +1 -1
  379. package/dist/utils/env.js +134 -44
  380. package/dist/utils/env.js.map +1 -1
  381. package/host-runtime/dist/governance-observation-store.d.ts +172 -0
  382. package/host-runtime/dist/governance-observation-store.js +649 -0
  383. package/host-runtime/dist/index.d.ts +6 -0
  384. package/host-runtime/dist/index.js +8 -0
  385. package/host-runtime/dist/product-telemetry/consent-store.d.ts +107 -0
  386. package/host-runtime/dist/product-telemetry/consent-store.js +329 -0
  387. package/host-runtime/dist/product-telemetry/eligibility.d.ts +53 -0
  388. package/host-runtime/dist/product-telemetry/eligibility.js +69 -0
  389. package/host-runtime/dist/product-telemetry/exporter.d.ts +46 -0
  390. package/host-runtime/dist/product-telemetry/exporter.js +71 -0
  391. package/host-runtime/dist/product-telemetry/milestone-readers.d.ts +61 -0
  392. package/host-runtime/dist/product-telemetry/milestone-readers.js +234 -0
  393. package/host-runtime/dist/product-telemetry/service.d.ts +142 -0
  394. package/host-runtime/dist/product-telemetry/service.js +532 -0
  395. package/host-runtime/dist/product-telemetry/workspace-scope.d.ts +38 -0
  396. package/host-runtime/dist/product-telemetry/workspace-scope.js +64 -0
  397. package/host-runtime/package.json +7 -2
  398. package/install-layout/dist/index.d.ts +48 -0
  399. package/install-layout/dist/index.js +81 -0
  400. package/install-layout/dist/index.test.d.ts +1 -0
  401. package/install-layout/dist/index.test.js +34 -0
  402. package/install-layout/package.json +33 -0
  403. package/package.json +16 -6
  404. package/pd-cli/dist/commands/__tests__/telemetry-flag-wiring.test.d.ts +9 -0
  405. package/pd-cli/dist/commands/__tests__/telemetry-flag-wiring.test.d.ts.map +1 -0
  406. package/pd-cli/dist/commands/__tests__/telemetry-flag-wiring.test.js +76 -0
  407. package/pd-cli/dist/commands/__tests__/telemetry-flag-wiring.test.js.map +1 -0
  408. package/pd-cli/dist/commands/__tests__/version.test.d.ts +2 -0
  409. package/pd-cli/dist/commands/__tests__/version.test.d.ts.map +1 -0
  410. package/pd-cli/dist/commands/__tests__/version.test.js +134 -0
  411. package/pd-cli/dist/commands/__tests__/version.test.js.map +1 -0
  412. package/pd-cli/dist/commands/console.d.ts.map +1 -1
  413. package/pd-cli/dist/commands/console.js +29 -10
  414. package/pd-cli/dist/commands/console.js.map +1 -1
  415. package/pd-cli/dist/commands/pain-record.d.ts.map +1 -1
  416. package/pd-cli/dist/commands/pain-record.js +6 -15
  417. package/pd-cli/dist/commands/pain-record.js.map +1 -1
  418. package/pd-cli/dist/commands/runtime-activation.d.ts +29 -0
  419. package/pd-cli/dist/commands/runtime-activation.d.ts.map +1 -1
  420. package/pd-cli/dist/commands/runtime-activation.js +70 -31
  421. package/pd-cli/dist/commands/runtime-activation.js.map +1 -1
  422. package/pd-cli/dist/commands/runtime-internalization-enqueue-successors.d.ts.map +1 -1
  423. package/pd-cli/dist/commands/runtime-internalization-enqueue-successors.js +2 -2
  424. package/pd-cli/dist/commands/runtime-internalization-enqueue-successors.js.map +1 -1
  425. package/pd-cli/dist/commands/telemetry.d.ts +82 -0
  426. package/pd-cli/dist/commands/telemetry.d.ts.map +1 -0
  427. package/pd-cli/dist/commands/telemetry.js +268 -0
  428. package/pd-cli/dist/commands/telemetry.js.map +1 -0
  429. package/pd-cli/dist/commands/version.d.ts +11 -0
  430. package/pd-cli/dist/commands/version.d.ts.map +1 -0
  431. package/pd-cli/dist/commands/version.js +48 -0
  432. package/pd-cli/dist/commands/version.js.map +1 -0
  433. package/pd-cli/dist/index.js +35 -2
  434. package/pd-cli/dist/index.js.map +1 -1
  435. package/pd-cli/dist/services/version-report.d.ts +44 -0
  436. package/pd-cli/dist/services/version-report.d.ts.map +1 -0
  437. package/pd-cli/dist/services/version-report.js +152 -0
  438. package/pd-cli/dist/services/version-report.js.map +1 -0
  439. package/pd-cli/package.json +3 -2
  440. package/plugin/dist/bundle.js +870 -932
  441. package/plugin/dist/core/init.d.ts +2 -1
  442. package/plugin/dist/core/principle-application-ledger.d.ts +10 -0
  443. package/plugin/dist/core/product-telemetry-trigger.d.ts +14 -0
  444. package/plugin/dist/core/thinking-os-parser.d.ts +5 -2
  445. package/plugin/dist/governance-audit.js +386 -0
  446. package/plugin/dist/hooks/gate-block-helper.d.ts +25 -1
  447. package/plugin/dist/hooks/gate.d.ts +22 -0
  448. package/plugin/dist/openclaw.plugin.json +1 -1
  449. package/plugin/dist/rulehost-evidence.js +832 -0
  450. package/plugin/dist/templates/langs/en/principles/THINKING_OS.md +53 -45
  451. package/plugin/dist/templates/langs/en/skills/pd-mentor/SKILL.md +1 -1
  452. package/plugin/dist/templates/langs/zh/principles/THINKING_OS.md +62 -46
  453. package/plugin/dist/templates/langs/zh/skills/pd-mentor/SKILL.md +1 -1
  454. package/plugin/dist/templates/workspace/.principles/THINKING_OS.md +66 -38
  455. package/plugin/openclaw.plugin.json +1 -1
  456. package/plugin/package.json +1 -1
  457. package/plugin/templates/langs/en/principles/THINKING_OS.md +53 -45
  458. package/plugin/templates/langs/en/skills/pd-mentor/SKILL.md +1 -1
  459. package/plugin/templates/langs/zh/principles/THINKING_OS.md +62 -46
  460. package/plugin/templates/langs/zh/skills/pd-mentor/SKILL.md +1 -1
  461. package/plugin/templates/workspace/.principles/THINKING_OS.md +66 -38
@@ -7,7 +7,15 @@ export * from './pd-config.js';
7
7
  export * from './production-rulehost-gate.js';
8
8
  export * from './rule-implementation-runtime.js';
9
9
  export * from './production-pain-evidence.js';
10
+ export * from './governance-observation-store.js';
10
11
  export * from './host-liveness-contract.js';
12
+ // Anonymous Product Telemetry v1 (PRI-595~603) — opt-in, default-off,
13
+ // read-only with respect to all PD governance facts.
14
+ export * from './product-telemetry/consent-store.js';
15
+ export * from './product-telemetry/eligibility.js';
16
+ export * from './product-telemetry/exporter.js';
17
+ export * from './product-telemetry/milestone-readers.js';
18
+ export * from './product-telemetry/service.js';
11
19
  export const HOST_RUNTIME_ROUTES = [
12
20
  'before_prompt_build',
13
21
  'before_tool_call',
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Product telemetry control-state store — Anonymous Product Telemetry v1
3
+ * (PRI-597, SPEC §44; review remediation: workspace-scoped export state).
4
+ *
5
+ * Persists the telemetry control state to `~/.pd/product-telemetry.json`.
6
+ * This file is Telemetry Control State — it never enters
7
+ * Principle/Pain/receipt/governance stores, and the secret never leaves the
8
+ * machine.
9
+ *
10
+ * Scope model (schema v2, review remediation P1-1):
11
+ * - MACHINE scope: consent, consentVersion, telemetrySecret.
12
+ * - WORKSPACE scope: `workspaceExports[scopeId]` — per-workspace dedup,
13
+ * retry, and attempt bookkeeping keyed by the opaque local scope ID
14
+ * (HMAC(secret, canonical workspace path); never uploaded). One
15
+ * workspace succeeding must never suppress another workspace's export.
16
+ *
17
+ * Migration from schema v1: consent, consentVersion, and telemetrySecret are
18
+ * preserved; legacy machine-global export bookkeeping (lastSucceededAt,
19
+ * retry state, attempt counters) is DISCARDED — it cannot be attributed to a
20
+ * workspace, and it is operational state, not a governance fact. Dropping it
21
+ * can cause at most one extra same-day snapshot per installation.
22
+ */
23
+ export declare const PRODUCT_TELEMETRY_STATE_FILENAME = "product-telemetry.json";
24
+ export declare const PRODUCT_TELEMETRY_CONTROL_SCHEMA_VERSION = "2";
25
+ /** v1 files are still read (then migrated in memory and rewritten as v2). */
26
+ export declare const PRODUCT_TELEMETRY_LEGACY_CONTROL_SCHEMA_VERSION = "1";
27
+ /** Hard bound on tracked workspaces so the file cannot grow unboundedly. */
28
+ export declare const MAX_WORKSPACE_EXPORT_ENTRIES = 200;
29
+ /**
30
+ * Entries untouched for this long are pruned on the next write. This is local
31
+ * telemetry operational state only — no workspace history is retained.
32
+ */
33
+ export declare const WORKSPACE_EXPORT_STATE_MAX_AGE_DAYS = 30;
34
+ export type ProductTelemetryConsent = 'unset' | 'granted' | 'denied';
35
+ /** Per-workspace export bookkeeping (operational state; never exported). */
36
+ export interface WorkspaceExportState {
37
+ lastAttemptedAt?: string;
38
+ lastSucceededAt?: string;
39
+ /** Coarse failure code (TelemetryFailureCode). No response bodies. */
40
+ lastFailureCode?: string;
41
+ nextRetryAt?: string;
42
+ /** Failed export attempts in the current attemptBucketDate (0–99; hard cap enforced by the service). */
43
+ dailyAttemptCount?: number;
44
+ /** UTC date bucket the dailyAttemptCount belongs to (resets on day change). */
45
+ attemptBucketDate?: string;
46
+ }
47
+ export interface ProductTelemetryControlState {
48
+ consent: ProductTelemetryConsent;
49
+ consentVersion: string;
50
+ /** Cryptographically random hex secret. Never uploaded. */
51
+ telemetrySecret?: string;
52
+ /** Per-workspace export bookkeeping keyed by opaque local scope ID. */
53
+ workspaceExports?: Record<string, WorkspaceExportState>;
54
+ schemaVersion: string;
55
+ }
56
+ export type ControlStateRead = {
57
+ ok: true;
58
+ state: ProductTelemetryControlState;
59
+ existed: boolean;
60
+ } | {
61
+ ok: false;
62
+ reason: string;
63
+ nextAction: string;
64
+ };
65
+ export type ControlStateWrite = {
66
+ ok: true;
67
+ } | {
68
+ ok: false;
69
+ reason: string;
70
+ nextAction: string;
71
+ };
72
+ export declare function defaultProductTelemetryControlState(): ProductTelemetryControlState;
73
+ export declare function getProductTelemetryStatePath(homeDir: string): string;
74
+ /**
75
+ * Read and validate the control state. A missing file is the normal
76
+ * never-configured case (defaults, existed=false). A malformed file is a
77
+ * loud failure — silently treating it as "unset" could re-prompt or re-export
78
+ * against the user's recorded decision (rc-3/rc-9).
79
+ *
80
+ * v1 files are migrated in memory (export bookkeeping dropped, consent
81
+ * identity preserved); the migration is persisted on the next write.
82
+ */
83
+ export declare function readProductTelemetryControlState(homeDir: string): ControlStateRead;
84
+ /**
85
+ * Drop `workspaceExports` entries whose most recent activity (attempt or
86
+ * success) is older than WORKSPACE_EXPORT_STATE_MAX_AGE_DAYS. Bounded local
87
+ * operational state only — this is not a workspace history database.
88
+ */
89
+ export declare function pruneWorkspaceExports(state: ProductTelemetryControlState, nowMs: number): ProductTelemetryControlState;
90
+ /** Atomic write (temp file + rename) so a crash never truncates the state. */
91
+ export declare function writeProductTelemetryControlState(homeDir: string, state: ProductTelemetryControlState): ControlStateWrite;
92
+ /** State after `pd telemetry enable`: explicit granted consent + secret. */
93
+ export declare function grantedControlState(previous: ProductTelemetryControlState): ProductTelemetryControlState;
94
+ /**
95
+ * State after `pd telemetry disable`: consent denied and all export identity
96
+ * removed (SPEC §19). The explicit `denied` choice is preserved so PD never
97
+ * re-prompts.
98
+ */
99
+ export declare function deniedControlState(): ProductTelemetryControlState;
100
+ /**
101
+ * State after `pd telemetry reset` (SPEC §18): secret and export status are
102
+ * deleted — no future daily ID relates to previous ones. The consent choice
103
+ * is preserved; a fresh secret is generated only while telemetry remains
104
+ * enabled. Workspace bookkeeping keyed under the OLD secret's scope IDs is
105
+ * dropped with it (the IDs are meaningless under a new secret).
106
+ */
107
+ export declare function resetControlState(previous: ProductTelemetryControlState): ProductTelemetryControlState;
@@ -0,0 +1,329 @@
1
+ /**
2
+ * Product telemetry control-state store — Anonymous Product Telemetry v1
3
+ * (PRI-597, SPEC §44; review remediation: workspace-scoped export state).
4
+ *
5
+ * Persists the telemetry control state to `~/.pd/product-telemetry.json`.
6
+ * This file is Telemetry Control State — it never enters
7
+ * Principle/Pain/receipt/governance stores, and the secret never leaves the
8
+ * machine.
9
+ *
10
+ * Scope model (schema v2, review remediation P1-1):
11
+ * - MACHINE scope: consent, consentVersion, telemetrySecret.
12
+ * - WORKSPACE scope: `workspaceExports[scopeId]` — per-workspace dedup,
13
+ * retry, and attempt bookkeeping keyed by the opaque local scope ID
14
+ * (HMAC(secret, canonical workspace path); never uploaded). One
15
+ * workspace succeeding must never suppress another workspace's export.
16
+ *
17
+ * Migration from schema v1: consent, consentVersion, and telemetrySecret are
18
+ * preserved; legacy machine-global export bookkeeping (lastSucceededAt,
19
+ * retry state, attempt counters) is DISCARDED — it cannot be attributed to a
20
+ * workspace, and it is operational state, not a governance fact. Dropping it
21
+ * can cause at most one extra same-day snapshot per installation.
22
+ */
23
+ import fs from 'node:fs';
24
+ import path from 'node:path';
25
+ import { generateTelemetrySecretHex, isValidBucketDate, isValidTelemetrySecretHex, PRODUCT_TELEMETRY_CONSENT_VERSION, } from '@principles/core/runtime-v2';
26
+ export const PRODUCT_TELEMETRY_STATE_FILENAME = 'product-telemetry.json';
27
+ export const PRODUCT_TELEMETRY_CONTROL_SCHEMA_VERSION = '2';
28
+ /** v1 files are still read (then migrated in memory and rewritten as v2). */
29
+ export const PRODUCT_TELEMETRY_LEGACY_CONTROL_SCHEMA_VERSION = '1';
30
+ /** Hard bound on tracked workspaces so the file cannot grow unboundedly. */
31
+ export const MAX_WORKSPACE_EXPORT_ENTRIES = 200;
32
+ /**
33
+ * Entries untouched for this long are pruned on the next write. This is local
34
+ * telemetry operational state only — no workspace history is retained.
35
+ */
36
+ export const WORKSPACE_EXPORT_STATE_MAX_AGE_DAYS = 30;
37
+ export function defaultProductTelemetryControlState() {
38
+ return { consent: 'unset', consentVersion: PRODUCT_TELEMETRY_CONSENT_VERSION, schemaVersion: PRODUCT_TELEMETRY_CONTROL_SCHEMA_VERSION };
39
+ }
40
+ export function getProductTelemetryStatePath(homeDir) {
41
+ return path.join(path.resolve(homeDir), '.pd', PRODUCT_TELEMETRY_STATE_FILENAME);
42
+ }
43
+ function isConsent(value) {
44
+ return value === 'unset' || value === 'granted' || value === 'denied';
45
+ }
46
+ /**
47
+ * Optional timestamp fields must be parseable dates, not just short strings —
48
+ * a "garbage" lastSucceededAt/nextRetryAt would otherwise slip validation and
49
+ * turn into NaN inside Date.parse, silently skipping same-day dedup or retry
50
+ * backoff (fail-loud contract, review round 2).
51
+ */
52
+ function isOptionalIsoString(value) {
53
+ if (value === undefined)
54
+ return true;
55
+ if (typeof value !== 'string' || value.length === 0 || value.length > 40)
56
+ return false;
57
+ return !Number.isNaN(Date.parse(value));
58
+ }
59
+ function isOptionalAttemptBucketDate(value) {
60
+ if (value === undefined)
61
+ return true;
62
+ return isValidBucketDate(value);
63
+ }
64
+ function isOptionalAttemptCount(value) {
65
+ return value === undefined || (typeof value === 'number' && Number.isInteger(value) && value >= 0 && value <= 99);
66
+ }
67
+ function isOptionalFailureCode(value) {
68
+ return value === undefined || (typeof value === 'string' && value.length > 0 && value.length <= 40);
69
+ }
70
+ function isScopeKey(value) {
71
+ return typeof value === 'string' && /^[0-9a-f]{4,32}$/.test(value);
72
+ }
73
+ /** Validate one `workspaceExports` entry; collect errors under `prefix`. */
74
+ function workspaceExportErrors(entry, prefix) {
75
+ const errors = [];
76
+ for (const key of Object.keys(entry)) {
77
+ if (!['lastAttemptedAt', 'lastSucceededAt', 'lastFailureCode', 'nextRetryAt', 'dailyAttemptCount', 'attemptBucketDate'].includes(key)) {
78
+ errors.push(`${prefix}: unknown field '${key}'`);
79
+ }
80
+ }
81
+ if (!isOptionalIsoString(entry.lastAttemptedAt) || !isOptionalIsoString(entry.lastSucceededAt) || !isOptionalIsoString(entry.nextRetryAt)) {
82
+ errors.push(`${prefix}: timestamps must be parseable ISO-8601 strings (≤40 chars) when present`);
83
+ }
84
+ if (!isOptionalAttemptCount(entry.dailyAttemptCount))
85
+ errors.push(`${prefix}: dailyAttemptCount must be an integer 0–99 when present`);
86
+ if (!isOptionalAttemptBucketDate(entry.attemptBucketDate))
87
+ errors.push(`${prefix}: attemptBucketDate must be a valid YYYY-MM-DD UTC date when present`);
88
+ if (!isOptionalFailureCode(entry.lastFailureCode))
89
+ errors.push(`${prefix}: lastFailureCode must be a short non-empty string when present`);
90
+ return errors;
91
+ }
92
+ function isPlainRecord(value) {
93
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
94
+ }
95
+ /**
96
+ * Read and validate the control state. A missing file is the normal
97
+ * never-configured case (defaults, existed=false). A malformed file is a
98
+ * loud failure — silently treating it as "unset" could re-prompt or re-export
99
+ * against the user's recorded decision (rc-3/rc-9).
100
+ *
101
+ * v1 files are migrated in memory (export bookkeeping dropped, consent
102
+ * identity preserved); the migration is persisted on the next write.
103
+ */
104
+ export function readProductTelemetryControlState(homeDir) {
105
+ const filePath = getProductTelemetryStatePath(homeDir);
106
+ let raw;
107
+ try {
108
+ raw = fs.readFileSync(filePath, 'utf8');
109
+ }
110
+ catch (error) {
111
+ // Guarded code access (rc-1/rc-2: runtime check before use; rc-5:
112
+ // Object.hasOwn on untrusted objects; no NodeJS namespace in this config).
113
+ const codeValue = typeof error === 'object' && error !== null && Object.hasOwn(error, 'code')
114
+ ? error.code
115
+ : undefined;
116
+ const code = typeof codeValue === 'string' ? codeValue : undefined;
117
+ if (code === 'ENOENT') {
118
+ return { ok: true, state: defaultProductTelemetryControlState(), existed: false };
119
+ }
120
+ return {
121
+ ok: false,
122
+ reason: `product_telemetry_state_unreadable: ${code ?? String(error)}`,
123
+ nextAction: `Check permissions on ${filePath}`,
124
+ };
125
+ }
126
+ let parsed;
127
+ try {
128
+ parsed = JSON.parse(raw);
129
+ }
130
+ catch {
131
+ return {
132
+ ok: false,
133
+ reason: 'product_telemetry_state_malformed_json',
134
+ nextAction: `Fix or delete ${filePath} (delete = consent returns to unset)`,
135
+ };
136
+ }
137
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
138
+ return {
139
+ ok: false,
140
+ reason: 'product_telemetry_state_malformed_shape',
141
+ nextAction: `Fix or delete ${filePath} (delete = consent returns to unset)`,
142
+ };
143
+ }
144
+ const obj = parsed;
145
+ const { schemaVersion } = obj;
146
+ const isV1 = schemaVersion === PRODUCT_TELEMETRY_LEGACY_CONTROL_SCHEMA_VERSION;
147
+ const isV2 = schemaVersion === PRODUCT_TELEMETRY_CONTROL_SCHEMA_VERSION;
148
+ if (!isV1 && !isV2) {
149
+ return {
150
+ ok: false,
151
+ reason: `product_telemetry_state_malformed: schemaVersion must be '${PRODUCT_TELEMETRY_CONTROL_SCHEMA_VERSION}' or legacy '${PRODUCT_TELEMETRY_LEGACY_CONTROL_SCHEMA_VERSION}'`,
152
+ nextAction: `Fix or delete ${filePath} (delete = consent returns to unset)`,
153
+ };
154
+ }
155
+ // v1 machine-global export fields exist only in v1 files; v2 files carry
156
+ // workspaceExports instead. Unknown keys are rejected per shape.
157
+ const allowedKeys = isV1
158
+ ? ['consent', 'consentVersion', 'telemetrySecret', 'lastAttemptedAt', 'lastSucceededAt', 'lastFailureCode', 'nextRetryAt', 'dailyAttemptCount', 'attemptBucketDate', 'schemaVersion']
159
+ : ['consent', 'consentVersion', 'telemetrySecret', 'workspaceExports', 'schemaVersion'];
160
+ const errors = [];
161
+ for (const key of Object.keys(obj)) {
162
+ if (!allowedKeys.includes(key)) {
163
+ errors.push(`unknown field '${key}'`);
164
+ }
165
+ }
166
+ if (!isConsent(obj.consent))
167
+ errors.push('consent must be unset|granted|denied');
168
+ if (typeof obj.consentVersion !== 'string' || obj.consentVersion.length === 0 || obj.consentVersion.length > 8)
169
+ errors.push('consentVersion must be a short non-empty string');
170
+ if (!isValidTelemetrySecretHex(obj.telemetrySecret) && obj.telemetrySecret !== undefined)
171
+ errors.push('telemetrySecret must be 64 hex chars when present');
172
+ if (isV1) {
173
+ // v1 legacy export fields are migrated by DISCARDING them — validating
174
+ // values that are about to be dropped would only turn a smooth migration
175
+ // into a hard failure (the identity fields carry the user's decision).
176
+ // Only the field-NAME allowlist above still applies to v1 files.
177
+ }
178
+ else {
179
+ if (obj.workspaceExports !== undefined) {
180
+ if (typeof obj.workspaceExports !== 'object' || obj.workspaceExports === null || Array.isArray(obj.workspaceExports)) {
181
+ errors.push('workspaceExports must be an object');
182
+ }
183
+ else {
184
+ const entries = obj.workspaceExports;
185
+ const scopeKeys = Object.keys(entries);
186
+ if (scopeKeys.length > MAX_WORKSPACE_EXPORT_ENTRIES) {
187
+ errors.push(`workspaceExports must track at most ${MAX_WORKSPACE_EXPORT_ENTRIES} workspaces`);
188
+ }
189
+ for (const scopeKey of scopeKeys) {
190
+ if (!isScopeKey(scopeKey)) {
191
+ errors.push(`workspaceExports key '${scopeKey}' must be 4–32 hex chars`);
192
+ continue;
193
+ }
194
+ const entry = entries[scopeKey];
195
+ if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {
196
+ errors.push(`workspaceExports['${scopeKey}'] must be an object`);
197
+ continue;
198
+ }
199
+ errors.push(...workspaceExportErrors(entry, `workspaceExports['${scopeKey}']`));
200
+ }
201
+ }
202
+ }
203
+ }
204
+ if (errors.length > 0) {
205
+ return {
206
+ ok: false,
207
+ reason: `product_telemetry_state_malformed: ${errors.join('; ')}`,
208
+ nextAction: `Fix or delete ${filePath} (delete = consent returns to unset)`,
209
+ };
210
+ }
211
+ // Post-validation reconstruction from guard-narrowed fields — no `as` on
212
+ // the untrusted parsed object (rc-2). isConsent is a type guard; the
213
+ // optional-field spreads carry only guard-passing values. v1 export
214
+ // bookkeeping is deliberately NOT carried over (see module doc).
215
+ const state = {
216
+ consent: isConsent(obj.consent) ? obj.consent : 'unset',
217
+ consentVersion: typeof obj.consentVersion === 'string' ? obj.consentVersion : PRODUCT_TELEMETRY_CONSENT_VERSION,
218
+ ...(isValidTelemetrySecretHex(obj.telemetrySecret) ? { telemetrySecret: obj.telemetrySecret } : {}),
219
+ ...(isV2 && isPlainRecord(obj.workspaceExports)
220
+ ? {
221
+ workspaceExports: Object.fromEntries(Object.entries(obj.workspaceExports)
222
+ .filter(([scopeKey, entry]) => isScopeKey(scopeKey) && isPlainRecord(entry))
223
+ .map(([scopeKey, entry]) => {
224
+ const record = entry;
225
+ return [
226
+ scopeKey,
227
+ {
228
+ ...(isOptionalIsoString(record.lastAttemptedAt) && record.lastAttemptedAt !== undefined ? { lastAttemptedAt: record.lastAttemptedAt } : {}),
229
+ ...(isOptionalIsoString(record.lastSucceededAt) && record.lastSucceededAt !== undefined ? { lastSucceededAt: record.lastSucceededAt } : {}),
230
+ ...(isOptionalIsoString(record.nextRetryAt) && record.nextRetryAt !== undefined ? { nextRetryAt: record.nextRetryAt } : {}),
231
+ ...(isOptionalFailureCode(record.lastFailureCode) && record.lastFailureCode !== undefined ? { lastFailureCode: record.lastFailureCode } : {}),
232
+ ...(isOptionalAttemptCount(record.dailyAttemptCount) && record.dailyAttemptCount !== undefined ? { dailyAttemptCount: record.dailyAttemptCount } : {}),
233
+ ...(isOptionalAttemptBucketDate(record.attemptBucketDate) && record.attemptBucketDate !== undefined ? { attemptBucketDate: record.attemptBucketDate } : {}),
234
+ },
235
+ ];
236
+ })),
237
+ }
238
+ : {}),
239
+ schemaVersion: PRODUCT_TELEMETRY_CONTROL_SCHEMA_VERSION,
240
+ };
241
+ if (state.workspaceExports !== undefined && Object.keys(state.workspaceExports).length === 0) {
242
+ delete state.workspaceExports;
243
+ }
244
+ return { ok: true, state, existed: true };
245
+ }
246
+ /**
247
+ * Drop `workspaceExports` entries whose most recent activity (attempt or
248
+ * success) is older than WORKSPACE_EXPORT_STATE_MAX_AGE_DAYS. Bounded local
249
+ * operational state only — this is not a workspace history database.
250
+ */
251
+ export function pruneWorkspaceExports(state, nowMs) {
252
+ const exports = state.workspaceExports;
253
+ if (exports === undefined)
254
+ return state;
255
+ const cutoff = nowMs - WORKSPACE_EXPORT_STATE_MAX_AGE_DAYS * 24 * 60 * 60 * 1000;
256
+ const kept = {};
257
+ for (const [scopeKey, entry] of Object.entries(exports)) {
258
+ const stamps = [entry.lastAttemptedAt, entry.lastSucceededAt].filter((s) => s !== undefined).map((s) => Date.parse(s));
259
+ const latest = stamps.length > 0 ? Math.max(...stamps) : Number.NEGATIVE_INFINITY;
260
+ if (Number.isNaN(latest) || latest < cutoff)
261
+ continue;
262
+ kept[scopeKey] = entry;
263
+ }
264
+ const next = { ...state };
265
+ if (Object.keys(kept).length > 0)
266
+ next.workspaceExports = kept;
267
+ else
268
+ delete next.workspaceExports;
269
+ return next;
270
+ }
271
+ /** Atomic write (temp file + rename) so a crash never truncates the state. */
272
+ export function writeProductTelemetryControlState(homeDir, state) {
273
+ const filePath = getProductTelemetryStatePath(homeDir);
274
+ const dir = path.dirname(filePath);
275
+ const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
276
+ try {
277
+ fs.mkdirSync(dir, { recursive: true });
278
+ fs.writeFileSync(tmpPath, `${JSON.stringify(state, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 });
279
+ fs.renameSync(tmpPath, filePath);
280
+ return { ok: true };
281
+ }
282
+ catch (error) {
283
+ const message = error instanceof Error ? error.message : String(error);
284
+ try {
285
+ fs.rmSync(tmpPath, { force: true });
286
+ }
287
+ catch {
288
+ // best-effort cleanup; the write failure below is the loud signal
289
+ }
290
+ return {
291
+ ok: false,
292
+ reason: `product_telemetry_state_write_failed: ${message}`,
293
+ nextAction: `Check permissions on ${dir}`,
294
+ };
295
+ }
296
+ }
297
+ /** State after `pd telemetry enable`: explicit granted consent + secret. */
298
+ export function grantedControlState(previous) {
299
+ return {
300
+ consent: 'granted',
301
+ consentVersion: PRODUCT_TELEMETRY_CONSENT_VERSION,
302
+ telemetrySecret: isValidTelemetrySecretHex(previous.telemetrySecret) ? previous.telemetrySecret : generateTelemetrySecretHex(),
303
+ ...(previous.workspaceExports !== undefined ? { workspaceExports: previous.workspaceExports } : {}),
304
+ schemaVersion: PRODUCT_TELEMETRY_CONTROL_SCHEMA_VERSION,
305
+ };
306
+ }
307
+ /**
308
+ * State after `pd telemetry disable`: consent denied and all export identity
309
+ * removed (SPEC §19). The explicit `denied` choice is preserved so PD never
310
+ * re-prompts.
311
+ */
312
+ export function deniedControlState() {
313
+ return { consent: 'denied', consentVersion: PRODUCT_TELEMETRY_CONSENT_VERSION, schemaVersion: PRODUCT_TELEMETRY_CONTROL_SCHEMA_VERSION };
314
+ }
315
+ /**
316
+ * State after `pd telemetry reset` (SPEC §18): secret and export status are
317
+ * deleted — no future daily ID relates to previous ones. The consent choice
318
+ * is preserved; a fresh secret is generated only while telemetry remains
319
+ * enabled. Workspace bookkeeping keyed under the OLD secret's scope IDs is
320
+ * dropped with it (the IDs are meaningless under a new secret).
321
+ */
322
+ export function resetControlState(previous) {
323
+ return {
324
+ consent: previous.consent,
325
+ consentVersion: PRODUCT_TELEMETRY_CONSENT_VERSION,
326
+ ...(previous.consent === 'granted' ? { telemetrySecret: generateTelemetrySecretHex() } : {}),
327
+ schemaVersion: PRODUCT_TELEMETRY_CONTROL_SCHEMA_VERSION,
328
+ };
329
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Production eligibility — Anonymous Product Telemetry v1
3
+ * (PRI-597, SPEC §35-§37).
4
+ *
5
+ * Environment suppression is evaluated independently of consent and the
6
+ * feature flag (both are AND-ed by the service). Every suppression reason is
7
+ * named in the result so `pd telemetry status` can show exactly why export is
8
+ * off (rc-9 — no silent suppression).
9
+ *
10
+ * Dev/CI/test detection follows the repository's explicit-marker philosophy
11
+ * (PD_E2E_MODE precedent): env markers and build-layout facts, never
12
+ * user-path heuristics.
13
+ */
14
+ export type TelemetrySuppressionReason = 'env_kill_switch' | 'ci_environment' | 'vitest_environment' | 'e2e_mode' | 'workspace_environment' | 'install_layout_missing' | 'repo_checkout';
15
+ export interface TelemetryEnvironmentInput {
16
+ env: {
17
+ /** PD_TELEMETRY_DISABLED raw value. */
18
+ killSwitch?: string;
19
+ /** process.env.CI raw value. */
20
+ ci?: string;
21
+ /** process.env.VITEST raw value (set by vitest workers). */
22
+ vitest?: string;
23
+ /** PD_E2E_MODE raw value. */
24
+ e2eMode?: string;
25
+ };
26
+ /** workspace.environment from .pd/config.yaml (PRI-587); 'unknown' when absent. */
27
+ workspaceEnvironment: 'production' | 'development' | 'demo' | 'test' | 'unknown';
28
+ /** Install layout mode; 'missing' = nothing installed. */
29
+ installMode: 'canonical' | 'legacy' | 'missing';
30
+ /** Directory of the executing telemetry module (repo-checkout detection). */
31
+ moduleDir: string;
32
+ }
33
+ export interface TelemetryEnvironmentResult {
34
+ suppressed: boolean;
35
+ reasons: TelemetrySuppressionReason[];
36
+ }
37
+ /** Boolean-style env flags follow the PD_SKIP_* convention: '1' or 'true'. */
38
+ export declare function isEnvFlagActive(value: string | undefined): boolean;
39
+ /**
40
+ * True when the executing module lives inside a PD monorepo checkout.
41
+ *
42
+ * Build-layout fact, not a path heuristic: an installed runtime (canonical
43
+ * `~/.pd/runtime/host-runtime/...` or legacy extension dir) never has a
44
+ * sibling `packages/principles-core` + `packages/host-runtime` tree, while
45
+ * a checkout always does. Prevents maintainer/AI development activity from
46
+ * polluting production telemetry.
47
+ */
48
+ export declare function isRepoCheckoutModuleDir(moduleDir: string): boolean;
49
+ /**
50
+ * Evaluate environment suppression. Kill switch outranks everything; the
51
+ * result lists every active reason.
52
+ */
53
+ export declare function computeTelemetryEnvironment(input: TelemetryEnvironmentInput): TelemetryEnvironmentResult;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Production eligibility — Anonymous Product Telemetry v1
3
+ * (PRI-597, SPEC §35-§37).
4
+ *
5
+ * Environment suppression is evaluated independently of consent and the
6
+ * feature flag (both are AND-ed by the service). Every suppression reason is
7
+ * named in the result so `pd telemetry status` can show exactly why export is
8
+ * off (rc-9 — no silent suppression).
9
+ *
10
+ * Dev/CI/test detection follows the repository's explicit-marker philosophy
11
+ * (PD_E2E_MODE precedent): env markers and build-layout facts, never
12
+ * user-path heuristics.
13
+ */
14
+ import fs from 'node:fs';
15
+ import path from 'node:path';
16
+ /** Boolean-style env flags follow the PD_SKIP_* convention: '1' or 'true'. */
17
+ export function isEnvFlagActive(value) {
18
+ return value === '1' || value === 'true';
19
+ }
20
+ function isTruthyEnv(value) {
21
+ return value !== undefined && value !== '' && value !== 'false' && value !== '0';
22
+ }
23
+ /**
24
+ * True when the executing module lives inside a PD monorepo checkout.
25
+ *
26
+ * Build-layout fact, not a path heuristic: an installed runtime (canonical
27
+ * `~/.pd/runtime/host-runtime/...` or legacy extension dir) never has a
28
+ * sibling `packages/principles-core` + `packages/host-runtime` tree, while
29
+ * a checkout always does. Prevents maintainer/AI development activity from
30
+ * polluting production telemetry.
31
+ */
32
+ export function isRepoCheckoutModuleDir(moduleDir) {
33
+ let current = path.resolve(moduleDir);
34
+ for (let depth = 0; depth < 8; depth += 1) {
35
+ const hasCore = fs.existsSync(path.join(current, 'packages', 'principles-core'));
36
+ const hasHostRuntime = fs.existsSync(path.join(current, 'packages', 'host-runtime'));
37
+ if (hasCore && hasHostRuntime) {
38
+ return true;
39
+ }
40
+ const parent = path.dirname(current);
41
+ if (parent === current)
42
+ break;
43
+ current = parent;
44
+ }
45
+ return false;
46
+ }
47
+ /**
48
+ * Evaluate environment suppression. Kill switch outranks everything; the
49
+ * result lists every active reason.
50
+ */
51
+ export function computeTelemetryEnvironment(input) {
52
+ const reasons = [];
53
+ if (isEnvFlagActive(input.env.killSwitch))
54
+ reasons.push('env_kill_switch');
55
+ if (isTruthyEnv(input.env.ci))
56
+ reasons.push('ci_environment');
57
+ if (isTruthyEnv(input.env.vitest))
58
+ reasons.push('vitest_environment');
59
+ if (input.env.e2eMode === '1')
60
+ reasons.push('e2e_mode');
61
+ if (input.workspaceEnvironment === 'test' || input.workspaceEnvironment === 'demo' || input.workspaceEnvironment === 'development') {
62
+ reasons.push('workspace_environment');
63
+ }
64
+ if (input.installMode === 'missing')
65
+ reasons.push('install_layout_missing');
66
+ if (isRepoCheckoutModuleDir(input.moduleDir))
67
+ reasons.push('repo_checkout');
68
+ return { suppressed: reasons.length > 0, reasons };
69
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Bounded asynchronous telemetry export client — Anonymous Product Telemetry
3
+ * v1 (PRI-599, SPEC §29-§34).
4
+ *
5
+ * One HTTPS POST per invocation, bounded by AbortController, never throwing.
6
+ * Failure mapping is coarse (SPEC §34): codes only, never messages, stacks,
7
+ * or response bodies. The injectable fetchFn keeps unit tests offline.
8
+ */
9
+ import type { ProductTelemetrySnapshotV1 } from '@principles/core/runtime-v2';
10
+ export declare const DEFAULT_PRODUCT_TELEMETRY_ENDPOINT = "https://principles-website.pages.dev/api/product-telemetry/snapshot";
11
+ export declare const PRODUCT_TELEMETRY_TIMEOUT_MS = 8000;
12
+ export declare const PRODUCT_TELEMETRY_MAX_BODY_BYTES = 4096;
13
+ export type TelemetryFailureCode = 'timeout' | 'network_error' | 'http_400' | 'http_429' | 'http_5xx' | 'http_unexpected_status' | 'invalid_response';
14
+ export type TelemetryExportResult = {
15
+ ok: true;
16
+ status: number;
17
+ } | {
18
+ ok: false;
19
+ code: TelemetryFailureCode;
20
+ retryable: boolean;
21
+ };
22
+ export type TelemetryFetchFn = (url: string, init: {
23
+ method: 'POST';
24
+ headers: Record<string, string>;
25
+ body: string;
26
+ signal: AbortSignal;
27
+ }) => Promise<{
28
+ status: number;
29
+ }>;
30
+ export interface ExportSnapshotArgs {
31
+ snapshot: ProductTelemetrySnapshotV1;
32
+ endpoint?: string;
33
+ timeoutMs?: number;
34
+ fetchFn?: TelemetryFetchFn;
35
+ }
36
+ /**
37
+ * Export one snapshot. Never throws; every failure maps to a coarse code
38
+ * with a retryable hint the service uses for backoff.
39
+ */
40
+ export declare function exportSnapshot(args: ExportSnapshotArgs): Promise<TelemetryExportResult>;
41
+ /**
42
+ * First failure retries after 1h; any further failure within 24h backs off 6h.
43
+ * Combined with the service's dailyAttemptCount hard cap this bounds a bad day
44
+ * to at most 5 attempts (0h/1h/7h/13h/19h), independent of clock skew.
45
+ */
46
+ export declare function nextRetryDelayMs(previousFailureWithin24h: boolean): number;