@itaila/archetype 0.3.30

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 (319) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +475 -0
  3. package/dist/audit/audit-persona.d.ts +163 -0
  4. package/dist/audit/audit-persona.d.ts.map +1 -0
  5. package/dist/audit/audit-persona.js +415 -0
  6. package/dist/audit/audit-persona.js.map +1 -0
  7. package/dist/audit/brain-reflection.d.ts +33 -0
  8. package/dist/audit/brain-reflection.d.ts.map +1 -0
  9. package/dist/audit/brain-reflection.js +148 -0
  10. package/dist/audit/brain-reflection.js.map +1 -0
  11. package/dist/audit/conversation-audit.d.ts +12 -0
  12. package/dist/audit/conversation-audit.d.ts.map +1 -0
  13. package/dist/audit/conversation-audit.js +76 -0
  14. package/dist/audit/conversation-audit.js.map +1 -0
  15. package/dist/audit/prompt-audit.d.ts +10 -0
  16. package/dist/audit/prompt-audit.d.ts.map +1 -0
  17. package/dist/audit/prompt-audit.js +153 -0
  18. package/dist/audit/prompt-audit.js.map +1 -0
  19. package/dist/audit/prompt-dump.d.ts +137 -0
  20. package/dist/audit/prompt-dump.d.ts.map +1 -0
  21. package/dist/audit/prompt-dump.js +269 -0
  22. package/dist/audit/prompt-dump.js.map +1 -0
  23. package/dist/audit/trace-integrity.d.ts +33 -0
  24. package/dist/audit/trace-integrity.d.ts.map +1 -0
  25. package/dist/audit/trace-integrity.js +109 -0
  26. package/dist/audit/trace-integrity.js.map +1 -0
  27. package/dist/audit/types.d.ts +92 -0
  28. package/dist/audit/types.d.ts.map +1 -0
  29. package/dist/audit/types.js +2 -0
  30. package/dist/audit/types.js.map +1 -0
  31. package/dist/audit/version.d.ts +14 -0
  32. package/dist/audit/version.d.ts.map +1 -0
  33. package/dist/audit/version.js +65 -0
  34. package/dist/audit/version.js.map +1 -0
  35. package/dist/brain.d.ts +7 -0
  36. package/dist/brain.d.ts.map +1 -0
  37. package/dist/brain.js +83 -0
  38. package/dist/brain.js.map +1 -0
  39. package/dist/builder/actions.d.ts +60 -0
  40. package/dist/builder/actions.d.ts.map +1 -0
  41. package/dist/builder/actions.js +257 -0
  42. package/dist/builder/actions.js.map +1 -0
  43. package/dist/builder/browser.d.ts +140 -0
  44. package/dist/builder/browser.d.ts.map +1 -0
  45. package/dist/builder/browser.js +232 -0
  46. package/dist/builder/browser.js.map +1 -0
  47. package/dist/builder/executor.d.ts +228 -0
  48. package/dist/builder/executor.d.ts.map +1 -0
  49. package/dist/builder/executor.js +1548 -0
  50. package/dist/builder/executor.js.map +1 -0
  51. package/dist/builder/index.d.ts +24 -0
  52. package/dist/builder/index.d.ts.map +1 -0
  53. package/dist/builder/index.js +24 -0
  54. package/dist/builder/index.js.map +1 -0
  55. package/dist/builder/node-test-discovery.d.ts +13 -0
  56. package/dist/builder/node-test-discovery.d.ts.map +1 -0
  57. package/dist/builder/node-test-discovery.js +45 -0
  58. package/dist/builder/node-test-discovery.js.map +1 -0
  59. package/dist/builder/sandbox.d.ts +172 -0
  60. package/dist/builder/sandbox.d.ts.map +1 -0
  61. package/dist/builder/sandbox.js +294 -0
  62. package/dist/builder/sandbox.js.map +1 -0
  63. package/dist/builder/workspace-files.d.ts +63 -0
  64. package/dist/builder/workspace-files.d.ts.map +1 -0
  65. package/dist/builder/workspace-files.js +190 -0
  66. package/dist/builder/workspace-files.js.map +1 -0
  67. package/dist/core/actions.d.ts +55 -0
  68. package/dist/core/actions.d.ts.map +1 -0
  69. package/dist/core/actions.js +311 -0
  70. package/dist/core/actions.js.map +1 -0
  71. package/dist/core/attachment-notes.d.ts +7 -0
  72. package/dist/core/attachment-notes.d.ts.map +1 -0
  73. package/dist/core/attachment-notes.js +38 -0
  74. package/dist/core/attachment-notes.js.map +1 -0
  75. package/dist/core/context.d.ts +10 -0
  76. package/dist/core/context.d.ts.map +1 -0
  77. package/dist/core/context.js +108 -0
  78. package/dist/core/context.js.map +1 -0
  79. package/dist/core/crud-prompt.d.ts +16 -0
  80. package/dist/core/crud-prompt.d.ts.map +1 -0
  81. package/dist/core/crud-prompt.js +268 -0
  82. package/dist/core/crud-prompt.js.map +1 -0
  83. package/dist/core/crud-schema.d.ts +12 -0
  84. package/dist/core/crud-schema.d.ts.map +1 -0
  85. package/dist/core/crud-schema.js +42 -0
  86. package/dist/core/crud-schema.js.map +1 -0
  87. package/dist/core/effective-config.d.ts +13 -0
  88. package/dist/core/effective-config.d.ts.map +1 -0
  89. package/dist/core/effective-config.js +33 -0
  90. package/dist/core/effective-config.js.map +1 -0
  91. package/dist/core/entities.d.ts +82 -0
  92. package/dist/core/entities.d.ts.map +1 -0
  93. package/dist/core/entities.js +116 -0
  94. package/dist/core/entities.js.map +1 -0
  95. package/dist/core/entity-helpers.d.ts +47 -0
  96. package/dist/core/entity-helpers.d.ts.map +1 -0
  97. package/dist/core/entity-helpers.js +122 -0
  98. package/dist/core/entity-helpers.js.map +1 -0
  99. package/dist/core/entity-registry.d.ts +47 -0
  100. package/dist/core/entity-registry.d.ts.map +1 -0
  101. package/dist/core/entity-registry.js +54 -0
  102. package/dist/core/entity-registry.js.map +1 -0
  103. package/dist/core/eq.d.ts +13 -0
  104. package/dist/core/eq.d.ts.map +1 -0
  105. package/dist/core/eq.js +41 -0
  106. package/dist/core/eq.js.map +1 -0
  107. package/dist/core/focus-context.d.ts +19 -0
  108. package/dist/core/focus-context.d.ts.map +1 -0
  109. package/dist/core/focus-context.js +46 -0
  110. package/dist/core/focus-context.js.map +1 -0
  111. package/dist/core/focus-mode-actions.d.ts +23 -0
  112. package/dist/core/focus-mode-actions.d.ts.map +1 -0
  113. package/dist/core/focus-mode-actions.js +74 -0
  114. package/dist/core/focus-mode-actions.js.map +1 -0
  115. package/dist/core/greeting.d.ts +10 -0
  116. package/dist/core/greeting.d.ts.map +1 -0
  117. package/dist/core/greeting.js +41 -0
  118. package/dist/core/greeting.js.map +1 -0
  119. package/dist/core/identity.d.ts +13 -0
  120. package/dist/core/identity.d.ts.map +1 -0
  121. package/dist/core/identity.js +54 -0
  122. package/dist/core/identity.js.map +1 -0
  123. package/dist/core/knowledge.d.ts +10 -0
  124. package/dist/core/knowledge.d.ts.map +1 -0
  125. package/dist/core/knowledge.js +40 -0
  126. package/dist/core/knowledge.js.map +1 -0
  127. package/dist/core/memory-actions.d.ts +38 -0
  128. package/dist/core/memory-actions.d.ts.map +1 -0
  129. package/dist/core/memory-actions.js +181 -0
  130. package/dist/core/memory-actions.js.map +1 -0
  131. package/dist/core/memory.d.ts +35 -0
  132. package/dist/core/memory.d.ts.map +1 -0
  133. package/dist/core/memory.js +168 -0
  134. package/dist/core/memory.js.map +1 -0
  135. package/dist/core/peer-actions.d.ts +15 -0
  136. package/dist/core/peer-actions.d.ts.map +1 -0
  137. package/dist/core/peer-actions.js +33 -0
  138. package/dist/core/peer-actions.js.map +1 -0
  139. package/dist/core/prompt-builder.d.ts +46 -0
  140. package/dist/core/prompt-builder.d.ts.map +1 -0
  141. package/dist/core/prompt-builder.js +543 -0
  142. package/dist/core/prompt-builder.js.map +1 -0
  143. package/dist/core/prompt-mode.d.ts +3 -0
  144. package/dist/core/prompt-mode.d.ts.map +1 -0
  145. package/dist/core/prompt-mode.js +6 -0
  146. package/dist/core/prompt-mode.js.map +1 -0
  147. package/dist/core/prompted-turn.d.ts +6 -0
  148. package/dist/core/prompted-turn.d.ts.map +1 -0
  149. package/dist/core/prompted-turn.js +48 -0
  150. package/dist/core/prompted-turn.js.map +1 -0
  151. package/dist/core/request-builder.d.ts +14 -0
  152. package/dist/core/request-builder.d.ts.map +1 -0
  153. package/dist/core/request-builder.js +64 -0
  154. package/dist/core/request-builder.js.map +1 -0
  155. package/dist/core/session-routing.d.ts +23 -0
  156. package/dist/core/session-routing.d.ts.map +1 -0
  157. package/dist/core/session-routing.js +59 -0
  158. package/dist/core/session-routing.js.map +1 -0
  159. package/dist/core/voice.d.ts +6 -0
  160. package/dist/core/voice.d.ts.map +1 -0
  161. package/dist/core/voice.js +30 -0
  162. package/dist/core/voice.js.map +1 -0
  163. package/dist/engine/chat.d.ts +45 -0
  164. package/dist/engine/chat.d.ts.map +1 -0
  165. package/dist/engine/chat.js +308 -0
  166. package/dist/engine/chat.js.map +1 -0
  167. package/dist/engine/continuity.d.ts +107 -0
  168. package/dist/engine/continuity.d.ts.map +1 -0
  169. package/dist/engine/continuity.js +320 -0
  170. package/dist/engine/continuity.js.map +1 -0
  171. package/dist/engine/crud.d.ts +62 -0
  172. package/dist/engine/crud.d.ts.map +1 -0
  173. package/dist/engine/crud.js +260 -0
  174. package/dist/engine/crud.js.map +1 -0
  175. package/dist/engine/side-effects.d.ts +93 -0
  176. package/dist/engine/side-effects.d.ts.map +1 -0
  177. package/dist/engine/side-effects.js +271 -0
  178. package/dist/engine/side-effects.js.map +1 -0
  179. package/dist/engine/staging.d.ts +29 -0
  180. package/dist/engine/staging.d.ts.map +1 -0
  181. package/dist/engine/staging.js +159 -0
  182. package/dist/engine/staging.js.map +1 -0
  183. package/dist/engine/working-set.d.ts +18 -0
  184. package/dist/engine/working-set.d.ts.map +1 -0
  185. package/dist/engine/working-set.js +246 -0
  186. package/dist/engine/working-set.js.map +1 -0
  187. package/dist/evals/action-contracts.d.ts +40 -0
  188. package/dist/evals/action-contracts.d.ts.map +1 -0
  189. package/dist/evals/action-contracts.js +208 -0
  190. package/dist/evals/action-contracts.js.map +1 -0
  191. package/dist/evals/brain-bloat.d.ts +39 -0
  192. package/dist/evals/brain-bloat.d.ts.map +1 -0
  193. package/dist/evals/brain-bloat.js +167 -0
  194. package/dist/evals/brain-bloat.js.map +1 -0
  195. package/dist/evals/brain-prescriptions.d.ts +30 -0
  196. package/dist/evals/brain-prescriptions.d.ts.map +1 -0
  197. package/dist/evals/brain-prescriptions.js +148 -0
  198. package/dist/evals/brain-prescriptions.js.map +1 -0
  199. package/dist/evals/cross-layer-duplicates.d.ts +49 -0
  200. package/dist/evals/cross-layer-duplicates.d.ts.map +1 -0
  201. package/dist/evals/cross-layer-duplicates.js +289 -0
  202. package/dist/evals/cross-layer-duplicates.js.map +1 -0
  203. package/dist/evals/entity-visibility.d.ts +28 -0
  204. package/dist/evals/entity-visibility.d.ts.map +1 -0
  205. package/dist/evals/entity-visibility.js +216 -0
  206. package/dist/evals/entity-visibility.js.map +1 -0
  207. package/dist/evals/index.d.ts +19 -0
  208. package/dist/evals/index.d.ts.map +1 -0
  209. package/dist/evals/index.js +11 -0
  210. package/dist/evals/index.js.map +1 -0
  211. package/dist/evals/judge.d.ts +22 -0
  212. package/dist/evals/judge.d.ts.map +1 -0
  213. package/dist/evals/judge.js +337 -0
  214. package/dist/evals/judge.js.map +1 -0
  215. package/dist/evals/operational-contract.d.ts +40 -0
  216. package/dist/evals/operational-contract.d.ts.map +1 -0
  217. package/dist/evals/operational-contract.js +115 -0
  218. package/dist/evals/operational-contract.js.map +1 -0
  219. package/dist/evals/prompt-content.d.ts +14 -0
  220. package/dist/evals/prompt-content.d.ts.map +1 -0
  221. package/dist/evals/prompt-content.js +104 -0
  222. package/dist/evals/prompt-content.js.map +1 -0
  223. package/dist/evals/runtime.d.ts +4 -0
  224. package/dist/evals/runtime.d.ts.map +1 -0
  225. package/dist/evals/runtime.js +197 -0
  226. package/dist/evals/runtime.js.map +1 -0
  227. package/dist/evals/sample-projects.d.ts +143 -0
  228. package/dist/evals/sample-projects.d.ts.map +1 -0
  229. package/dist/evals/sample-projects.js +644 -0
  230. package/dist/evals/sample-projects.js.map +1 -0
  231. package/dist/evals/types.d.ts +88 -0
  232. package/dist/evals/types.d.ts.map +1 -0
  233. package/dist/evals/types.js +2 -0
  234. package/dist/evals/types.js.map +1 -0
  235. package/dist/foundation/index.d.ts +158 -0
  236. package/dist/foundation/index.d.ts.map +1 -0
  237. package/dist/foundation/index.js +256 -0
  238. package/dist/foundation/index.js.map +1 -0
  239. package/dist/index.d.ts +223 -0
  240. package/dist/index.d.ts.map +1 -0
  241. package/dist/index.js +998 -0
  242. package/dist/index.js.map +1 -0
  243. package/dist/managed/autonomous-loop.d.ts +199 -0
  244. package/dist/managed/autonomous-loop.d.ts.map +1 -0
  245. package/dist/managed/autonomous-loop.js +451 -0
  246. package/dist/managed/autonomous-loop.js.map +1 -0
  247. package/dist/managed/conversation.d.ts +20 -0
  248. package/dist/managed/conversation.d.ts.map +1 -0
  249. package/dist/managed/conversation.js +40 -0
  250. package/dist/managed/conversation.js.map +1 -0
  251. package/dist/managed/knowledge.d.ts +7 -0
  252. package/dist/managed/knowledge.d.ts.map +1 -0
  253. package/dist/managed/knowledge.js +174 -0
  254. package/dist/managed/knowledge.js.map +1 -0
  255. package/dist/managed/memory-manager.d.ts +7 -0
  256. package/dist/managed/memory-manager.d.ts.map +1 -0
  257. package/dist/managed/memory-manager.js +18 -0
  258. package/dist/managed/memory-manager.js.map +1 -0
  259. package/dist/managed/memory-review.d.ts +45 -0
  260. package/dist/managed/memory-review.d.ts.map +1 -0
  261. package/dist/managed/memory-review.js +130 -0
  262. package/dist/managed/memory-review.js.map +1 -0
  263. package/dist/managed/storage.d.ts +2 -0
  264. package/dist/managed/storage.d.ts.map +1 -0
  265. package/dist/managed/storage.js +2 -0
  266. package/dist/managed/storage.js.map +1 -0
  267. package/dist/managed/work-history.d.ts +23 -0
  268. package/dist/managed/work-history.d.ts.map +1 -0
  269. package/dist/managed/work-history.js +31 -0
  270. package/dist/managed/work-history.js.map +1 -0
  271. package/dist/observability/index.d.ts +15 -0
  272. package/dist/observability/index.d.ts.map +1 -0
  273. package/dist/observability/index.js +15 -0
  274. package/dist/observability/index.js.map +1 -0
  275. package/dist/observability/render-run-markdown.d.ts +90 -0
  276. package/dist/observability/render-run-markdown.d.ts.map +1 -0
  277. package/dist/observability/render-run-markdown.js +231 -0
  278. package/dist/observability/render-run-markdown.js.map +1 -0
  279. package/dist/observability/turn-reporter.d.ts +20 -0
  280. package/dist/observability/turn-reporter.d.ts.map +1 -0
  281. package/dist/observability/turn-reporter.js +106 -0
  282. package/dist/observability/turn-reporter.js.map +1 -0
  283. package/dist/persona.d.ts +49 -0
  284. package/dist/persona.d.ts.map +1 -0
  285. package/dist/persona.js +287 -0
  286. package/dist/persona.js.map +1 -0
  287. package/dist/playbook/defaults.d.ts +25 -0
  288. package/dist/playbook/defaults.d.ts.map +1 -0
  289. package/dist/playbook/defaults.js +108 -0
  290. package/dist/playbook/defaults.js.map +1 -0
  291. package/dist/playbook/invariants.d.ts +244 -0
  292. package/dist/playbook/invariants.d.ts.map +1 -0
  293. package/dist/playbook/invariants.js +259 -0
  294. package/dist/playbook/invariants.js.map +1 -0
  295. package/dist/playbook/templates.d.ts +7 -0
  296. package/dist/playbook/templates.d.ts.map +1 -0
  297. package/dist/playbook/templates.js +437 -0
  298. package/dist/playbook/templates.js.map +1 -0
  299. package/dist/providers/gemini.d.ts +73 -0
  300. package/dist/providers/gemini.d.ts.map +1 -0
  301. package/dist/providers/gemini.js +536 -0
  302. package/dist/providers/gemini.js.map +1 -0
  303. package/dist/providers/types.d.ts +2 -0
  304. package/dist/providers/types.d.ts.map +1 -0
  305. package/dist/providers/types.js +2 -0
  306. package/dist/providers/types.js.map +1 -0
  307. package/dist/providers/zod-to-gemini.d.ts +8 -0
  308. package/dist/providers/zod-to-gemini.d.ts.map +1 -0
  309. package/dist/providers/zod-to-gemini.js +148 -0
  310. package/dist/providers/zod-to-gemini.js.map +1 -0
  311. package/dist/samples/pm-spec-agent.d.ts +22 -0
  312. package/dist/samples/pm-spec-agent.d.ts.map +1 -0
  313. package/dist/samples/pm-spec-agent.js +53 -0
  314. package/dist/samples/pm-spec-agent.js.map +1 -0
  315. package/dist/types.d.ts +920 -0
  316. package/dist/types.d.ts.map +1 -0
  317. package/dist/types.js +2 -0
  318. package/dist/types.js.map +1 -0
  319. package/package.json +68 -0
@@ -0,0 +1,208 @@
1
+ const GENERIC_NAME_WORDS = new Set([
2
+ 'data',
3
+ 'handle',
4
+ 'process',
5
+ 'execute',
6
+ 'perform',
7
+ 'do',
8
+ 'action',
9
+ 'thing',
10
+ 'item',
11
+ 'object',
12
+ 'stuff',
13
+ 'info',
14
+ 'update',
15
+ 'manage',
16
+ 'run',
17
+ ]);
18
+ export function auditActionContracts(input) {
19
+ const issues = [];
20
+ const actions = input.config.actions ?? {};
21
+ const entities = input.config.entities ?? {};
22
+ for (const [name, action] of Object.entries(actions)) {
23
+ issues.push(...auditSingleAction(name, action));
24
+ }
25
+ for (const [name, entity] of Object.entries(entities)) {
26
+ issues.push(...auditSingleEntity(name, entity));
27
+ }
28
+ return {
29
+ pass: !issues.some((i) => i.severity === 'error'),
30
+ issues,
31
+ };
32
+ }
33
+ function auditSingleAction(name, action) {
34
+ const issues = [];
35
+ const desc = action.description ?? '';
36
+ if (isGenericName(name)) {
37
+ issues.push({
38
+ severity: 'error',
39
+ surface: 'action',
40
+ name,
41
+ principle: 'generic-name',
42
+ message: `Action name "${name}" is too generic — the AI has to read the description to guess what it does.`,
43
+ suggestion: `Rename to something self-documenting (verb + noun: sendEmail, logMeal, scheduleCall). A good action name makes the description redundant for the happy path.`,
44
+ });
45
+ }
46
+ if (!desc.trim()) {
47
+ issues.push({
48
+ severity: 'warn',
49
+ surface: 'action',
50
+ name,
51
+ principle: 'missing-description',
52
+ message: `Action "${name}" has no description.`,
53
+ suggestion: `If the name is self-documenting the description can be one line about WHEN to use it (not WHAT it does — the name carries that).`,
54
+ });
55
+ }
56
+ // If name is self-documenting but description is long, flag over-documentation
57
+ if (!isGenericName(name) && desc.length > 180) {
58
+ const restatesName = looksLikeNameRestatement(name, desc);
59
+ if (restatesName) {
60
+ issues.push({
61
+ severity: 'warn',
62
+ surface: 'action',
63
+ name,
64
+ principle: 'self-documenting-overdocumented',
65
+ message: `Action "${name}" is self-documenting but the ${desc.length}-char description seems to restate what the name says.`,
66
+ suggestion: `A self-documenting name deserves a one-line description about when to use it, not a restatement of what it does.`,
67
+ });
68
+ }
69
+ }
70
+ // Check schema shape for vagueness
71
+ if (action.schema) {
72
+ const vague = detectVagueSchema(action.schema);
73
+ for (const v of vague) {
74
+ issues.push({
75
+ severity: v.severity,
76
+ surface: 'action',
77
+ name,
78
+ principle: v.principle,
79
+ message: v.message,
80
+ suggestion: v.suggestion,
81
+ });
82
+ }
83
+ }
84
+ return issues;
85
+ }
86
+ function auditSingleEntity(name, entity) {
87
+ const issues = [];
88
+ const desc = entity.description ?? '';
89
+ if (isGenericName(name)) {
90
+ issues.push({
91
+ severity: 'warn',
92
+ surface: 'entity',
93
+ name,
94
+ principle: 'generic-name',
95
+ message: `Entity name "${name}" is generic — the AI will have trouble routing between this and other entities.`,
96
+ suggestion: `Rename to match the domain noun (meal, task, shift, etc.).`,
97
+ });
98
+ }
99
+ if (!desc.trim()) {
100
+ issues.push({
101
+ severity: 'warn',
102
+ surface: 'entity',
103
+ name,
104
+ principle: 'missing-description',
105
+ message: `Entity "${name}" has no description — the AI may not know when to use it vs. memory or other entities.`,
106
+ suggestion: `Describe what this entity represents and when the AI should route changes here (vs. memory, vs. another entity).`,
107
+ });
108
+ }
109
+ // Field-level checks
110
+ const schema = entity.schema;
111
+ if (schema && 'shape' in schema) {
112
+ const shape = schema.shape;
113
+ for (const [fieldName, fieldSchema] of Object.entries(shape)) {
114
+ const fieldDescription = fieldSchema?.description ?? fieldSchema?._def?.description;
115
+ if (!fieldDescription && !isObviouslyTypedField(fieldName, fieldSchema)) {
116
+ issues.push({
117
+ severity: 'warn',
118
+ surface: 'entity',
119
+ name,
120
+ principle: 'missing-field-description',
121
+ message: `Entity "${name}" field "${fieldName}" has no describe() annotation.`,
122
+ suggestion: `Add .describe('...') explaining the semantics — especially if the field name isn't self-explanatory or if values need examples/routing hints.`,
123
+ });
124
+ }
125
+ }
126
+ }
127
+ return issues;
128
+ }
129
+ function isGenericName(name) {
130
+ const tokens = name
131
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
132
+ .replace(/[_-]/g, ' ')
133
+ .toLowerCase()
134
+ .split(/\s+/)
135
+ .filter(Boolean);
136
+ if (tokens.length === 0)
137
+ return false;
138
+ if (tokens.every((token) => GENERIC_NAME_WORDS.has(token)))
139
+ return true;
140
+ // Single-word generic
141
+ if (tokens.length === 1 && GENERIC_NAME_WORDS.has(tokens[0]))
142
+ return true;
143
+ return false;
144
+ }
145
+ function looksLikeNameRestatement(name, description) {
146
+ const nameTokens = name
147
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
148
+ .replace(/[_-]/g, ' ')
149
+ .toLowerCase()
150
+ .split(/\s+/)
151
+ .filter((token) => token.length > 3);
152
+ if (nameTokens.length === 0)
153
+ return false;
154
+ const descLower = description.toLowerCase();
155
+ const matches = nameTokens.filter((token) => descLower.includes(token));
156
+ return matches.length === nameTokens.length;
157
+ }
158
+ function detectVagueSchema(schema, path = '') {
159
+ const issues = [];
160
+ const typeName = schema?._def?.typeName;
161
+ const here = path ? ` (at ${path})` : '';
162
+ if (typeName === 'ZodAny' || typeName === 'ZodUnknown') {
163
+ issues.push({
164
+ severity: 'error',
165
+ principle: 'vague-schema-type',
166
+ message: `Schema uses z.any() or z.unknown()${here} — the AI has no type guidance for the payload.`,
167
+ suggestion: `Tighten to the actual shape. If the payload is dynamic, use z.record() or discriminated unions so the AI knows the space.`,
168
+ });
169
+ }
170
+ // Recurse into object fields
171
+ if (typeName === 'ZodObject' && 'shape' in schema) {
172
+ const shape = schema.shape;
173
+ for (const [fieldName, fieldSchema] of Object.entries(shape)) {
174
+ issues.push(...detectVagueSchema(fieldSchema, path ? `${path}.${fieldName}` : fieldName));
175
+ }
176
+ }
177
+ // Unwrap optional/nullable/default
178
+ const innerType = schema?._def?.innerType;
179
+ if (innerType && (typeName === 'ZodOptional' || typeName === 'ZodNullable' || typeName === 'ZodDefault')) {
180
+ issues.push(...detectVagueSchema(innerType, path));
181
+ }
182
+ return issues;
183
+ }
184
+ function isObviouslyTypedField(name, schema) {
185
+ const n = name.toLowerCase();
186
+ const typeName = schema?._def?.typeName;
187
+ // Well-known field names whose semantics are obvious from the type
188
+ const obvious = new Set([
189
+ 'id',
190
+ 'uuid',
191
+ 'name',
192
+ 'title',
193
+ 'description',
194
+ 'createdat',
195
+ 'updatedat',
196
+ 'email',
197
+ 'url',
198
+ 'count',
199
+ 'index',
200
+ ]);
201
+ if (obvious.has(n))
202
+ return true;
203
+ // Enums are self-documenting
204
+ if (typeName === 'ZodEnum' || typeName === 'ZodNativeEnum')
205
+ return true;
206
+ return false;
207
+ }
208
+ //# sourceMappingURL=action-contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-contracts.js","sourceRoot":"","sources":["../../src/evals/action-contracts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { LoadedBrainArtifact } from '../types.js';
2
+ export interface BrainBloatAuditInput {
3
+ markdown?: string;
4
+ brain?: LoadedBrainArtifact;
5
+ sourcePath?: string;
6
+ options?: Partial<BrainBloatAuditOptions>;
7
+ }
8
+ export interface BrainBloatAuditOptions {
9
+ maxTotalChars: number;
10
+ maxParagraphChars: number;
11
+ sectionCharBudgets: Record<string, number>;
12
+ defaultSectionChars: number;
13
+ }
14
+ export interface BrainBloatAuditIssue {
15
+ severity: 'error' | 'warn';
16
+ kind: 'total-brain-size' | 'section-size' | 'long-paragraph' | 'repeated-line' | 'implementation-leakage';
17
+ message: string;
18
+ section?: string;
19
+ actual?: number;
20
+ limit?: number;
21
+ }
22
+ export interface BrainBloatSectionMetric {
23
+ name: string;
24
+ chars: number;
25
+ lines: number;
26
+ paragraphs: number;
27
+ }
28
+ export interface BrainBloatAuditResult {
29
+ pass: boolean;
30
+ issues: BrainBloatAuditIssue[];
31
+ metrics: {
32
+ totalChars: number;
33
+ totalLines: number;
34
+ sectionCount: number;
35
+ sections: BrainBloatSectionMetric[];
36
+ };
37
+ }
38
+ export declare function auditBrainBloat(input: BrainBloatAuditInput): BrainBloatAuditResult;
39
+ //# sourceMappingURL=brain-bloat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brain-bloat.d.ts","sourceRoot":"","sources":["../../src/evals/brain-bloat.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEtD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,mBAAmB,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAA;CAC1C;AAED,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;IACzB,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1C,mBAAmB,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAA;IAC1B,IAAI,EACA,kBAAkB,GAClB,cAAc,GACd,gBAAgB,GAChB,eAAe,GACf,wBAAwB,CAAA;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE,oBAAoB,EAAE,CAAA;IAC9B,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAA;QAClB,UAAU,EAAE,MAAM,CAAA;QAClB,YAAY,EAAE,MAAM,CAAA;QACpB,QAAQ,EAAE,uBAAuB,EAAE,CAAA;KACpC,CAAA;CACF;AAmDD,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,qBAAqB,CAwFlF"}
@@ -0,0 +1,167 @@
1
+ import { parseBrainMarkdown } from '../brain.js';
2
+ const DEFAULT_OPTIONS = {
3
+ maxTotalChars: 4000,
4
+ maxParagraphChars: 420,
5
+ defaultSectionChars: 900,
6
+ sectionCharBudgets: {
7
+ // Voice formatting enumerates markdown/rendering capabilities — it's
8
+ // mechanical, not prescriptive, so a slightly longer section is OK here.
9
+ 'voice-formatting': 320,
10
+ methodology: 1400,
11
+ 'action-protocol': 1200,
12
+ 'greeting-guidelines': 250,
13
+ 'retrospective-guidelines': 350,
14
+ directives: 500,
15
+ discovery: 450,
16
+ },
17
+ };
18
+ const CONCISE_SECTIONS = new Set([
19
+ 'voice-formatting',
20
+ 'action-protocol',
21
+ 'greeting-guidelines',
22
+ 'retrospective-guidelines',
23
+ 'directives',
24
+ 'discovery',
25
+ ]);
26
+ /**
27
+ * Patterns that indicate actual implementation mechanics leaking into the brain.
28
+ * Tuned to avoid false positives on domain vocabulary — e.g., a nutrition brain
29
+ * talking about a "food record" is scene-setting, not implementation leakage.
30
+ * The patterns below look for infrastructure phrasing, not just nouns.
31
+ */
32
+ const IMPLEMENTATION_LEAKAGE_PATTERNS = [
33
+ /\bcrud\b/i,
34
+ /\buse the (\w+\s+)?entity\b/i,
35
+ /\buse the id shown\b/i,
36
+ /\bthe id (shown|from)\b/i,
37
+ /\bcontext block\b/i,
38
+ /\bupdate (the |your )?record\b/i,
39
+ /\buse the record\b/i,
40
+ /\brecord (cleanup|update|id|entry)\b/i,
41
+ /\brecord shows\b/i,
42
+ /\brecipe:\s*null\b/i,
43
+ /\bzod\b/i,
44
+ /\bjson (schema|format|response)\b/i,
45
+ /\breturn.*\bjson\b/i,
46
+ /\bschema\b.*\b(compliance|validation)\b/i,
47
+ ];
48
+ export function auditBrainBloat(input) {
49
+ const options = { ...DEFAULT_OPTIONS, ...input.options, sectionCharBudgets: { ...DEFAULT_OPTIONS.sectionCharBudgets, ...(input.options?.sectionCharBudgets ?? {}) } };
50
+ const brain = input.brain ?? parseBrainMarkdown(input.markdown ?? '', input.sourcePath);
51
+ const sections = Object.entries(brain.sections).map(([name, content]) => ({
52
+ name,
53
+ content,
54
+ chars: content.length,
55
+ lines: content.split('\n').length,
56
+ paragraphs: countParagraphs(content),
57
+ }));
58
+ const issues = [];
59
+ const totalChars = sections.reduce((sum, section) => sum + section.chars, 0);
60
+ const totalLines = sections.reduce((sum, section) => sum + section.lines, 0);
61
+ if (totalChars > options.maxTotalChars) {
62
+ issues.push({
63
+ severity: 'error',
64
+ kind: 'total-brain-size',
65
+ message: `Brain carries ${totalChars} chars across sections (limit ${options.maxTotalChars}).`,
66
+ actual: totalChars,
67
+ limit: options.maxTotalChars,
68
+ });
69
+ }
70
+ for (const section of sections) {
71
+ const sectionLimit = options.sectionCharBudgets[section.name] ?? options.defaultSectionChars;
72
+ if (section.chars > sectionLimit) {
73
+ issues.push({
74
+ severity: 'error',
75
+ kind: 'section-size',
76
+ section: section.name,
77
+ message: `Section "${section.name}" carries ${section.chars} chars (limit ${sectionLimit}).`,
78
+ actual: section.chars,
79
+ limit: sectionLimit,
80
+ });
81
+ }
82
+ for (const paragraph of collectParagraphs(section.content)) {
83
+ if (paragraph.length > options.maxParagraphChars) {
84
+ issues.push({
85
+ severity: CONCISE_SECTIONS.has(section.name) ? 'error' : 'warn',
86
+ kind: 'long-paragraph',
87
+ section: section.name,
88
+ message: `Section "${section.name}" contains a long paragraph of ${paragraph.length} chars.`,
89
+ actual: paragraph.length,
90
+ limit: options.maxParagraphChars,
91
+ });
92
+ }
93
+ }
94
+ for (const rawLine of section.content.split('\n')) {
95
+ const trimmed = rawLine.trim();
96
+ if (!trimmed)
97
+ continue;
98
+ if (!IMPLEMENTATION_LEAKAGE_PATTERNS.some(pattern => pattern.test(trimmed)))
99
+ continue;
100
+ issues.push({
101
+ severity: CONCISE_SECTIONS.has(section.name) ? 'error' : 'warn',
102
+ kind: 'implementation-leakage',
103
+ section: section.name,
104
+ message: `Section "${section.name}" leaks implementation mechanics instead of staying brain-level: "${trimmed}"`,
105
+ });
106
+ }
107
+ }
108
+ const repeatedLines = findRepeatedLines(sections.map(section => ({ name: section.name, content: section.content })));
109
+ for (const repeated of repeatedLines) {
110
+ issues.push({
111
+ severity: 'warn',
112
+ kind: 'repeated-line',
113
+ message: `Repeated line appears across sections: "${repeated.line}"`,
114
+ });
115
+ }
116
+ return {
117
+ pass: issues.every(issue => issue.severity !== 'error'),
118
+ issues,
119
+ metrics: {
120
+ totalChars,
121
+ totalLines,
122
+ sectionCount: sections.length,
123
+ sections: sections.map(section => ({
124
+ name: section.name,
125
+ chars: section.chars,
126
+ lines: section.lines,
127
+ paragraphs: section.paragraphs,
128
+ })),
129
+ },
130
+ };
131
+ }
132
+ function collectParagraphs(content) {
133
+ return content
134
+ .split(/\n\s*\n/g)
135
+ .map(paragraph => paragraph.replace(/\s+/g, ' ').trim())
136
+ .filter(Boolean);
137
+ }
138
+ function countParagraphs(content) {
139
+ return collectParagraphs(content).length;
140
+ }
141
+ function normalizeRepeatedLineCandidate(line) {
142
+ return line
143
+ .replace(/^[-*]\s+/, '')
144
+ .replace(/\s+/g, ' ')
145
+ .trim()
146
+ .toLowerCase();
147
+ }
148
+ function findRepeatedLines(sections) {
149
+ const seen = new Map();
150
+ const canonical = new Map();
151
+ for (const section of sections) {
152
+ for (const rawLine of section.content.split('\n')) {
153
+ const normalized = normalizeRepeatedLineCandidate(rawLine);
154
+ if (!normalized || normalized.length < 45)
155
+ continue;
156
+ if (!canonical.has(normalized))
157
+ canonical.set(normalized, rawLine.trim());
158
+ const owners = seen.get(normalized) ?? new Set();
159
+ owners.add(section.name);
160
+ seen.set(normalized, owners);
161
+ }
162
+ }
163
+ return Array.from(seen.entries())
164
+ .filter(([, owners]) => owners.size > 1)
165
+ .map(([normalized]) => ({ line: canonical.get(normalized) ?? normalized }));
166
+ }
167
+ //# sourceMappingURL=brain-bloat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brain-bloat.js","sourceRoot":"","sources":["../../src/evals/brain-bloat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { LoadedBrainArtifact } from '../types.js';
2
+ export interface BrainPrescriptionsAuditInput {
3
+ markdown?: string;
4
+ brain?: LoadedBrainArtifact;
5
+ sourcePath?: string;
6
+ }
7
+ export interface BrainPrescription {
8
+ severity: 'error' | 'warn';
9
+ shape: 'trigger-response' | 'exception-rule' | 'negative-contrast' | 'field-value-prescription' | 'enum-semantic-definition' | 'announce-actions';
10
+ section: string;
11
+ brainText: string;
12
+ /** Why it's a problem. */
13
+ issue: string;
14
+ /** Concrete next step — either move to a specific layer or delete. */
15
+ suggestion: string;
16
+ }
17
+ export interface BrainPrescriptionsAuditResult {
18
+ pass: boolean;
19
+ prescriptions: BrainPrescription[];
20
+ /** What this audit catches and what it cannot — always returned so callers
21
+ * know to pair with auditPrompt for full coverage. */
22
+ scope: AuditScope;
23
+ }
24
+ export interface AuditScope {
25
+ catches: string[];
26
+ misses: string[];
27
+ recommendation: string;
28
+ }
29
+ export declare function auditBrainPrescriptions(input: BrainPrescriptionsAuditInput): BrainPrescriptionsAuditResult;
30
+ //# sourceMappingURL=brain-prescriptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brain-prescriptions.d.ts","sourceRoot":"","sources":["../../src/evals/brain-prescriptions.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEtD,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,mBAAmB,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAA;IAC1B,KAAK,EACD,kBAAkB,GAClB,gBAAgB,GAChB,mBAAmB,GACnB,0BAA0B,GAC1B,0BAA0B,GAC1B,kBAAkB,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,OAAO,CAAA;IACb,aAAa,EAAE,iBAAiB,EAAE,CAAA;IAClC;2DACuD;IACvD,KAAK,EAAE,UAAU,CAAA;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;CACvB;AAoHD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,GAAG,6BAA6B,CA0B1G"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Brain prescriptions detector — catches trigger-response rules, exception
3
+ * rules, field-value prescription, and enum semantics that belong in schemas,
4
+ * even when they don't name a specific entity.
5
+ *
6
+ * The cross-layer duplicate detector is entity-gated: it triggers only when
7
+ * a brain line names a specific entity and looks prescriptive. That misses
8
+ * the common shape where the brain prescribes behavior without naming the
9
+ * entity — "if you are changing weight, preserve its duration" — which is
10
+ * exactly the boxing pattern a scenario-first audit must catch.
11
+ *
12
+ * This audit catches those shapes structurally. It is necessarily partial —
13
+ * pattern matching will never catch semantic issues. For full coverage, pair
14
+ * with auditPrompt (LLM reviewer). Each finding has a `suggestion` that
15
+ * points to where the rule should live (field describe, enum describe, or
16
+ * deletion if the standard is already implicit in the persona).
17
+ */
18
+ import { parseBrainMarkdown } from '../brain.js';
19
+ const PRESCRIPTIONS_SCOPE = {
20
+ catches: [
21
+ 'explicit trigger-response shapes: "if you are X, Y", "when you X, Y", "after X, Y"',
22
+ 'exception rules: "do X unless Y"',
23
+ 'negative contrast: "X rather than Y"',
24
+ 'field-value prescription: "set X 0", "include Y", numeric field assignments in brain',
25
+ 'enum semantics baked into brain: "X-category are only for Y", "X is for Y"',
26
+ 'announce-action anti-patterns: "speak to", "narrate", explicit talk-about-action verbs',
27
+ ],
28
+ misses: [
29
+ 'semantic contradictions between sections (needs auditPrompt)',
30
+ 'underspecified / vague instructions (needs auditPrompt)',
31
+ 'trigger-response wrapped in indirect phrasing the patterns miss (needs auditPrompt)',
32
+ 'subtle boxing that uses domain vocabulary creatively (needs auditPrompt)',
33
+ ],
34
+ recommendation: 'Pair this with auditPrompt (LLM reviewer) for coverage of semantic issues this pattern-based audit cannot catch.',
35
+ };
36
+ const PATTERNS = [
37
+ // Trigger-response shapes
38
+ {
39
+ shape: 'trigger-response',
40
+ regex: /\bif you (are |'re )?\w+ing\b/i,
41
+ issue: '"if you are [verb]ing" is a classic trigger-response shape — it prescribes behavior for a specific situation the expert can judge.',
42
+ severity: 'warn',
43
+ suggest: 'Describe the standard or move the situational cue into field describe()s the AI can read at decision time.',
44
+ },
45
+ {
46
+ shape: 'trigger-response',
47
+ // Must be a sentence-level trigger (start of sentence or after punctuation),
48
+ // so subordinate clauses like "use formatting when it helps" don't match.
49
+ regex: /(^|[.!?;]\s+)\bwhen (you|the user|the athlete|the client|they) \w+.*,\s/i,
50
+ issue: '"when [actor] [verb], [do X]" prescribes what to do in a specific scenario. The expert should decide.',
51
+ severity: 'warn',
52
+ suggest: 'Describe the standard. If the rule is real routing logic, move it to the entity/schema layer.',
53
+ },
54
+ {
55
+ shape: 'trigger-response',
56
+ regex: /\bafter (the |you |your )?\w+ing\b/i,
57
+ issue: '"after [verb]ing" prescribes sequencing — classic announce-actions or step-ordering boxing.',
58
+ severity: 'warn',
59
+ suggest: 'Trust the expert to decide what comes next. If the constraint is real, describe it as a standard.',
60
+ },
61
+ // Exception rules
62
+ {
63
+ shape: 'exception-rule',
64
+ regex: /\b(preserve|use|do|keep|hold)\b[^\.]{0,80}\bunless\b/i,
65
+ issue: '"X unless Y" is an exception rule — prescribing default behavior plus an escape hatch. The expert knows when exceptions apply.',
66
+ severity: 'warn',
67
+ suggest: 'Describe the field\'s semantics (what it represents) so the AI can reason about it naturally.',
68
+ },
69
+ // Negative contrast
70
+ {
71
+ shape: 'negative-contrast',
72
+ regex: /\brather than\b|\bnot.{0,30}\binstead\b/i,
73
+ issue: '"X rather than Y" prescribes a specific choice over another — the expert should decide.',
74
+ severity: 'warn',
75
+ suggest: 'Describe why the standard matters or delete if the keystone/identity already implies it.',
76
+ },
77
+ // Field-value prescription
78
+ {
79
+ shape: 'field-value-prescription',
80
+ regex: /\bset \w+ (?:to )?\d+\b/i,
81
+ issue: 'Brain is prescribing a specific field value numerically. That\'s a mechanical rule, not persona guidance.',
82
+ severity: 'error',
83
+ suggest: 'Move the value into the relevant field describe() or the enum value that owns the semantics.',
84
+ },
85
+ {
86
+ shape: 'field-value-prescription',
87
+ regex: /\binclude \w+(Seconds|Ms|Lbs|Kg|Reps|Sets)\b/i,
88
+ issue: 'Brain is prescribing which schema field to include. That\'s routing logic that belongs in the schema.',
89
+ severity: 'warn',
90
+ suggest: 'Move the inclusion rule to the field describe() or to the enum value\'s semantics.',
91
+ },
92
+ // Enum semantic definition
93
+ {
94
+ shape: 'enum-semantic-definition',
95
+ regex: /\b\w+[- ]?category (are|is) (only )?(for|used)\b/i,
96
+ issue: 'Brain is defining what a category/enum value means. That semantic belongs in the enum\'s describe() annotation.',
97
+ severity: 'warn',
98
+ suggest: 'Move this definition into the enum field\'s describe(): `z.enum([\'X\', ...]).describe(\'X is for ..., ...\')`',
99
+ },
100
+ {
101
+ shape: 'enum-semantic-definition',
102
+ regex: /\b(are only for|only for standalone|exclusively (for|used))\b/i,
103
+ issue: 'Brain is narrowing the scope of a category — defining its semantic boundary. Belongs in the enum\'s describe().',
104
+ severity: 'warn',
105
+ suggest: 'Move the scope definition to the enum field\'s describe() so the schema carries the meaning.',
106
+ },
107
+ // Announce-actions
108
+ {
109
+ shape: 'announce-actions',
110
+ regex: /\b(speak to|narrate|describe (the|your) action|mention (your )?action)\b/i,
111
+ issue: 'Brain is directing the AI on how to talk about its own actions — a common boxing anti-pattern.',
112
+ severity: 'warn',
113
+ suggest: 'Delete. The keystone + identity handle this naturally when the AI is briefed, not micromanaged.',
114
+ },
115
+ ];
116
+ export function auditBrainPrescriptions(input) {
117
+ const brain = input.brain ?? parseBrainMarkdown(input.markdown ?? '', input.sourcePath);
118
+ const prescriptions = [];
119
+ for (const [sectionName, sectionContent] of Object.entries(brain.sections)) {
120
+ for (const line of extractMeaningfulLines(sectionContent)) {
121
+ for (const pattern of PATTERNS) {
122
+ if (!pattern.regex.test(line))
123
+ continue;
124
+ prescriptions.push({
125
+ severity: pattern.severity,
126
+ shape: pattern.shape,
127
+ section: sectionName,
128
+ brainText: line,
129
+ issue: pattern.issue,
130
+ suggestion: pattern.suggest,
131
+ });
132
+ // Continue — a single line can match multiple patterns and each is a distinct signal
133
+ }
134
+ }
135
+ }
136
+ return {
137
+ pass: !prescriptions.some((p) => p.severity === 'error'),
138
+ prescriptions,
139
+ scope: PRESCRIPTIONS_SCOPE,
140
+ };
141
+ }
142
+ function extractMeaningfulLines(content) {
143
+ return content
144
+ .split('\n')
145
+ .map((raw) => raw.replace(/^[-*]\s+/, '').trim())
146
+ .filter((line) => line.length >= 15 && !line.startsWith('#'));
147
+ }
148
+ //# sourceMappingURL=brain-prescriptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brain-prescriptions.js","sourceRoot":"","sources":["../../src/evals/brain-prescriptions.ts"],"names":[],"mappings":"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"}