@a-company/paradigm 5.38.0 → 6.0.4

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 (355) hide show
  1. package/dist/{accept-orchestration-OATWIRHP.js → accept-orchestration-TIXUQQGR.js} +1 -1
  2. package/dist/add-UOR4INIV.js +8 -0
  3. package/dist/agent-MB3H5EZA.js +33 -0
  4. package/dist/{agent-loader-RIVI6QPP.js → agent-loader-VGBPL3TH.js} +1 -1
  5. package/dist/{agent-loader-RJRVO5GQ.js → agent-loader-W3RQJVW7.js} +1 -1
  6. package/dist/{agents-suggest-HYTFMQD3.js → agents-suggest-IKY6VD2R.js} +1 -1
  7. package/dist/{ambient-WTLYUAQM.js → ambient-AI42BOM5.js} +12 -12
  8. package/dist/{ambient-76YMUA5Q.js → ambient-FNNFB4AP.js} +1 -1
  9. package/dist/{assess-UFPYEJKP.js → assess-63WXHWJV.js} +1 -1
  10. package/dist/authority-FA3HLEOA.js +2 -0
  11. package/dist/{calibration-OLJYB5HN.js → calibration-BDHGYJOK.js} +1 -1
  12. package/dist/chunk-23T6UG73.js +605 -0
  13. package/dist/{chunk-4L7665QV.js → chunk-2AU5L333.js} +1 -1
  14. package/dist/{chunk-BOYQAMGC.js → chunk-4N56FRNE.js} +1 -1
  15. package/dist/{chunk-5QOCKWK5.js → chunk-4PSD5R7N.js} +2 -2
  16. package/dist/{chunk-MQIG6SMF.js → chunk-6QXBXZF6.js} +1 -1
  17. package/dist/{chunk-ORDKEGII.js → chunk-AMLD7IYC.js} +1 -1
  18. package/dist/{chunk-3DZK54RU.js → chunk-DBEWOKD6.js} +32 -7
  19. package/dist/{chunk-AGFPVSX5.js → chunk-F6E3HW45.js} +1 -1
  20. package/dist/{chunk-X3U3IGYT.js → chunk-GD4F2HC6.js} +2 -2
  21. package/dist/chunk-GRZQIKST.js +2 -0
  22. package/dist/{chunk-HOBHJPTL.js → chunk-IOVHF4SR.js} +1 -1
  23. package/dist/{chunk-RLCH7DXQ.js → chunk-K7X3Z3GL.js} +1 -1
  24. package/dist/{chunk-74SGKSRQ.js → chunk-KAFQA7HV.js} +2 -2
  25. package/dist/{chunk-NEJ4ZLCY.js → chunk-LAYBUKMB.js} +1 -1
  26. package/dist/{chunk-4VKSEOXZ.js → chunk-LPBCQM5Y.js} +3 -3
  27. package/dist/chunk-Q527BPUF.js +2 -0
  28. package/dist/{chunk-AO7ZSRME.js → chunk-TQOT2LBO.js} +2 -2
  29. package/dist/{chunk-3XGNXXCT.js → chunk-UZ5H7K6Q.js} +1 -1
  30. package/dist/chunk-VIG5LSGZ.js +2 -0
  31. package/dist/chunk-VNIX5KBT.js +3 -0
  32. package/dist/chunk-WXF5VFB4.js +111 -0
  33. package/dist/chunk-XQLO5URP.js +11 -0
  34. package/dist/{chunk-DOCDDDTD.js → chunk-YNDPSWOE.js} +5 -5
  35. package/dist/chunk-Z5QW6USC.js +2 -0
  36. package/dist/{compliance-D7GD6ZYC.js → compliance-J3VOV445.js} +1 -1
  37. package/dist/config-schema-FLHRVZMI.js +2 -0
  38. package/dist/{context-audit-XRPT3OU2.js → context-audit-JVCA6GSV.js} +1 -1
  39. package/dist/{cursorrules-U5O4G5T4.js → cursorrules-ZXPXPZ3P.js} +1 -1
  40. package/dist/decision-loader-HELL2AMX.js +2 -0
  41. package/dist/{delete-P5VULXR4.js → delete-2C6ALLYY.js} +1 -1
  42. package/dist/{diff-YGHBIJY5.js → diff-75MABOSL.js} +1 -1
  43. package/dist/{dist-KGRCLBJP-2QAPFYNF.js → dist-GQ42YS5N-4HIJZVBB.js} +10 -10
  44. package/dist/{docs-USDAF26F.js → docs-TSAAS4W3.js} +1 -1
  45. package/dist/doctor-L5XZENCF.js +2 -0
  46. package/dist/{edit-GUU3HBVW.js → edit-P3MDAZLU.js} +1 -1
  47. package/dist/{flow-FVZR3YJ4.js → flow-BGXOVE2V.js} +1 -1
  48. package/dist/{hooks-TFMMMB2H.js → hooks-KUEE5KMM.js} +1 -1
  49. package/dist/index.js +6 -6
  50. package/dist/init-M44SO65G.js +2 -0
  51. package/dist/{init-XYB62Q3X.js → init-V4KSEKPK.js} +1 -1
  52. package/dist/{list-YKIQNKGB.js → list-2XIWUEMA.js} +1 -1
  53. package/dist/list-CFHINXIS.js +12 -0
  54. package/dist/lore-loader-D2ISOASW.js +2 -0
  55. package/dist/lore-loader-PXFKMKAN.js +2 -0
  56. package/dist/mcp.js +4 -4
  57. package/dist/metrics-UESGUHTA.js +2 -0
  58. package/dist/{migrate-Z5UQN57G.js → migrate-ZPNYDNM4.js} +1 -1
  59. package/dist/migrate-assessments-YSITX7KM.js +4 -0
  60. package/dist/migrate-decisions-NPLQOEEH.js +6 -0
  61. package/dist/migrate-plsat-EM2ACIQ3.js +6 -0
  62. package/dist/migration-notices-BHLEYC4T.js +4 -0
  63. package/dist/{nomination-engine-EALA5MGI.js → nomination-engine-NCLTGMAK.js} +1 -1
  64. package/dist/{notebook-loader-PXNRBBXD.js → notebook-loader-3J2OFMS3.js} +1 -1
  65. package/dist/{orchestrate-M5PBZBJQ.js → orchestrate-K4KBTBYK.js} +1 -1
  66. package/dist/{platform-server-DNAMH4YI.js → platform-server-ANOALDPL.js} +1 -1
  67. package/dist/{portal-check-ZMLVBIGW.js → portal-check-DV2VSJ5E.js} +1 -1
  68. package/dist/portal-compliance-JONQ4SOP.js +2 -0
  69. package/dist/{probe-3FTG6LYO.js → probe-5HAXULAD.js} +1 -1
  70. package/dist/{providers-AWA7WLLM.js → providers-TBPOE4DI.js} +1 -1
  71. package/dist/quiz-WYIZJG5K.js +10 -0
  72. package/dist/{record-YXPB34MY.js → record-N3VNYYKJ.js} +1 -1
  73. package/dist/registry-OUTA3DXW.js +20 -0
  74. package/dist/reindex-IZCD2JGD.js +2 -0
  75. package/dist/{retag-N5XF3KXP.js → retag-72R2OSZV.js} +1 -1
  76. package/dist/{review-77QI6VOC.js → review-2INNWLTW.js} +1 -1
  77. package/dist/{sentinel-HYAZ3CO5.js → sentinel-EFPEX246.js} +1 -1
  78. package/dist/{sentinel-bridge-VR357PKL.js → sentinel-bridge-UR2MKARY.js} +1 -1
  79. package/dist/{serve-U47GULB6.js → serve-3FMUWW5K.js} +1 -1
  80. package/dist/serve-OQYUO7CR.js +12 -0
  81. package/dist/{server-4YNUIK4W.js → server-4D77LCST.js} +1 -1
  82. package/dist/server-FGUL2FWQ.js +7 -0
  83. package/dist/session-tracker-HHNY6J4I.js +2 -0
  84. package/dist/{session-work-log-ZP45TREI.js → session-work-log-MEJ33TYD.js} +1 -1
  85. package/dist/{session-work-log-PAKXOFGL.js → session-work-log-ZVVJGO7X.js} +1 -1
  86. package/dist/{setup-FEWSYS3Y.js → setup-ZSEC72BS.js} +1 -1
  87. package/dist/shift-WGMZGWOC.js +60 -0
  88. package/dist/{show-PJ5LFLIL.js → show-JH7LJ5MT.js} +1 -1
  89. package/dist/show-WVHAL4VU.js +7 -0
  90. package/dist/{spawn-M5BAV252.js → spawn-KKDDR6UR.js} +1 -1
  91. package/dist/status-S7Z5FVIE.js +6 -0
  92. package/dist/{summary-PYTEIJ4U.js → summary-WLI3NF4G.js} +2 -2
  93. package/dist/{sweep-HU74OPVW.js → sweep-7TZFN5NS.js} +1 -1
  94. package/dist/sync-55U6QPIA.js +2 -0
  95. package/dist/{sync-llms-7CAI74QL.js → sync-llms-GF7DDQDI.js} +1 -1
  96. package/dist/{team-PDK64JXI.js → team-2LGZQRP4.js} +1 -1
  97. package/dist/{timeline-K3ZFKJ3R.js → timeline-RK7O2SCM.js} +1 -1
  98. package/dist/tools-4RRFTU5H.js +2 -0
  99. package/dist/university-content/notes/N-para-001-build-something.md +126 -0
  100. package/dist/university-content/notes/N-para-001-meet-the-team.md +85 -0
  101. package/dist/university-content/notes/N-para-001-shift-setup.md +74 -0
  102. package/dist/university-content/notes/N-para-101-component-types.md +99 -0
  103. package/dist/university-content/notes/N-para-101-first-steps.md +134 -0
  104. package/dist/university-content/notes/N-para-101-five-symbols.md +128 -0
  105. package/dist/university-content/notes/N-para-101-paradigm-logger.md +89 -0
  106. package/dist/university-content/notes/N-para-101-portal-yaml.md +112 -0
  107. package/dist/university-content/notes/N-para-101-project-structure.md +143 -0
  108. package/dist/university-content/notes/N-para-101-purpose-files.md +121 -0
  109. package/dist/university-content/notes/N-para-101-tags-and-classification.md +93 -0
  110. package/dist/university-content/notes/N-para-101-welcome.md +51 -0
  111. package/dist/university-content/notes/N-para-201-architecture-review.md +175 -0
  112. package/dist/university-content/notes/N-para-201-aspect-graph.md +79 -0
  113. package/dist/university-content/notes/N-para-201-aspects-and-anchors.md +112 -0
  114. package/dist/university-content/notes/N-para-201-component-patterns.md +138 -0
  115. package/dist/university-content/notes/N-para-201-cross-cutting-concerns.md +145 -0
  116. package/dist/university-content/notes/N-para-201-disciplines.md +187 -0
  117. package/dist/university-content/notes/N-para-201-flows-deep-dive.md +119 -0
  118. package/dist/university-content/notes/N-para-201-gates-deep-dive.md +165 -0
  119. package/dist/university-content/notes/N-para-201-portal-protocol.md +133 -0
  120. package/dist/university-content/notes/N-para-201-signal-patterns.md +159 -0
  121. package/dist/university-content/notes/N-para-201-symbol-naming.md +149 -0
  122. package/dist/university-content/notes/N-para-301-context-management.md +53 -0
  123. package/dist/university-content/notes/N-para-301-decisions.md +99 -0
  124. package/dist/university-content/notes/N-para-301-doctor-and-validation.md +70 -0
  125. package/dist/university-content/notes/N-para-301-enforcement-levels.md +102 -0
  126. package/dist/university-content/notes/N-para-301-fragility-tracking.md +50 -0
  127. package/dist/university-content/notes/N-para-301-history-system.md +42 -0
  128. package/dist/university-content/notes/N-para-301-navigation-system.md +55 -0
  129. package/dist/university-content/notes/N-para-301-operations-review.md +55 -0
  130. package/dist/university-content/notes/N-para-301-paradigm-shift.md +93 -0
  131. package/dist/university-content/notes/N-para-301-protocols.md +113 -0
  132. package/dist/university-content/notes/N-para-301-ripple-analysis.md +53 -0
  133. package/dist/university-content/notes/N-para-301-sentinel-observability.md +87 -0
  134. package/dist/university-content/notes/N-para-301-sync-and-maintenance.md +57 -0
  135. package/dist/university-content/notes/N-para-301-wisdom-system.md +89 -0
  136. package/dist/university-content/notes/N-para-401-agent-identity.md +99 -0
  137. package/dist/university-content/notes/N-para-401-agent-interop.md +87 -0
  138. package/dist/university-content/notes/N-para-401-agent-roles.md +107 -0
  139. package/dist/university-content/notes/N-para-401-commit-conventions.md +82 -0
  140. package/dist/university-content/notes/N-para-401-mastery-review.md +71 -0
  141. package/dist/university-content/notes/N-para-401-mcp-tools-overview.md +102 -0
  142. package/dist/university-content/notes/N-para-401-multi-agent-coordination.md +80 -0
  143. package/dist/university-content/notes/N-para-401-notebooks-permissions.md +66 -0
  144. package/dist/university-content/notes/N-para-401-orchestration-workflow.md +101 -0
  145. package/dist/university-content/notes/N-para-401-pm-governance.md +71 -0
  146. package/dist/university-content/notes/N-para-401-provider-cascade.md +75 -0
  147. package/dist/university-content/notes/N-para-401-quick-check.md +95 -0
  148. package/dist/university-content/notes/N-para-451-agent-routing.md +117 -0
  149. package/dist/university-content/notes/N-para-451-archetypes-vs-instances.md +82 -0
  150. package/dist/university-content/notes/N-para-451-identity-layers.md +76 -0
  151. package/dist/university-content/notes/N-para-451-orchestration-modes.md +85 -0
  152. package/dist/university-content/notes/N-para-451-paradigm-shift.md +95 -0
  153. package/dist/university-content/notes/N-para-451-partners-primitive.md +107 -0
  154. package/dist/university-content/notes/N-para-451-roster-management.md +132 -0
  155. package/dist/university-content/notes/N-para-451-roster-reference.md +106 -0
  156. package/dist/university-content/notes/N-para-451-the-team-pattern.md +87 -0
  157. package/dist/university-content/notes/N-para-451-tiers.md +81 -0
  158. package/dist/university-content/notes/N-para-451-welcome.md +55 -0
  159. package/dist/university-content/notes/N-para-451-what-is-an-agent.md +73 -0
  160. package/dist/university-content/notes/N-para-501-advanced-workflows.md +122 -0
  161. package/dist/university-content/notes/N-para-501-aspect-graph-advanced.md +195 -0
  162. package/dist/university-content/notes/N-para-501-aspect-graph-internals.md +97 -0
  163. package/dist/university-content/notes/N-para-501-assessment-loops.md +116 -0
  164. package/dist/university-content/notes/N-para-501-conductor-workspace.md +77 -0
  165. package/dist/university-content/notes/N-para-501-habits-practice.md +164 -0
  166. package/dist/university-content/notes/N-para-501-hook-enforcement.md +100 -0
  167. package/dist/university-content/notes/N-para-501-lore-system.md +155 -0
  168. package/dist/university-content/notes/N-para-501-platform-agent-ui.md +108 -0
  169. package/dist/university-content/notes/N-para-501-review-compliance.md +72 -0
  170. package/dist/university-content/notes/N-para-501-sentinel-deep-dive.md +173 -0
  171. package/dist/university-content/notes/N-para-501-session-intelligence.md +104 -0
  172. package/dist/university-content/notes/N-para-501-symphony-a-mail.md +120 -0
  173. package/dist/university-content/notes/N-para-501-symphony-networking.md +119 -0
  174. package/dist/university-content/notes/N-para-501-task-management.md +100 -0
  175. package/dist/university-content/notes/N-para-601-agent-renaissance.md +121 -0
  176. package/dist/university-content/notes/N-para-601-attention-scoring.md +129 -0
  177. package/dist/university-content/notes/N-para-601-context-composition.md +146 -0
  178. package/dist/university-content/notes/N-para-601-data-sovereignty.md +140 -0
  179. package/dist/university-content/notes/N-para-601-event-stream.md +126 -0
  180. package/dist/university-content/notes/N-para-601-knowledge-streams.md +144 -0
  181. package/dist/university-content/notes/N-para-601-learning-loop.md +68 -0
  182. package/dist/university-content/notes/N-para-601-maestro-team-collab.md +136 -0
  183. package/dist/university-content/notes/N-para-601-nominations-debates.md +115 -0
  184. package/dist/university-content/notes/N-para-701-agent-notebooks.md +131 -0
  185. package/dist/university-content/notes/N-para-701-agent-pods-nevrland.md +182 -0
  186. package/dist/university-content/notes/N-para-701-agent-profiles.md +197 -0
  187. package/dist/university-content/notes/N-para-701-agent-roster.md +82 -0
  188. package/dist/university-content/notes/N-para-701-agent-state.md +180 -0
  189. package/dist/university-content/notes/N-para-701-learning-feedback-loop.md +188 -0
  190. package/dist/university-content/notes/N-para-701-model-tier-resolution.md +204 -0
  191. package/dist/university-content/notes/N-para-701-orchestration-enforcement.md +169 -0
  192. package/dist/university-content/notes/N-para-701-per-project-rosters.md +198 -0
  193. package/dist/university-content/notes/N-para-701-symphony-visibility.md +142 -0
  194. package/dist/university-content/paths/LP-para-001.yaml +29 -0
  195. package/dist/university-content/paths/LP-para-101.yaml +59 -0
  196. package/dist/university-content/paths/LP-para-201.yaml +69 -0
  197. package/dist/university-content/paths/LP-para-301.yaml +84 -0
  198. package/dist/university-content/paths/LP-para-401.yaml +74 -0
  199. package/dist/university-content/paths/LP-para-451.yaml +69 -0
  200. package/dist/university-content/paths/LP-para-501.yaml +89 -0
  201. package/dist/university-content/paths/LP-para-601.yaml +59 -0
  202. package/dist/university-content/paths/LP-para-701.yaml +64 -0
  203. package/dist/university-content/quizzes/Q-para-001-build-something.yaml +46 -0
  204. package/dist/university-content/quizzes/Q-para-001-meet-the-team.yaml +46 -0
  205. package/dist/university-content/quizzes/Q-para-001-shift-setup.yaml +46 -0
  206. package/dist/university-content/quizzes/Q-para-101-component-types.yaml +46 -0
  207. package/dist/university-content/quizzes/Q-para-101-first-steps.yaml +56 -0
  208. package/dist/university-content/quizzes/Q-para-101-five-symbols.yaml +66 -0
  209. package/dist/university-content/quizzes/Q-para-101-paradigm-logger.yaml +56 -0
  210. package/dist/university-content/quizzes/Q-para-101-portal-yaml.yaml +56 -0
  211. package/dist/university-content/quizzes/Q-para-101-project-structure.yaml +66 -0
  212. package/dist/university-content/quizzes/Q-para-101-purpose-files.yaml +56 -0
  213. package/dist/university-content/quizzes/Q-para-101-tags-and-classification.yaml +56 -0
  214. package/dist/university-content/quizzes/Q-para-101-welcome.yaml +56 -0
  215. package/dist/university-content/quizzes/Q-para-201-architecture-review.yaml +66 -0
  216. package/dist/university-content/quizzes/Q-para-201-aspect-graph.yaml +46 -0
  217. package/dist/university-content/quizzes/Q-para-201-aspects-and-anchors.yaml +56 -0
  218. package/dist/university-content/quizzes/Q-para-201-component-patterns.yaml +56 -0
  219. package/dist/university-content/quizzes/Q-para-201-cross-cutting-concerns.yaml +56 -0
  220. package/dist/university-content/quizzes/Q-para-201-disciplines.yaml +66 -0
  221. package/dist/university-content/quizzes/Q-para-201-flows-deep-dive.yaml +66 -0
  222. package/dist/university-content/quizzes/Q-para-201-gates-deep-dive.yaml +66 -0
  223. package/dist/university-content/quizzes/Q-para-201-portal-protocol.yaml +56 -0
  224. package/dist/university-content/quizzes/Q-para-201-signal-patterns.yaml +56 -0
  225. package/dist/university-content/quizzes/Q-para-201-symbol-naming.yaml +66 -0
  226. package/dist/university-content/quizzes/Q-para-301-context-management.yaml +56 -0
  227. package/dist/university-content/quizzes/Q-para-301-decisions.yaml +76 -0
  228. package/dist/university-content/quizzes/Q-para-301-doctor-and-validation.yaml +66 -0
  229. package/dist/university-content/quizzes/Q-para-301-enforcement-levels.yaml +46 -0
  230. package/dist/university-content/quizzes/Q-para-301-fragility-tracking.yaml +46 -0
  231. package/dist/university-content/quizzes/Q-para-301-history-system.yaml +56 -0
  232. package/dist/university-content/quizzes/Q-para-301-navigation-system.yaml +56 -0
  233. package/dist/university-content/quizzes/Q-para-301-operations-review.yaml +66 -0
  234. package/dist/university-content/quizzes/Q-para-301-paradigm-shift.yaml +46 -0
  235. package/dist/university-content/quizzes/Q-para-301-protocols.yaml +56 -0
  236. package/dist/university-content/quizzes/Q-para-301-ripple-analysis.yaml +56 -0
  237. package/dist/university-content/quizzes/Q-para-301-sentinel-observability.yaml +46 -0
  238. package/dist/university-content/quizzes/Q-para-301-sync-and-maintenance.yaml +46 -0
  239. package/dist/university-content/quizzes/Q-para-301-wisdom-system.yaml +56 -0
  240. package/dist/university-content/quizzes/Q-para-401-agent-identity.yaml +66 -0
  241. package/dist/university-content/quizzes/Q-para-401-agent-interop.yaml +46 -0
  242. package/dist/university-content/quizzes/Q-para-401-agent-roles.yaml +56 -0
  243. package/dist/university-content/quizzes/Q-para-401-commit-conventions.yaml +56 -0
  244. package/dist/university-content/quizzes/Q-para-401-mastery-review.yaml +66 -0
  245. package/dist/university-content/quizzes/Q-para-401-mcp-tools-overview.yaml +66 -0
  246. package/dist/university-content/quizzes/Q-para-401-multi-agent-coordination.yaml +76 -0
  247. package/dist/university-content/quizzes/Q-para-401-notebooks-permissions.yaml +61 -0
  248. package/dist/university-content/quizzes/Q-para-401-orchestration-workflow.yaml +66 -0
  249. package/dist/university-content/quizzes/Q-para-401-pm-governance.yaml +66 -0
  250. package/dist/university-content/quizzes/Q-para-401-provider-cascade.yaml +56 -0
  251. package/dist/university-content/quizzes/Q-para-401-quick-check.yaml +46 -0
  252. package/dist/university-content/quizzes/Q-para-451-foundations.yaml +154 -0
  253. package/dist/university-content/quizzes/Q-para-451-when-to-invoke.yaml +182 -0
  254. package/dist/university-content/quizzes/Q-para-501-advanced-workflows.yaml +66 -0
  255. package/dist/university-content/quizzes/Q-para-501-aspect-graph-advanced.yaml +66 -0
  256. package/dist/university-content/quizzes/Q-para-501-aspect-graph-internals.yaml +66 -0
  257. package/dist/university-content/quizzes/Q-para-501-assessment-loops.yaml +46 -0
  258. package/dist/university-content/quizzes/Q-para-501-conductor-workspace.yaml +46 -0
  259. package/dist/university-content/quizzes/Q-para-501-habits-practice.yaml +56 -0
  260. package/dist/university-content/quizzes/Q-para-501-hook-enforcement.yaml +66 -0
  261. package/dist/university-content/quizzes/Q-para-501-lore-system.yaml +66 -0
  262. package/dist/university-content/quizzes/Q-para-501-platform-agent-ui.yaml +66 -0
  263. package/dist/university-content/quizzes/Q-para-501-review-compliance.yaml +61 -0
  264. package/dist/university-content/quizzes/Q-para-501-sentinel-deep-dive.yaml +86 -0
  265. package/dist/university-content/quizzes/Q-para-501-session-intelligence.yaml +66 -0
  266. package/dist/university-content/quizzes/Q-para-501-symphony-a-mail.yaml +66 -0
  267. package/dist/university-content/quizzes/Q-para-501-symphony-networking.yaml +66 -0
  268. package/dist/university-content/quizzes/Q-para-501-task-management.yaml +46 -0
  269. package/dist/university-content/quizzes/Q-para-601-agent-renaissance.yaml +66 -0
  270. package/dist/university-content/quizzes/Q-para-601-attention-scoring.yaml +56 -0
  271. package/dist/university-content/quizzes/Q-para-601-context-composition.yaml +66 -0
  272. package/dist/university-content/quizzes/Q-para-601-data-sovereignty.yaml +56 -0
  273. package/dist/university-content/quizzes/Q-para-601-event-stream.yaml +66 -0
  274. package/dist/university-content/quizzes/Q-para-601-knowledge-streams.yaml +66 -0
  275. package/dist/university-content/quizzes/Q-para-601-learning-loop.yaml +56 -0
  276. package/dist/university-content/quizzes/Q-para-601-maestro-team-collab.yaml +86 -0
  277. package/dist/university-content/quizzes/Q-para-601-nominations-debates.yaml +66 -0
  278. package/dist/university-content/quizzes/Q-para-701-agent-notebooks.yaml +66 -0
  279. package/dist/university-content/quizzes/Q-para-701-agent-pods-nevrland.yaml +66 -0
  280. package/dist/university-content/quizzes/Q-para-701-agent-profiles.yaml +66 -0
  281. package/dist/university-content/quizzes/Q-para-701-agent-roster.yaml +66 -0
  282. package/dist/university-content/quizzes/Q-para-701-agent-state.yaml +66 -0
  283. package/dist/university-content/quizzes/Q-para-701-learning-feedback-loop.yaml +66 -0
  284. package/dist/university-content/quizzes/Q-para-701-model-tier-resolution.yaml +66 -0
  285. package/dist/university-content/quizzes/Q-para-701-orchestration-enforcement.yaml +66 -0
  286. package/dist/university-content/quizzes/Q-para-701-per-project-rosters.yaml +66 -0
  287. package/dist/university-content/quizzes/Q-para-701-symphony-visibility.yaml +66 -0
  288. package/dist/university-content/quizzes/Q-plsat-v2.yaml +904 -0
  289. package/dist/university-content/quizzes/Q-plsat-v3.yaml +2909 -0
  290. package/dist/university-content/reference.json +2 -2
  291. package/dist/university-ui/assets/{index-CecQrfSn.js → index-nNgzO1il.js} +2 -2
  292. package/dist/university-ui/assets/{index-CecQrfSn.js.map → index-nNgzO1il.js.map} +1 -1
  293. package/dist/university-ui/index.html +1 -1
  294. package/dist/{upgrade-GX56QE3C.js → upgrade-NKN63VTY.js} +2 -2
  295. package/dist/validate-XUQZTF3H.js +9 -0
  296. package/dist/{watch-YCODNIET.js → watch-25GJHQYT.js} +1 -1
  297. package/lore-ui/dist/assets/{index-Bk-K0qgN.js → index-DKhNxgtW.js} +10 -10
  298. package/lore-ui/dist/index.html +1 -1
  299. package/package.json +2 -2
  300. package/platform-ui/dist/assets/{AmbientSection-BYjt75R1.js → AmbientSection-CwatqcBD.js} +1 -1
  301. package/platform-ui/dist/assets/{CanvasSection-rKvA_vZj.js → CanvasSection-dFAthehN.js} +1 -1
  302. package/platform-ui/dist/assets/{DocsSection-CI9K73M-.js → DocsSection-BZ2SFJBZ.js} +1 -1
  303. package/platform-ui/dist/assets/{GitSection-DSGj_c6S.js → GitSection-MNNYU1tO.js} +1 -1
  304. package/platform-ui/dist/assets/{GraphSection-CawN7pC5.js → GraphSection-COYjb4Pt.js} +1 -1
  305. package/platform-ui/dist/assets/LoreSection-B0hUbfsJ.js +1 -0
  306. package/platform-ui/dist/assets/{SentinelSection-DNgoYMH0.js → SentinelSection-BCxW1DCp.js} +1 -1
  307. package/platform-ui/dist/assets/{SymphonySection-C0zfcqv3.js → SymphonySection-BsucZRqy.js} +1 -1
  308. package/platform-ui/dist/assets/{TeamSection-Bzd3Dt9Q.js → TeamSection-C0QNTudW.js} +1 -1
  309. package/platform-ui/dist/assets/{UniversitySection-tBr62R0S.js → UniversitySection-DN1-g9pw.js} +1 -1
  310. package/platform-ui/dist/assets/{index-BaOmyn11.js → index-DwUT8pju.js} +2 -2
  311. package/platform-ui/dist/index.html +1 -1
  312. package/dist/add-P76GEMGF.js +0 -8
  313. package/dist/agent-X6I2YWOB.js +0 -33
  314. package/dist/chunk-JQKKVAAN.js +0 -2
  315. package/dist/chunk-NQ47TA6C.js +0 -111
  316. package/dist/chunk-ODVKPZZ4.js +0 -2
  317. package/dist/chunk-Q2J542ST.js +0 -2
  318. package/dist/chunk-RBLK34IA.js +0 -11
  319. package/dist/chunk-RN4VE6P3.js +0 -521
  320. package/dist/chunk-WS2N27RX.js +0 -3
  321. package/dist/config-schema-GUQY2QN7.js +0 -2
  322. package/dist/decision-loader-2XPZE4EZ.js +0 -2
  323. package/dist/doctor-WMVULMQD.js +0 -2
  324. package/dist/list-5IUGP3ZB.js +0 -7
  325. package/dist/lore-loader-RVQI5GXL.js +0 -2
  326. package/dist/lore-loader-XY5MZRR2.js +0 -2
  327. package/dist/migrate-assessments-GEI5WMI2.js +0 -4
  328. package/dist/portal-compliance-6YR27IQU.js +0 -2
  329. package/dist/quiz-FE5UGAY2.js +0 -10
  330. package/dist/registry-KOOKFUWD.js +0 -20
  331. package/dist/reindex-I6LPAKCC.js +0 -2
  332. package/dist/serve-OY6XYL7F.js +0 -12
  333. package/dist/server-2MNROHF6.js +0 -7
  334. package/dist/session-tracker-MWJAJA6Z.js +0 -2
  335. package/dist/shift-PC6C7NUX.js +0 -60
  336. package/dist/show-BOAVWZPZ.js +0 -7
  337. package/dist/status-A37ECYNJ.js +0 -6
  338. package/dist/sync-DLUBV5HQ.js +0 -2
  339. package/dist/tools-5ITPEPSV.js +0 -2
  340. package/dist/university-content/courses/.purpose +0 -492
  341. package/dist/university-content/courses/para-001.json +0 -166
  342. package/dist/university-content/courses/para-101.json +0 -615
  343. package/dist/university-content/courses/para-201.json +0 -794
  344. package/dist/university-content/courses/para-301.json +0 -830
  345. package/dist/university-content/courses/para-401.json +0 -868
  346. package/dist/university-content/courses/para-501.json +0 -1166
  347. package/dist/university-content/courses/para-601.json +0 -719
  348. package/dist/university-content/courses/para-701.json +0 -807
  349. package/dist/university-content/plsat/.purpose +0 -162
  350. package/dist/university-content/plsat/v2.0.json +0 -760
  351. package/dist/university-content/plsat/v3.0.json +0 -3453
  352. package/dist/validate-C6SMKGYD.js +0 -9
  353. package/platform-ui/dist/assets/LoreSection-oO5dCe6O.js +0 -1
  354. /package/dist/{chunk-BV5PRPLB.js → chunk-HXGYVS2N.js} +0 -0
  355. /package/templates/paradigm/specs/{scan.md → probe.md} +0 -0
@@ -1,794 +0,0 @@
1
- {
2
- "id": "para-201",
3
- "title": "PARA 201: Architecture",
4
- "description": "Deepen your Paradigm expertise with advanced patterns for flows, gates, aspects, disciplines, naming conventions, and architectural design. Learn to build complete features end-to-end using the full symbol system.",
5
- "lessons": [
6
- {
7
- "id": "flows-deep-dive",
8
- "title": "Flows in Depth",
9
- "content": "## When to Create a Flow\n\nNot every process needs a `$flow`. The rule of thumb is: **create a flow when logic spans three or more components in a specific order**. A two-component interaction (service A calls service B) is simple enough to document in the component's `.purpose` entry. But once a third component enters the picture — and the order matters — a flow captures the choreography that no single component can describe.\n\nConsider these scenarios:\n- User clicks \"Buy\" → cart validates → payment charges → order creates → email sends. That is four components in sequence. This needs a `$checkout-flow`.\n- A cron job triggers → data fetches → report generates → file uploads → Slack notifies. Five components. This needs a `$daily-report-flow`.\n- A controller calls a service which returns data. Two components, no sequence ambiguity. This does NOT need a flow.\n\n## Flow Step Structure\n\nEach step in a flow is a `component + action` pair. The component references a `#component` defined in a `.purpose` file, and the action describes what that component does in this step:\n\n```yaml\nflows:\n $onboarding:\n description: New user setup from registration to first project\n steps:\n - component: \"#auth-handler\"\n action: create-account\n description: Validates email, hashes password, creates user record\n - component: \"#email-service\"\n action: send-welcome\n description: Sends welcome email with verification link\n - component: \"#project-service\"\n action: create-default-project\n description: Creates a starter project for the new user\n - component: \"#notification-service\"\n action: notify-team\n description: Alerts the team Slack channel about the new signup\n signals: [\"!user-created\", \"!welcome-email-sent\"]\n gates: []\n```\n\nThe `description` on each step is optional but valuable — it tells AI agents what happens at each point without reading the source code.\n\n## Documenting Flows in .purpose Files\n\nFlows are defined in the `flows` section of a `.purpose` file, usually in the directory of the *initiating* component. If the checkout flow starts in the cart module, define `$checkout-flow` in `src/cart/.purpose`. The flow references components from other directories — that is expected and correct.\n\nYou can also reference flows from component definitions:\n\n```yaml\ncomponents:\n #cart-service:\n description: Shopping cart management\n flows: [\"$checkout-flow\", \"$cart-abandonment-flow\"]\n```\n\nThis bidirectional referencing lets `paradigm_ripple` calculate the full impact when you modify a component — it knows which flows pass through it.\n\n## Flow Validation\n\nParadigm provides `paradigm_flow_check` to check that your flow definitions are consistent:\n\n```\nparadigm_flow_check({ flowId: \"$checkout-flow\", checkImplementation: true })\n```\n\nWith `checkImplementation: true`, the validator goes beyond schema checks — it verifies that the referenced components exist in `.purpose` files, that the actions are implemented in the codebase, and that any signals listed are actually emitted. This catches drift between documentation and code.\n\nYou can also validate all flows at once by omitting the `flowId` parameter. This is useful as a pre-commit check or CI step.\n\n## Circular Dependency Detection\n\nWhen flows reference each other via `relatedFlows` or step-level `$flow` symbols, they form a dependency graph. Paradigm automatically detects circular dependencies in this graph using depth-first search.\n\nA circular dependency looks like this:\n\n```yaml\n$checkout-flow:\n relatedFlows: [$payment-flow]\n$payment-flow:\n relatedFlows: [$checkout-flow] # Creates a cycle!\n```\n\nWhen you run `paradigm_flow_check({})` (validate all flows), the output includes a `circularDependencies` section:\n\n```\n⚠ Circular Dependencies (1)\n\n $checkout-flow → $payment-flow → $checkout-flow\n\n Resolution: Break the cycle by extracting shared logic into a\n separate flow, or remove one direction of the dependency.\n```\n\nTo resolve circular dependencies:\n1. **Extract shared logic** into a new flow that both original flows reference\n2. **Remove one direction** if only one flow truly depends on the other\n3. **Replace with signals** — use `!signal` communication instead of direct flow references\n\nCircular dependencies are not just a documentation problem — they indicate architectural coupling that can lead to cascading failures and maintenance difficulty.\n\n## Flows Are Documentation, Not Orchestration\n\nA critical distinction: flows describe *what happens*, not *how to make it happen*. They are not workflow engines or saga orchestrators. Your code still calls services, handles errors, and manages state however it needs to. The flow definition is metadata that helps humans and AI agents understand the sequence — it does not replace your implementation.",
10
- "keyConcepts": [
11
- "Create flows when 3+ components are involved in sequence",
12
- "Steps are component + action pairs",
13
- "Define flows in the .purpose file of the initiating component",
14
- "paradigm_flow_check checks consistency with codebase",
15
- "Circular dependency detection catches cycles in flow relatedFlows references",
16
- "Flows are documentation, not orchestration code",
17
- "'paradigm flow diagram $flowId' generates Mermaid flowcharts — gates as diamonds, actions as rectangles, signals as rounded boxes"
18
- ],
19
- "quiz": [
20
- {
21
- "id": "q1",
22
- "question": "A controller calls a service, which queries a database and returns a result. Should this be a $flow?",
23
- "choices": {
24
- "A": "Yes — any multi-step process should be a flow",
25
- "B": "Yes — database queries always require flow documentation",
26
- "C": "No — this is a two-component interaction with no sequence ambiguity",
27
- "D": "No — flows can only be used for user-facing features",
28
- "E": "It depends on whether the service emits a signal"
29
- },
30
- "correct": "C",
31
- "explanation": "A flow is warranted when logic spans three or more components in a specific order. A controller calling a service (with its database query) is a straightforward two-component interaction that can be documented on the component itself."
32
- },
33
- {
34
- "id": "q2",
35
- "question": "Where should a $checkout-flow be defined if the checkout process starts in the cart module?",
36
- "choices": {
37
- "A": "In .paradigm/flows/checkout.yaml",
38
- "B": "In portal.yaml under a flows section",
39
- "C": "In src/cart/.purpose, since the cart module initiates the flow",
40
- "D": "In every .purpose file of every component involved in the flow",
41
- "E": "In a standalone checkout-flow.purpose file at the project root"
42
- },
43
- "correct": "C",
44
- "explanation": "Flows are defined in the .purpose file of the initiating component's directory. Since the checkout flow starts in the cart module, it belongs in src/cart/.purpose. The flow will reference components from other directories."
45
- },
46
- {
47
- "id": "q3",
48
- "question": "What does `paradigm_flow_check` with `checkImplementation: true` verify?",
49
- "choices": {
50
- "A": "That the flow executes correctly at runtime",
51
- "B": "That referenced components exist in .purpose files, actions are implemented, and signals are emitted",
52
- "C": "That the flow has fewer than 10 steps",
53
- "D": "That all flows use the same naming convention",
54
- "E": "That the flow is referenced in portal.yaml"
55
- },
56
- "correct": "B",
57
- "explanation": "With checkImplementation: true, the validator performs deep checks: it verifies that referenced #components exist in .purpose files, that the named actions are implemented in the actual codebase, and that listed signals are actually emitted. This catches documentation-code drift."
58
- },
59
- {
60
- "id": "q4",
61
- "question": "What is the fundamental nature of a Paradigm flow?",
62
- "choices": {
63
- "A": "A workflow engine that orchestrates service calls at runtime",
64
- "B": "A saga implementation with rollback support",
65
- "C": "Documentation metadata describing what happens in a sequence, not how to execute it",
66
- "D": "A state machine that transitions between components",
67
- "E": "An event bus configuration defining message routing"
68
- },
69
- "correct": "C",
70
- "explanation": "Flows are documentation, not orchestration. They describe the sequence of operations for humans and AI agents to understand. Your code still handles the actual service calls, error handling, and state management however you choose to implement it."
71
- },
72
- {
73
- "id": "q5",
74
- "question": "`$checkout-flow` lists `relatedFlows: [$payment-flow]` and `$payment-flow` lists `relatedFlows: [$checkout-flow]`. What does `paradigm_flow_check` report?",
75
- "choices": {
76
- "A": "No issues — bidirectional references are valid",
77
- "B": "A circular dependency: $checkout-flow → $payment-flow → $checkout-flow",
78
- "C": "A missing step error — related flows must appear as steps",
79
- "D": "A naming violation — flows cannot reference each other",
80
- "E": "A warning about duplicate flow definitions"
81
- },
82
- "correct": "B",
83
- "explanation": "When flows reference each other in a cycle via relatedFlows, Paradigm detects it as a circular dependency using depth-first search. The resolution is to extract shared logic into a third flow, remove one direction of the dependency, or replace direct flow references with signal-based communication."
84
- }
85
- ]
86
- },
87
- {
88
- "id": "gates-deep-dive",
89
- "title": "Gates in Depth",
90
- "content": "## Gate Types\n\nGates are general-purpose condition checkers. While authorization is a common use case, gates can check any defined condition — feature flags, environment requirements, data prerequisites, system health, and more. Here are the common gate types:\n\n**Auth gates** verify identity — is the user who they claim to be?\n```yaml\n^authenticated:\n description: User must have a valid session\n check: req.session.userId != null\n type: auth\n```\n\n**Role gates** verify permission level — does the user hold the right role?\n```yaml\n^project-admin:\n description: User must be an admin of the project\n check: project.admins.includes(req.user.id)\n type: role\n requires: [^authenticated]\n```\n\n**Ownership gates** verify resource ownership — does the user own this specific item?\n```yaml\n^comment-author:\n description: User must be the author of this comment\n check: comment.authorId === req.user.id\n type: ownership\n requires: [^authenticated]\n```\n\n**State-precondition gates** verify system state — is the system in the right condition?\n```yaml\n^payment-method-exists:\n description: User must have a payment method on file\n check: user.paymentMethods.length > 0\n type: state-precondition\n requires: [^authenticated]\n```\n\n**Environment gates** verify deployment context — is the system running in the right environment?\n```yaml\n^production-only:\n description: Action is restricted to production environment\n check: process.env.NODE_ENV === 'production'\n type: environment\n```\n\n**Capability gates** verify that a feature or capability is available:\n```yaml\n^feature-enabled:\n description: The feature flag must be active for this user\n check: features.isEnabled('new-checkout', req.user)\n type: capability\n```\n\n**Data-readiness gates** verify that required data exists before proceeding:\n```yaml\n^profile-complete:\n description: User must have completed their profile before accessing this feature\n check: user.profile.isComplete === true\n type: data-readiness\n```\n\nThe `type` field is metadata for humans and tools — Paradigm does not enforce different behavior based on type. But categorizing gates helps AI agents suggest appropriate checks. Auth, role, and ownership are common in web applications, while state-precondition, environment, capability, and data-readiness gates are equally important across all disciplines.\n\n## Check Expressions\n\nThe `check` field contains a **pseudo-code expression** that describes the gate's condition logic. It is not executable code — it is precise documentation:\n\n```yaml\n# Good: clear and implementable\ncheck: project.members.some(m => m.userId === req.user.id && m.role === 'admin')\n\n# Bad: too vague\ncheck: user is admin\n\n# Bad: too implementation-specific\ncheck: await db.query('SELECT * FROM project_members WHERE...')\n```\n\nThe check should be specific enough that a developer can implement it from reading the expression, but abstract enough that it does not depend on a particular ORM or database.\n\n## Gate Chains\n\nGates chain through the `requires` field. When a route specifies `[^authenticated, ^project-admin]`, the gates are checked in order:\n\n1. `^authenticated` runs first. If it fails, the request is rejected (in HTTP, this is a 401 Unauthorized; other disciplines handle failure differently).\n2. `^project-admin` runs next (which itself requires `^authenticated`, already passed). If it fails, the request is denied (in HTTP, a 403 Forbidden).\n\nChains prevent redundant checks. You never need to re-check authentication inside a role gate — the `requires` field guarantees it already passed.\n\nDeep chains are possible but should be kept shallow for clarity:\n```yaml\n^super-admin:\n requires: [^authenticated, ^org-admin] # ^org-admin itself requires ^authenticated\n```\n\n## The Effects Field\n\nGates can trigger side effects when they pass, defined in the `effects` field:\n\n```yaml\n^first-purchase:\n description: User is making their first purchase\n check: user.purchaseCount === 0\n type: state-precondition\n requires: [^authenticated]\n effects:\n - id: first-purchase-badge\n oneTime: true\n - id: welcome-discount\n oneTime: true\n```\n\nThe `oneTime: true` flag ensures the effect triggers only once per user. Effects are useful for gamification, onboarding rewards, and analytics events. If a gate has no side effects, use `effects: []`.\n\n## Implementing Gates\n\nWhile `portal.yaml` defines *what* gates exist and *where* they apply, your application code must *implement* them. In web applications, the typical pattern is middleware (other disciplines use different enforcement mechanisms):\n\n```typescript\n// Express middleware implementing ^authenticated\nfunction authenticated(req, res, next) {\n if (!req.session?.userId) {\n return res.status(401).json({ error: 'Authentication required' });\n }\n next();\n}\n\n// Express middleware implementing ^project-admin\nfunction projectAdmin(req, res, next) {\n const project = await Project.findById(req.params.id);\n if (!project.admins.includes(req.user.id)) {\n return res.status(403).json({ error: 'Admin access required' });\n }\n next();\n}\n\n// Route applying the gate chain from portal.yaml\nrouter.put('/api/projects/:id', authenticated, projectAdmin, updateProject);\n```\n\nThe key discipline: the `portal.yaml` definition and the implementation must match. If `portal.yaml` says an operation requires `^project-admin`, the code must actually enforce that check.",
91
- "keyConcepts": [
92
- "Gate types include auth, role, ownership, state-precondition, environment, capability, and data-readiness",
93
- "Check expressions are precise pseudo-code, not executable code",
94
- "Gates chain via the requires field to prevent redundant checks",
95
- "Effects trigger side effects on gate pass (badges, rewards)",
96
- "portal.yaml defines gates; application code implements them"
97
- ],
98
- "quiz": [
99
- {
100
- "id": "q1",
101
- "question": "A gate checks whether a user's subscription is active before allowing access to premium content. What type should this gate be?",
102
- "choices": {
103
- "A": "auth — it verifies the user's identity",
104
- "B": "role — it checks the user's permission level",
105
- "C": "ownership — it verifies resource ownership",
106
- "D": "state-precondition — it verifies the system is in the right condition",
107
- "E": "integration — it checks a third-party service"
108
- },
109
- "correct": "D",
110
- "explanation": "This gate verifies system state — whether the subscription is active — rather than identity (auth), permission level (role), or resource ownership. State-precondition gates check conditions about the current state of data."
111
- },
112
- {
113
- "id": "q2",
114
- "question": "What is wrong with this gate check expression: `check: user is admin`?",
115
- "choices": {
116
- "A": "Nothing — it is clear and concise",
117
- "B": "It should use JavaScript syntax, not English",
118
- "C": "It is too vague — a developer cannot implement it without more information",
119
- "D": "It is missing the req. prefix",
120
- "E": "Gate checks must be written in YAML, not pseudo-code"
121
- },
122
- "correct": "C",
123
- "explanation": "Check expressions should be precise enough to implement from reading the expression. 'user is admin' does not specify how admin status is determined — is it a boolean field? A role in an array? A separate table? A better expression: project.admins.includes(req.user.id)."
124
- },
125
- {
126
- "id": "q3",
127
- "question": "A route requires `[^authenticated, ^org-admin, ^billing-enabled]`. The `^org-admin` gate has `requires: [^authenticated]`. What happens at runtime?",
128
- "choices": {
129
- "A": "^authenticated runs twice — once from the route, once from ^org-admin's requires",
130
- "B": "^authenticated runs once, ^org-admin runs once, ^billing-enabled runs once — in that order",
131
- "C": "An error is thrown because ^authenticated is listed both in the route and in requires",
132
- "D": "All three gates run in parallel for performance",
133
- "E": "Only ^billing-enabled runs because the other two are implicit from requires"
134
- },
135
- "correct": "B",
136
- "explanation": "Gate chains prevent redundant checks. ^authenticated is required by ^org-admin, but since the route lists ^authenticated first, it runs once and subsequent gates know it already passed. The three gates execute in order: authenticated, org-admin, billing-enabled."
137
- },
138
- {
139
- "id": "q4",
140
- "question": "When should the `effects` field be an empty array `[]`?",
141
- "choices": {
142
- "A": "Never — every gate must have at least one prize",
143
- "B": "When the gate has no side effects to trigger on pass",
144
- "C": "When the gate is of type 'auth'",
145
- "D": "When the gate is used on GET routes only",
146
- "E": "When the gate has been deprecated"
147
- },
148
- "correct": "B",
149
- "explanation": "Use effects: [] when the gate has no side effects. Most gates simply allow or deny access without triggering additional actions. Effects are for special cases like gamification badges, onboarding rewards, or analytics events."
150
- },
151
- {
152
- "id": "q5",
153
- "question": "portal.yaml says `\"DELETE /api/posts/:id\": [^authenticated, ^post-author]`, but the route handler only checks authentication, not authorship. What is the consequence?",
154
- "choices": {
155
- "A": "No consequence — portal.yaml is just documentation",
156
- "B": "The route will return 403 automatically based on portal.yaml",
157
- "C": "Any authenticated user can delete any post — a security vulnerability caused by the implementation not matching the specification",
158
- "D": "The paradigm scan command will fix the discrepancy automatically",
159
- "E": "The delete will fail silently"
160
- },
161
- "correct": "C",
162
- "explanation": "portal.yaml defines what SHOULD happen, but your code must implement it. If the middleware only checks authentication without verifying post authorship, any logged-in user can delete any post. This is a security vulnerability caused by specification-implementation drift."
163
- }
164
- ]
165
- },
166
- {
167
- "id": "aspects-and-anchors",
168
- "title": "Aspects & Code Anchors",
169
- "content": "## Why Aspects Require Anchors\n\nAspects (`~`) are unique among Paradigm's five symbols because they are the only ones that **require code anchors**. An anchor is a pointer to the exact lines of code where the aspect is enforced. This requirement exists for a practical reason: an aspect without an anchor is just a wish.\n\nConsider `~audit-required`. If you define it without anchors, you are saying \"financial operations should be audited\" — but there is no proof that they actually are. With anchors pointing to `src/middleware/audit.ts:15-35`, you are saying \"financial operations are audited, and here is the enforcement code.\" AI agents can verify the anchor, developers can review it, and `paradigm_aspect_check` can validate that the code still exists.\n\n## Anchor Format\n\nAnchors support three formats:\n\n```yaml\n~rate-limited:\n description: API endpoints are rate-limited to prevent abuse\n anchors:\n - src/middleware/rate-limiter.ts:42 # Single line\n - src/middleware/rate-limiter.ts:42-78 # Line range\n - src/decorators/throttle.ts:10,15,22 # Multiple specific lines\n applies-to: [\"#*-handler\"]\n```\n\n- **Single line** (`file:42`) — Points to one specific line. Use when the enforcement is a single check or decorator.\n- **Range** (`file:42-78`) — Points to a block of code. Use when the enforcement spans multiple lines (a middleware function, a class method).\n- **Multiple lines** (`file:10,15,22`) — Points to several non-contiguous lines. Use when the enforcement is scattered across a file (multiple decorators, multiple conditional checks).\n\nAnchors must point to *real files with real code*. If the file does not exist or the lines are outside the file's range, `paradigm_aspect_check` will report an error.\n\n## The applies-to Pattern\n\nThe `applies-to` field uses glob patterns to declare which symbols the aspect covers:\n\n```yaml\n~audit-required:\n applies-to: [\"#*Service\"] # All components ending in 'Service'\n\n~rate-limited:\n applies-to: [\"#*-handler\", \"#*-endpoint\"] # All handlers and endpoints\n\n~cached:\n applies-to: [\"#*-query\"] # All query components\n```\n\nThis is declarative — it says \"this aspect should apply to these components.\" AI agents use this to check whether a new component matching the pattern has the aspect applied. If you create `#billing-service` and `~audit-required` applies to `#*Service`, the agent knows to apply the audit aspect.\n\n## Defining Aspects in .purpose Files\n\n```yaml\naspects:\n ~audit-required:\n description: All financial operations must log to the audit trail\n anchors:\n - src/middleware/audit.ts:15-35\n - src/decorators/auditable.ts:1-20\n applies-to: [\"#*Service\"]\n enforcement: middleware\n tags: [compliance, security]\n\n ~rate-limited:\n description: API endpoints enforce per-user rate limits\n anchors:\n - src/middleware/rate-limiter.ts:42-78\n applies-to: [\"#*-handler\"]\n enforcement: middleware\n tags: [security, performance]\n```\n\nThe `enforcement` field is optional metadata that describes *how* the aspect is enforced — via middleware, decorator, wrapper function, etc. It helps AI agents understand the enforcement mechanism when they need to apply the aspect to new components.\n\n## Validating Aspects\n\nUse `paradigm_aspect_check` to verify that an aspect's anchors are valid:\n\n```\nparadigm_aspect_check({ aspect: \"~audit-required\" })\n```\n\nThis tool checks:\n1. **Anchor existence** — Do the referenced files exist?\n2. **Line validity** — Are the line numbers within the file's range?\n3. **Coverage** — Are all components matching `applies-to` actually covered?\n\nRun this after refactoring. If you move or rename files, the anchors break — and a broken anchor means the enforcement code is lost or relocated. The aspect check catches this drift.\n\n## Aspects vs Gates\n\nA common confusion: when should you use an aspect (`~`) versus a gate (`^`)? The distinction is clear:\n\n- **Gates** check a *specific condition at a specific time*. \"Can this user access this project?\" or \"Is this feature flag enabled?\" is a gate.\n- **Aspects** enforce rules *across many components as a pattern*. \"All financial services must log to the audit trail\" is an aspect.\n\nGates are reactive (triggered per request or operation). Aspects are structural (enforced by code patterns). A gate checks one condition at one point; an aspect applies to all components matching a pattern.",
170
- "keyConcepts": [
171
- "Aspects are the only symbol requiring code anchors",
172
- "Anchor formats: single line, range, and multiple lines",
173
- "applies-to uses glob patterns to declare coverage",
174
- "paradigm_aspect_check validates anchor existence and coverage",
175
- "Aspects enforce patterns across components; gates check per-request conditions"
176
- ],
177
- "quiz": [
178
- {
179
- "id": "q1",
180
- "question": "Why do aspects require anchors while other symbols do not?",
181
- "choices": {
182
- "A": "Because aspects are more important than other symbols",
183
- "B": "Because without anchors, an aspect is an unenforced rule — a wish, not a constraint",
184
- "C": "Because YAML requires at least one nested field under aspects",
185
- "D": "Because AI agents cannot understand aspects without seeing the code",
186
- "E": "Because aspects are always defined in middleware files"
187
- },
188
- "correct": "B",
189
- "explanation": "An aspect without anchors is just a statement of intent with no proof of enforcement. Anchors point to the actual code that enforces the rule, making the aspect verifiable by tools, reviewable by developers, and auditable by compliance."
190
- },
191
- {
192
- "id": "q2",
193
- "question": "The anchor `src/middleware/auth.ts:42-78` points to what?",
194
- "choices": {
195
- "A": "Lines 42 and 78 only (two specific lines)",
196
- "B": "The 42nd through 78th characters on line 1",
197
- "C": "A range of lines from line 42 to line 78 inclusive",
198
- "D": "Column 42 through column 78 on every line in the file",
199
- "E": "The 42nd and 78th functions defined in the file"
200
- },
201
- "correct": "C",
202
- "explanation": "The range format (file:start-end) points to a block of consecutive lines. src/middleware/auth.ts:42-78 covers lines 42 through 78 inclusive — typically a complete function or middleware definition."
203
- },
204
- {
205
- "id": "q3",
206
- "question": "You define `~cached` with `applies-to: [\"#*-query\"]`. You then create `#user-query` without applying the cache aspect. What should happen?",
207
- "choices": {
208
- "A": "Nothing — applies-to is just a suggestion",
209
- "B": "paradigm_aspect_check reports a coverage gap: #user-query matches the pattern but is not covered",
210
- "C": "The build fails because the aspect is not applied",
211
- "D": "The component is automatically cached by Paradigm",
212
- "E": "#user-query is renamed to #user-query-cached"
213
- },
214
- "correct": "B",
215
- "explanation": "The applies-to field is declarative — it says 'this aspect should cover all components matching this pattern.' When paradigm_aspect_check runs, it identifies #user-query as matching #*-query but not having the caching aspect applied, reporting a coverage gap."
216
- },
217
- {
218
- "id": "q4",
219
- "question": "After a major refactor, several source files were renamed and moved. What is the risk to aspects?",
220
- "choices": {
221
- "A": "No risk — aspects are tied to symbol names, not file paths",
222
- "B": "Anchor references break because they point to file paths and line numbers that may no longer exist",
223
- "C": "The aspect definitions are automatically updated by git",
224
- "D": "Aspects are deleted when their files move",
225
- "E": "The refactor cannot proceed if aspects exist"
226
- },
227
- "correct": "B",
228
- "explanation": "Anchors contain file paths and line numbers (e.g., src/middleware/audit.ts:15-35). When files are renamed, moved, or heavily edited, these references break. Running paradigm_aspect_check after refactoring catches this drift."
229
- }
230
- ]
231
- },
232
- {
233
- "id": "aspect-graph",
234
- "title": "The Aspect Graph",
235
- "content": "## What Is the Aspect Graph?\n\nIn earlier lessons you learned that aspects (`~`) represent cross-cutting rules, constraints, and configuration values anchored to specific lines of code. The **aspect graph** connects those aspects to each other and to the rest of your symbol system — components, gates, flows, and signals — creating a queryable relationship map.\n\nThink of it this way: a single aspect like `~token-expiry-24h` is useful on its own. But when you can see that it is *enforced by* `^authenticated`, *related to* `~refresh-token-7d`, and linked to a lore entry explaining why the team chose 24 hours — that is the graph at work.\n\n## v3.5 Aspect Fields\n\nParadigm v3.5 extended aspects with structured fields that make them graph-ready:\n\n```yaml\naspects:\n ~rate-limit-100:\n description: API rate limited to 100 requests per minute\n value: 100/min\n category: constraint\n severity: high\n anchors:\n - src/middleware/rate-limiter.ts:12-18\n applies-to: [#api-gateway]\n edges:\n - symbol: ^authenticated\n relation: enforced-by\n tags: [security, performance]\n```\n\nKey fields:\n- **value** — The concrete value (a number, duration, threshold) making aspects searchable by content\n- **category** — One of five types: `rule` (behavioral), `decision` (architectural choice), `constraint` (hard limit), `configuration` (environment-specific), `invariant` (always-true condition)\n- **severity** — Impact of violation: `low`, `medium`, `high`, `critical`\n- **edges** — Explicit relationships to other symbols with typed relations: `enforced-by`, `depends-on`, `contradicts`, `supersedes`, `related-to`\n- **lore** — References to lore entries providing historical context\n\n## Working with the Graph\n\nSeven MCP tools let you interact with the aspect graph:\n\n| Tool | Purpose |\n|------|---------|\n| `paradigm_aspect_search` | Find aspects by keyword — uses a three-tier search (learned mappings, full-text, fuzzy) |\n| `paradigm_aspect_get` | Deep-dive: full definition, code snippets at anchors, edges, linked lore |\n| `paradigm_aspect_graph` | Explore the neighborhood around a symbol (N hops out) |\n| `paradigm_aspect_heatmap` | See which aspects are accessed most (search, ripple, navigate, direct) |\n| `paradigm_aspect_suggest_scan` | Scan a source file for undocumented aspects (magic numbers, hardcoded strings, rate limits, etc.) |\n| `paradigm_aspect_drift` | Check if code at anchored lines changed since last scan (SHA-256 hash comparison) |\n| `paradigm_aspect_confirm` | Confirm a search result to improve future search accuracy (learning loop) |\n\nThe graph is stored as a SQLite database at `.paradigm/aspect-graph.db` — a derived artifact rebuilt by `paradigm_reindex`. The YAML `.purpose` files remain the source of truth.\n\n## When to Use the Aspect Graph\n\n- **Before modifying enforcement code** — call `paradigm_aspect_drift` to check for stale anchors\n- **Exploring unfamiliar rules** — call `paradigm_aspect_search` then `paradigm_aspect_get` for full context\n- **Understanding impact** — call `paradigm_aspect_graph` to see what a change affects\n- **Finding undocumented rules** — call `paradigm_aspect_suggest_scan` on source files\n\n> **Deep dive:** PARA 501 covers the SQLite schema, three-tier search internals, the learning loop, edge origins (explicit vs inferred vs learned), and the materialization pipeline in detail.",
236
- "keyConcepts": [
237
- "Aspect graph connects aspects to components, gates, flows, and signals",
238
- "Five aspect categories: rule, decision, constraint, configuration, invariant",
239
- "Five edge relations: enforced-by, depends-on, contradicts, supersedes, related-to",
240
- "Seven MCP tools for search, detail, graph, heatmap, suggest, drift, and confirm",
241
- "SQLite graph at .paradigm/aspect-graph.db is a derived artifact — YAML is source of truth",
242
- "Deep internals covered in PARA 501"
243
- ],
244
- "quiz": [
245
- {
246
- "id": "q1",
247
- "question": "Your team's rate limiter was recently changed from 100 req/min to 500 req/min, but no one updated the aspect definition. Which tool would catch this?",
248
- "choices": {
249
- "A": "paradigm_aspect_search — it would find the stale value in search results",
250
- "B": "paradigm_aspect_drift — it compares code hashes at anchor line ranges and detects the change",
251
- "C": "paradigm_aspect_heatmap — it shows the aspect is no longer being accessed",
252
- "D": "paradigm_aspect_graph — it reveals the broken edge to the rate limiter component",
253
- "E": "paradigm_reindex — it automatically updates the aspect value during reindexing"
254
- },
255
- "correct": "B",
256
- "explanation": "paradigm_aspect_drift compares SHA-256 hashes of code at anchored line ranges against the hashes from the last scan. When the rate limiter code changed, the hash changed, flagging the anchor as drifted. The other tools don't detect code changes — reindex rebuilds the graph from YAML, which still has the old value."
257
- },
258
- {
259
- "id": "q2",
260
- "question": "Which aspect category best fits \"JWT access tokens expire after 24 hours\"?",
261
- "choices": {
262
- "A": "rule — it defines a behavioral pattern that code must follow",
263
- "B": "decision — it captures an architectural choice",
264
- "C": "constraint — it is a hard limit that cannot be violated",
265
- "D": "configuration — it is a value that may differ across environments",
266
- "E": "invariant — it is a condition that must always hold true"
267
- },
268
- "correct": "D",
269
- "explanation": "A JWT expiry duration is a configuration value — it could reasonably differ between environments (shorter in dev, longer in production). A constraint is a hard limitation (like \"maximum 100 items per page\"). A rule is a behavioral pattern. Configuration captures what specific value was set and where."
270
- },
271
- {
272
- "id": "q3",
273
- "question": "An aspect has edges: [{symbol: \"^authenticated\", relation: \"enforced-by\"}]. What does this tell you?",
274
- "choices": {
275
- "A": "The aspect enforces the ^authenticated gate",
276
- "B": "The ^authenticated gate depends on the aspect existing",
277
- "C": "The ^authenticated gate is the mechanism that ensures the aspect holds true",
278
- "D": "The aspect and the gate are in conflict",
279
- "E": "The aspect will be removed if the gate is deleted"
280
- },
281
- "correct": "C",
282
- "explanation": "The enforced-by relation means the target symbol is what ensures the aspect's rule holds. Here, the ^authenticated gate is the checkpoint that enforces whatever the aspect defines. Aspects declare what must be true; gates enforce those truths. The edge makes this relationship explicit and queryable."
283
- }
284
- ]
285
- },
286
- {
287
- "id": "portal-protocol",
288
- "title": "The Portal Protocol",
289
- "content": "## Specification Before Implementation\n\nThe Portal Protocol is Paradigm's prescribed workflow for adding guarded operations. Its core principle is **specification before implementation** — you define what conditions must be met before you write the handler code. This inverts the common (and dangerous) pattern of building functionality first and bolting on checks later.\n\nThe idea is universal: define what gates an operation needs before you implement the operation itself. In a web API, this means defining route gates before writing handlers. In a mobile app, it might mean specifying which screens require which conditions before building the UI. In a CLI tool, it means declaring what preconditions a command requires before writing the command logic.\n\n## The Four Steps\n\n### Step 1: Ask Paradigm\n\nBefore writing any handler, call `paradigm_gates_for_route` with the route and method:\n\n```\nparadigm_gates_for_route({ route: \"/api/projects/:id/members\", method: \"POST\" })\n```\n\nThis tool analyzes your existing `portal.yaml` and suggests gates based on patterns:\n- The route is under `/api/` → probably needs `^authenticated`\n- It modifies a project resource → probably needs `^project-admin` or `^project-member`\n- It is a POST (mutation) → higher gate requirements than a GET\n\nThe suggestions are not binding, but they catch common oversights. You might realize you need a gate you had not considered.\n\n### Step 2: Add to portal.yaml\n\nAdd the route with its required gates:\n\n```yaml\nroutes:\n # Existing routes...\n \"POST /api/projects/:id/members\": [^authenticated, ^project-admin]\n```\n\nIf you need a new gate that does not exist yet, define it in the `gates` section:\n\n```yaml\ngates:\n ^project-admin:\n description: User must be an admin of the project\n check: project.admins.includes(req.user.id)\n type: role\n requires: [^authenticated]\n effects: []\n```\n\n### Step 3: Implement the Gate Checks\n\nWrite the middleware or handler code that enforces each gate. The implementation must match the `check` expression in portal.yaml. How a failed gate manifests depends on your discipline:\n\n- **Web APIs** return HTTP status codes (401 for failed identity checks, 403 for failed authorization)\n- **Mobile apps** might disable UI elements or show an upgrade prompt\n- **CLI tools** might exit with a specific error code and message\n- **Desktop apps** might gray out menu items or show a dialog\n\nHere is an example for a web API:\n\n```typescript\nasync function projectAdmin(req, res, next) {\n const project = await Project.findById(req.params.id);\n if (!project) {\n return res.status(404).json({ error: 'Project not found' });\n }\n if (!project.admins.includes(req.user.id)) {\n log.gate('^project-admin').warn('Access denied', {\n userId: req.user.id,\n projectId: req.params.id\n });\n return res.status(403).json({ error: 'Admin access required' });\n }\n req.project = project; // Attach for downstream use\n next();\n}\n```\n\nNotice the Paradigm logger usage: `log.gate('^project-admin').warn(...)` for a denied gate.\n\n### Step 4: Test Gate Failures\n\nVerify that failing a gate produces the correct behavior. In a web API, this means testing rejection status codes:\n\n```typescript\nit('rejects non-admin attempting to add member', async () => {\n const res = await request(app)\n .post('/api/projects/proj_123/members')\n .set('Authorization', `Bearer ${memberToken}`) // member, not admin\n .send({ email: 'newuser@example.com' });\n\n expect(res.status).toBe(403);\n});\n```\n\nTest both the pass path (authorized user succeeds) and the fail path (unauthorized user is rejected). The concept of pass/fail is universal across all disciplines — only the specific failure response varies.\n\n## Common Gate Patterns\n\nOver time, projects develop recurring gate patterns:\n\n| Pattern | Gate Name | Check |\n|---------|-----------|-------|\n| Any logged-in user | `^authenticated` | `req.user != null` |\n| Resource membership | `^{resource}-member` | `resource.members.includes(req.user.id)` |\n| Resource admin | `^{resource}-admin` | `resource.admins.includes(req.user.id)` |\n| Resource creator | `^{resource}-creator` | `resource.createdBy === req.user.id` |\n| Item author | `^{item}-author` | `item.authorId === req.user.id` |\n| Feature flag | `^feature-{name}` | `features.isEnabled(name, req.user)` |\n\nThese patterns are reusable across projects. When you call `paradigm_gates_for_route`, the tool draws from these patterns to make suggestions.\n\n## The Cost of Skipping the Protocol\n\nThe Portal Protocol makes conditions a first thought rather than an afterthought. By defining gates in portal.yaml before writing handlers, you create an auditable specification that is separate from (and checkable against) the implementation. Whether you are protecting API endpoints, gating CLI commands, or controlling feature access in a mobile app, the principle is the same: specify first, implement second.",
290
- "keyConcepts": [
291
- "Specification before implementation — define gates before writing handlers",
292
- "Four steps: ask Paradigm, add to portal.yaml, implement, test gate failures",
293
- "paradigm_gates_for_route suggests gates based on existing patterns",
294
- "Implementation must match the check expression in portal.yaml",
295
- "Test both the pass path and the fail path",
296
- "paradigm portal test --gate introspects lock key expressions to auto-generate test fixtures",
297
- "paradigm portal export outputs gate/route config as json, csv, or markdown"
298
- ],
299
- "quiz": [
300
- {
301
- "id": "q1",
302
- "question": "You need to add `DELETE /api/teams/:id`. What is the FIRST step in the Portal Protocol?",
303
- "choices": {
304
- "A": "Write the delete handler and add authentication middleware",
305
- "B": "Add the route to portal.yaml with [^authenticated]",
306
- "C": "Call paradigm_gates_for_route to get gate suggestions",
307
- "D": "Write a test for the 403 response",
308
- "E": "Create a ^team-admin gate in middleware"
309
- },
310
- "correct": "C",
311
- "explanation": "The Portal Protocol starts with asking Paradigm. Call paradigm_gates_for_route with the route and method to get suggestions based on existing patterns. This ensures you consider all necessary gates before implementation."
312
- },
313
- {
314
- "id": "q2",
315
- "question": "Your portal.yaml specifies `\"PUT /api/posts/:id\": [^authenticated, ^post-author]`. Your middleware only checks ^authenticated. What is the security impact?",
316
- "choices": {
317
- "A": "None — portal.yaml automatically enforces all listed gates",
318
- "B": "Any authenticated user can edit any post, because the ^post-author check is missing from the implementation",
319
- "C": "The route will return 500 because of the missing gate",
320
- "D": "Paradigm will block the request at the framework level",
321
- "E": "The post-author gate runs automatically via the requires field"
322
- },
323
- "correct": "B",
324
- "explanation": "portal.yaml is a specification, not enforcement. If the middleware does not implement the ^post-author check, any authenticated user can edit any post. This is a security vulnerability caused by the implementation not matching the specification."
325
- },
326
- {
327
- "id": "q3",
328
- "question": "In a web API, which HTTP status code should a failed authentication gate return, versus a failed authorization gate?",
329
- "choices": {
330
- "A": "Both return 403 Forbidden",
331
- "B": "Authentication returns 401 Unauthorized; authorization returns 403 Forbidden",
332
- "C": "Authentication returns 403 Forbidden; authorization returns 401 Unauthorized",
333
- "D": "Both return 401 Unauthorized",
334
- "E": "Authentication returns 400 Bad Request; authorization returns 403 Forbidden"
335
- },
336
- "correct": "B",
337
- "explanation": "In the HTTP discipline, the standard distinguishes between authentication (who are you?) and authorization (are you allowed?). A failed auth gate (^authenticated) returns 401 Unauthorized. A failed role/ownership gate (^project-admin) returns 403 Forbidden. Note that this is the web API implementation — other disciplines express gate failure differently (a mobile app might show a login screen or disable a button; a CLI might exit with an error code)."
338
- },
339
- {
340
- "id": "q4",
341
- "question": "Why does the Portal Protocol require defining gates BEFORE writing handler code?",
342
- "choices": {
343
- "A": "Because Paradigm cannot parse handler code that already exists",
344
- "B": "Because it creates an auditable specification separate from implementation, preventing conditions as an afterthought",
345
- "C": "Because TypeScript requires gate types to be defined before use",
346
- "D": "Because AI agents refuse to write code without portal.yaml",
347
- "E": "Because gate middleware must be loaded before route handlers in the server stack"
348
- },
349
- "correct": "B",
350
- "explanation": "The Portal Protocol's core principle is specification before implementation. By specifying gates in portal.yaml first, you create an auditable specification that is separate from (and checkable against) the implementation. This prevents the common pattern of building features first and bolting on checks later."
351
- }
352
- ]
353
- },
354
- {
355
- "id": "disciplines",
356
- "title": "Disciplines",
357
- "content": "## How Symbols Map Across Domains\n\nA Paradigm `discipline` defines how directory patterns and code structures map to symbol types in a specific development domain. A web frontend project organizes code differently from a backend API, which differs from a CLI tool. Disciplines capture these differences so that tooling — the navigator, the logging conventions, gate recommendations, and auto-scan — works correctly regardless of your tech stack.\n\n## Auto-Detection\n\nWhen you run `paradigm shift` or `paradigm init`, Paradigm automatically detects the discipline from your project structure. It examines `package.json`, `Cargo.toml`, `go.mod`, `pyproject.toml`, and other project markers to infer the best match. The detected discipline is written to `.paradigm/config.yaml`:\n\n```yaml\ndiscipline: fullstack # auto-detected from Next.js in package.json\n```\n\nDetection heuristics include: monorepo markers (workspaces), framework deps (Next.js → fullstack, React alone → web, Express alone → api), Python ML deps (PyTorch → ml), Rust crate deps (clap → cli, axum → api, bevy → game), and more. You can always override the detected value.\n\n## The 14 Disciplines\n\nParadigm supports 14 disciplines, each with tailored symbol mappings, purpose-required paths, and scan patterns:\n\n| Discipline | When to Use | Key Directories |\n|------------|-------------|------------------|\n| `web` | Frontend-only (React, Vue, Svelte) | `components/`, `pages/`, `hooks/`, `stores/` |\n| `backend` | General backend (fallback) | `services/`, `routes/`, `models/` |\n| `fullstack` | SSR or combined frontend+backend (Next.js, Django) | `components/`, `pages/`, `api/`, `services/` |\n| `api` | API-only (Express, FastAPI, Gin) | `routes/`, `endpoints/`, `controllers/` |\n| `cli` | CLI tools (Node bin, Click, clap) | `commands/`, `cmd/` |\n| `ml` | Machine learning (PyTorch, TF, scikit-learn) | `models/`, `experiments/`, `pipelines/` |\n| `mobile` | Mobile apps (React Native, Flutter) | `screens/`, `widgets/`, `navigation/` |\n| `game` | Game dev (Bevy, Godot, Unity) | `gameplay/`, `entities/`, `systems/` |\n| `embedded` | Embedded/IoT (embedded-hal, PlatformIO) | `drivers/`, `hal/`, `protocols/` |\n| `devops` | Infrastructure (Terraform, Ansible) | `modules/`, `pipelines/`, `scripts/` |\n| `data` | Data engineering (dbt, Airflow, Spark) | `models/`, `dags/`, `transforms/` |\n| `library` | Reusable packages (npm, PyPI, crates) | `src/`, `lib/` |\n| `monorepo` | Multi-package repos (workspaces, Nx) | `packages/`, `apps/`, `libs/` |\n| `custom` | User-defined mappings | Whatever you configure |\n\n## Web Discipline\n\nIn a web project, the primary units are routes, components, and pages:\n\n| Directory | Symbol | Rationale |\n|-----------|--------|-----------|\n| `routes/`, `pages/`, `views/` | `#` component | User-facing entry points |\n| `components/` | `#` component | Reusable UI elements |\n| `hooks/` | `#` component | Shared logic (hooks are code units, not signals) |\n| `stores/`, `state/` | `#` component (tag: `[state]`) | Client-side state |\n| `middleware/` | `^` gate | Route guards and auth checks |\n| `api/` | `#` component | API client wrappers |\n\nAn important distinction: **hooks are components, not signals**. A frontend hook like `useAuth` encapsulates logic — it is `#useAuth`, a component. The `!` signal prefix is reserved for events that trigger decoupled side effects.\n\n## Backend / API Discipline\n\nIn a backend or API project, the primary units are services, controllers, and models:\n\n| Directory | Symbol | Rationale |\n|-----------|--------|-----------|\n| `services/` | `#` component | Business logic |\n| `controllers/`, `handlers/` | `#` component | Request handlers |\n| `models/`, `entities/` | `#` component (tag: `[state]`) | Data models |\n| `middleware/`, `guards/` | `^` gate | Auth and validation |\n| `events/`, `listeners/` | `!` signal | Event emitters and handlers |\n| `jobs/`, `workers/` | `#` component | Background processing |\n| `integrations/`, `clients/` | `#` component (tag: `[integration]`) | External service wrappers |\n\nThe `api` discipline is like `backend` but focused on HTTP endpoints (adds `endpoints/`, `controllers/`, `webhooks/`).\n\n## Fullstack Discipline\n\nThe fullstack discipline combines both mappings. Paradigm determines which mapping to use based on the directory path:\n\n```\nsrc/\n client/ → Web discipline mappings apply\n server/ → Backend discipline mappings apply\n shared/ → Common mappings (# for all code units)\n```\n\nAuto-detected for SSR frameworks like Next.js, Nuxt, SvelteKit, or when both React and Express are present.\n\n## Domain-Specific Disciplines\n\n**ML**: Scans `models/`, `experiments/`, `notebooks/`. Pipelines map to `$` flows. Training events map to `!` signals.\n\n**Data**: Scans `dbt/`, `dags/`, `transforms/`. ETL pipelines are `$` flows. Data quality checks are `!` signals.\n\n**Game**: Scans `gameplay/`, `entities/`, `systems/`. Game loops are `$` flows. Game events are `!` signals.\n\n**Embedded**: Scans `drivers/`, `hal/`, `protocols/`. State machines are `$` flows. Interrupts are `!` signals.\n\n## Why Disciplines Matter\n\nDisciplines affect four things:\n\n1. **Symbol mappings** — Each discipline populates the `logging.symbol-mapping` section in config.yaml with directory-to-symbol mappings appropriate for your domain.\n2. **Navigator generation** — `paradigm scan` uses the discipline to categorize directories and suggest symbol types for undocumented code.\n3. **Gate recommendations** — `paradigm_gates_for_route` uses the discipline to understand which routes exist and what patterns apply.\n4. **Auto-scan patterns** — `paradigm scan --auto` adds discipline-specific file patterns (e.g., ML scans `.ipynb` notebooks, game scans `.gd` scripts).\n\nWith auto-detection, most projects get the right discipline without any manual configuration.\n\n## Custom Mappings\n\nIf your project does not fit a standard discipline, you can override mappings in `config.yaml`:\n\n```yaml\ndiscipline: backend\ncustom-mappings:\n \"workers/\": \"#\" # Override default if needed\n \"policies/\": \"^\" # Treat policies as gates\n \"sagas/\": \"$\" # Treat sagas as flows\n```\n\nCustom mappings extend (not replace) the discipline defaults. Or set `discipline: custom` and define everything yourself.\n\n## Stack Presets\n\nDisciplines tell Paradigm *what kind* of project you have (web, backend, mobile). Stack presets go one level deeper — they tell Paradigm *which framework* you are using. A stack preset layers framework-specific configuration on top of the discipline.\n\nParadigm ships 16 stack presets:\n\n| Preset | Discipline | What It Adds |\n|--------|------------|-------------|\n| `nextjs` | fullstack | `app/` routes, server actions, RSC patterns |\n| `remix` | fullstack | loader/action patterns, nested routes |\n| `sveltekit` | fullstack | `+page.svelte`, `+server.ts` patterns |\n| `nuxt` | fullstack | `composables/`, auto-imports |\n| `react-spa` | web | CRA/Vite SPA patterns, `hooks/`, `contexts/` |\n| `vue-spa` | web | Composition API, Pinia stores |\n| `express` | api | `app.get/post`, middleware chains |\n| `fastapi` | api | `@app.get`, Pydantic models, dependency injection |\n| `django` | fullstack | `views.py`, `models.py`, `urls.py` |\n| `flask` | api | `@app.route`, blueprints |\n| `gin-go` | api | `r.GET`, handler groups |\n| `axum-rs` | api | Axum extractors, tower middleware |\n| `swift-ios` | mobile | SwiftUI views, `@Observable`, navigation |\n| `kotlin-android` | mobile | Jetpack Compose, ViewModels, Hilt |\n| `react-native` | mobile | Expo/bare RN, navigation, native modules |\n| `flutter` | mobile | Widgets, BLoC/Riverpod, platform channels |\n\nStack presets are auto-detected during `paradigm init` from your dependencies and project files. You can also specify one explicitly:\n\n```bash\nparadigm init --stack nextjs\n```\n\nThe detected stack is written to config.yaml:\n\n```yaml\ndiscipline: fullstack\nstack: nextjs\n```\n\nStack presets add three things on top of the discipline:\n1. **Refined symbol mappings** — Framework-specific directories (e.g., `app/api/` for Next.js route handlers)\n2. **Purpose-required paths** — Directories that should have `.purpose` files for the framework to work well with Paradigm\n3. **Scan hints** — Framework-specific patterns for component detection, route patterns, auth patterns, and state management\n\nTo see all available presets:\n\n```bash\nparadigm presets\nparadigm presets --discipline mobile # Filter by discipline\n```\n\nStack presets solve the cold-start problem: when you run `paradigm init` on an existing Next.js project, the preset knows to look for `app/` routes, server components, and API handlers — producing meaningful `.purpose` scaffolding instead of generic stubs.",
358
- "keyConcepts": [
359
- "Disciplines define how directories map to symbol types per domain",
360
- "14 disciplines: web, backend, fullstack, api, cli, ml, mobile, game, embedded, devops, data, library, monorepo, custom",
361
- "Auto-detection at init time from project markers (package.json, Cargo.toml, etc.)",
362
- "Hooks are components (#), not signals (!)",
363
- "Disciplines affect symbol mappings, navigator, gate recommendations, and auto-scan patterns",
364
- "Custom mappings can extend discipline defaults",
365
- "16 stack presets layer framework-specific config on top of disciplines",
366
- "Stack presets add refined symbol mappings, purpose-required paths, and scan hints",
367
- "paradigm presets lists available presets, filterable by discipline"
368
- ],
369
- "quiz": [
370
- {
371
- "id": "q1",
372
- "question": "In a web discipline project, what symbol type should a frontend hook like `useAuth` be classified as?",
373
- "choices": {
374
- "A": "! signal — hooks fire events",
375
- "B": "^ gate — hooks check conditions",
376
- "C": "# component — hooks are code units that encapsulate logic",
377
- "D": "$ flow — hooks define sequences",
378
- "E": "~ aspect — hooks are cross-cutting concerns"
379
- },
380
- "correct": "C",
381
- "explanation": "Hooks are code units, not events. A frontend hook like useAuth encapsulates authentication logic — it is #useAuth, a component. The ! signal prefix is reserved for events that trigger decoupled side effects, which is not what hooks do."
382
- },
383
- {
384
- "id": "q2",
385
- "question": "A project has `src/client/` for frontend and `src/server/` for backend code. Which discipline should be used?",
386
- "choices": {
387
- "A": "web — because the client directory is listed first",
388
- "B": "backend — because server code is more important",
389
- "C": "fullstack — it combines both web and backend mappings based on directory path",
390
- "D": "library — because the code is shared between client and server",
391
- "E": "cli — because the server might have CLI commands"
392
- },
393
- "correct": "C",
394
- "explanation": "The fullstack discipline combines web and backend mappings. It uses the directory path to determine which mapping applies: src/client/ uses web discipline rules, src/server/ uses backend rules."
395
- },
396
- {
397
- "id": "q3",
398
- "question": "What three things does the discipline setting affect in Paradigm tooling?",
399
- "choices": {
400
- "A": "Build output, test runner, deployment target",
401
- "B": "Navigator generation, logging conventions, gate recommendations",
402
- "C": "File naming, import paths, type definitions",
403
- "D": "Package manager, bundler, linter configuration",
404
- "E": "Database schema, API schema, UI schema"
405
- },
406
- "correct": "B",
407
- "explanation": "The discipline affects: (1) navigator generation — how paradigm scan categorizes directories, (2) logging conventions — which log methods are conventional for each directory, and (3) gate recommendations — what paradigm_gates_for_route suggests."
408
- },
409
- {
410
- "id": "q4",
411
- "question": "Your backend project has a `policies/` directory for authorization policies. You want Paradigm to treat them as gates. How do you configure this?",
412
- "choices": {
413
- "A": "Rename the directory to middleware/",
414
- "B": "Change the discipline to 'web' since it handles auth differently",
415
- "C": "Add a custom-mappings entry in config.yaml: \"policies/\": \"^\"",
416
- "D": "Create a .purpose file with only gate definitions",
417
- "E": "It is not possible — gates can only live in middleware/"
418
- },
419
- "correct": "C",
420
- "explanation": "Custom mappings in config.yaml extend the discipline defaults. Adding \"policies/\": \"^\" tells Paradigm to treat files in the policies/ directory as gates, without changing the overall discipline or renaming directories."
421
- },
422
- {
423
- "id": "q5",
424
- "question": "A Next.js project runs `paradigm init`. The output shows `discipline: fullstack` and `stack: nextjs`. What does the stack preset add that the discipline alone does not provide?",
425
- "choices": {
426
- "A": "A completely different set of symbol mappings that replaces the discipline",
427
- "B": "Framework-specific scan hints, refined symbol mappings for Next.js patterns like app/ routes, and purpose-required paths",
428
- "C": "Automatic code generation for Next.js boilerplate",
429
- "D": "A Next.js-specific version of portal.yaml with pre-defined gates",
430
- "E": "Nothing — stack presets and disciplines are the same thing"
431
- },
432
- "correct": "B",
433
- "explanation": "Stack presets layer framework-specific configuration on top of disciplines. For Next.js, the preset adds knowledge about app/ directory routing, server components, API route handlers, and other Next.js-specific patterns. It refines the generic fullstack discipline with framework-aware scan hints and purpose-required paths. Presets extend disciplines — they do not replace them."
434
- }
435
- ]
436
- },
437
- {
438
- "id": "symbol-naming",
439
- "title": "Symbol Naming Conventions",
440
- "content": "## Consistency Is the Goal\n\nNaming conventions exist so that anyone — human or AI — can predict what a symbol is called without looking it up. If your payment service is sometimes `#PaymentService`, sometimes `#payment-service`, and sometimes `#paymentSvc`, agents waste tokens searching and developers waste time guessing. Paradigm defines clear naming rules for each symbol type.\n\n## The Base Rule: kebab-case for IDs\n\nAll symbol IDs in `.purpose` files use **kebab-case**:\n\n```yaml\n# Correct\n#payment-service:\n#user-profile:\n#cart-item-list:\n\n# Incorrect\n#PaymentService: # PascalCase is for display, not IDs\n#payment_service: # No underscores\n#paymentService: # No camelCase\n```\n\nThis applies to all five symbol types: `#component-name`, `$flow-name`, `^gate-name`, `!signal-name`, `~aspect-name`.\n\n## Component Naming (`#`)\n\nComponents follow the base kebab-case rule, with one exception: **class-like components** can use PascalCase in display names and code references while keeping kebab-case in the `.purpose` ID:\n\n```yaml\ncomponents:\n #payment-service: # kebab-case ID\n description: PaymentService class # PascalCase in description is fine\n file: PaymentService.ts # PascalCase file names are fine\n```\n\nNaming patterns for components:\n- **Services**: `#noun-service` — `#payment-service`, `#email-service`, `#auth-service`\n- **Handlers**: `#noun-handler` — `#login-handler`, `#webhook-handler`\n- **Stores/State**: `#noun-store` — `#user-store`, `#cart-store`\n- **Utilities**: `#noun-utils` or `#verb-helper` — `#date-utils`, `#format-helper`\n\n## Flow Naming (`$`)\n\nFlows describe processes, so they use **noun-flow** or **verb-noun-flow** patterns:\n\n```yaml\n# Good\n$checkout-flow\n$user-onboarding\n$password-reset-flow\n$daily-report-generation\n\n# Bad\n$doCheckout # Avoid imperative verb-only names\n$flow1 # Non-descriptive\n$theProcessOfCheckingOut # Too verbose\n```\n\nThe `-flow` suffix is optional but recommended for clarity. `$checkout-flow` is more immediately recognizable as a flow than `$checkout` (which could be confused with a component).\n\n## Gate Naming (`^`)\n\nGates use a **resource-role** or **condition** pattern:\n\n```yaml\n# Resource-role pattern\n^authenticated # Base auth\n^project-admin # Admin of a project\n^project-member # Member of a project\n^comment-author # Author of a comment\n^team-owner # Owner of a team\n\n# Condition pattern\n^email-verified # Email has been verified\n^payment-method-exists # User has a payment method\n^subscription-active # Subscription is not expired\n```\n\nAvoid vague names like `^check1` or `^gate-a`. The name should describe what the gate verifies.\n\n## Signal Naming (`!`)\n\nSignals represent events that have already happened, so they use **past-tense** naming:\n\n```yaml\n# Good — past tense describes what happened\n!payment-completed\n!user-created\n!login-failed\n!order-shipped\n!cache-invalidated\n\n# Bad — present tense or imperative\n!process-payment # Sounds like a command, not an event\n!creating-user # Progressive tense is ambiguous\n!login # Too vague — login succeeded or failed?\n```\n\nPast tense makes the intent clear: the signal fires *after* something happened. `!payment-completed` means the payment is done; listeners can react to the completed event.\n\n## Aspect Naming (`~`)\n\nAspects describe rules or qualities, using **adjective** or **past-participle** patterns:\n\n```yaml\n# Good\n~audit-required\n~rate-limited\n~cached\n~encrypted-at-rest\n~idempotent\n\n# Bad\n~doAudit # Imperative — sounds like an action\n~auditStuff # Vague and informal\n~Aspect1 # Non-descriptive\n```\n\nAspect names should read naturally in a sentence: \"This service is ~rate-limited\" or \"This endpoint is ~audit-required.\"\n\n## Summary Table\n\n| Symbol | Pattern | Examples |\n|--------|---------|----------|\n| `#` | `noun-role` | `#payment-service`, `#login-handler` |\n| `$` | `noun-flow` | `$checkout-flow`, `$onboarding` |\n| `^` | `resource-role` or `condition` | `^project-admin`, `^email-verified` |\n| `!` | `past-tense-event` | `!payment-completed`, `!login-failed` |\n| `~` | `adjective` / `past-participle` | `~rate-limited`, `~audit-required` |",
441
- "keyConcepts": [
442
- "All symbol IDs use kebab-case in .purpose files",
443
- "Components: noun-role (#payment-service)",
444
- "Gates: resource-role or condition (^project-admin)",
445
- "Signals: past-tense events (!payment-completed)",
446
- "Aspects: adjectives or past-participles (~rate-limited)"
447
- ],
448
- "quiz": [
449
- {
450
- "id": "q1",
451
- "question": "Which of these signal names follows Paradigm naming conventions?",
452
- "choices": {
453
- "A": "!processPayment",
454
- "B": "!payment-completed",
455
- "C": "!PaymentSignal",
456
- "D": "!creating-user",
457
- "E": "!payment_done"
458
- },
459
- "correct": "B",
460
- "explanation": "Signals use kebab-case and past-tense naming: !payment-completed. Option A uses camelCase and imperative mood. C uses PascalCase. D uses progressive tense. E uses underscores instead of hyphens."
461
- },
462
- {
463
- "id": "q2",
464
- "question": "A flow that handles user registration from form submission to welcome email should be named:",
465
- "choices": {
466
- "A": "$doRegistration",
467
- "B": "$registerUser",
468
- "C": "$user-registration-flow",
469
- "D": "$REGISTRATION",
470
- "E": "$flow_register"
471
- },
472
- "correct": "C",
473
- "explanation": "Flows use kebab-case with a noun-flow pattern. $user-registration-flow is descriptive and follows the convention. Imperative names (doRegistration, registerUser), ALL CAPS, and underscores all violate the naming rules."
474
- },
475
- {
476
- "id": "q3",
477
- "question": "What is wrong with the gate name `^check1`?",
478
- "choices": {
479
- "A": "Nothing — it is valid kebab-case",
480
- "B": "Gates must start with a verb",
481
- "C": "The number 1 is not allowed in symbol names",
482
- "D": "It is non-descriptive — the name should describe what the gate verifies",
483
- "E": "Gates must end with '-gate'"
484
- },
485
- "correct": "D",
486
- "explanation": "Gate names should describe what they verify: ^project-admin, ^email-verified, ^subscription-active. The name ^check1 tells you nothing about what condition is being checked. A developer or AI agent cannot infer the gate's purpose from its name."
487
- },
488
- {
489
- "id": "q4",
490
- "question": "A component wraps the Stripe API for payment processing. Its class is `StripePaymentClient`. What should its .purpose ID be?",
491
- "choices": {
492
- "A": "#StripePaymentClient",
493
- "B": "#stripe-payment-client",
494
- "C": "#stripe_payment_client",
495
- "D": "#stripePaymentClient",
496
- "E": "#STRIPE-CLIENT"
497
- },
498
- "correct": "B",
499
- "explanation": "All symbol IDs in .purpose files use kebab-case: #stripe-payment-client. The PascalCase class name (StripePaymentClient) is fine in code and descriptions, but the ID must be kebab-case."
500
- },
501
- {
502
- "id": "q5",
503
- "question": "Which aspect name reads most naturally in the sentence: 'All financial services are ___'?",
504
- "choices": {
505
- "A": "~doAudit",
506
- "B": "~auditStuff",
507
- "C": "~audit-required",
508
- "D": "~auditService",
509
- "E": "~the-audit-aspect"
510
- },
511
- "correct": "C",
512
- "explanation": "Aspect names should read as adjectives or past-participles: 'All financial services are ~audit-required.' Options A and B are informal/imperative, D sounds like a component name, and E is unnecessarily verbose."
513
- }
514
- ]
515
- },
516
- {
517
- "id": "component-patterns",
518
- "title": "Component Patterns",
519
- "content": "## The Many Faces of `#`\n\nThe `#` component is Paradigm's most used symbol — and intentionally the broadest. It covers everything from a React button to a database service to a CLI command parser. This breadth is a feature, not a bug: it means you never struggle to classify code. But it also means you need **tags** to create meaningful subcategories.\n\nThis lesson covers the major component patterns and when to use each one.\n\n## Feature Components\n\nFeature components represent **user-facing functionality**. They are the things your users interact with — checkout, search, profile editing, notification preferences.\n\n```yaml\n#checkout:\n description: Shopping cart checkout with payment processing\n file: checkout.ts\n tags: [feature, critical, payments]\n flows: [\"$checkout-flow\"]\n signals: [\"!order-placed\"]\n gates: [\"^authenticated\"]\n\n#search:\n description: Full-text search across products and content\n file: search.ts\n tags: [feature, search]\n```\n\nFeature components often have the richest cross-references: they participate in flows, emit signals, and require gates. They are the entry points into your system's behavior.\n\n## Integration Components\n\nIntegration components wrap **third-party services**. They isolate external API calls behind a stable internal interface:\n\n```yaml\n#stripe-service:\n description: Stripe API client for payment processing\n file: stripe-service.ts\n tags: [integration, stripe, payments]\n signals: [\"!payment-completed\", \"!payment-failed\"]\n\n#sendgrid-client:\n description: SendGrid email delivery wrapper\n file: sendgrid.ts\n tags: [integration, sendgrid, email]\n```\n\nThe convention is to tag integrations with both `[integration]` and the service name (`[stripe]`, `[sendgrid]`). This lets you search for all integrations OR for all Stripe-related code specifically.\n\n## State Components\n\nState components manage **data storage and state containers** — databases, caches, in-memory stores, Redux slices:\n\n```yaml\n#user-store:\n description: User data persistence and caching layer\n file: user-store.ts\n tags: [state, users, cache]\n\n#session-cache:\n description: Redis-backed session storage with 24h TTL\n file: session-cache.ts\n tags: [state, session, redis]\n```\n\nState components are often referenced by many other components. Use `paradigm_ripple` before modifying them — a change to `#user-store` might impact every feature that reads user data.\n\n## Infrastructure Components\n\nInfrastructure components provide **foundational services** that other components depend on but users never directly interact with:\n\n```yaml\n#logger:\n description: Structured logging with symbol tagging\n file: logger.ts\n tags: [infrastructure, observability]\n\n#config-loader:\n description: Environment-aware configuration loading\n file: config.ts\n tags: [infrastructure, config]\n\n#database-pool:\n description: PostgreSQL connection pool with health checks\n file: db.ts\n tags: [infrastructure, database, postgres]\n```\n\nInfrastructure components rarely have flows or gates, but they are often the most fragile — many other components depend on them. Check `paradigm_history_fragility` before making changes.\n\n## When to Split vs Combine\n\nA common question: should a large module be one component or several?\n\n**Split when:**\n- The module has distinct responsibilities that could change independently\n- Different parts require different gates or emit different signals\n- The file exceeds ~300 lines and contains clearly separable logic\n\n**Combine when:**\n- The parts are tightly coupled and always change together\n- Splitting would create components with trivial descriptions (\"calls the other half\")\n- The module is a cohesive unit with a single responsibility\n\n```yaml\n# Good split — distinct responsibilities\n#payment-processor:\n description: Charges cards via Stripe\n#payment-validator:\n description: Validates payment amounts and currencies\n\n# Bad split — artificial separation\n#payment-step-1:\n description: First half of payment processing\n#payment-step-2:\n description: Second half of payment processing\n```\n\nIf you cannot describe the component without referencing the other half, they should be one component.",
520
- "keyConcepts": [
521
- "Feature components: user-facing, tagged [feature]",
522
- "Integration components: third-party wrappers, tagged [integration, service-name]",
523
- "State components: data storage, tagged [state]",
524
- "Infrastructure components: foundational services, tagged [infrastructure]",
525
- "Split when responsibilities are distinct; combine when tightly coupled"
526
- ],
527
- "quiz": [
528
- {
529
- "id": "q1",
530
- "question": "A Redis caching layer is used by the user service, the product service, and the search service. How should it be tagged?",
531
- "choices": {
532
- "A": "tags: [feature, redis] — because users interact with cached data",
533
- "B": "tags: [integration, redis] — because Redis is a third-party service",
534
- "C": "tags: [state, cache, redis] — because it manages data storage",
535
- "D": "tags: [infrastructure, redis] — because it is a foundational service",
536
- "E": "Both C and D are acceptable, depending on whether caching is the primary purpose or a supporting capability"
537
- },
538
- "correct": "E",
539
- "explanation": "If the component's primary purpose is data caching (storing and retrieving cached data), tags: [state, cache, redis] is appropriate. If it is more of a foundational service that provides caching as infrastructure, tags: [infrastructure, cache, redis] fits. Both are valid interpretations."
540
- },
541
- {
542
- "id": "q2",
543
- "question": "You have a 500-line module that handles payment processing AND sends email receipts. What should you do?",
544
- "choices": {
545
- "A": "Keep it as one component — splitting would be premature optimization",
546
- "B": "Split into #payment-processor and #receipt-emailer — they have distinct responsibilities",
547
- "C": "Create a $payment-receipt-flow instead of splitting",
548
- "D": "Add more tags to cover both responsibilities in one component",
549
- "E": "Move the email logic into the logger"
550
- },
551
- "correct": "B",
552
- "explanation": "Payment processing and email sending are distinct responsibilities that could change independently (e.g., switching email providers without touching payment logic). The module is also large (500 lines). Splitting into two focused components follows the 'split when responsibilities are distinct' guideline."
553
- },
554
- {
555
- "id": "q3",
556
- "question": "Why should you check paradigm_history_fragility before modifying infrastructure components?",
557
- "choices": {
558
- "A": "Because infrastructure components have more lines of code",
559
- "B": "Because many other components depend on them, making changes high-risk",
560
- "C": "Because infrastructure components are never tested",
561
- "D": "Because the fragility check automatically creates a backup",
562
- "E": "Because infrastructure tags prevent direct modification"
563
- },
564
- "correct": "B",
565
- "explanation": "Infrastructure components (logger, config-loader, database-pool) are foundational — many other components depend on them. A breaking change to #database-pool could cascade across the entire application. Fragility analysis warns you about this risk before you make changes."
566
- },
567
- {
568
- "id": "q4",
569
- "question": "What is wrong with splitting a payment module into `#payment-step-1` and `#payment-step-2`?",
570
- "choices": {
571
- "A": "Components cannot have numbers in their names",
572
- "B": "There should be three components minimum",
573
- "C": "The names are non-descriptive and the split is artificial — neither component has an independent responsibility",
574
- "D": "Steps should be defined as a flow, not as components",
575
- "E": "The hyphen before the number violates kebab-case"
576
- },
577
- "correct": "C",
578
- "explanation": "If you cannot describe a component without referencing 'the other half,' the split is artificial. #payment-step-1 and #payment-step-2 are not independent responsibilities — they are an arbitrary division of a single unit. Keep them as one component with a clear description."
579
- }
580
- ]
581
- },
582
- {
583
- "id": "signal-patterns",
584
- "title": "Signal Patterns",
585
- "content": "## Events That Drive Side Effects\n\nSignals (`!`) are Paradigm's mechanism for documenting **decoupled communication**. When a component emits a signal, it announces that something happened without caring who listens. This decoupling is fundamental to maintainable systems — the payment service should not know about the email service, the analytics tracker, or the loyalty points calculator. It just announces `!payment-completed` and moves on.\n\n## Signal Categories\n\n### Business Signals\n\nBusiness signals represent **domain events** — things that matter to the business:\n\n```yaml\n!order-placed:\n description: A new order has been successfully created\n emitters: [\"#order-service\"]\n category: business\n data:\n orderId: string\n userId: string\n total: number\n\n!subscription-renewed:\n description: A recurring subscription payment succeeded\n emitters: [\"#billing-service\"]\n category: business\n\n!user-upgraded:\n description: User upgraded from free to paid plan\n emitters: [\"#plan-service\"]\n category: business\n```\n\nBusiness signals are the most important category. They define the key moments in your application's lifecycle. If you had to explain your system to a new team member, you would list these events.\n\n### System Signals\n\nSystem signals represent **infrastructure events** — things that matter to operations:\n\n```yaml\n!cache-invalidated:\n description: A cache entry or cache region was cleared\n emitters: [\"#cache-manager\"]\n category: system\n data:\n region: string\n reason: string\n\n!database-failover:\n description: Primary database failed, switched to replica\n emitters: [\"#database-pool\"]\n category: system\n severity: warn\n\n!rate-limit-exceeded:\n description: A user or IP exceeded the API rate limit\n emitters: [\"#rate-limiter\"]\n category: system\n```\n\nSystem signals are consumed by monitoring, alerting, and health-check systems rather than by business logic.\n\n### Security Signals\n\nSecurity signals represent **authentication and authorization events**:\n\n```yaml\n!login-failed:\n description: User provided invalid credentials\n emitters: [\"#auth-handler\"]\n category: security\n data:\n email: string\n reason: string\n ipAddress: string\n\n!permission-denied:\n description: Authenticated user tried to access a resource they lack permission for\n emitters: [\"#gate-middleware\"]\n category: security\n\n!suspicious-activity:\n description: Unusual access pattern detected (multiple failed logins, geographic anomaly)\n emitters: [\"#security-monitor\"]\n category: security\n severity: error\n```\n\nSecurity signals are critical for audit trails and intrusion detection. They should always include enough data to reconstruct what happened.\n\n## Emitters and Listeners\n\nEvery signal has one or more **emitters** — the components that fire the event:\n\n```yaml\n!payment-completed:\n emitters: [\"#payment-service\", \"#manual-charge-handler\"]\n```\n\nListeners are not defined on the signal itself — they are documented on the listening component:\n\n```yaml\n#email-service:\n description: Sends transactional emails\n listens: [\"!payment-completed\", \"!user-created\", \"!password-reset-requested\"]\n```\n\nThis asymmetry is intentional. The emitter must know it is emitting (so it is declared on the signal). But the listener can be added or removed without changing the signal definition — true decoupling.\n\n## Signals for Decoupled Side Effects\n\nThe power of signals is in the side effects they enable without direct coupling:\n\n```\n!order-placed is emitted by #order-service\n → #email-service listens → sends confirmation email\n → #analytics-tracker listens → records conversion event\n → #loyalty-service listens → awards loyalty points\n → #inventory-service listens → decrements stock\n```\n\nThe order service knows nothing about these four listeners. You can add a fifth listener (say, `#slack-notifier`) without touching the order service at all. This is the architectural benefit of signal-based communication.\n\n## The Data Field\n\nSignals can declare a `data` schema describing the payload emitted with the event:\n\n```yaml\n!user-created:\n description: A new user account was registered\n emitters: [\"#auth-handler\"]\n category: business\n data:\n userId: string\n email: string\n registrationSource: string\n```\n\nThe data field is documentation, not runtime validation. It tells listeners what to expect in the event payload, reducing the need to read the emitter's source code.",
586
- "keyConcepts": [
587
- "Business signals: domain events (order-placed, subscription-renewed)",
588
- "System signals: infrastructure events (cache-invalidated, database-failover)",
589
- "Security signals: auth events (login-failed, permission-denied)",
590
- "Emitters are declared on signals; listeners are declared on components",
591
- "Signals enable decoupled side effects — emitters do not know about listeners"
592
- ],
593
- "quiz": [
594
- {
595
- "id": "q1",
596
- "question": "The order service needs to send a confirmation email after an order is placed. What is the correct architecture?",
597
- "choices": {
598
- "A": "The order service directly calls the email service's sendEmail method",
599
- "B": "The order service emits !order-placed; the email service listens to that signal",
600
- "C": "The email service polls the order service every 5 seconds for new orders",
601
- "D": "A $send-email-flow orchestrates the interaction",
602
- "E": "The order service includes email logic internally"
603
- },
604
- "correct": "B",
605
- "explanation": "Signal-based communication decouples the order service from the email service. The order service emits !order-placed and does not know who listens. The email service independently listens for that signal. This means you can add more listeners (analytics, loyalty points) without touching the order service."
606
- },
607
- {
608
- "id": "q2",
609
- "question": "Where are signal listeners documented in Paradigm?",
610
- "choices": {
611
- "A": "On the signal definition in the 'listeners' field",
612
- "B": "On the listening component in a 'listens' field",
613
- "C": "In portal.yaml under a 'listeners' section",
614
- "D": "In .paradigm/config.yaml",
615
- "E": "They are not documented — only emitters are tracked"
616
- },
617
- "correct": "B",
618
- "explanation": "Listeners are documented on the component that listens, using a 'listens' field. This asymmetry is intentional — the emitter declares what it emits (on the signal), and each listener independently declares what it consumes (on the component). This maintains true decoupling."
619
- },
620
- {
621
- "id": "q3",
622
- "question": "A failed login attempt from an unknown IP should emit what category of signal?",
623
- "choices": {
624
- "A": "business — it affects the user's experience",
625
- "B": "system — it is an infrastructure event",
626
- "C": "security — it is an authentication event relevant to audit trails",
627
- "D": "error — it indicates a system failure",
628
- "E": "It should not emit a signal — failed logins are expected"
629
- },
630
- "correct": "C",
631
- "explanation": "Failed login attempts are security events. They are critical for audit trails, intrusion detection, and monitoring suspicious activity. The signal (!login-failed) should include data like email, reason, and IP address to support security analysis."
632
- },
633
- {
634
- "id": "q4",
635
- "question": "A system currently has !order-placed consumed by 3 listeners. A developer needs to add a Slack notification when orders are placed. What must change?",
636
- "choices": {
637
- "A": "The !order-placed signal definition must be updated to list the Slack notifier as an emitter",
638
- "B": "The $order-flow must add a Slack notification step",
639
- "C": "Only the new #slack-notifier component needs a 'listens: [\"!order-placed\"]' declaration — nothing else changes",
640
- "D": "The #order-service must be modified to call the Slack API",
641
- "E": "portal.yaml must add a ^slack-authorized gate"
642
- },
643
- "correct": "C",
644
- "explanation": "This is the power of signal-based decoupling. Adding a new listener requires only defining the new component with its 'listens' field. The signal definition, the emitting component, and all existing listeners remain untouched."
645
- }
646
- ]
647
- },
648
- {
649
- "id": "cross-cutting-concerns",
650
- "title": "Cross-Cutting Concerns",
651
- "content": "## Rules That Span the System\n\nSome requirements do not belong to any single component. \"All financial operations must be audited.\" \"All API endpoints must be rate-limited.\" \"All sensitive data must be encrypted at rest.\" These are **cross-cutting concerns** — rules that apply across multiple components as a structural pattern rather than a per-request check.\n\nParadigm models cross-cutting concerns as **aspects** (`~`). Unlike gates (which check access per request) or signals (which fire per event), aspects describe ongoing constraints that are enforced by code patterns, middleware, decorators, or architectural choices.\n\n## Common Aspect Patterns\n\n### Audit Trails\n\n```yaml\n~audit-required:\n description: All financial operations must log to the audit trail with user, action, and timestamp\n anchors:\n - src/middleware/audit.ts:15-35\n - src/decorators/auditable.ts:1-20\n applies-to: [\"#*Service\"]\n enforcement: middleware\n tags: [compliance, security]\n```\n\nAudit aspects ensure that certain operations leave a trail. The anchors point to the middleware or decorator that performs the logging. Any service matching `#*Service` is expected to use this middleware.\n\n### Rate Limiting\n\n```yaml\n~rate-limited:\n description: API endpoints enforce per-user rate limits (100 req/min default)\n anchors:\n - src/middleware/rate-limiter.ts:10-45\n applies-to: [\"#*-handler\", \"#*-endpoint\"]\n enforcement: middleware\n tags: [security, performance]\n```\n\nRate limiting protects against abuse. The aspect documents the default limit (100 req/min) and points to the middleware that enforces it.\n\n### Caching\n\n```yaml\n~cached:\n description: Read-heavy queries use a 5-minute TTL cache\n anchors:\n - src/lib/cache-wrapper.ts:20-55\n applies-to: [\"#*-query\"]\n enforcement: wrapper-function\n tags: [performance]\n```\n\n### Input Validation\n\n```yaml\n~validated:\n description: All API inputs are validated against defined schemas before processing\n anchors:\n - src/middleware/validate.ts:1-30\n - src/schemas/index.ts:1-50\n applies-to: [\"#*-handler\"]\n enforcement: middleware\n tags: [security, data-integrity]\n```\n\n### Idempotency\n\n```yaml\n~idempotent:\n description: Mutation endpoints use idempotency keys to prevent duplicate processing\n anchors:\n - src/middleware/idempotency.ts:15-60\n applies-to: [\"#*-handler\"]\n enforcement: middleware\n tags: [reliability, payments]\n```\n\n### Encryption at Rest\n\n```yaml\n~encrypted-at-rest:\n description: Sensitive fields are encrypted before storage using AES-256-GCM\n anchors:\n - src/lib/encryption.ts:10-45\n - src/models/base-model.ts:30-50\n applies-to: [\"#*-store\"]\n enforcement: model-hook\n tags: [security, compliance]\n```\n\n## The applies-to Glob Pattern\n\nThe `applies-to` field uses glob patterns to declare which symbols the aspect covers:\n\n| Pattern | Matches |\n|---------|---------|\n| `#*Service` | `#payment-service`, `#email-service`, `#auth-service` |\n| `#*-handler` | `#login-handler`, `#webhook-handler` |\n| `#*-store` | `#user-store`, `#session-store` |\n| `#*` | All components (use sparingly) |\n\nWhen an AI agent creates a new component matching a pattern, it should check whether any aspects apply. If `~rate-limited` applies to `#*-handler` and the agent creates `#upload-handler`, the agent should ensure rate limiting middleware is applied.\n\n## Aspects vs Other Symbols\n\nUnderstanding when to use each symbol avoids misclassification:\n\n| If the rule... | Use |\n|----------------|-----|\n| Checks a specific condition per request or operation | `^` Gate |\n| Fires an event that triggers side effects | `!` Signal |\n| Applies the same pattern across many components | `~` Aspect |\n| Describes a multi-step process | `$` Flow |\n\nA rate limiter is an aspect (it applies the same pattern to all handlers), not a gate (it does not check authorization). An audit log is an aspect (it applies to all financial services), not a signal (it is a structural requirement, not a one-time event).\n\n## Maintaining Aspects During Refactors\n\nAspects are the most maintenance-sensitive symbol because their anchors contain file paths and line numbers. When you refactor:\n\n1. Run `paradigm_aspect_check` before the refactor to know the current state.\n2. Make your code changes.\n3. Run `paradigm_aspect_check` again to find broken anchors.\n4. Update the anchors in the `.purpose` file to point to the new locations.\n\nThis is a conscious trade-off: anchors create maintenance burden, but they prevent the much worse problem of unverified rules that silently stop being enforced.",
652
- "keyConcepts": [
653
- "Cross-cutting concerns apply across multiple components as patterns",
654
- "Common aspects: audit trails, rate limiting, caching, validation, encryption, idempotency",
655
- "applies-to uses glob patterns to declare which symbols are covered",
656
- "Aspects differ from gates (per-request) and signals (per-event) — they are structural",
657
- "Anchors require maintenance during refactors but prevent silent rule abandonment"
658
- ],
659
- "quiz": [
660
- {
661
- "id": "q1",
662
- "question": "All API handlers must validate input against a defined schema. Should this be modeled as a gate, signal, or aspect?",
663
- "choices": {
664
- "A": "^ gate — it checks a condition before processing",
665
- "B": "! signal — it fires when validation fails",
666
- "C": "~ aspect — it is a structural pattern applied across all handlers",
667
- "D": "$ flow — it is a step in the request processing flow",
668
- "E": "# component — it is a validation utility"
669
- },
670
- "correct": "C",
671
- "explanation": "Input validation across all handlers is a cross-cutting concern — the same pattern (validate against a schema) applies to every handler. This is an aspect (~validated), not a gate (gates check conditions like authorization, not input format) or a signal (validation is a structural requirement, not an event)."
672
- },
673
- {
674
- "id": "q2",
675
- "question": "An aspect `~cached` has `applies-to: [\"#*-query\"]`. You create `#user-query` without applying caching. What is the recommended action?",
676
- "choices": {
677
- "A": "Nothing — aspects are just documentation",
678
- "B": "Delete the ~cached aspect since it does not apply universally",
679
- "C": "Apply the caching pattern to #user-query, since it matches the applies-to pattern",
680
- "D": "Rename #user-query to #user-fetch to avoid matching the pattern",
681
- "E": "Add an exception for #user-query in the aspect definition"
682
- },
683
- "correct": "C",
684
- "explanation": "When a new component matches an aspect's applies-to pattern, the aspect should be applied. If ~cached applies to all #*-query components, then #user-query should use the caching pattern. If there is a genuine reason to exempt it, document that exception rather than working around the naming."
685
- },
686
- {
687
- "id": "q3",
688
- "question": "Why is a rate limiter classified as an aspect (~rate-limited) rather than a gate (^rate-limited)?",
689
- "choices": {
690
- "A": "Because rate limiters are implemented in middleware",
691
- "B": "Because rate limiters do not return 403 status codes",
692
- "C": "Because rate limiting is a structural pattern applied across many endpoints, not a per-resource authorization check",
693
- "D": "Because rate limiters do not require authentication",
694
- "E": "Because the ~ prefix is alphabetically closer to 'rate'"
695
- },
696
- "correct": "C",
697
- "explanation": "Gates check specific conditions per request — 'is this user allowed to access this resource?' or 'is this feature enabled?' Rate limiting is a different concern — it applies the same pattern (request counting and throttling) across many endpoints as a structural rule. This cross-cutting nature makes it an aspect."
698
- },
699
- {
700
- "id": "q4",
701
- "question": "After a large refactor that moved files, what is the correct procedure for maintaining aspects?",
702
- "choices": {
703
- "A": "Delete all aspects and recreate them from scratch",
704
- "B": "Run paradigm_aspect_check to find broken anchors, then update the anchor paths in .purpose files",
705
- "C": "Aspects automatically update their anchors when files move",
706
- "D": "Ignore broken anchors — they will fix themselves on the next paradigm scan",
707
- "E": "Convert all aspects to gates since gates do not have anchors"
708
- },
709
- "correct": "B",
710
- "explanation": "After refactoring, run paradigm_aspect_check to identify which anchors now point to moved or renamed files. Then update the anchors in the .purpose files to reflect the new file paths and line numbers. This maintenance is the trade-off for having verifiable enforcement code."
711
- }
712
- ]
713
- },
714
- {
715
- "id": "architecture-review",
716
- "title": "Putting It All Together",
717
- "content": "## Building a Complete Feature\n\nYou have learned flows, gates, aspects, disciplines, naming conventions, component patterns, signal patterns, and cross-cutting concerns. Now let us walk through building a complete feature from scratch, using every tool in the Paradigm toolkit. The feature: **a team invitation system** where team admins can invite new members via email.\n\n## Step 1: Identify Components\n\nStart by listing the code units you will need:\n\n```yaml\n#invitation-service:\n description: Creates and manages team invitations\n tags: [feature, teams]\n\n#invitation-email:\n description: Sends invitation emails via SendGrid\n tags: [integration, sendgrid, email]\n\n#invitation-token:\n description: Generates and validates secure invitation tokens\n tags: [infrastructure, security]\n\n#invitation-store:\n description: Persists invitations with status tracking\n tags: [state, teams]\n```\n\nFour components — one feature, one integration, one infrastructure, one state. Each has a clear responsibility and appropriate tags.\n\n## Step 2: Define the Flow\n\nThe invitation process spans all four components in sequence:\n\n```yaml\n$team-invitation-flow:\n description: Admin invites a user, email is sent, user accepts and joins team\n steps:\n - component: \"#invitation-service\"\n action: create-invitation\n description: Validates admin permissions and creates invitation record\n - component: \"#invitation-token\"\n action: generate-token\n description: Creates a cryptographically secure token with 7-day expiry\n - component: \"#invitation-store\"\n action: persist-invitation\n description: Saves invitation with pending status\n - component: \"#invitation-email\"\n action: send-invite\n description: Sends email with accept link containing the token\n signals: [\"!invitation-sent\", \"!invitation-accepted\"]\n gates: [\"^authenticated\", \"^team-admin\"]\n```\n\n## Step 3: Add Gates\n\nTwo gates are needed. First, check `portal.yaml` for existing gates. `^authenticated` likely exists. `^team-admin` may need to be created:\n\n```yaml\n# In portal.yaml\ngates:\n ^team-admin:\n description: User must be an admin of the specified team\n check: team.admins.includes(req.user.id)\n type: role\n requires: [^authenticated]\n effects: []\n\nroutes:\n \"POST /api/teams/:id/invitations\": [^authenticated, ^team-admin]\n \"POST /api/invitations/:token/accept\": [^authenticated]\n \"GET /api/teams/:id/invitations\": [^authenticated, ^team-admin]\n \"DELETE /api/invitations/:id\": [^authenticated, ^team-admin]\n```\n\nNotice that accepting an invitation only requires `^authenticated` — any logged-in user with a valid token can accept. But creating, listing, and deleting invitations requires `^team-admin`.\n\n## Step 4: Define Signals\n\n```yaml\n!invitation-sent:\n description: An invitation email was successfully sent to a prospective team member\n emitters: [\"#invitation-service\"]\n category: business\n data:\n invitationId: string\n teamId: string\n email: string\n\n!invitation-accepted:\n description: A user accepted a team invitation and joined the team\n emitters: [\"#invitation-service\"]\n category: business\n data:\n invitationId: string\n teamId: string\n userId: string\n```\n\nThese business signals enable decoupled side effects — an analytics tracker can listen for `!invitation-accepted` to track conversion rates, and a notification service can alert existing team members.\n\n## Step 5: Apply Aspects\n\nCheck which aspects apply to the new components:\n\n- `~audit-required` applies to `#*Service` → `#invitation-service` is covered. Ensure the audit middleware is applied.\n- `~rate-limited` applies to `#*-handler` → Not directly applicable here (no handler component), but the API route should go through the rate limiter.\n- `~validated` applies to `#*-handler` → The invitation endpoint should validate input (email format, team existence).\n\n## Step 6: Write the .purpose File\n\nAssemble everything into `src/invitations/.purpose`:\n\n```yaml\nname: Team Invitations\ndescription: Team admin invitation system with email delivery and token-based acceptance\ncontext:\n - Invitation tokens expire after 7 days\n - Maximum 50 pending invitations per team\n - Uses SendGrid for email delivery\n\ncomponents:\n #invitation-service:\n description: Creates and manages team invitations\n file: invitation-service.ts\n tags: [feature, teams]\n flows: [\"$team-invitation-flow\"]\n signals: [\"!invitation-sent\", \"!invitation-accepted\"]\n gates: [\"^authenticated\", \"^team-admin\"]\n aspects: [\"~audit-required\"]\n # ... (remaining components)\n\nflows:\n $team-invitation-flow:\n # ... (as defined above)\n\nsignals:\n !invitation-sent:\n # ... (as defined above)\n !invitation-accepted:\n # ... (as defined above)\n```\n\n## Step 7: Validate\n\nBefore writing any implementation code, validate the Paradigm definitions:\n\n1. `paradigm_purpose_validate` — Checks the .purpose file for schema errors.\n2. `paradigm_flow_check` — Verifies the flow references valid components.\n3. `paradigm_aspect_check` — Confirms aspect anchors are valid for applied aspects.\n4. `paradigm_ripple` — Shows what existing code is affected by the new components.\n\n## The Pattern\n\nEvery feature follows this pattern: **identify components** → **define flows** → **add gates** → **define signals** → **apply aspects** → **write .purpose** → **validate** → **implement**. The implementation comes last — after the architecture is documented and validated. This front-loaded documentation pays dividends: AI agents can navigate the new feature immediately, security is defined before code, and the team has a clear map of what will be built.",
718
- "keyConcepts": [
719
- "Feature building follows: components → flows → gates → signals → aspects → .purpose → validate → implement",
720
- "Implementation comes LAST, after architecture is documented",
721
- "Check existing aspects with applies-to patterns for new components",
722
- "Validate definitions before writing code",
723
- "paradigm_ripple shows impact on existing code"
724
- ],
725
- "quiz": [
726
- {
727
- "id": "q1",
728
- "question": "A team invitation feature uses a token to accept invitations. The token was created by an admin. Should the accept action require the ^team-admin gate?",
729
- "choices": {
730
- "A": "Yes — only admins should be able to modify team membership",
731
- "B": "No — the invitation token itself serves as proof of authorization, so any authenticated user with a valid token should be able to accept",
732
- "C": "Yes — ^team-admin is always required for team-related operations",
733
- "D": "No — acceptance actions should be completely public with no gates at all",
734
- "E": "It depends on whether the token has expired"
735
- },
736
- "correct": "B",
737
- "explanation": "The invitation token itself is the authorization. The admin already approved the invitation by creating it. Any authenticated user who possesses the valid token (received via email) should be able to accept. Requiring ^team-admin would make the feature useless — the invitee is not yet a team member, let alone an admin. The token acts as a delegated authorization from the admin."
738
- },
739
- {
740
- "id": "q2",
741
- "question": "The walkthrough creates four components. Put them in the correct order of the $team-invitation-flow steps.",
742
- "choices": {
743
- "A": "#invitation-email → #invitation-token → #invitation-store → #invitation-service",
744
- "B": "#invitation-service → #invitation-token → #invitation-store → #invitation-email",
745
- "C": "#invitation-store → #invitation-service → #invitation-email → #invitation-token",
746
- "D": "#invitation-token → #invitation-email → #invitation-service → #invitation-store",
747
- "E": "#invitation-service → #invitation-email → #invitation-token → #invitation-store"
748
- },
749
- "correct": "B",
750
- "explanation": "The flow is: (1) #invitation-service validates and creates, (2) #invitation-token generates the secure token, (3) #invitation-store persists the invitation, (4) #invitation-email sends the email. The service orchestrates, the token is needed before storage, and the email is sent last."
751
- },
752
- {
753
- "id": "q3",
754
- "question": "The feature building pattern ends with 'validate → implement'. Why does implementation come last?",
755
- "choices": {
756
- "A": "Because Paradigm generates the implementation code automatically",
757
- "B": "Because implementation is the least important step",
758
- "C": "Because documenting architecture first ensures security is defined before code, AI agents can navigate immediately, and the team has a clear map",
759
- "D": "Because .purpose files must be committed before any source files",
760
- "E": "Because the validator rejects implementations that do not match definitions"
761
- },
762
- "correct": "C",
763
- "explanation": "Front-loading documentation has three benefits: (1) security gates are defined in portal.yaml before handler code exists, preventing auth as an afterthought, (2) AI agents can navigate the feature structure immediately, and (3) the team has a validated architectural map before writing any implementation."
764
- },
765
- {
766
- "id": "q4",
767
- "question": "After defining all components for the invitation feature, you run paradigm_ripple on #invitation-service. What is this checking?",
768
- "choices": {
769
- "A": "Whether the invitation service's code compiles",
770
- "B": "Whether the service name follows naming conventions",
771
- "C": "What existing code and symbols would be affected by changes to #invitation-service",
772
- "D": "Whether the service has enough test coverage",
773
- "E": "Whether the service's dependencies are installed"
774
- },
775
- "correct": "C",
776
- "explanation": "paradigm_ripple analyzes the dependency graph to show what would be impacted if #invitation-service changes. This reveals connections to flows, signals, gates, and other components — helping you understand the blast radius before implementation."
777
- },
778
- {
779
- "id": "q5",
780
- "question": "You notice that ~audit-required applies-to [\"#*Service\"] and your new #invitation-service matches this pattern. What should you do?",
781
- "choices": {
782
- "A": "Rename #invitation-service to #invitation-handler to avoid the aspect",
783
- "B": "Delete the ~audit-required aspect since it is too broad",
784
- "C": "Ensure the audit middleware is applied to #invitation-service and add aspects: [\"~audit-required\"] to its definition",
785
- "D": "Nothing — aspects are enforced automatically by Paradigm",
786
- "E": "Create a new aspect ~invitation-audit specific to this service"
787
- },
788
- "correct": "C",
789
- "explanation": "When a new component matches an existing aspect's applies-to pattern, you should apply that aspect. This means ensuring the enforcement code (audit middleware) is used by the new service and documenting the relationship by adding aspects: [\"~audit-required\"] to the component's .purpose definition."
790
- }
791
- ]
792
- }
793
- ]
794
- }