@xhulz/nina 0.53.2 → 0.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/package.json +1 -1
  2. package/releases/0.53.3/core/GAPS.md +125 -0
  3. package/releases/0.53.3/core/answered.json +68 -0
  4. package/releases/0.53.3/core/defaults/tree/.claude/agents/architect.md +1 -0
  5. package/releases/0.53.3/core/defaults/tree/.claude/agents/dba.md +3 -0
  6. package/releases/0.53.3/core/defaults/tree/.claude/agents/devops.md +1 -0
  7. package/releases/0.53.3/core/defaults/tree/.claude/agents/implementer.md +1 -0
  8. package/releases/0.53.3/core/defaults/tree/.claude/agents/integration-tester.md +3 -0
  9. package/releases/0.53.3/core/defaults/tree/.claude/agents/qa.md +7 -0
  10. package/releases/0.53.3/core/defaults/tree/.claude/agents/reviewer.md +3 -0
  11. package/releases/0.53.3/core/defaults/tree/.claude/agents/secops.md +3 -0
  12. package/releases/0.53.3/core/defaults/tree/.claude/agents/solidity-auditor.md +3 -0
  13. package/releases/0.53.3/core/defaults/tree/.claude/agents/solidity-dev.md +3 -0
  14. package/releases/0.53.3/core/tree/.claude/agents/architect.md +129 -0
  15. package/releases/0.53.3/core/tree/.claude/agents/dba.md +117 -0
  16. package/releases/0.53.3/core/tree/.claude/agents/devops.md +118 -0
  17. package/releases/0.53.3/core/tree/.claude/agents/implementer.md +163 -0
  18. package/releases/0.53.3/core/tree/.claude/agents/integration-tester.md +168 -0
  19. package/releases/0.53.3/core/tree/.claude/agents/planner.md +132 -0
  20. package/releases/0.53.3/core/tree/.claude/agents/qa.md +150 -0
  21. package/releases/0.53.3/core/tree/.claude/agents/reviewer.md +184 -0
  22. package/releases/0.53.3/core/tree/.claude/agents/secops.md +120 -0
  23. package/releases/0.53.3/core/tree/.claude/agents/solidity-auditor.md +126 -0
  24. package/releases/0.53.3/core/tree/.claude/agents/solidity-dev.md +123 -0
  25. package/releases/0.53.3/core/tree/.claude/agents-overview.md +64 -0
  26. package/releases/0.53.3/core/tree/.claude/frontend.md +10 -0
  27. package/releases/0.53.3/core/tree/.claude/graph.md +75 -0
  28. package/releases/0.53.3/core/tree/.claude/patterns.md +251 -0
  29. package/releases/0.53.3/core/tree/.claude/pills/README.md +150 -0
  30. package/releases/0.53.3/core/tree/.claude/pipeline.md +101 -0
  31. package/releases/0.53.3/core/tree/.claude/retrieval.md +103 -0
  32. package/releases/0.53.3/core/tree/.claude/router.md +202 -0
  33. package/releases/0.53.3/core/tree/.claude/templates/integration.md +46 -0
  34. package/releases/0.53.3/core/tree/CLAUDE.md +164 -0
  35. package/releases/0.53.3/core/tree/scripts/cost-watch.mjs +25 -0
  36. package/releases/0.53.3/core/tree/scripts/edit-guard.mjs +24 -0
  37. package/releases/0.53.3/core/tree/scripts/harness-check.mjs +71 -0
  38. package/releases/0.53.3/core/tree/scripts/loop-gate.mjs +19 -0
  39. package/releases/0.53.3/core/vocabulary.json +13 -0
  40. package/releases/0.53.3/surfaces/blockchain/tree/.claude/agents/architect.md +5 -0
  41. package/releases/0.53.3/surfaces/blockchain/tree/.claude/agents/devops.md +5 -0
  42. package/releases/0.53.3/surfaces/blockchain/tree/.claude/agents/reviewer.md +5 -0
  43. package/releases/0.53.3/surfaces/blockchain/tree/.claude/agents/solidity-auditor.md +18 -0
  44. package/releases/0.53.3/surfaces/blockchain/tree/.claude/agents/solidity-dev.md +16 -0
  45. package/releases/0.53.3/surfaces/blockchain/tree/.claude/agents-overview.md +6 -0
  46. package/releases/0.53.3/surfaces/blockchain/tree/.claude/graph.md +11 -0
  47. package/releases/0.53.3/surfaces/blockchain/tree/.claude/router.md +6 -0
  48. package/releases/0.53.3/surfaces/blockchain/tree/CLAUDE.md +12 -0
  49. package/releases/0.53.3/surfaces/d1/tree/.claude/agents/dba.md +15 -0
  50. package/releases/0.53.3/surfaces/d1/tree/.claude/agents/devops.md +2 -0
  51. package/releases/0.53.3/surfaces/d1/tree/.claude/agents/implementer.md +2 -0
  52. package/releases/0.53.3/surfaces/d1/tree/.claude/patterns.md +8 -0
  53. package/releases/0.53.3/surfaces/d1/tree/CLAUDE.md +2 -0
  54. package/releases/0.53.3/surfaces/db/tree/.claude/agents/architect.md +5 -0
  55. package/releases/0.53.3/surfaces/db/tree/.claude/agents/dba.md +54 -0
  56. package/releases/0.53.3/surfaces/db/tree/.claude/agents/devops.md +5 -0
  57. package/releases/0.53.3/surfaces/db/tree/.claude/agents/implementer.md +2 -0
  58. package/releases/0.53.3/surfaces/db/tree/.claude/agents/integration-tester.md +10 -0
  59. package/releases/0.53.3/surfaces/db/tree/.claude/agents/planner.md +2 -0
  60. package/releases/0.53.3/surfaces/db/tree/.claude/agents/reviewer.md +22 -0
  61. package/releases/0.53.3/surfaces/db/tree/.claude/agents/secops.md +2 -0
  62. package/releases/0.53.3/surfaces/db/tree/.claude/agents-overview.md +5 -0
  63. package/releases/0.53.3/surfaces/db/tree/.claude/graph.md +8 -0
  64. package/releases/0.53.3/surfaces/db/tree/.claude/patterns.md +22 -0
  65. package/releases/0.53.3/surfaces/db/tree/.claude/pipeline.md +13 -0
  66. package/releases/0.53.3/surfaces/db/tree/.claude/retrieval.md +5 -0
  67. package/releases/0.53.3/surfaces/db/tree/.claude/router.md +4 -0
  68. package/releases/0.53.3/surfaces/db/tree/CLAUDE.md +17 -0
  69. package/releases/0.53.3/surfaces/drizzle/tree/.claude/agents/dba.md +9 -0
  70. package/releases/0.53.3/surfaces/drizzle/tree/.claude/agents/devops.md +5 -0
  71. package/releases/0.53.3/surfaces/drizzle/tree/.claude/agents/implementer.md +2 -0
  72. package/releases/0.53.3/surfaces/drizzle/tree/.claude/patterns.md +7 -0
  73. package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/architect.md +14 -0
  74. package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/dba.md +2 -0
  75. package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/devops.md +29 -0
  76. package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/implementer.md +14 -0
  77. package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/integration-tester.md +11 -0
  78. package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/qa.md +3 -0
  79. package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/reviewer.md +8 -0
  80. package/releases/0.53.3/surfaces/edge-cf/tree/.claude/agents/secops.md +8 -0
  81. package/releases/0.53.3/surfaces/edge-cf/tree/.claude/patterns.md +17 -0
  82. package/releases/0.53.3/surfaces/edge-cf/tree/.claude/retrieval.md +8 -0
  83. package/releases/0.53.3/surfaces/edge-cf/tree/CLAUDE.md +27 -0
  84. package/releases/0.53.3/surfaces/frontend/tree/.claude/agents/architect.md +20 -0
  85. package/releases/0.53.3/surfaces/frontend/tree/.claude/agents/devops.md +28 -0
  86. package/releases/0.53.3/surfaces/frontend/tree/.claude/agents/implementer.md +25 -0
  87. package/releases/0.53.3/surfaces/frontend/tree/.claude/agents/qa.md +17 -0
  88. package/releases/0.53.3/surfaces/frontend/tree/.claude/agents/reviewer.md +56 -0
  89. package/releases/0.53.3/surfaces/frontend/tree/.claude/patterns.md +8 -0
  90. package/releases/0.53.3/surfaces/frontend/tree/.claude/retrieval.md +2 -0
  91. package/releases/0.53.3/surfaces/frontend/tree/.claude/router.md +14 -0
  92. package/releases/0.53.3/surfaces/frontend/tree/CLAUDE.md +5 -0
  93. package/releases/0.53.3/surfaces/integrations/tree/.claude/agents/architect.md +16 -0
  94. package/releases/0.53.3/surfaces/integrations/tree/.claude/agents/implementer.md +12 -0
  95. package/releases/0.53.3/surfaces/integrations/tree/.claude/agents/integration-tester.md +20 -0
  96. package/releases/0.53.3/surfaces/integrations/tree/.claude/agents/planner.md +2 -0
  97. package/releases/0.53.3/surfaces/integrations/tree/.claude/agents/reviewer.md +21 -0
  98. package/releases/0.53.3/surfaces/integrations/tree/.claude/agents/secops.md +2 -0
  99. package/releases/0.53.3/surfaces/integrations/tree/.claude/agents-overview.md +8 -0
  100. package/releases/0.53.3/surfaces/integrations/tree/.claude/graph.md +10 -0
  101. package/releases/0.53.3/surfaces/integrations/tree/.claude/patterns.md +38 -0
  102. package/releases/0.53.3/surfaces/integrations/tree/.claude/pipeline.md +16 -0
  103. package/releases/0.53.3/surfaces/integrations/tree/.claude/retrieval.md +16 -0
  104. package/releases/0.53.3/surfaces/integrations/tree/.claude/router.md +6 -0
  105. package/releases/0.53.3/surfaces/integrations/tree/CLAUDE.md +17 -0
  106. package/releases/0.53.3/surfaces/money/tree/.claude/agents/architect.md +12 -0
  107. package/releases/0.53.3/surfaces/money/tree/.claude/agents/dba.md +14 -0
  108. package/releases/0.53.3/surfaces/money/tree/.claude/agents/implementer.md +11 -0
  109. package/releases/0.53.3/surfaces/money/tree/.claude/agents/integration-tester.md +3 -0
  110. package/releases/0.53.3/surfaces/money/tree/.claude/agents/reviewer.md +23 -0
  111. package/releases/0.53.3/surfaces/money/tree/.claude/agents/secops.md +5 -0
  112. package/releases/0.53.3/surfaces/money/tree/.claude/agents/solidity-auditor.md +4 -0
  113. package/releases/0.53.3/surfaces/money/tree/.claude/agents/solidity-dev.md +4 -0
  114. package/releases/0.53.3/surfaces/money/tree/.claude/graph.md +2 -0
  115. package/releases/0.53.3/surfaces/money/tree/.claude/patterns.md +49 -0
  116. package/releases/0.53.3/surfaces/money/tree/.claude/pipeline.md +2 -0
  117. package/releases/0.53.3/surfaces/money/tree/.claude/retrieval.md +2 -0
  118. package/releases/0.53.3/surfaces/money/tree/CLAUDE.md +11 -0
  119. package/releases/0.53.3/surfaces/pii/tree/.claude/agents/dba.md +2 -0
  120. package/releases/0.53.3/surfaces/pii/tree/.claude/agents/devops.md +8 -0
  121. package/releases/0.53.3/surfaces/pii/tree/.claude/agents/reviewer.md +8 -0
  122. package/releases/0.53.3/surfaces/pii/tree/.claude/agents/secops.md +2 -0
  123. package/releases/0.53.3/surfaces/pii/tree/.claude/agents/solidity-auditor.md +5 -0
  124. package/releases/0.53.3/surfaces/pii/tree/CLAUDE.md +5 -0
  125. package/releases/0.53.3/surfaces/prisma/tree/.claude/agents/architect.md +2 -0
  126. package/releases/0.53.3/surfaces/prisma/tree/.claude/agents/dba.md +42 -0
  127. package/releases/0.53.3/surfaces/prisma/tree/.claude/agents/devops.md +11 -0
  128. package/releases/0.53.3/surfaces/prisma/tree/.claude/agents/implementer.md +2 -0
  129. package/releases/0.53.3/surfaces/prisma/tree/.claude/agents/integration-tester.md +2 -0
  130. package/releases/0.53.3/surfaces/prisma/tree/.claude/agents/reviewer.md +2 -0
  131. package/releases/0.53.3/surfaces/prisma/tree/.claude/patterns.md +15 -0
  132. package/releases/0.53.3/surfaces/prisma/tree/CLAUDE.md +5 -0
  133. package/releases/0.54.0/core/GAPS.md +125 -0
  134. package/releases/0.54.0/core/answered.json +68 -0
  135. package/releases/0.54.0/core/defaults/tree/.claude/agents/architect.md +1 -0
  136. package/releases/0.54.0/core/defaults/tree/.claude/agents/dba.md +3 -0
  137. package/releases/0.54.0/core/defaults/tree/.claude/agents/devops.md +1 -0
  138. package/releases/0.54.0/core/defaults/tree/.claude/agents/implementer.md +1 -0
  139. package/releases/0.54.0/core/defaults/tree/.claude/agents/integration-tester.md +3 -0
  140. package/releases/0.54.0/core/defaults/tree/.claude/agents/qa.md +7 -0
  141. package/releases/0.54.0/core/defaults/tree/.claude/agents/reviewer.md +3 -0
  142. package/releases/0.54.0/core/defaults/tree/.claude/agents/secops.md +3 -0
  143. package/releases/0.54.0/core/defaults/tree/.claude/agents/solidity-auditor.md +3 -0
  144. package/releases/0.54.0/core/defaults/tree/.claude/agents/solidity-dev.md +3 -0
  145. package/releases/0.54.0/core/tree/.claude/agents/architect.md +129 -0
  146. package/releases/0.54.0/core/tree/.claude/agents/dba.md +117 -0
  147. package/releases/0.54.0/core/tree/.claude/agents/devops.md +118 -0
  148. package/releases/0.54.0/core/tree/.claude/agents/implementer.md +163 -0
  149. package/releases/0.54.0/core/tree/.claude/agents/integration-tester.md +168 -0
  150. package/releases/0.54.0/core/tree/.claude/agents/planner.md +132 -0
  151. package/releases/0.54.0/core/tree/.claude/agents/qa.md +150 -0
  152. package/releases/0.54.0/core/tree/.claude/agents/reviewer.md +184 -0
  153. package/releases/0.54.0/core/tree/.claude/agents/secops.md +120 -0
  154. package/releases/0.54.0/core/tree/.claude/agents/solidity-auditor.md +126 -0
  155. package/releases/0.54.0/core/tree/.claude/agents/solidity-dev.md +123 -0
  156. package/releases/0.54.0/core/tree/.claude/agents-overview.md +64 -0
  157. package/releases/0.54.0/core/tree/.claude/frontend.md +10 -0
  158. package/releases/0.54.0/core/tree/.claude/graph.md +75 -0
  159. package/releases/0.54.0/core/tree/.claude/patterns.md +251 -0
  160. package/releases/0.54.0/core/tree/.claude/pills/README.md +150 -0
  161. package/releases/0.54.0/core/tree/.claude/pipeline.md +101 -0
  162. package/releases/0.54.0/core/tree/.claude/retrieval.md +103 -0
  163. package/releases/0.54.0/core/tree/.claude/router.md +202 -0
  164. package/releases/0.54.0/core/tree/.claude/templates/integration.md +48 -0
  165. package/releases/0.54.0/core/tree/CLAUDE.md +164 -0
  166. package/releases/0.54.0/core/tree/scripts/cost-watch.mjs +25 -0
  167. package/releases/0.54.0/core/tree/scripts/edit-guard.mjs +24 -0
  168. package/releases/0.54.0/core/tree/scripts/harness-check.mjs +71 -0
  169. package/releases/0.54.0/core/tree/scripts/loop-gate.mjs +19 -0
  170. package/releases/0.54.0/core/vocabulary.json +13 -0
  171. package/releases/0.54.0/surfaces/blockchain/tree/.claude/agents/architect.md +5 -0
  172. package/releases/0.54.0/surfaces/blockchain/tree/.claude/agents/devops.md +5 -0
  173. package/releases/0.54.0/surfaces/blockchain/tree/.claude/agents/reviewer.md +5 -0
  174. package/releases/0.54.0/surfaces/blockchain/tree/.claude/agents/solidity-auditor.md +18 -0
  175. package/releases/0.54.0/surfaces/blockchain/tree/.claude/agents/solidity-dev.md +16 -0
  176. package/releases/0.54.0/surfaces/blockchain/tree/.claude/agents-overview.md +6 -0
  177. package/releases/0.54.0/surfaces/blockchain/tree/.claude/graph.md +11 -0
  178. package/releases/0.54.0/surfaces/blockchain/tree/.claude/router.md +6 -0
  179. package/releases/0.54.0/surfaces/blockchain/tree/CLAUDE.md +12 -0
  180. package/releases/0.54.0/surfaces/d1/tree/.claude/agents/dba.md +15 -0
  181. package/releases/0.54.0/surfaces/d1/tree/.claude/agents/devops.md +2 -0
  182. package/releases/0.54.0/surfaces/d1/tree/.claude/agents/implementer.md +2 -0
  183. package/releases/0.54.0/surfaces/d1/tree/.claude/patterns.md +8 -0
  184. package/releases/0.54.0/surfaces/d1/tree/CLAUDE.md +2 -0
  185. package/releases/0.54.0/surfaces/db/tree/.claude/agents/architect.md +5 -0
  186. package/releases/0.54.0/surfaces/db/tree/.claude/agents/dba.md +54 -0
  187. package/releases/0.54.0/surfaces/db/tree/.claude/agents/devops.md +5 -0
  188. package/releases/0.54.0/surfaces/db/tree/.claude/agents/implementer.md +2 -0
  189. package/releases/0.54.0/surfaces/db/tree/.claude/agents/integration-tester.md +10 -0
  190. package/releases/0.54.0/surfaces/db/tree/.claude/agents/planner.md +2 -0
  191. package/releases/0.54.0/surfaces/db/tree/.claude/agents/reviewer.md +22 -0
  192. package/releases/0.54.0/surfaces/db/tree/.claude/agents/secops.md +2 -0
  193. package/releases/0.54.0/surfaces/db/tree/.claude/agents-overview.md +5 -0
  194. package/releases/0.54.0/surfaces/db/tree/.claude/graph.md +8 -0
  195. package/releases/0.54.0/surfaces/db/tree/.claude/patterns.md +22 -0
  196. package/releases/0.54.0/surfaces/db/tree/.claude/pipeline.md +13 -0
  197. package/releases/0.54.0/surfaces/db/tree/.claude/retrieval.md +5 -0
  198. package/releases/0.54.0/surfaces/db/tree/.claude/router.md +4 -0
  199. package/releases/0.54.0/surfaces/db/tree/CLAUDE.md +17 -0
  200. package/releases/0.54.0/surfaces/drizzle/tree/.claude/agents/dba.md +9 -0
  201. package/releases/0.54.0/surfaces/drizzle/tree/.claude/agents/devops.md +5 -0
  202. package/releases/0.54.0/surfaces/drizzle/tree/.claude/agents/implementer.md +2 -0
  203. package/releases/0.54.0/surfaces/drizzle/tree/.claude/patterns.md +7 -0
  204. package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/architect.md +14 -0
  205. package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/dba.md +2 -0
  206. package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/devops.md +29 -0
  207. package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/implementer.md +14 -0
  208. package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/integration-tester.md +11 -0
  209. package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/qa.md +3 -0
  210. package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/reviewer.md +8 -0
  211. package/releases/0.54.0/surfaces/edge-cf/tree/.claude/agents/secops.md +8 -0
  212. package/releases/0.54.0/surfaces/edge-cf/tree/.claude/patterns.md +17 -0
  213. package/releases/0.54.0/surfaces/edge-cf/tree/.claude/retrieval.md +8 -0
  214. package/releases/0.54.0/surfaces/edge-cf/tree/CLAUDE.md +27 -0
  215. package/releases/0.54.0/surfaces/frontend/tree/.claude/agents/architect.md +20 -0
  216. package/releases/0.54.0/surfaces/frontend/tree/.claude/agents/devops.md +28 -0
  217. package/releases/0.54.0/surfaces/frontend/tree/.claude/agents/implementer.md +25 -0
  218. package/releases/0.54.0/surfaces/frontend/tree/.claude/agents/qa.md +17 -0
  219. package/releases/0.54.0/surfaces/frontend/tree/.claude/agents/reviewer.md +56 -0
  220. package/releases/0.54.0/surfaces/frontend/tree/.claude/patterns.md +8 -0
  221. package/releases/0.54.0/surfaces/frontend/tree/.claude/retrieval.md +2 -0
  222. package/releases/0.54.0/surfaces/frontend/tree/.claude/router.md +14 -0
  223. package/releases/0.54.0/surfaces/frontend/tree/CLAUDE.md +5 -0
  224. package/releases/0.54.0/surfaces/integrations/tree/.claude/agents/architect.md +16 -0
  225. package/releases/0.54.0/surfaces/integrations/tree/.claude/agents/implementer.md +12 -0
  226. package/releases/0.54.0/surfaces/integrations/tree/.claude/agents/integration-tester.md +20 -0
  227. package/releases/0.54.0/surfaces/integrations/tree/.claude/agents/planner.md +2 -0
  228. package/releases/0.54.0/surfaces/integrations/tree/.claude/agents/reviewer.md +21 -0
  229. package/releases/0.54.0/surfaces/integrations/tree/.claude/agents/secops.md +2 -0
  230. package/releases/0.54.0/surfaces/integrations/tree/.claude/agents-overview.md +8 -0
  231. package/releases/0.54.0/surfaces/integrations/tree/.claude/graph.md +10 -0
  232. package/releases/0.54.0/surfaces/integrations/tree/.claude/patterns.md +38 -0
  233. package/releases/0.54.0/surfaces/integrations/tree/.claude/pipeline.md +16 -0
  234. package/releases/0.54.0/surfaces/integrations/tree/.claude/retrieval.md +16 -0
  235. package/releases/0.54.0/surfaces/integrations/tree/.claude/router.md +6 -0
  236. package/releases/0.54.0/surfaces/integrations/tree/CLAUDE.md +17 -0
  237. package/releases/0.54.0/surfaces/money/tree/.claude/agents/architect.md +12 -0
  238. package/releases/0.54.0/surfaces/money/tree/.claude/agents/dba.md +14 -0
  239. package/releases/0.54.0/surfaces/money/tree/.claude/agents/implementer.md +11 -0
  240. package/releases/0.54.0/surfaces/money/tree/.claude/agents/integration-tester.md +3 -0
  241. package/releases/0.54.0/surfaces/money/tree/.claude/agents/reviewer.md +23 -0
  242. package/releases/0.54.0/surfaces/money/tree/.claude/agents/secops.md +5 -0
  243. package/releases/0.54.0/surfaces/money/tree/.claude/agents/solidity-auditor.md +4 -0
  244. package/releases/0.54.0/surfaces/money/tree/.claude/agents/solidity-dev.md +4 -0
  245. package/releases/0.54.0/surfaces/money/tree/.claude/graph.md +2 -0
  246. package/releases/0.54.0/surfaces/money/tree/.claude/patterns.md +49 -0
  247. package/releases/0.54.0/surfaces/money/tree/.claude/pipeline.md +2 -0
  248. package/releases/0.54.0/surfaces/money/tree/.claude/retrieval.md +2 -0
  249. package/releases/0.54.0/surfaces/money/tree/CLAUDE.md +11 -0
  250. package/releases/0.54.0/surfaces/pii/tree/.claude/agents/dba.md +2 -0
  251. package/releases/0.54.0/surfaces/pii/tree/.claude/agents/devops.md +8 -0
  252. package/releases/0.54.0/surfaces/pii/tree/.claude/agents/reviewer.md +8 -0
  253. package/releases/0.54.0/surfaces/pii/tree/.claude/agents/secops.md +2 -0
  254. package/releases/0.54.0/surfaces/pii/tree/.claude/agents/solidity-auditor.md +5 -0
  255. package/releases/0.54.0/surfaces/pii/tree/CLAUDE.md +5 -0
  256. package/releases/0.54.0/surfaces/prisma/tree/.claude/agents/architect.md +2 -0
  257. package/releases/0.54.0/surfaces/prisma/tree/.claude/agents/dba.md +42 -0
  258. package/releases/0.54.0/surfaces/prisma/tree/.claude/agents/devops.md +11 -0
  259. package/releases/0.54.0/surfaces/prisma/tree/.claude/agents/implementer.md +2 -0
  260. package/releases/0.54.0/surfaces/prisma/tree/.claude/agents/integration-tester.md +2 -0
  261. package/releases/0.54.0/surfaces/prisma/tree/.claude/agents/reviewer.md +2 -0
  262. package/releases/0.54.0/surfaces/prisma/tree/.claude/patterns.md +15 -0
  263. package/releases/0.54.0/surfaces/prisma/tree/CLAUDE.md +5 -0
  264. package/src/commands/check.mjs +107 -6
  265. package/src/commands/learn.mjs +60 -23
  266. package/src/commands/pills.mjs +6 -2
  267. package/src/dashboard.html +105 -20
  268. package/src/dashboard.mjs +5 -1
@@ -38,8 +38,8 @@ import { deepLearn, transcriptsOf } from '../deep.mjs';
38
38
  import { autoExport } from './export.mjs';
39
39
  import { beforeModel } from '../detectors.mjs';
40
40
 
41
- /** Loop-backs from one role, since its newest lesson, that make a lesson overdue. */
42
- const CAPTURE_AT = 3;
41
+ /** Times one stage's work was sent back, since its newest lesson, that make a lesson overdue. */
42
+ export const CAPTURE_AT = 3;
43
43
 
44
44
  /**
45
45
  * How far back a loop-back still counts. Older ones are history nobody remembers well enough to
@@ -111,11 +111,16 @@ const SENT_BACK_HOURS = 24;
111
111
 
112
112
  /**
113
113
  * The stage each loop-back sent work back to: the next one dispatched in its session, after it reported, among
114
- * the stages the project's graph routes that verdict of that stage to — or the only one it routes it to.
114
+ * the stages the project's graph routes that verdict of that stage to — or the only one it routes it to. One the
115
+ * graph routes to several, none of which has taken it back yet, went to no stage that can be told: it is charged to
116
+ * none, where it was charged to the stage that gave it — a gate that rejected work, doing its job, read as a stage
117
+ * sent back, and asked every turn for a lesson that was not its own.
115
118
  *
116
119
  * @param {object[]} records - Recorded dispatches.
117
120
  * @param {Map<string, Map<string, Map<string, number>>>|null} loops - The graph's capped loop-back edges.
118
- * @returns {Map<object, string>} Loop-back record → the stage it sent work back to, where one can be told.
121
+ * @returns {Map<object, {to: string|null, fix: object|null}>} Loop-back record → the stage it sent work back to, null
122
+ * while that cannot be told, and the dispatch of that stage that took the work back, where one was found. A
123
+ * loop-back the graph does not route is not in it.
119
124
  */
120
125
  export function sentBackTo(records, loops) {
121
126
  const out = new Map();
@@ -133,11 +138,32 @@ export function sentBackTo(records, loops) {
133
138
  const within = (x) => Date.parse(x.ts) - Date.parse(back) <= SENT_BACK_HOURS * 3_600_000;
134
139
  const next = (bySession.get(r.session) ?? []).find((x) => String(x.ts) > back && within(x) && targets.has(x.role));
135
140
  const to = next?.role ?? (targets.size === 1 ? [...targets.keys()][0] : null);
136
- if (to) out.set(r, to);
141
+ out.set(r, { to, fix: next ?? null });
137
142
  }
138
143
  return out;
139
144
  }
140
145
 
146
+ /**
147
+ * The stage a loop-back is charged to: where it sent work back (`sentBackTo`), none while that cannot be told, and
148
+ * the stage that gave it only where the graph routes it nowhere.
149
+ *
150
+ * @param {ReturnType<typeof sentBackTo>} owners
151
+ * @param {object} r - A loop-back record.
152
+ * @returns {string|null}
153
+ */
154
+ const chargedTo = (owners, r) => (owners.has(r) ? owners.get(r).to : r.role);
155
+
156
+ /**
157
+ * How many rounds some loop-backs sent back: those one dispatch took back are one, since the checkers that run beside
158
+ * each other each reject the same work. One no dispatch took back counts on its own, since nothing then says which
159
+ * work it rejected.
160
+ *
161
+ * @param {ReturnType<typeof sentBackTo>} owners
162
+ * @param {object[]} loops - Loop-back records.
163
+ * @returns {number}
164
+ */
165
+ const sendings = (owners, loops) => new Set(loops.map((r) => owners.get(r)?.fix ?? r)).size;
166
+
141
167
  /**
142
168
  * Roles that looped back often enough, since their newest lesson, that one is overdue.
143
169
  *
@@ -155,7 +181,7 @@ export function overdue(records, known, now = new Date(), days = CAPTURE_DAYS, o
155
181
  // A loop-back is the lesson of the stage it sent work back to, where that is known (`sentBackTo`): charged
156
182
  // to the stage that gave the verdict, the reviewer owed the implementer's lessons, and only a pill naming
157
183
  // every checker in its applies_to ever settled the count.
158
- const ownerOf = (r) => owners.get(r) ?? r.role;
184
+ const ownerOf = (r) => chargedTo(owners, r);
159
185
  const roles = [...new Set(records.map(ownerOf).filter(Boolean))];
160
186
  const out = [];
161
187
  for (const role of roles) {
@@ -175,12 +201,17 @@ export function overdue(records, known, now = new Date(), days = CAPTURE_DAYS, o
175
201
  const at = floor === newest ? taught?.at ?? null : null;
176
202
  const after = (r) => day(r.ts) > floor || (at !== null && day(r.ts) === floor && String(r.ts) > at);
177
203
  const loops = records.filter((r) => ownerOf(r) === role && readable(r.verdict) && isLoopBack(r.verdict) && after(r));
178
- if (loops.length >= CAPTURE_AT) {
204
+ // Rounds sent back, not loop-backs: three reviewers beside each other rejecting one change sent it back once.
205
+ const count = sendings(owners, loops);
206
+ if (count >= CAPTURE_AT) {
207
+ // One per round sent back, as the count is: three reviewers beside each other are one entry, not three.
208
+ const listed = new Set();
179
209
  const recent = loops
180
210
  .sort((a, b) => String(b.ts).localeCompare(String(a.ts)))
211
+ .filter((r) => !listed.has(owners.get(r)?.fix ?? r) && listed.add(owners.get(r)?.fix ?? r))
181
212
  .slice(0, 3)
182
213
  .map((r) => ({ ts: day(r.ts), desc: r.desc ?? '', session: String(r.session ?? '').slice(0, 8) }));
183
- out.push({ role, count: loops.length, since: newest, recent });
214
+ out.push({ role, count, since: newest, recent });
184
215
  }
185
216
  }
186
217
  return out.sort((a, b) => b.count - a.count);
@@ -214,7 +245,7 @@ export function applied(records, known) {
214
245
  }
215
246
 
216
247
  /** How many days either side of a lesson's date its role is measured over: the same on both sides. */
217
- const VERIFY_DAYS = 14;
248
+ export const VERIFY_DAYS = 14;
218
249
 
219
250
  /** A day as `YYYY-MM-DD`, moved by some days. */
220
251
  const shift = (date, days) => new Date(Date.parse(`${date}T12:00:00Z`) + days * 86_400_000).toISOString().slice(0, 10);
@@ -248,18 +279,27 @@ function wilson(k, n) {
248
279
  * graph sends work back to. A change is called only where the two intervals do not overlap. Not proof — the
249
280
  * work changes too — but a number where one can be had, and the reason where it cannot.
250
281
  *
282
+ * A round is counted sent back once, however many loop-backs sent it: the checkers that run beside each other
283
+ * each reject the same work, and one project's architect had 14 loop-backs on a day it ran 7 rounds, which the
284
+ * share read as 100% sent back where 5 of the 7 were. Loop-backs that the same dispatch took back are one.
285
+ *
251
286
  * @param {object[]} records - Recorded dispatches.
252
287
  * @param {Awaited<ReturnType<typeof lessons>>} known - The project's pills.
253
- * @param {{owners?: Map<object, string>, targets?: Set<string>|null}} [graph] - Who each loop-back sent work
254
- * back to, and the stages the graph sends work back to at all.
288
+ * @param {{owners?: ReturnType<typeof sentBackTo>, targets?: Set<string>|null}} [graph] - Who each loop-back sent
289
+ * work back to, and the stages the graph sends work back to at all.
255
290
  * @returns {{rel: string, date: string, role: string, comparable: boolean, why?: string, on?: string|null,
256
- * was?: string, before?: {n: number, loops: number}, after?: {n: number, loops: number},
257
- * change?: 'lower'|'higher'|'unclear', control?: {before: {n: number, loops: number}, after: {n: number, loops: number}}}[]}
291
+ * was?: string, before?: Side, after?: Side, change?: 'lower'|'higher'|'unclear', control?: {before: Side, after: Side}}[]}
292
+ * A `Side` is `{n, loops, span}`: the stage's rounds, how many were sent back, and the first and last day a round
293
+ * of it was recorded on, since a project younger than the window has fewer days than fourteen to show.
258
294
  */
259
295
  export function verified(records, known, { owners = new Map(), targets = null } = {}) {
260
296
  const out = [];
261
- const ownerOf = (r) => owners.get(r) ?? r.role;
297
+ const ownerOf = (r) => chargedTo(owners, r);
262
298
  const sentBack = records.filter((r) => readable(r.verdict) && isLoopBack(r.verdict));
299
+ const sideOf = (these, backs) => {
300
+ const days = these.map((r) => day(r.ts)).sort();
301
+ return { n: these.length, loops: Math.min(these.length, sendings(owners, backs)), span: [days[0] ?? null, days.at(-1) ?? null] };
302
+ };
263
303
  const ranOn = (r) => (r.usage_model ? `${r.usage_model}${r.effort ? ` · ${r.effort}` : ''}` : null);
264
304
  for (const lesson of known.filter((l) => l.date)) {
265
305
  const from = shift(lesson.date, -VERIFY_DAYS);
@@ -274,10 +314,7 @@ export function verified(records, known, { owners = new Map(), targets = null }
274
314
  }
275
315
  const rounds = records.filter((r) => r.role === role && readable(r.verdict));
276
316
  const backs = sentBack.filter((r) => ownerOf(r) === role);
277
- const side = (pick, mine) => {
278
- const n = mine.filter(pick).length;
279
- return { n, loops: Math.min(n, backs.filter(pick).length) };
280
- };
317
+ const side = (pick, mine) => sideOf(mine.filter(pick), backs.filter(pick));
281
318
  if (side(pre, rounds).n < VERIFY_MIN || side(post, rounds).n < VERIFY_MIN) {
282
319
  const [b, a] = [side(pre, rounds).n, side(post, rounds).n];
283
320
  out.push({ ...base, comparable: false, why: `too few rounds of ${role} either side (${b} before, ${a} after, in ${VERIFY_DAYS} days each)` });
@@ -299,10 +336,10 @@ export function verified(records, known, { owners = new Map(), targets = null }
299
336
  const [bLo, bHi] = wilson(before.loops, before.n);
300
337
  const [aLo, aHi] = wilson(after.loops, after.n);
301
338
  const change = aHi < bLo ? 'lower' : aLo > bHi ? 'higher' : 'unclear';
302
- const others = [...(targets ?? new Set(sentBack.map(ownerOf)))].filter((x) => x !== role);
339
+ const others = [...(targets ?? new Set(sentBack.map(ownerOf)))].filter((x) => x && x !== role);
303
340
  const theirs = records.filter((r) => others.includes(r.role) && readable(r.verdict));
304
341
  const otherBacks = sentBack.filter((r) => others.includes(ownerOf(r)));
305
- const control = (pick) => ({ n: theirs.filter(pick).length, loops: Math.min(theirs.filter(pick).length, otherBacks.filter(pick).length) });
342
+ const control = (pick) => sideOf(theirs.filter(pick), otherBacks.filter(pick));
306
343
  out.push({ ...base, comparable: true, on, before, after, change, control: { before: control(pre), after: control(post) } });
307
344
  }
308
345
  }
@@ -1047,7 +1084,7 @@ export async function learn(argv, ctx) {
1047
1084
  }
1048
1085
  for (const o of late) {
1049
1086
  console.log(
1050
- ` ${o.role}: ${o.count} loop-back(s) in the last ${days} days ` +
1087
+ ` ${o.role}: sent back ${o.count} time(s) in the last ${days} days ` +
1051
1088
  (o.since ? `since its newest lesson (${o.since})` : 'and no lesson at all') +
1052
1089
  ' — the newest:',
1053
1090
  );
@@ -1109,10 +1146,10 @@ export async function learn(argv, ctx) {
1109
1146
  ? ` observe ${learning.runs} run(s) in ${records.length} round(s) recorded, ${span}`
1110
1147
  : ' observe ✗ nothing recorded — no transcripts found for this project, so no link below can be measured',
1111
1148
  );
1112
- if (late.length === 0) console.log(` capture ✓ no role has looped back ${CAPTURE_AT}+ times without a lesson in the last ${days} days`);
1149
+ if (late.length === 0) console.log(` capture ✓ no role has been sent back ${CAPTURE_AT}+ times without a lesson in the last ${days} days`);
1113
1150
  late.forEach((o, i) => {
1114
1151
  console.log(
1115
- ` ${i === 0 ? 'capture ' : ' '} ✗ ${o.role}: ${o.count} loop-back(s) ` +
1152
+ ` ${i === 0 ? 'capture ' : ' '} ✗ ${o.role}: sent back ${o.count} time(s) ` +
1116
1153
  (o.since ? `since its newest lesson (${o.since})` : 'and no lesson at all'),
1117
1154
  );
1118
1155
  });
@@ -12,6 +12,7 @@
12
12
 
13
13
  import { mkdir, readFile, readdir, rename } from 'node:fs/promises';
14
14
  import { HARNESS, readProfile } from '../paths.mjs';
15
+ import { localDay } from '../store.mjs';
15
16
  import { existsSync, readFileSync, statSync } from 'node:fs';
16
17
  import { spawnSync } from 'node:child_process';
17
18
  import { dirname, join, resolve } from 'node:path';
@@ -124,7 +125,7 @@ export function list(value) {
124
125
  * @param {string} citation - `path` or `path:line`.
125
126
  * @returns {{state: 'ok'|'gone'|'truncated', path: string, line: number|null, lines?: number}}
126
127
  */
127
- function resolveCitation(target, citation) {
128
+ export function resolveCitation(target, citation) {
128
129
  const at = /^(.*):(\d+)$/.exec(citation);
129
130
  const path = at ? at[1] : citation;
130
131
  const line = at ? Number(at[2]) : null;
@@ -350,7 +351,10 @@ export async function pillsData(target, ctx) {
350
351
  .filter((f) => f.endsWith('.md'))
351
352
  .map((f) => f.replace(/\.md$/, ''))
352
353
  .sort();
353
- const today = new Date().toISOString().slice(0, 10);
354
+ // The day where this machine is, the one the capture detector counts loop-backs by and names its requests with: read
355
+ // in UTC, for an hour after midnight at UTC+1 a lesson dated today was refused as in the future, and the loop-backs
356
+ // it answered, dated today, went on being reported.
357
+ const today = localDay(new Date().toISOString());
354
358
  const files = existsSync(pillsDir) ? await pillFiles(pillsDir) : [];
355
359
 
356
360
  if (files.length === 0) return { files: 0, active: 0, retired: 0, problems: [], notes: [], pills: [] };
@@ -61,7 +61,21 @@
61
61
  .stage { display: grid; grid-template-columns: 170px 1fr; gap: 4px 14px; padding: 12px 0; border-bottom: 1px solid #2a2838; }
62
62
  .empty { color: var(--faint); padding: 30px 0; text-align: center; }
63
63
  .note { margin: 4px 0; font-size: 13px; }
64
- @media (max-width: 640px) { .stage { grid-template-columns: 1fr; } nav { margin-left: 0; } }
64
+ .answer { background: var(--panel); border: 1px solid var(--line); border-left: 4px solid var(--faint); border-radius: 6px; padding: 12px 16px; margin: 0 0 14px; }
65
+ .answer[data-tone="ok"] { border-left-color: var(--green); } .answer[data-tone="bad"] { border-left-color: var(--red); } .answer[data-tone="warn"] { border-left-color: var(--amber); }
66
+ .answer .q { color: var(--faint); font-size: 12px; }
67
+ .answer .head { font: 600 18px var(--sans); margin: 2px 0 4px; }
68
+ .answer p { margin: 2px 0; color: var(--soft); font-size: 13px; }
69
+ .cmp { background: var(--panel); border: 1px solid var(--line); border-radius: 6px; padding: 12px 14px; margin: 0 0 10px; }
70
+ .cmp .top { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 8px; }
71
+ .cmp .verdict { margin-left: auto; font: 600 13px var(--mono); }
72
+ .chip.wraps { white-space: normal; overflow-wrap: anywhere; }
73
+ .meter { display: grid; grid-template-columns: 48px minmax(60px, 1fr) 44px minmax(0, 230px); align-items: center; gap: 2px 10px; margin: 4px 0; font-size: 13px; }
74
+ .meter .pctv { text-align: right; }
75
+ @media (max-width: 640px) {
76
+ .stage { grid-template-columns: 1fr; } nav { margin-left: 0; }
77
+ .meter { grid-template-columns: 48px minmax(60px, 1fr) 44px; } .meter .detail { grid-column: 2 / -1; }
78
+ }
65
79
  </style>
66
80
  </head>
67
81
  <body>
@@ -210,34 +224,105 @@ const RENDER = {
210
224
 
211
225
  learning(d) {
212
226
  if (!d) return el('p', { class: 'empty' }, 'No profile here to read the learning cycle of.');
213
- const measured = d.checks.filter((c) => c.before);
227
+ const name = (rel) => rel.replace(/^\.claude\/pills\//, '').replace(/^retired\//, '').replace(/\.md$/, '');
228
+ const graduated = (rel) => rel.startsWith('.claude/pills/retired/');
229
+ const dayOf = (iso) => new Date(`${iso}T12:00:00`).toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
230
+ const daysIn = ([a, b]) => Math.round((Date.parse(`${b}T12:00:00Z`) - Date.parse(`${a}T12:00:00Z`)) / 86_400_000) + 1;
231
+ const lessonChip = (rel) => el('span', { class: 'chip wraps', title: rel }, name(rel), graduated(rel) ? el('span', { class: 'faint' }, ' · graduated') : null);
232
+ // Lessons written the same day for the same stage are read over the same rounds, so they are one comparison, not
233
+ // a row each repeating its numbers.
234
+ const groups = [];
235
+ for (const c of d.checks.filter((x) => x.before)) {
236
+ const same = groups.find((g) => g.role === c.role && g.date === c.date && g.on === c.on);
237
+ if (same) same.lessons.push(c.rel);
238
+ else groups.push({ ...c, lessons: [c.rel] });
239
+ }
240
+ const rank = { higher: 0, lower: 1, unclear: 2 };
241
+ groups.sort((a, b) => rank[a.change] - rank[b.change] || b.date.localeCompare(a.date) || a.role.localeCompare(b.role));
214
242
  const unmeasured = d.checks.filter((c) => !c.before);
243
+ const [less, more, unclear] = ['lower', 'higher', 'unclear'].map((k) => groups.filter((g) => g.change === k).length);
244
+ const lessonsRead = new Set(groups.flatMap((g) => g.lessons)).size;
245
+ const history = d.span ? daysIn(d.span) : 0;
246
+ const shortest = Math.min(...groups.flatMap((g) => [g.before, g.after]).map((side) => (side.span[0] ? daysIn(side.span) : 0)));
247
+ // The share is of work sent back, so up is worse. A move the rounds are too few to tell from chance still says
248
+ // which way it went: "could be chance" alone read, beside 33% → 67%, as if the larger number were the better one.
249
+ const share = (side) => (side.n ? Math.round((100 * side.loops) / side.n) : 0);
250
+ const verdict = (g) =>
251
+ g.change === 'lower' ? ['ok', '▼ better: sent back less']
252
+ : g.change === 'higher' ? ['bad', '▲ worse: sent back more']
253
+ : share(g.after) > share(g.before) ? ['faint', '▲ sent back more, but could be chance']
254
+ : share(g.after) < share(g.before) ? ['faint', '▼ sent back less, but could be chance']
255
+ : ['faint', '≈ no change'];
256
+
257
+ const answer = !groups.length
258
+ ? { tone: 'faint', head: 'Not measurable yet', body: unmeasured.length ? `None of the ${unmeasured.length} lesson-and-stage pairs has enough rounds of its stage on both sides of its date — the reasons are at the bottom.` : 'No lesson has been written yet.' }
259
+ : less && more
260
+ ? { tone: 'warn', head: 'Mixed', body: `${less} comparison(s) sent back less since their lessons, ${more} sent back more, ${unclear} with no clear change.` }
261
+ : more
262
+ ? { tone: 'bad', head: 'Sent back more since', body: `In ${more} of ${groups.length} comparison(s) the stage had more of its work sent back after its lessons than before; ${unclear ? `the other ${unclear} show no clear change` : 'none shows less'}.` }
263
+ : less
264
+ ? { tone: 'ok', head: 'Sent back less since', body: `In ${less} of ${groups.length} comparison(s) the stage had less of its work sent back after its lessons than before${unclear ? `; the other ${unclear} show no clear change` : ''}.` }
265
+ : { tone: 'faint', head: 'No clear change yet', body: `None of the ${groups.length} comparison(s) moved by more than chance moves a share at that many rounds.` };
266
+
267
+ const meter = (label, side) => el('div', { class: 'meter' },
268
+ el('span', { class: 'faint' }, label),
269
+ bar([[side.n ? side.loops / side.n : 0, 'var(--amber)']]),
270
+ el('span', { class: 'mono pctv' }, pct(side.loops, side.n)),
271
+ el('span', { class: 'faint detail' }, `${side.loops} of ${side.n} rounds · ${side.span[0] ? `${dayOf(side.span[0])}${side.span[1] !== side.span[0] ? ` – ${dayOf(side.span[1])}` : ''}` : 'no day'}`),
272
+ );
273
+ const comparison = (g) => el('div', { class: 'cmp' },
274
+ el('div', { class: 'top' },
275
+ el('span', { class: 'role' }, g.role),
276
+ el('span', { class: 'soft' }, `${g.lessons.length} lesson${g.lessons.length > 1 ? 's' : ''} written ${dayOf(g.date)}`),
277
+ g.on ? el('span', { class: 'faint mono' }, g.on) : null,
278
+ el('span', { class: `verdict ${verdict(g)[0]}` }, verdict(g)[1]),
279
+ ),
280
+ el('div', { class: 'faint', style: 'font-size:12px;margin:0 0 2px' }, `share of the ${g.role}'s rounds sent back to it · lower is better`),
281
+ meter('before', g.before),
282
+ meter('after', g.after),
283
+ el('div', { class: 'faint', style: 'margin:6px 0 8px' }, `for reference, the other stages over the same days: ${pct(g.control.before.loops, g.control.before.n)} → ${pct(g.control.after.loops, g.control.after.n)}`),
284
+ el('div', { class: 'chips' }, g.lessons.map(lessonChip)),
285
+ );
286
+ // What could not be measured, by its reason: the same reason, word for word, is one line.
287
+ const reasons = new Map();
288
+ for (const c of unmeasured) reasons.set(c.why, [...(reasons.get(c.why) ?? []), c.rel]);
289
+
215
290
  return el('div', {},
216
291
  el('h2', {}, 'Learning'),
217
292
  el('p', { class: 'sub' }, said('Whether the pipeline learns from its own runs, link by link, as `nina learn` reads it.')),
293
+ el('div', { class: 'answer', 'data-tone': answer.tone },
294
+ el('div', { class: 'q' }, 'Did the lessons help?'),
295
+ el('div', { class: 'head' }, answer.head),
296
+ el('p', {}, answer.body),
297
+ groups.length && history < 2 * d.window + 1
298
+ ? el('p', {}, `This project has ${history} day(s) of history, so a lesson is compared over fewer than the ${d.window} days either side the measure asks for: read it as an early sign.`)
299
+ : groups.length && shortest < d.window
300
+ ? el('p', {}, `The shortest comparison has rounds on ${shortest} day(s) of one side, of the ${d.window} the measure reads: read it as an early sign.`)
301
+ : null,
302
+ ),
218
303
  el('div', { class: 'cards' },
219
- card('observe', d.rounds ? `${d.runs} runs` : '—', d.rounds ? `${d.rounds} rounds, ${d.span[0]} → ${d.span[1]}` : 'nothing recorded'),
220
- card('capture', d.late.length ? `${d.late.length} owed` : '✓', d.late.length ? 'stages sent back with nothing written down' : `no stage sent back 3+ times without a lesson in ${d.days} days`),
221
- card('apply', d.use.measured ? pct(d.use.read, d.use.measured) : '—', d.use.measured ? `of ${d.use.measured} runs read a lesson` : 'not measured yet'),
222
- card('graduate', `${d.open.length} open`, `${d.ready.length} at 3+ · ${d.madeHere} made a rule here`),
304
+ card('observe · what ran', d.rounds ? `${d.runs} runs` : '—', d.rounds ? `${d.rounds} rounds, ${d.span[0]} → ${d.span[1]}` : 'nothing recorded'),
305
+ card('capture · written down?', d.late.length ? `${d.late.length} owed` : '✓', d.late.length ? 'stages sent back with nothing written down' : `no stage sent back ${d.at}+ times without a lesson in ${d.days} days`),
306
+ card('apply · read?', d.use.measured ? pct(d.use.read, d.use.measured) : '—', d.use.measured ? `of ${d.use.measured} runs read a lesson` : 'not measured yet'),
307
+ card('verify · helped?', !groups.length ? '—' : less && more ? 'mixed' : more ? '▲ more' : less ? '▼ less' : '≈ unclear', groups.length ? `${groups.length} comparison(s) of ${lessonsRead} lesson(s): ${less} sent back less, ${more} more` : 'nothing measurable yet'),
308
+ card('graduate · made rules?', `${d.open.length} open`, `${d.ready.length} at ${d.at}+ · ${d.madeHere} made a rule here${d.relapses.length ? ` · ${d.relapses.length} watched` : ''}`),
223
309
  card('loops', d.gated ? (d.activity ? String(d.activity.rounds) : '—') : 'no gate', d.activity ? `rounds on capped edges · ${d.activity.held} sent to you` : d.gated ? 'no ledger yet' : 'caps are instructions'),
224
310
  ),
225
- d.late.length ? [el('h3', {}, 'capture · sent back with nothing written down'), d.late.map((o) => el('div', { class: 'note' }, el('span', { class: 'role' }, o.role), ` ${o.count} loop-back(s) ${o.since ? `since its newest lesson (${o.since})` : 'and no lesson at all'}`, el('ul', { class: 'list soft' }, o.recent.map((r) => el('li', {}, `${when(r.ts)} · ${r.desc ?? '(no description)'}`)))))] : null,
311
+ d.late.length ? [el('h3', {}, 'capture · sent back with nothing written down'), d.late.map((o) => el('div', { class: 'note' }, el('span', { class: 'role' }, o.role), ` sent back ${o.count} time(s) ${o.since ? `since its newest lesson (${o.since})` : 'and no lesson at all'}`, el('ul', { class: 'list soft' }, o.recent.map((r) => el('li', {}, `${when(r.ts)} · ${r.desc ?? '(no description)'}`)))))] : null,
312
+ el('h3', {}, 'verify · is each stage sent back less since its lessons?'),
313
+ el('p', { class: 'note soft', style: 'margin-bottom:12px' }, `For each lesson, the share of its stage's rounds that a later stage sent back, in the ${d.window} days before it was written and the ${d.window} after — lower is better. A change is called only when it is larger than chance moves a share at that many rounds. The other stages, over the same days, say whether everything moved at once: then it was the work that changed, not the lesson.`),
314
+ groups.length ? groups.map(comparison) : el('p', { class: 'note faint' }, 'No lesson could be measured yet.'),
226
315
  d.owed.length ? [el('h3', {}, 'to graduate · here or in the harness'), d.owed.map((o) => el('p', { class: 'note' }, el('span', { class: 'mono' }, o.rel), o.declined ? el('span', { class: 'soft' }, ` — declined by the harness${o.declined.in ? ` in ${o.declined.in}` : ''}: ${o.declined.why}`) : el('span', { class: 'soft' }, ` — recurred ${o.occurrences} times`)))] : null,
227
316
  d.open.length ? [el('h3', {}, 'requests open in the harness'), table(['since', 'pill', 'proposed for'], d.open.map((r) => [el('span', { class: 'mono soft' }, r.date), el('span', { class: 'mono' }, r.pill), r.target]))] : null,
228
- d.relapses.length ? [el('h3', {}, 'came back after graduating'), d.relapses.map((r) => el('p', { class: `note ${r.due ? 'bad' : 'soft'}` }, `${r.due ? '✗' : '·'} ${r.rel} came back ${r.recurred} time(s) after ${r.target === 'project' ? `it became a rule here in ${r.rule_in}` : `its rule shipped in ${r.answered_in || 'a release'}`}${r.due ? ' — the rule did not hold' : ' — watched'}`))] : null,
229
- el('h3', {}, 'verify · is each lesson sent back less since?'),
230
- measured.length
231
- ? table(['lesson', 'stage', 'before → after', 'n', 'change', 'other stages'], measured.map((c) => [
232
- el('span', { class: 'mono' }, c.rel.replace(/^\.claude\/pills\//, '')),
233
- el('span', { class: 'role' }, c.role),
234
- `${pct(c.before.loops, c.before.n)} → ${pct(c.after.loops, c.after.n)}`,
235
- `${c.before.n} → ${c.after.n}`,
236
- el('span', { class: c.change === 'lower' ? 'ok' : c.change === 'higher' ? 'bad' : 'faint' }, { lower: 'sent back less', higher: 'sent back more', unclear: 'no clear change' }[c.change]),
237
- el('span', { class: 'soft' }, `${pct(c.control.before.loops, c.control.before.n)} → ${pct(c.control.after.loops, c.control.after.n)}`),
238
- ]), [3])
239
- : el('p', { class: 'note faint' }, 'No lesson could be measured yet.'),
240
- unmeasured.length ? el('p', { class: 'note faint' }, `${unmeasured.length} more could not be measured.`) : null,
317
+ d.relapses.length ? [el('h3', {}, 'graduated, then seen again'),
318
+ d.relapses.map((r) => el('p', { class: 'note' },
319
+ el('span', { class: r.due ? 'bad' : 'faint' }, r.due ? '✗ ' : '· '),
320
+ el('span', { class: 'mono', title: r.rel }, name(r.rel)),
321
+ el('span', { class: 'soft' }, ` — seen ${r.recurred} time(s) since its rule ${r.target === 'project' ? `was made here in ${r.rule_in}` : `shipped in ${r.answered_in || 'a release'}`}`),
322
+ r.due ? el('span', { class: 'bad' }, ': the rule did not hold') : el('span', { class: 'faint' }, `; watched, it reopens at ${d.at}`)))] : null,
323
+ unmeasured.length ? el('details', { style: 'margin-top:24px' },
324
+ el('summary', { class: 'soft', style: 'cursor:pointer' }, `${unmeasured.length} lesson-and-stage pair(s) could not be measured, and why`),
325
+ [...reasons].map(([why, rels]) => el('div', { class: 'note', style: 'margin:10px 0' }, el('div', { class: 'soft' }, why), el('div', { class: 'chips', style: 'margin-top:4px' }, rels.map(lessonChip))))) : null,
241
326
  );
242
327
  },
243
328
 
package/src/dashboard.mjs CHANGED
@@ -21,7 +21,7 @@ import { layerRootFor } from './commands/compose.mjs';
21
21
  import { taskList } from './commands/runs.mjs';
22
22
  import { pipelineData } from './commands/pipeline.mjs';
23
23
  import { pillsData } from './commands/pills.mjs';
24
- import { learningData } from './commands/learn.mjs';
24
+ import { CAPTURE_AT, VERIFY_DAYS, learningData } from './commands/learn.mjs';
25
25
  import { statsData } from './commands/stats.mjs';
26
26
 
27
27
  /** The page: one self-contained file, nothing fetched from anywhere else. */
@@ -72,6 +72,10 @@ export function dashboardTabs(target, ctx) {
72
72
  const d = await learningData(target, layers.dir, profile, { records: roundsOf(target) });
73
73
  return {
74
74
  days: d.days,
75
+ // How many times makes an event: a stage sent back, a lesson recurring, a rule that came back. And the days
76
+ // either side of a lesson that verify reads, which a project younger than them cannot fill.
77
+ at: CAPTURE_AT,
78
+ window: VERIFY_DAYS,
75
79
  runs: d.runs,
76
80
  rounds: d.rounds,
77
81
  span: d.span,