@rubytech/create-maxy-code 0.1.62 → 0.1.64

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 (689) hide show
  1. package/dist/__tests__/installer-specialist-registration.test.js +112 -0
  2. package/dist/index.js +22 -0
  3. package/dist/specialist-registration.js +78 -0
  4. package/package.json +1 -1
  5. package/payload/platform/plugins/admin/PLUGIN.md +22 -0
  6. package/payload/platform/plugins/admin/hooks/__tests__/turn-completed-graph-write.test.sh +50 -13
  7. package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +22 -21
  8. package/payload/platform/plugins/contacts/PLUGIN.md +9 -0
  9. package/payload/platform/plugins/docs/references/admin-session.md +57 -8
  10. package/payload/platform/plugins/docs/references/platform.md +4 -0
  11. package/payload/platform/plugins/email/PLUGIN.md +9 -0
  12. package/payload/platform/plugins/memory/PLUGIN.md +37 -0
  13. package/payload/platform/plugins/memory/mcp/dist/index.js +3 -3
  14. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  15. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/live-schema-source.test.js +137 -75
  16. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/live-schema-source.test.js.map +1 -1
  17. package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.d.ts +0 -17
  18. package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.d.ts.map +1 -1
  19. package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.js +32 -4
  20. package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.js.map +1 -1
  21. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts +65 -0
  22. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts.map +1 -0
  23. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js +182 -0
  24. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js.map +1 -0
  25. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection.test.js +8 -8
  26. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection.test.js.map +1 -1
  27. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.d.ts +2 -0
  28. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.d.ts.map +1 -0
  29. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.js +241 -0
  30. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/log-ingest.test.js.map +1 -0
  31. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.d.ts.map +1 -1
  32. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js +9 -0
  33. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js.map +1 -1
  34. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.d.ts +1 -1
  35. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.d.ts.map +1 -1
  36. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.js +9 -1
  37. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.js.map +1 -1
  38. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.d.ts.map +1 -1
  39. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.js +10 -2
  40. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-memory-expunge.js.map +1 -1
  41. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.d.ts +1 -1
  42. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.d.ts.map +1 -1
  43. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.js +5 -1
  44. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-add.js.map +1 -1
  45. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.d.ts +1 -1
  46. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.d.ts.map +1 -1
  47. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.js +5 -1
  48. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-denylist-remove.js.map +1 -1
  49. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts.map +1 -1
  50. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js +4 -0
  51. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js.map +1 -1
  52. package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.d.ts.map +1 -1
  53. package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.js +4 -0
  54. package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.js.map +1 -1
  55. package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.d.ts.map +1 -1
  56. package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.js +4 -0
  57. package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.js.map +1 -1
  58. package/payload/platform/plugins/memory/mcp/dist/tools/memory-edit-attachment.d.ts.map +1 -1
  59. package/payload/platform/plugins/memory/mcp/dist/tools/memory-edit-attachment.js +4 -0
  60. package/payload/platform/plugins/memory/mcp/dist/tools/memory-edit-attachment.js.map +1 -1
  61. package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.d.ts.map +1 -1
  62. package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.js +4 -0
  63. package/payload/platform/plugins/memory/mcp/dist/tools/memory-empty-trash.js.map +1 -1
  64. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.d.ts.map +1 -1
  65. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.js +4 -0
  66. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.js.map +1 -1
  67. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-web.d.ts.map +1 -1
  68. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-web.js +4 -0
  69. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-web.js.map +1 -1
  70. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts.map +1 -1
  71. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +5 -0
  72. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
  73. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.d.ts.map +1 -1
  74. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.js +4 -0
  75. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.js.map +1 -1
  76. package/payload/platform/plugins/memory/mcp/dist/tools/memory-rename-attachment.d.ts.map +1 -1
  77. package/payload/platform/plugins/memory/mcp/dist/tools/memory-rename-attachment.js +4 -0
  78. package/payload/platform/plugins/memory/mcp/dist/tools/memory-rename-attachment.js.map +1 -1
  79. package/payload/platform/plugins/memory/mcp/dist/tools/memory-restore.d.ts.map +1 -1
  80. package/payload/platform/plugins/memory/mcp/dist/tools/memory-restore.js +4 -0
  81. package/payload/platform/plugins/memory/mcp/dist/tools/memory-restore.js.map +1 -1
  82. package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.d.ts.map +1 -1
  83. package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js +5 -0
  84. package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js.map +1 -1
  85. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts.map +1 -1
  86. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +6 -0
  87. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
  88. package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.d.ts.map +1 -1
  89. package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.js +4 -0
  90. package/payload/platform/plugins/memory/mcp/dist/tools/profile-delete.js.map +1 -1
  91. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts.map +1 -1
  92. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +4 -0
  93. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
  94. package/payload/platform/plugins/memory/mcp/vitest.config.ts +10 -3
  95. package/payload/platform/plugins/outlook/PLUGIN.md +7 -0
  96. package/payload/platform/plugins/replicate/PLUGIN.md +3 -0
  97. package/payload/platform/plugins/scheduling/PLUGIN.md +8 -0
  98. package/payload/platform/plugins/tasks/PLUGIN.md +14 -0
  99. package/payload/platform/plugins/telegram/PLUGIN.md +3 -0
  100. package/payload/platform/plugins/waitlist/PLUGIN.md +7 -0
  101. package/payload/platform/plugins/whatsapp/PLUGIN.md +12 -0
  102. package/payload/platform/plugins/workflows/PLUGIN.md +8 -0
  103. package/payload/platform/services/claude-session-manager/dist/index.js +43 -1
  104. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  105. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +33 -0
  106. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  107. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +214 -59
  108. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  109. package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts +23 -0
  110. package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts.map +1 -0
  111. package/payload/platform/services/claude-session-manager/dist/specialist-drift.js +141 -0
  112. package/payload/platform/services/claude-session-manager/dist/specialist-drift.js.map +1 -0
  113. package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts +13 -2
  114. package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts.map +1 -1
  115. package/payload/platform/services/claude-session-manager/dist/tool-surface.js +150 -37
  116. package/payload/platform/services/claude-session-manager/dist/tool-surface.js.map +1 -1
  117. package/payload/platform/services/claude-session-manager/dist/types.d.ts +5 -0
  118. package/payload/platform/services/claude-session-manager/dist/types.d.ts.map +1 -1
  119. package/payload/platform/templates/agents/admin/IDENTITY.md +1 -1
  120. package/payload/premium-plugins/real-agent/BUNDLE.md +2 -4
  121. package/payload/premium-plugins/real-agent/agents/compliance.md +1 -1
  122. package/payload/premium-plugins/real-agent/agents/valuer.md +1 -2
  123. package/payload/premium-plugins/real-agent/plugins/epc/.claude-plugin/plugin.json +3 -3
  124. package/payload/premium-plugins/real-agent/plugins/listings/.claude-plugin/plugin.json +1 -1
  125. package/payload/premium-plugins/real-agent/plugins/listings/PLUGIN.md +1 -3
  126. package/payload/premium-plugins/real-agent/plugins/listings/skills/new-instruction/SKILL.md +11 -12
  127. package/payload/premium-plugins/real-agent/plugins/loop/PLUGIN.md +27 -0
  128. package/payload/premium-plugins/real-agent/plugins/preval/.claude-plugin/plugin.json +1 -1
  129. package/payload/premium-plugins/real-agent/plugins/preval/PLUGIN.md +16 -8
  130. package/payload/premium-plugins/real-agent/plugins/preval/hooks/preval-prompt-required.sh +140 -0
  131. package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/SKILL.md +92 -40
  132. package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/references/__tests__/adherence.test.py +373 -0
  133. package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/references/render.py +299 -115
  134. package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/references/template-inputs.schema.json +34 -19
  135. package/payload/premium-plugins/real-agent/plugins/preval/skills/property-preval/references/template.html +88 -19
  136. package/payload/premium-plugins/real-agent/plugins/property-data/PLUGIN.md +22 -0
  137. package/payload/premium-plugins/real-agent/specs/03-new-instruction.md +8 -12
  138. package/payload/server/{chunk-2IKQERHN.js → chunk-S6PQA6Q4.js} +43 -34
  139. package/payload/server/maxy-edge.js +1 -1
  140. package/payload/server/public/assets/{admin-DhN3G8W7.js → admin-ymReS1mN.js} +1 -1
  141. package/payload/server/public/assets/{data-B2ZVXOcE.js → data-D6U2e85B.js} +1 -1
  142. package/payload/server/public/assets/{graph-BAMGPHrK.js → graph-C274PN27.js} +1 -1
  143. package/payload/server/public/assets/{graph-labels-D9eBbvxo.js → graph-labels-DQFzd1FY.js} +1 -1
  144. package/payload/server/public/assets/{page-DjdVMWCz.js → page-D-OLjort.js} +1 -1
  145. package/payload/server/public/assets/{page-CV27Al6Z.js → page-DFFt9_Q0.js} +1 -1
  146. package/payload/server/public/data.html +3 -3
  147. package/payload/server/public/graph.html +3 -3
  148. package/payload/server/public/index.html +4 -4
  149. package/payload/server/server.js +2 -2
  150. package/payload/platform/plugins/brochures/.claude-plugin/plugin.json +0 -8
  151. package/payload/platform/plugins/brochures/PLUGIN.md +0 -38
  152. package/payload/platform/plugins/brochures/commands/make-brochure.md +0 -11
  153. package/payload/platform/plugins/brochures/skills/a4-print-documents/SKILL.md +0 -478
  154. package/payload/platform/plugins/brochures/skills/brand-design/SKILL.md +0 -192
  155. package/payload/platform/plugins/brochures/skills/make-brochure/SKILL.md +0 -354
  156. package/payload/platform/plugins/brochures/skills/make-brochure/references/seller-brief-template.md +0 -115
  157. package/payload/platform/plugins/brochures/skills/property-brochure/SKILL.md +0 -142
  158. package/payload/platform/plugins/brochures/skills/property-brochure/references/build.md +0 -270
  159. package/payload/platform/plugins/brochures/skills/property-brochure/references/copy.md +0 -211
  160. package/payload/platform/plugins/brochures/skills/property-brochure/references/images.md +0 -166
  161. package/payload/platform/plugins/brochures/skills/property-brochure/references/index-landing.md +0 -376
  162. package/payload/platform/plugins/brochures/skills/property-brochure/references/index.html +0 -1288
  163. package/payload/platform/plugins/brochures/skills/property-brochure/references/placeholders.md +0 -250
  164. package/payload/platform/plugins/brochures/skills/property-brochure/references/registers.md +0 -47
  165. package/payload/platform/plugins/brochures/skills/property-brochure/references/seller-brief.md +0 -56
  166. package/payload/platform/plugins/brochures/skills/property-brochure/references/structure.md +0 -249
  167. package/payload/platform/plugins/brochures/skills/property-brochure/references/template.html +0 -2370
  168. package/payload/platform/plugins/brochures/skills/property-extract/SKILL.md +0 -372
  169. package/payload/platform/plugins/brochures/skills/property-market-report/SKILL.md +0 -100
  170. package/payload/platform/plugins/brochures/skills/property-market-report/references/render.py +0 -267
  171. package/payload/platform/plugins/brochures/skills/property-market-report/references/template.html +0 -266
  172. package/payload/platform/plugins/brochures/skills/property-socials/SKILL.md +0 -141
  173. package/payload/platform/plugins/buyers/.claude-plugin/plugin.json +0 -8
  174. package/payload/platform/plugins/buyers/PLUGIN.md +0 -34
  175. package/payload/platform/plugins/buyers/skills/buyer-feedback/SKILL.md +0 -109
  176. package/payload/platform/plugins/buyers/skills/buyer-management/SKILL.md +0 -42
  177. package/payload/platform/plugins/buyers/skills/buyer-management/references/buyer-qualification-questions.md +0 -16
  178. package/payload/platform/plugins/buyers/skills/buyer-management/references/buyer-qualification.md +0 -59
  179. package/payload/platform/plugins/buyers/skills/buyer-management/references/buyer-scripts.md +0 -63
  180. package/payload/platform/plugins/buyers/skills/buyer-management/references/buyer-working-scripts.md +0 -54
  181. package/payload/platform/plugins/buyers/skills/buyer-management/references/feedback-collection.md +0 -42
  182. package/payload/platform/plugins/buyers/skills/buyer-management/references/offer-capture.md +0 -38
  183. package/payload/platform/plugins/buyers/skills/buyer-management/references/viewing-booking.md +0 -32
  184. package/payload/platform/plugins/buyers/skills/buyer-management/references/viewing-management.md +0 -52
  185. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/SKILL.md +0 -407
  186. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/references/care-fees-guide.md +0 -68
  187. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/references/divorce-sales-guide.md +0 -61
  188. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/references/downsizing-guide.md +0 -45
  189. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/references/first-time-buyers.md +0 -92
  190. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/references/first-time-sellers.md +0 -78
  191. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/references/probate-guide.md +0 -53
  192. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/references/upsizing-guide.md +0 -41
  193. package/payload/platform/plugins/buyers/skills/property-enquiry/SKILL.md +0 -126
  194. package/payload/platform/plugins/buyers/skills/viewing-management/SKILL.md +0 -111
  195. package/payload/platform/plugins/epc/.claude-plugin/plugin.json +0 -17
  196. package/payload/platform/plugins/epc/PLUGIN.md +0 -85
  197. package/payload/platform/plugins/epc/mcp/dist/index.d.ts +0 -2
  198. package/payload/platform/plugins/epc/mcp/dist/index.d.ts.map +0 -1
  199. package/payload/platform/plugins/epc/mcp/dist/index.js +0 -117
  200. package/payload/platform/plugins/epc/mcp/dist/index.js.map +0 -1
  201. package/payload/platform/plugins/epc/mcp/dist/lib/crypto.d.ts +0 -3
  202. package/payload/platform/plugins/epc/mcp/dist/lib/crypto.d.ts.map +0 -1
  203. package/payload/platform/plugins/epc/mcp/dist/lib/crypto.js +0 -72
  204. package/payload/platform/plugins/epc/mcp/dist/lib/crypto.js.map +0 -1
  205. package/payload/platform/plugins/epc/mcp/dist/lib/epc-api.d.ts +0 -60
  206. package/payload/platform/plugins/epc/mcp/dist/lib/epc-api.d.ts.map +0 -1
  207. package/payload/platform/plugins/epc/mcp/dist/lib/epc-api.js +0 -181
  208. package/payload/platform/plugins/epc/mcp/dist/lib/epc-api.js.map +0 -1
  209. package/payload/platform/plugins/epc/mcp/dist/lib/file-crypto.d.ts +0 -3
  210. package/payload/platform/plugins/epc/mcp/dist/lib/file-crypto.d.ts.map +0 -1
  211. package/payload/platform/plugins/epc/mcp/dist/lib/file-crypto.js +0 -49
  212. package/payload/platform/plugins/epc/mcp/dist/lib/file-crypto.js.map +0 -1
  213. package/payload/platform/plugins/epc/mcp/dist/lib/key-store.d.ts +0 -15
  214. package/payload/platform/plugins/epc/mcp/dist/lib/key-store.d.ts.map +0 -1
  215. package/payload/platform/plugins/epc/mcp/dist/lib/key-store.js +0 -130
  216. package/payload/platform/plugins/epc/mcp/dist/lib/key-store.js.map +0 -1
  217. package/payload/platform/plugins/epc/mcp/dist/lib/neo4j.d.ts +0 -5
  218. package/payload/platform/plugins/epc/mcp/dist/lib/neo4j.d.ts.map +0 -1
  219. package/payload/platform/plugins/epc/mcp/dist/lib/neo4j.js +0 -38
  220. package/payload/platform/plugins/epc/mcp/dist/lib/neo4j.js.map +0 -1
  221. package/payload/platform/plugins/epc/mcp/dist/tools/key-deregister.d.ts +0 -4
  222. package/payload/platform/plugins/epc/mcp/dist/tools/key-deregister.d.ts.map +0 -1
  223. package/payload/platform/plugins/epc/mcp/dist/tools/key-deregister.js +0 -9
  224. package/payload/platform/plugins/epc/mcp/dist/tools/key-deregister.js.map +0 -1
  225. package/payload/platform/plugins/epc/mcp/dist/tools/key-list.d.ts +0 -4
  226. package/payload/platform/plugins/epc/mcp/dist/tools/key-list.d.ts.map +0 -1
  227. package/payload/platform/plugins/epc/mcp/dist/tools/key-list.js +0 -10
  228. package/payload/platform/plugins/epc/mcp/dist/tools/key-list.js.map +0 -1
  229. package/payload/platform/plugins/epc/mcp/dist/tools/key-register.d.ts +0 -5
  230. package/payload/platform/plugins/epc/mcp/dist/tools/key-register.d.ts.map +0 -1
  231. package/payload/platform/plugins/epc/mcp/dist/tools/key-register.js +0 -36
  232. package/payload/platform/plugins/epc/mcp/dist/tools/key-register.js.map +0 -1
  233. package/payload/platform/plugins/epc/mcp/dist/tools/lookup.d.ts +0 -10
  234. package/payload/platform/plugins/epc/mcp/dist/tools/lookup.d.ts.map +0 -1
  235. package/payload/platform/plugins/epc/mcp/dist/tools/lookup.js +0 -30
  236. package/payload/platform/plugins/epc/mcp/dist/tools/lookup.js.map +0 -1
  237. package/payload/platform/plugins/epc/mcp/package-lock.json +0 -2566
  238. package/payload/platform/plugins/epc/mcp/package.json +0 -21
  239. package/payload/platform/plugins/epc/mcp/src/__tests__/epc-api.test.ts +0 -251
  240. package/payload/platform/plugins/epc/mcp/src/__tests__/key-roundtrip.test.ts +0 -113
  241. package/payload/platform/plugins/epc/mcp/src/__tests__/lookup.test.ts +0 -181
  242. package/payload/platform/plugins/epc/mcp/src/__tests__/schema-parity.test.ts +0 -54
  243. package/payload/platform/plugins/epc/mcp/src/index.ts +0 -156
  244. package/payload/platform/plugins/epc/mcp/src/lib/crypto.ts +0 -79
  245. package/payload/platform/plugins/epc/mcp/src/lib/epc-api.ts +0 -241
  246. package/payload/platform/plugins/epc/mcp/src/lib/file-crypto.ts +0 -55
  247. package/payload/platform/plugins/epc/mcp/src/lib/key-store.ts +0 -172
  248. package/payload/platform/plugins/epc/mcp/src/lib/neo4j.ts +0 -47
  249. package/payload/platform/plugins/epc/mcp/src/tools/key-deregister.ts +0 -9
  250. package/payload/platform/plugins/epc/mcp/src/tools/key-list.ts +0 -10
  251. package/payload/platform/plugins/epc/mcp/src/tools/key-register.ts +0 -44
  252. package/payload/platform/plugins/epc/mcp/src/tools/lookup.ts +0 -43
  253. package/payload/platform/plugins/epc/mcp/tsconfig.json +0 -20
  254. package/payload/platform/plugins/epc/mcp/vitest.config.ts +0 -8
  255. package/payload/platform/plugins/estate-business/.claude-plugin/plugin.json +0 -8
  256. package/payload/platform/plugins/estate-business/PLUGIN.md +0 -64
  257. package/payload/platform/plugins/estate-business/skills/business-growth/SKILL.md +0 -133
  258. package/payload/platform/plugins/estate-business/skills/business-growth/references/buy-back-your-time.md +0 -37
  259. package/payload/platform/plugins/estate-business/skills/business-growth/references/firewave-gost-scorecards.md +0 -14
  260. package/payload/platform/plugins/estate-business/skills/business-growth/references/keller-org-model.md +0 -17
  261. package/payload/platform/plugins/estate-business/skills/business-growth/references/lencioni-team-models.md +0 -22
  262. package/payload/platform/plugins/estate-business/skills/business-growth/references/listing-management-system.md +0 -11
  263. package/payload/platform/plugins/estate-business/skills/business-growth/references/net-figure-form.md +0 -11
  264. package/payload/platform/plugins/estate-business/skills/business-growth/references/serhant-bizinbox-notes.md +0 -13
  265. package/payload/platform/plugins/estate-business/skills/business-growth/references/team-roles-commission.md +0 -14
  266. package/payload/platform/plugins/estate-business/skills/business-growth/references/va-2026-ops.md +0 -43
  267. package/payload/platform/plugins/estate-business/skills/business-growth/references/wingman-structure.md +0 -13
  268. package/payload/platform/plugins/estate-business/skills/business-operations/SKILL.md +0 -32
  269. package/payload/platform/plugins/estate-business/skills/business-operations/references/crm-systems.md +0 -57
  270. package/payload/platform/plugins/estate-business/skills/business-operations/references/hiring-guide.md +0 -59
  271. package/payload/platform/plugins/estate-business/skills/business-operations/references/impact-framework.md +0 -47
  272. package/payload/platform/plugins/estate-business/skills/business-operations/references/minutes-equal-money.md +0 -55
  273. package/payload/platform/plugins/estate-business/skills/business-operations/references/team-management.md +0 -48
  274. package/payload/platform/plugins/estate-business/skills/commission-calculator/SKILL.md +0 -40
  275. package/payload/platform/plugins/estate-business/skills/exp-partnership/SKILL.md +0 -52
  276. package/payload/platform/plugins/estate-business/skills/exp-partnership/references/12-reasons.md +0 -39
  277. package/payload/platform/plugins/estate-business/skills/exp-partnership/references/95-5-system.md +0 -66
  278. package/payload/platform/plugins/estate-business/skills/exp-partnership/references/agent-attraction-scripts.md +0 -90
  279. package/payload/platform/plugins/estate-business/skills/exp-partnership/references/business-partnership.md +0 -92
  280. package/payload/platform/plugins/estate-business/skills/exp-partnership/references/exp-model-overview.md +0 -66
  281. package/payload/platform/plugins/estate-business/skills/exp-partnership/references/model-comparison.md +0 -66
  282. package/payload/platform/plugins/estate-business/skills/exp-partnership/references/revenue-share-explained.md +0 -57
  283. package/payload/platform/plugins/estate-business/skills/month-end-close/SKILL.md +0 -69
  284. package/payload/platform/plugins/estate-business/skills/payment-batch-stager/SKILL.md +0 -42
  285. package/payload/platform/plugins/estate-business/skills/period-reconciler/SKILL.md +0 -42
  286. package/payload/platform/plugins/estate-business/skills/personal-branding/SKILL.md +0 -117
  287. package/payload/platform/plugins/estate-business/skills/personal-branding/references/attraction-agent-notes.md +0 -31
  288. package/payload/platform/plugins/estate-business/skills/personal-branding/references/attraction-agent.md +0 -58
  289. package/payload/platform/plugins/estate-business/skills/personal-branding/references/authenticity-boundaries.md +0 -28
  290. package/payload/platform/plugins/estate-business/skills/personal-branding/references/become-a-brand-leader-notes.md +0 -19
  291. package/payload/platform/plugins/estate-business/skills/personal-branding/references/blast-formula.md +0 -42
  292. package/payload/platform/plugins/estate-business/skills/personal-branding/references/brand-leader.md +0 -48
  293. package/payload/platform/plugins/estate-business/skills/personal-branding/references/brand-strategy-system.md +0 -59
  294. package/payload/platform/plugins/estate-business/skills/personal-branding/references/content-engine.md +0 -49
  295. package/payload/platform/plugins/estate-business/skills/personal-branding/references/firewave-blast-and-blogging.md +0 -23
  296. package/payload/platform/plugins/estate-business/skills/personal-branding/references/gary-v-content.md +0 -52
  297. package/payload/platform/plugins/estate-business/skills/personal-branding/references/gary-v-principles.md +0 -20
  298. package/payload/platform/plugins/estate-business/skills/personal-branding/references/oversubscribed-positioning.md +0 -18
  299. package/payload/platform/plugins/estate-business/skills/personal-branding/references/platforms.md +0 -41
  300. package/payload/platform/plugins/estate-business/skills/personal-branding/references/priestley-oversubscribed.md +0 -54
  301. package/payload/platform/plugins/estate-business/skills/personal-branding/references/storeys-style-examples.md +0 -25
  302. package/payload/platform/plugins/estate-business/skills/personal-branding/references/visual-identity.md +0 -27
  303. package/payload/platform/plugins/estate-coaching/.claude-plugin/plugin.json +0 -8
  304. package/payload/platform/plugins/estate-coaching/PLUGIN.md +0 -54
  305. package/payload/platform/plugins/estate-coaching/skills/agent-performance/SKILL.md +0 -371
  306. package/payload/platform/plugins/estate-coaching/skills/agent-performance/references/atomic-habits.md +0 -52
  307. package/payload/platform/plugins/estate-coaching/skills/agent-performance/references/daily-routine-scorecard.md +0 -104
  308. package/payload/platform/plugins/estate-coaching/skills/agent-performance/references/hp6-model.md +0 -63
  309. package/payload/platform/plugins/estate-coaching/skills/agent-performance/references/twelve-week-year.md +0 -71
  310. package/payload/platform/plugins/estate-coaching/skills/bespoke-coaching/SKILL.md +0 -36
  311. package/payload/platform/plugins/estate-coaching/skills/bespoke-coaching/references/coaching-boundaries.md +0 -56
  312. package/payload/platform/plugins/estate-coaching/skills/bespoke-coaching/references/feedback-framework.md +0 -61
  313. package/payload/platform/plugins/estate-coaching/skills/bespoke-coaching/references/performance-framework.md +0 -109
  314. package/payload/platform/plugins/estate-coaching/skills/coaching-toolkit/SKILL.md +0 -421
  315. package/payload/platform/plugins/estate-coaching/skills/coaching-toolkit/references/coaching-exercises.md +0 -86
  316. package/payload/platform/plugins/estate-coaching/skills/coaching-toolkit/references/goal-setting.md +0 -78
  317. package/payload/platform/plugins/estate-coaching/skills/coaching-toolkit/references/one-to-one-framework.md +0 -92
  318. package/payload/platform/plugins/estate-coaching/skills/coaching-toolkit/references/soi-workbook.md +0 -103
  319. package/payload/platform/plugins/estate-coaching/skills/serhant-training/SKILL.md +0 -410
  320. package/payload/platform/plugins/estate-coaching/skills/serhant-training/references/agent-training-guide.md +0 -70
  321. package/payload/platform/plugins/estate-coaching/skills/serhant-training/references/business-in-a-box.md +0 -72
  322. package/payload/platform/plugins/estate-coaching/skills/serhant-training/references/buyers-guide.md +0 -53
  323. package/payload/platform/plugins/estate-coaching/skills/serhant-training/references/codo-method.md +0 -72
  324. package/payload/platform/plugins/estate-coaching/skills/serhant-training/references/website-planning-guide.md +0 -79
  325. package/payload/platform/plugins/estate-sales/.claude-plugin/plugin.json +0 -8
  326. package/payload/platform/plugins/estate-sales/PLUGIN.md +0 -52
  327. package/payload/platform/plugins/estate-sales/skills/chase-progression/SKILL.md +0 -107
  328. package/payload/platform/plugins/estate-sales/skills/negotiation/SKILL.md +0 -35
  329. package/payload/platform/plugins/estate-sales/skills/negotiation/references/deal-saving.md +0 -47
  330. package/payload/platform/plugins/estate-sales/skills/negotiation/references/negotiation-deep-guide.md +0 -64
  331. package/payload/platform/plugins/estate-sales/skills/negotiation/references/negotiation-prep-principles.md +0 -29
  332. package/payload/platform/plugins/estate-sales/skills/negotiation/references/negotiation-techniques.md +0 -42
  333. package/payload/platform/plugins/estate-sales/skills/negotiation/references/offer-presentation.md +0 -43
  334. package/payload/platform/plugins/estate-sales/skills/risk-scorer/SKILL.md +0 -42
  335. package/payload/platform/plugins/estate-sales/skills/sales-closer/SKILL.md +0 -24
  336. package/payload/platform/plugins/estate-sales/skills/sales-closer/references/serhant-emotion-stages.md +0 -36
  337. package/payload/platform/plugins/estate-sales/skills/sales-discovery/SKILL.md +0 -30
  338. package/payload/platform/plugins/estate-sales/skills/sales-discovery/references/chris-voss-discovery.md +0 -88
  339. package/payload/platform/plugins/estate-sales/skills/sales-discovery/references/firewave-gost-journey.md +0 -68
  340. package/payload/platform/plugins/estate-sales/skills/sales-discovery/references/phil-jones-openers.md +0 -78
  341. package/payload/platform/plugins/estate-sales/skills/sales-discovery/references/pre-listing-checklist.md +0 -77
  342. package/payload/platform/plugins/estate-sales/skills/sales-discovery/references/serhant-improv.md +0 -22
  343. package/payload/platform/plugins/estate-sales/skills/sales-discovery/references/tom-ferry-discovery.md +0 -103
  344. package/payload/platform/plugins/estate-sales/skills/sales-discovery/references/vendor-motivation-competitor.md +0 -52
  345. package/payload/platform/plugins/estate-sales/skills/sales-negotiation/SKILL.md +0 -29
  346. package/payload/platform/plugins/estate-sales/skills/sales-negotiation/references/chris-voss-negotiation.md +0 -70
  347. package/payload/platform/plugins/estate-sales/skills/sales-negotiation/references/phil-jones-price-words.md +0 -40
  348. package/payload/platform/plugins/estate-sales/skills/sales-negotiation/references/serhant-negotiation-plus.md +0 -55
  349. package/payload/platform/plugins/estate-sales/skills/sales-negotiation/references/tom-panos-commission-pricing.md +0 -57
  350. package/payload/platform/plugins/estate-sales/skills/sales-negotiation/references/tony-morris-questioning.md +0 -54
  351. package/payload/platform/plugins/estate-sales/skills/sales-progression/SKILL.md +0 -27
  352. package/payload/platform/plugins/estate-sales/skills/sales-progression/references/conveyancing-guide.md +0 -54
  353. package/payload/platform/plugins/estate-sales/skills/sales-progression/references/transaction-tracking.md +0 -66
  354. package/payload/platform/plugins/estate-teaching/.claude-plugin/plugin.json +0 -8
  355. package/payload/platform/plugins/estate-teaching/PLUGIN.md +0 -30
  356. package/payload/platform/plugins/estate-teaching/skills/content-directory/SKILL.md +0 -39
  357. package/payload/platform/plugins/estate-teaching/skills/content-directory/references/module-delivery.md +0 -65
  358. package/payload/platform/plugins/estate-teaching/skills/content-directory/references/progress-tracking.md +0 -47
  359. package/payload/platform/plugins/leads/.claude-plugin/plugin.json +0 -8
  360. package/payload/platform/plugins/leads/PLUGIN.md +0 -61
  361. package/payload/platform/plugins/leads/skills/chain-progression-tracker/SKILL.md +0 -51
  362. package/payload/platform/plugins/leads/skills/diary-builder/SKILL.md +0 -38
  363. package/payload/platform/plugins/leads/skills/enquiry-triage/SKILL.md +0 -36
  364. package/payload/platform/plugins/leads/skills/lead-nurturing/SKILL.md +0 -137
  365. package/payload/platform/plugins/leads/skills/lead-nurturing/references/buyer-search-letter.md +0 -28
  366. package/payload/platform/plugins/leads/skills/lead-nurturing/references/buyer-search-letters.md +0 -37
  367. package/payload/platform/plugins/leads/skills/lead-nurturing/references/database-reactivation.md +0 -30
  368. package/payload/platform/plugins/leads/skills/lead-nurturing/references/email-nurture-sequences.md +0 -45
  369. package/payload/platform/plugins/leads/skills/lead-nurturing/references/facebook-referrals.md +0 -30
  370. package/payload/platform/plugins/leads/skills/lead-nurturing/references/firewave-email-nurture-sequences.md +0 -41
  371. package/payload/platform/plugins/leads/skills/lead-nurturing/references/keller-33-touch.md +0 -34
  372. package/payload/platform/plugins/leads/skills/lead-nurturing/references/neighbour-letters.md +0 -31
  373. package/payload/platform/plugins/leads/skills/lead-nurturing/references/neighbour-notification-letter.md +0 -20
  374. package/payload/platform/plugins/leads/skills/lead-nurturing/references/ofi-follow-up-dialogue.md +0 -22
  375. package/payload/platform/plugins/leads/skills/lead-nurturing/references/ofi-follow-up.md +0 -26
  376. package/payload/platform/plugins/leads/skills/lead-nurturing/references/serhant-three-fs-plus.md +0 -21
  377. package/payload/platform/plugins/leads/skills/lead-nurturing/references/sharran-10x10x10.md +0 -18
  378. package/payload/platform/plugins/leads/skills/lead-nurturing/references/sms-templates.md +0 -40
  379. package/payload/platform/plugins/leads/skills/lead-nurturing/references/sphere-of-influence-notes.md +0 -34
  380. package/payload/platform/plugins/leads/skills/lead-nurturing/references/sphere-of-influence.md +0 -60
  381. package/payload/platform/plugins/leads/skills/lead-nurturing/references/tom-panos-sms-templates.md +0 -59
  382. package/payload/platform/plugins/leads/skills/morning-round/SKILL.md +0 -72
  383. package/payload/platform/plugins/leads/skills/prospecting/SKILL.md +0 -33
  384. package/payload/platform/plugins/leads/skills/prospecting/references/database-matching.md +0 -30
  385. package/payload/platform/plugins/leads/skills/prospecting/references/database-value.md +0 -53
  386. package/payload/platform/plugins/leads/skills/prospecting/references/prospecting-dialogues.md +0 -24
  387. package/payload/platform/plugins/leads/skills/prospecting/references/reactivation.md +0 -34
  388. package/payload/platform/plugins/listings/.claude-plugin/plugin.json +0 -8
  389. package/payload/platform/plugins/listings/PLUGIN.md +0 -102
  390. package/payload/platform/plugins/listings/skills/comparable-finder/SKILL.md +0 -52
  391. package/payload/platform/plugins/listings/skills/epc-checker/SKILL.md +0 -38
  392. package/payload/platform/plugins/listings/skills/home-preparation/SKILL.md +0 -28
  393. package/payload/platform/plugins/listings/skills/home-preparation/references/kerb-appeal.md +0 -38
  394. package/payload/platform/plugins/listings/skills/home-preparation/references/photo-day.md +0 -59
  395. package/payload/platform/plugins/listings/skills/home-preparation/references/situational-tips.md +0 -50
  396. package/payload/platform/plugins/listings/skills/home-preparation/references/staging-guide.md +0 -52
  397. package/payload/platform/plugins/listings/skills/listing-copy-writer/SKILL.md +0 -55
  398. package/payload/platform/plugins/listings/skills/listing-presentation/SKILL.md +0 -286
  399. package/payload/platform/plugins/listings/skills/listing-presentation/references/booking-script.md +0 -51
  400. package/payload/platform/plugins/listings/skills/listing-presentation/references/objection-scripts.md +0 -193
  401. package/payload/platform/plugins/listings/skills/listing-presentation/references/penhaul-presentation.md +0 -123
  402. package/payload/platform/plugins/listings/skills/listing-presentation/references/pre-listing-kit.md +0 -139
  403. package/payload/platform/plugins/listings/skills/listing-presentation/references/set-to-sell.md +0 -55
  404. package/payload/platform/plugins/listings/skills/listing-presentation/references/sharran-frameworks.md +0 -107
  405. package/payload/platform/plugins/listings/skills/local-market-stats/SKILL.md +0 -33
  406. package/payload/platform/plugins/listings/skills/new-instruction/SKILL.md +0 -78
  407. package/payload/platform/plugins/listings/skills/particulars-builder/SKILL.md +0 -48
  408. package/payload/platform/plugins/listings/skills/portal-launch-scheduler/SKILL.md +0 -49
  409. package/payload/platform/plugins/listings/skills/pricing-scenario-builder/SKILL.md +0 -35
  410. package/payload/platform/plugins/listings/skills/property-marketing/SKILL.md +0 -337
  411. package/payload/platform/plugins/listings/skills/property-marketing/references/auction-report-template.md +0 -41
  412. package/payload/platform/plugins/listings/skills/property-marketing/references/coming-soon-campaign.md +0 -43
  413. package/payload/platform/plugins/listings/skills/property-marketing/references/direct-mail-templates.md +0 -121
  414. package/payload/platform/plugins/listings/skills/property-marketing/references/eoi-form-template.md +0 -62
  415. package/payload/platform/plugins/listings/skills/property-marketing/references/monthly-scorecard.md +0 -63
  416. package/payload/platform/plugins/listings/skills/supplier-booker/SKILL.md +0 -39
  417. package/payload/platform/plugins/listings/skills/talk-track-composer/SKILL.md +0 -36
  418. package/payload/platform/plugins/listings/skills/terms-of-business-drafter/SKILL.md +0 -54
  419. package/payload/platform/plugins/listings/skills/valuation-prep/SKILL.md +0 -69
  420. package/payload/platform/plugins/loop/.claude-plugin/plugin.json +0 -17
  421. package/payload/platform/plugins/loop/PLUGIN.md +0 -233
  422. package/payload/platform/plugins/loop/mcp/dist/index.d.ts +0 -2
  423. package/payload/platform/plugins/loop/mcp/dist/index.d.ts.map +0 -1
  424. package/payload/platform/plugins/loop/mcp/dist/index.js +0 -320
  425. package/payload/platform/plugins/loop/mcp/dist/index.js.map +0 -1
  426. package/payload/platform/plugins/loop/mcp/dist/lib/crypto.d.ts +0 -10
  427. package/payload/platform/plugins/loop/mcp/dist/lib/crypto.d.ts.map +0 -1
  428. package/payload/platform/plugins/loop/mcp/dist/lib/crypto.js +0 -88
  429. package/payload/platform/plugins/loop/mcp/dist/lib/crypto.js.map +0 -1
  430. package/payload/platform/plugins/loop/mcp/dist/lib/file-crypto.d.ts +0 -3
  431. package/payload/platform/plugins/loop/mcp/dist/lib/file-crypto.d.ts.map +0 -1
  432. package/payload/platform/plugins/loop/mcp/dist/lib/file-crypto.js +0 -48
  433. package/payload/platform/plugins/loop/mcp/dist/lib/file-crypto.js.map +0 -1
  434. package/payload/platform/plugins/loop/mcp/dist/lib/key-store.d.ts +0 -22
  435. package/payload/platform/plugins/loop/mcp/dist/lib/key-store.d.ts.map +0 -1
  436. package/payload/platform/plugins/loop/mcp/dist/lib/key-store.js +0 -165
  437. package/payload/platform/plugins/loop/mcp/dist/lib/key-store.js.map +0 -1
  438. package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.d.ts +0 -82
  439. package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.d.ts.map +0 -1
  440. package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.js +0 -392
  441. package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.js.map +0 -1
  442. package/payload/platform/plugins/loop/mcp/dist/lib/neo4j.d.ts +0 -5
  443. package/payload/platform/plugins/loop/mcp/dist/lib/neo4j.d.ts.map +0 -1
  444. package/payload/platform/plugins/loop/mcp/dist/lib/neo4j.js +0 -40
  445. package/payload/platform/plugins/loop/mcp/dist/lib/neo4j.js.map +0 -1
  446. package/payload/platform/plugins/loop/mcp/dist/tools/auto-responder.d.ts +0 -12
  447. package/payload/platform/plugins/loop/mcp/dist/tools/auto-responder.d.ts.map +0 -1
  448. package/payload/platform/plugins/loop/mcp/dist/tools/auto-responder.js +0 -22
  449. package/payload/platform/plugins/loop/mcp/dist/tools/auto-responder.js.map +0 -1
  450. package/payload/platform/plugins/loop/mcp/dist/tools/customer-preferences.d.ts +0 -10
  451. package/payload/platform/plugins/loop/mcp/dist/tools/customer-preferences.d.ts.map +0 -1
  452. package/payload/platform/plugins/loop/mcp/dist/tools/customer-preferences.js +0 -24
  453. package/payload/platform/plugins/loop/mcp/dist/tools/customer-preferences.js.map +0 -1
  454. package/payload/platform/plugins/loop/mcp/dist/tools/feedback.d.ts +0 -16
  455. package/payload/platform/plugins/loop/mcp/dist/tools/feedback.d.ts.map +0 -1
  456. package/payload/platform/plugins/loop/mcp/dist/tools/feedback.js +0 -35
  457. package/payload/platform/plugins/loop/mcp/dist/tools/feedback.js.map +0 -1
  458. package/payload/platform/plugins/loop/mcp/dist/tools/key-deregister.d.ts +0 -5
  459. package/payload/platform/plugins/loop/mcp/dist/tools/key-deregister.d.ts.map +0 -1
  460. package/payload/platform/plugins/loop/mcp/dist/tools/key-deregister.js +0 -9
  461. package/payload/platform/plugins/loop/mcp/dist/tools/key-deregister.js.map +0 -1
  462. package/payload/platform/plugins/loop/mcp/dist/tools/key-list.d.ts +0 -4
  463. package/payload/platform/plugins/loop/mcp/dist/tools/key-list.d.ts.map +0 -1
  464. package/payload/platform/plugins/loop/mcp/dist/tools/key-list.js +0 -14
  465. package/payload/platform/plugins/loop/mcp/dist/tools/key-list.js.map +0 -1
  466. package/payload/platform/plugins/loop/mcp/dist/tools/key-register.d.ts +0 -9
  467. package/payload/platform/plugins/loop/mcp/dist/tools/key-register.d.ts.map +0 -1
  468. package/payload/platform/plugins/loop/mcp/dist/tools/key-register.js +0 -43
  469. package/payload/platform/plugins/loop/mcp/dist/tools/key-register.js.map +0 -1
  470. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-enquiry.d.ts +0 -6
  471. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-enquiry.d.ts.map +0 -1
  472. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-enquiry.js +0 -7
  473. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-enquiry.js.map +0 -1
  474. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-batch.d.ts +0 -9
  475. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-batch.d.ts.map +0 -1
  476. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-batch.js +0 -16
  477. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-batch.js.map +0 -1
  478. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-request.d.ts +0 -15
  479. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-request.d.ts.map +0 -1
  480. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-request.js +0 -11
  481. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-request.js.map +0 -1
  482. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match.d.ts +0 -10
  483. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match.d.ts.map +0 -1
  484. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match.js +0 -39
  485. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match.js.map +0 -1
  486. package/payload/platform/plugins/loop/mcp/dist/tools/people-detail.d.ts +0 -9
  487. package/payload/platform/plugins/loop/mcp/dist/tools/people-detail.d.ts.map +0 -1
  488. package/payload/platform/plugins/loop/mcp/dist/tools/people-detail.js +0 -125
  489. package/payload/platform/plugins/loop/mcp/dist/tools/people-detail.js.map +0 -1
  490. package/payload/platform/plugins/loop/mcp/dist/tools/people-search.d.ts +0 -18
  491. package/payload/platform/plugins/loop/mcp/dist/tools/people-search.d.ts.map +0 -1
  492. package/payload/platform/plugins/loop/mcp/dist/tools/people-search.js +0 -87
  493. package/payload/platform/plugins/loop/mcp/dist/tools/people-search.js.map +0 -1
  494. package/payload/platform/plugins/loop/mcp/dist/tools/property-detail.d.ts +0 -10
  495. package/payload/platform/plugins/loop/mcp/dist/tools/property-detail.d.ts.map +0 -1
  496. package/payload/platform/plugins/loop/mcp/dist/tools/property-detail.js +0 -82
  497. package/payload/platform/plugins/loop/mcp/dist/tools/property-detail.js.map +0 -1
  498. package/payload/platform/plugins/loop/mcp/dist/tools/property-intent.d.ts +0 -33
  499. package/payload/platform/plugins/loop/mcp/dist/tools/property-intent.d.ts.map +0 -1
  500. package/payload/platform/plugins/loop/mcp/dist/tools/property-intent.js +0 -19
  501. package/payload/platform/plugins/loop/mcp/dist/tools/property-intent.js.map +0 -1
  502. package/payload/platform/plugins/loop/mcp/dist/tools/property-listed.d.ts +0 -11
  503. package/payload/platform/plugins/loop/mcp/dist/tools/property-listed.d.ts.map +0 -1
  504. package/payload/platform/plugins/loop/mcp/dist/tools/property-listed.js +0 -26
  505. package/payload/platform/plugins/loop/mcp/dist/tools/property-listed.js.map +0 -1
  506. package/payload/platform/plugins/loop/mcp/dist/tools/property-request.d.ts +0 -15
  507. package/payload/platform/plugins/loop/mcp/dist/tools/property-request.d.ts.map +0 -1
  508. package/payload/platform/plugins/loop/mcp/dist/tools/property-request.js +0 -11
  509. package/payload/platform/plugins/loop/mcp/dist/tools/property-request.js.map +0 -1
  510. package/payload/platform/plugins/loop/mcp/dist/tools/property-search.d.ts +0 -16
  511. package/payload/platform/plugins/loop/mcp/dist/tools/property-search.d.ts.map +0 -1
  512. package/payload/platform/plugins/loop/mcp/dist/tools/property-search.js +0 -41
  513. package/payload/platform/plugins/loop/mcp/dist/tools/property-search.js.map +0 -1
  514. package/payload/platform/plugins/loop/mcp/dist/tools/property-sold.d.ts +0 -9
  515. package/payload/platform/plugins/loop/mcp/dist/tools/property-sold.d.ts.map +0 -1
  516. package/payload/platform/plugins/loop/mcp/dist/tools/property-sold.js +0 -19
  517. package/payload/platform/plugins/loop/mcp/dist/tools/property-sold.js.map +0 -1
  518. package/payload/platform/plugins/loop/mcp/dist/tools/supplier.d.ts +0 -13
  519. package/payload/platform/plugins/loop/mcp/dist/tools/supplier.d.ts.map +0 -1
  520. package/payload/platform/plugins/loop/mcp/dist/tools/supplier.js +0 -49
  521. package/payload/platform/plugins/loop/mcp/dist/tools/supplier.js.map +0 -1
  522. package/payload/platform/plugins/loop/mcp/dist/tools/team-availability.d.ts +0 -7
  523. package/payload/platform/plugins/loop/mcp/dist/tools/team-availability.d.ts.map +0 -1
  524. package/payload/platform/plugins/loop/mcp/dist/tools/team-availability.js +0 -19
  525. package/payload/platform/plugins/loop/mcp/dist/tools/team-availability.js.map +0 -1
  526. package/payload/platform/plugins/loop/mcp/dist/tools/team-info.d.ts +0 -5
  527. package/payload/platform/plugins/loop/mcp/dist/tools/team-info.d.ts.map +0 -1
  528. package/payload/platform/plugins/loop/mcp/dist/tools/team-info.js +0 -32
  529. package/payload/platform/plugins/loop/mcp/dist/tools/team-info.js.map +0 -1
  530. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-create.d.ts +0 -14
  531. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-create.d.ts.map +0 -1
  532. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-create.js +0 -11
  533. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-create.js.map +0 -1
  534. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-detail.d.ts +0 -9
  535. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-detail.d.ts.map +0 -1
  536. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-detail.js +0 -85
  537. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-detail.js.map +0 -1
  538. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-search.d.ts +0 -13
  539. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-search.d.ts.map +0 -1
  540. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-search.js +0 -44
  541. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-search.js.map +0 -1
  542. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-update.d.ts +0 -14
  543. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-update.d.ts.map +0 -1
  544. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-update.js +0 -18
  545. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-update.js.map +0 -1
  546. package/payload/platform/plugins/loop/mcp/package-lock.json +0 -2549
  547. package/payload/platform/plugins/loop/mcp/package.json +0 -21
  548. package/payload/platform/plugins/loop/mcp/src/__tests__/loop-swagger.snapshot.json +0 -26467
  549. package/payload/platform/plugins/loop/mcp/src/__tests__/new-tool-shape.test.ts +0 -99
  550. package/payload/platform/plugins/loop/mcp/src/__tests__/plugin-md-time-doctrine.test.ts +0 -132
  551. package/payload/platform/plugins/loop/mcp/src/__tests__/swagger-write-coverage.test.ts +0 -154
  552. package/payload/platform/plugins/loop/mcp/src/index.ts +0 -498
  553. package/payload/platform/plugins/loop/mcp/src/lib/crypto.ts +0 -105
  554. package/payload/platform/plugins/loop/mcp/src/lib/file-crypto.ts +0 -54
  555. package/payload/platform/plugins/loop/mcp/src/lib/key-store.ts +0 -221
  556. package/payload/platform/plugins/loop/mcp/src/lib/loop-api.ts +0 -567
  557. package/payload/platform/plugins/loop/mcp/src/lib/neo4j.ts +0 -51
  558. package/payload/platform/plugins/loop/mcp/src/tools/auto-responder.ts +0 -80
  559. package/payload/platform/plugins/loop/mcp/src/tools/customer-preferences.ts +0 -66
  560. package/payload/platform/plugins/loop/mcp/src/tools/feedback.ts +0 -86
  561. package/payload/platform/plugins/loop/mcp/src/tools/key-deregister.ts +0 -12
  562. package/payload/platform/plugins/loop/mcp/src/tools/key-list.ts +0 -19
  563. package/payload/platform/plugins/loop/mcp/src/tools/key-register.ts +0 -70
  564. package/payload/platform/plugins/loop/mcp/src/tools/marketing-enquiry.ts +0 -27
  565. package/payload/platform/plugins/loop/mcp/src/tools/marketing-match-batch.ts +0 -53
  566. package/payload/platform/plugins/loop/mcp/src/tools/marketing-match-request.ts +0 -42
  567. package/payload/platform/plugins/loop/mcp/src/tools/marketing-match.ts +0 -84
  568. package/payload/platform/plugins/loop/mcp/src/tools/people-detail.ts +0 -245
  569. package/payload/platform/plugins/loop/mcp/src/tools/people-search.ts +0 -180
  570. package/payload/platform/plugins/loop/mcp/src/tools/property-detail.ts +0 -145
  571. package/payload/platform/plugins/loop/mcp/src/tools/property-intent.ts +0 -84
  572. package/payload/platform/plugins/loop/mcp/src/tools/property-listed.ts +0 -81
  573. package/payload/platform/plugins/loop/mcp/src/tools/property-search.ts +0 -92
  574. package/payload/platform/plugins/loop/mcp/src/tools/property-sold.ts +0 -67
  575. package/payload/platform/plugins/loop/mcp/src/tools/supplier.ts +0 -129
  576. package/payload/platform/plugins/loop/mcp/src/tools/team-availability.ts +0 -52
  577. package/payload/platform/plugins/loop/mcp/src/tools/team-info.ts +0 -95
  578. package/payload/platform/plugins/loop/mcp/src/tools/viewing-create.ts +0 -41
  579. package/payload/platform/plugins/loop/mcp/src/tools/viewing-detail.ts +0 -171
  580. package/payload/platform/plugins/loop/mcp/src/tools/viewing-search.ts +0 -92
  581. package/payload/platform/plugins/loop/mcp/src/tools/viewing-update.ts +0 -53
  582. package/payload/platform/plugins/loop/mcp/tsconfig.json +0 -20
  583. package/payload/platform/plugins/loop/mcp/vitest.config.ts +0 -9
  584. package/payload/platform/plugins/loop/skills/compliance-flag-checker/SKILL.md +0 -53
  585. package/payload/platform/plugins/loop/skills/priority-ranker/SKILL.md +0 -40
  586. package/payload/platform/plugins/loop/skills/tone-matched-drafter/SKILL.md +0 -53
  587. package/payload/platform/plugins/loop/skills/variance-narrator/SKILL.md +0 -50
  588. package/payload/platform/plugins/loop/skills/vendor-research/SKILL.md +0 -54
  589. package/payload/platform/plugins/preval/.claude-plugin/plugin.json +0 -8
  590. package/payload/platform/plugins/preval/PLUGIN.md +0 -47
  591. package/payload/platform/plugins/preval/skills/property-preval/SKILL.md +0 -146
  592. package/payload/platform/plugins/preval/skills/property-preval/references/render.py +0 -630
  593. package/payload/platform/plugins/preval/skills/property-preval/references/template-inputs.schema.json +0 -189
  594. package/payload/platform/plugins/preval/skills/property-preval/references/template.html +0 -312
  595. package/payload/platform/plugins/property-data/.claude-plugin/plugin.json +0 -17
  596. package/payload/platform/plugins/property-data/PLUGIN.md +0 -158
  597. package/payload/platform/plugins/property-data/mcp/dist/index.d.ts +0 -2
  598. package/payload/platform/plugins/property-data/mcp/dist/index.d.ts.map +0 -1
  599. package/payload/platform/plugins/property-data/mcp/dist/index.js +0 -236
  600. package/payload/platform/plugins/property-data/mcp/dist/index.js.map +0 -1
  601. package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.d.ts +0 -3
  602. package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.d.ts.map +0 -1
  603. package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.js +0 -72
  604. package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.js.map +0 -1
  605. package/payload/platform/plugins/property-data/mcp/dist/lib/file-crypto.d.ts +0 -3
  606. package/payload/platform/plugins/property-data/mcp/dist/lib/file-crypto.d.ts.map +0 -1
  607. package/payload/platform/plugins/property-data/mcp/dist/lib/file-crypto.js +0 -49
  608. package/payload/platform/plugins/property-data/mcp/dist/lib/file-crypto.js.map +0 -1
  609. package/payload/platform/plugins/property-data/mcp/dist/lib/key-store.d.ts +0 -15
  610. package/payload/platform/plugins/property-data/mcp/dist/lib/key-store.d.ts.map +0 -1
  611. package/payload/platform/plugins/property-data/mcp/dist/lib/key-store.js +0 -135
  612. package/payload/platform/plugins/property-data/mcp/dist/lib/key-store.js.map +0 -1
  613. package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.d.ts +0 -5
  614. package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.d.ts.map +0 -1
  615. package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.js +0 -38
  616. package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.js.map +0 -1
  617. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts +0 -28
  618. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts.map +0 -1
  619. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.js +0 -101
  620. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.js.map +0 -1
  621. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.d.ts +0 -24
  622. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.d.ts.map +0 -1
  623. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.js +0 -33
  624. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.js.map +0 -1
  625. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.d.ts +0 -4
  626. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.d.ts.map +0 -1
  627. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.js +0 -9
  628. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.js.map +0 -1
  629. package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.d.ts +0 -4
  630. package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.d.ts.map +0 -1
  631. package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.js +0 -10
  632. package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.js.map +0 -1
  633. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.d.ts +0 -5
  634. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.d.ts.map +0 -1
  635. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.js +0 -50
  636. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.js.map +0 -1
  637. package/payload/platform/plugins/property-data/mcp/package-lock.json +0 -2566
  638. package/payload/platform/plugins/property-data/mcp/package.json +0 -21
  639. package/payload/platform/plugins/property-data/mcp/src/__tests__/endpoints.test.ts +0 -252
  640. package/payload/platform/plugins/property-data/mcp/src/__tests__/key-roundtrip.test.ts +0 -107
  641. package/payload/platform/plugins/property-data/mcp/src/__tests__/propertydata-api.test.ts +0 -184
  642. package/payload/platform/plugins/property-data/mcp/src/__tests__/schema-parity.test.ts +0 -62
  643. package/payload/platform/plugins/property-data/mcp/src/index.ts +0 -409
  644. package/payload/platform/plugins/property-data/mcp/src/lib/crypto.ts +0 -79
  645. package/payload/platform/plugins/property-data/mcp/src/lib/file-crypto.ts +0 -55
  646. package/payload/platform/plugins/property-data/mcp/src/lib/key-store.ts +0 -181
  647. package/payload/platform/plugins/property-data/mcp/src/lib/neo4j.ts +0 -47
  648. package/payload/platform/plugins/property-data/mcp/src/lib/propertydata-api.ts +0 -120
  649. package/payload/platform/plugins/property-data/mcp/src/tools/endpoints.ts +0 -47
  650. package/payload/platform/plugins/property-data/mcp/src/tools/key-deregister.ts +0 -9
  651. package/payload/platform/plugins/property-data/mcp/src/tools/key-list.ts +0 -10
  652. package/payload/platform/plugins/property-data/mcp/src/tools/key-register.ts +0 -54
  653. package/payload/platform/plugins/property-data/mcp/tsconfig.json +0 -20
  654. package/payload/platform/plugins/property-data/mcp/vitest.config.ts +0 -8
  655. package/payload/platform/plugins/property-data/skills/property-data/SKILL.md +0 -77
  656. package/payload/platform/plugins/vendors/.claude-plugin/plugin.json +0 -8
  657. package/payload/platform/plugins/vendors/PLUGIN.md +0 -33
  658. package/payload/platform/plugins/vendors/skills/vendor-communication/SKILL.md +0 -42
  659. package/payload/platform/plugins/vendors/skills/vendor-communication/references/fee-protection-and-agenda.md +0 -28
  660. package/payload/platform/plugins/vendors/skills/vendor-communication/references/listing-scripts.md +0 -44
  661. package/payload/platform/plugins/vendors/skills/vendor-communication/references/negotiation-deep-guide.md +0 -70
  662. package/payload/platform/plugins/vendors/skills/vendor-communication/references/price-alignment-scripts.md +0 -33
  663. package/payload/platform/plugins/vendors/skills/vendor-communication/references/price-alignment.md +0 -34
  664. package/payload/platform/plugins/vendors/skills/vendor-communication/references/scenario-scripts.md +0 -38
  665. package/payload/platform/plugins/vendors/skills/vendor-communication/references/seller-engagement.md +0 -51
  666. package/payload/platform/plugins/vendors/skills/vendor-communication/references/valuation-booking.md +0 -76
  667. package/payload/platform/plugins/vendors/skills/vendor-communication/references/vendor-scripts.md +0 -63
  668. package/payload/platform/plugins/vendors/skills/vendor-communication/references/vendor-updates.md +0 -41
  669. package/payload/platform/plugins/vendors/skills/vendor-updates/SKILL.md +0 -153
  670. package/payload/premium-plugins/real-agent/plugins/epc/PLUGIN.md +0 -85
  671. package/payload/premium-plugins/real-agent/plugins/epc/mcp/package-lock.json +0 -2566
  672. package/payload/premium-plugins/real-agent/plugins/epc/mcp/package.json +0 -21
  673. package/payload/premium-plugins/real-agent/plugins/epc/mcp/src/__tests__/epc-api.test.ts +0 -251
  674. package/payload/premium-plugins/real-agent/plugins/epc/mcp/src/__tests__/key-roundtrip.test.ts +0 -113
  675. package/payload/premium-plugins/real-agent/plugins/epc/mcp/src/__tests__/lookup.test.ts +0 -181
  676. package/payload/premium-plugins/real-agent/plugins/epc/mcp/src/__tests__/schema-parity.test.ts +0 -54
  677. package/payload/premium-plugins/real-agent/plugins/epc/mcp/src/index.ts +0 -156
  678. package/payload/premium-plugins/real-agent/plugins/epc/mcp/src/lib/crypto.ts +0 -79
  679. package/payload/premium-plugins/real-agent/plugins/epc/mcp/src/lib/epc-api.ts +0 -241
  680. package/payload/premium-plugins/real-agent/plugins/epc/mcp/src/lib/file-crypto.ts +0 -55
  681. package/payload/premium-plugins/real-agent/plugins/epc/mcp/src/lib/key-store.ts +0 -172
  682. package/payload/premium-plugins/real-agent/plugins/epc/mcp/src/lib/neo4j.ts +0 -47
  683. package/payload/premium-plugins/real-agent/plugins/epc/mcp/src/tools/key-deregister.ts +0 -9
  684. package/payload/premium-plugins/real-agent/plugins/epc/mcp/src/tools/key-list.ts +0 -10
  685. package/payload/premium-plugins/real-agent/plugins/epc/mcp/src/tools/key-register.ts +0 -44
  686. package/payload/premium-plugins/real-agent/plugins/epc/mcp/src/tools/lookup.ts +0 -43
  687. package/payload/premium-plugins/real-agent/plugins/epc/mcp/tsconfig.json +0 -20
  688. package/payload/premium-plugins/real-agent/plugins/epc/mcp/vitest.config.ts +0 -8
  689. package/payload/premium-plugins/real-agent/plugins/listings/skills/epc-checker/SKILL.md +0 -38
@@ -1,21 +1,38 @@
1
1
  ---
2
2
  name: property-preval
3
- description: Use when an operator wants a pre-valuation pack to pitch for a UK property listing — a 5-page A4 PDF that combines a market-data report for the postcode with the subject property's own valuation range, full-width sold + asking comparables, and the agent's recent successes as the sales close. Triggers include "preval <address>", "pre-valuation for <address>", "valuation pitch for <address>", "what's <address> worth and pitch us to list it", "pre-appraisal pack for <address>".
3
+ description: Use when an operator wants a pre-valuation pack to pitch for a UK property listing — a 7-page A4 PDF that combines subject facts, postcode market context, market depth, vendor-side "what gets the best price" prep tips, full-width sold + asking comparables, and the agent's recent successes as the sales close. Available in two style variants (premium = editorial Cormorant/Lora/Inter lock; on-brand = follows the agent's DESIGN.md fonts end-to-end). Triggers include "preval <address>", "pre-valuation for <address>", "valuation pitch for <address>", "what's <address> worth and pitch us to list it", "pre-appraisal pack for <address>".
4
4
  ---
5
5
 
6
6
  # Property Preval
7
7
 
8
- A 5-page A4 PDF that pitches the agent for the listing: cover (full-bleed subject hero), subject valuation (sqft × £/sqft band with operator adjustments), market context, full-width comparables (sold + asking stacked), and the agent's recent successes + disclaimer. **Preval is a sales pitch, not just a data sheet** every page either tells the vendor what the property is worth or what the agent has recently delivered nearby.
8
+ A 7-page A4 PDF that pitches the agent for the listing: cover (full-bleed subject hero + agent byline), subject facts, market context, market depth, vendor-side prep tips ("What gets the best price"), full-width comparables, and the agent's recent successes + disclaimer. **Preval is the data-and-comparables half of the pitch the human agent values the property in person.** The pack never quotes a numeric estimate or range; that's the agent's job, supported by the comparables on page 6.
9
9
 
10
- ## Typography is fixed; only colours and logos come from the agent
10
+ ## Style variants premium (default) or on-brand
11
11
 
12
- Same typographic lock as `property-market-report`:
12
+ The pack renders in one of two variants, selected via the top-level `variant` field on `inputs.json`. The two variants share the same content and layout — only typography differs.
13
+
14
+ ### `variant: "premium"` (default — editorial folio)
15
+
16
+ Typography lock — never substituted:
13
17
 
14
18
  - **Display** — Cormorant Garamond (italic for headlines, KPI values, prices, addresses)
15
19
  - **Body** — Lora
16
20
  - **Sans / labels** — Inter (eyebrows, KPI labels, chips, footer meta)
17
21
 
18
- Never substitute the agent's body or display fonts even if their `DESIGN.md` specifies different families. The pack reads as an editorial / luxury document across every brand. The agent's identity comes through the **palette and logo only**.
22
+ The pack reads as an editorial / luxury document across every brand. The agent's identity comes through the **palette and logo only**. The agent's `DESIGN.md` font tokens are ignored.
23
+
24
+ ### `variant: "on-brand"` (follows the agent's DESIGN.md end-to-end)
25
+
26
+ Renderer reads `brand.font_display` and `brand.font_body` from `inputs.json` (sourced from the agent's `DESIGN.md` font tokens) and overrides the `--display` / `--body` / `--sans` CSS variables. Headlines, body copy, eyebrows and labels all switch to the agent's identity. Colour tokens + logo apply as in premium.
27
+
28
+ Schema requires `brand.font_display` to be set for `on-brand` to engage — a missing display font silently falls back to the premium lock (no broken render). `brand.font_body` defaults to `brand.font_display` if not supplied.
29
+
30
+ ### Decision rule (mirrors `property-brochure`)
31
+
32
+ 1. Operator said "premium" / "super-premium" / "editorial" → premium (regardless of DESIGN.md).
33
+ 2. Operator said "on-brand" / "branded" / "follow our DESIGN.md" → on-brand.
34
+ 3. Operator silent + `DESIGN.md` provides both font tokens → on-brand (default for branded shops).
35
+ 4. Otherwise → premium.
19
36
 
20
37
  ## Inputs (never invented)
21
38
 
@@ -25,10 +42,15 @@ Never substitute the agent's body or display fonts even if their `DESIGN.md` spe
25
42
  - `cover_hero` (filesystem path or URL to a photo of the subject — required for the cover).
26
43
  - Optional `beds`, `type`, `tenure`, `condition` (well / average / needs work).
27
44
  - `adjustments[]` — operator-curated array of `{label, delta_pct}` covering esoteric factors that shift the headline range (e.g. `{"label":"South-facing garden","delta_pct":3}`, `{"label":"Needs full reno","delta_pct":-8}`). Deltas sum linearly into the final range.
28
- - `narrative` — one short paragraph the operator writes about the property.
29
- - **Floor area is auto-pulled from the EPC register** via `real-agent-epc` (`epc-lookup-by-address`) and surfaced as `sqft_m2` + derived `sqft`. Both are required. If EPC has no record (pre-2008 property never sold or let; Scotland/NI; unmatched), the operator pastes `subject.sqft` directly **before invocation** as a deliberate override. There is no mid-run paste prompt and no benchmark-only render — a null `sqft` aborts the run with `reason=subject-sqft-missing`.
45
+ - **EPC certificate fields are pasted by the operator before invocation.** The three required fields are `subject.total_floor_area_m2`, `subject.current_energy_rating`, and `subject.lodgement_date` copied verbatim from the EPC certificate. The renderer derives `sqft` from `total_floor_area_m2 × 10.7639`. There is no mid-run paste prompt and no benchmark-only render — a null in any of the three aborts the run with `reason=epc-certificate-not-supplied`.
30
46
  - **`agent_listings`** — the agent's recent sold / under-offer / live listings to feature on the closing page. Up to 6 entries of `{url, address, price, beds, type, image, status, slug}` where `status ∈ {"Sold","Under offer","For sale"}`. Operator picks the comps that make the strongest pitch; this is *not* the PropertyData sample.
31
- - **`market_summary`** — `headline` (one display-italic line), `paragraphs[]` (2–3 short paragraphs), `demand_gauge_position` (percentage string like `"62%"`), `price_growth_note`, `demand_note`. The operator drafts or accepts an LLM stub.
47
+
48
+ ## Composed by the agent from the fan-out (never operator-supplied)
49
+
50
+ Two prose fields are written by the agent from the 12-call PropertyData fan-out plus the EPC and council-tax records — the operator is never prompted for them.
51
+
52
+ - **`subject.narrative`** — one short paragraph (1–3 sentences) under the valuation panel. Composed from: EPC sqft + rating, `lodgement_date` vs today (age), subject council-tax band (from the per-property `council-tax.properties[]` entry that matches the subject's house number), street context (count of dwellings on the road from the same response), plus the operator's `subject.adjustments[]` labels. Pure facts only — never speculate about orientation, decor, or interior condition that the data doesn't carry.
53
+ - **`market_summary`** — `headline` (one display-italic line), `paragraphs[]` (2–3 short paragraphs), `demand_gauge_position` (percentage string like `"62%"`), `price_growth_note`, `demand_note`. Every value composed from the 12-call fan-out output. Mapping: `headline` summarises the postcode in one line (e.g. demand rating + scarcity + £/sqft direction); paragraph 1 covers £/sqft band (sold vs asking) + Land Registry sample window; paragraph 2 covers demand (for-sale count, sales/mo, MoI, DoM, turnover) + property-type mix; paragraph 3 covers growth (£ + £/sqft YoY) + rental pillar. `demand_gauge_position` maps the demand rating to a percentage: Buyer's market ≈ 20–30%, Balanced market ≈ 45–55%, Seller's market ≈ 75–85%, tuned within band by MoI/DoM.
32
54
 
33
55
  ## Tools the skill calls
34
56
 
@@ -48,57 +70,56 @@ Parallel fan-out keyed on the derived postcode + the subject address:
48
70
  11. `property-data-flood-risk` — area flood risk (full postcode only).
49
71
  12. `property-data-council-tax` — band D + per-property bands (full postcode only).
50
72
 
51
- **EPC (1 callfree, rate-limited):**
52
-
53
- 13. `epc-lookup-by-address(address, postcode)` — subject floor area + energy ratings + lodgement date.
73
+ EPC certificate fields are operator paste-in see `subject.total_floor_area_m2`, `subject.current_energy_rating`, `subject.lodgement_date` in the Inputs section. There is no EPC MCP fan-out.
54
74
 
55
75
  `address-match-uprn` and `planning-applications` are deliberately omitted (CRM hygiene and dev-precedent reports respectively).
56
76
 
57
77
  ## Output
58
78
 
59
- Directory under `~/Documents/Maxy/preval/<postcode-compact>-<YYYY-MM-DD>/` containing:
79
+ Directory under `~/estate-agents/<brand-slug>/preval/<address-slug>/` (e.g. `~/estate-agents/muvin/preval/11-phoenix-drive-cm23-2uj/`) containing:
60
80
 
61
81
  - `index.html` — single self-contained file.
62
82
  - `img/` — copied logos and the subject hero image.
63
- - `<slug>-<date>.pdf` — exactly **5** A4 pages. Renderer asserts via `pdfinfo` and raises if ≠ 5.
83
+ - `<slug>-<date>.pdf` — exactly **7** A4 pages. Renderer asserts via `pdfinfo` and raises if ≠ 7.
84
+ - `property-data.md` — markdown dump of the 12 raw PropertyData fan-out responses for transparency / vendor audit (operator may share or strip before sending).
85
+ - `inputs.json` + `preval.log` — the assembled input shape + the `[preval]` start/done/aborted audit lines.
64
86
 
65
- Return the PDF path to the operator.
87
+ Output is agent-centric so each brand owns its own preval history alongside its `properties/`, `reports/` and `DESIGN.md`. Return the PDF path to the operator.
66
88
 
67
89
  ## Pages
68
90
 
69
- 1. **Cover** — full-bleed `subject.cover_hero` with vertical gradient scrim; light logo top-left; eyebrow "`<brand.name>` · Pre-valuation"; address in display-italic; postcode chip; four-up meta strip (Report · Address · Postcode · Generated). Lifted from property-market-report's cover contract.
70
- 2. **Subject valuation** — KPI strip (sqft, beds, EPC rating, type). Centre panel: headline range = `sqft × sold_psf_low–high` (Land Registry 70pc band) with `sqft × asking_psf` shown as a cross-check. Operator `adjustments[]` displayed as a stacked list (label · delta% · running £). Final range pill at the foot. One paragraph of `subject.narrative` under the panel. `sqft` is required — a null value aborts the run, never renders a benchmark-only panel.
71
- 3. **Market context** — KPI cube (avg asking, avg sold, £/sqft, YoY); pill + gauge for demand; 7y growth sparkline solid + £/sqft dashed); summary paragraphs. Same patterns as property-market-report's page 2.
72
- 4. **Comparables (full-width, stacked)** — Nearest sold table (top 6) full-width across the page; Live asking tile grid (top 4) full-width below. Vertically stacked, never side-by-side corrects the cramped two-column layout in the v1 preval where the asking tiles got pushed to ~40mm columns of italic addresses.
73
- 5. **Recently with `<brand.name>` + sources** — agent's own listings as a clickable tile grid (`<a>` per card, status badge: Sold / Under offer / For sale), then the sources / methodology / accuracy / investment block. Closes with `Real Agent · Generated <date> · <postcode>` in the footer.
91
+ 1. **Cover** — full-bleed `subject.cover_hero` with vertical gradient scrim; light logo top-left; eyebrow "`<brand.name>` · Pre-valuation"; address in display-italic; postcode chip; four-up meta strip (Prepared by · Address · Postcode · Generated). When `brand.agent_name` is set, "Prepared by" displays that name (ties the cover photo to the individual agent pitching).
92
+ 2. **About the property** — KPI strip (sqft, beds, EPC rating, type, tenure). Agent-composed `subject.narrative` under the KPIs (drawn from EPC + council-tax records see "Composed by the agent from the fan-out"). Optional "Notable features" bullet list rendered from `subject.adjustments[].label` (label-only `delta_pct` is held in the schema for backward compat but no longer rendered). **No estimate, no range, no adjustments-with-running-£**. `sqft` is required — a null value aborts the run, never renders a benchmark-only panel.
93
+ 3. **Market context** — Market-summary headline + 2–3 paragraphs (dropcap on first); KPI cube (avg asking, avg sold, £/sqft); two-col panels (price growth + demand gauge). The 7-year chart used to live here; it now has its own page (page 4) to give it space.
94
+ 4. **Market depth** — Full-width 7-year price-trend chart (£ headline solid + £/sqft dashed gold, 48mm tall). Below: two-col panels output-area stock mix (`demand_trend.type_dist` bars) on the left, rental pillar on the right (`demand_trend.rating` pill + 3-up KPIs for for-rent count, DoM, monthly take-up).
95
+ 5. **What gets the best price** — Vendor-facing prep advice condensed from `real-agent/listings/home-preparation/staging-guide.md`. Two-col panel: "Five high-impact moves" (declutter / deep-clean / open the light / fix the small things / define each room) on the left; "Common mistakes" (air fresheners / personal items / cold house / overgrown garden / wardrobes) on the right. Closes with a line attributing the room-by-room walkthrough to the agent ("`<agent_name>` can walk you through this room-by-room ahead of photo day."). Content is hard-coded into the template — not per-pack-editable; for per-property customisation operators should swap to the brochure flow.
96
+ 6. **Comparables (full-width, stacked)** — Nearest sold table (top 6, columns Date · Address · Type · Beds · Price) full-width across the page; Live asking tile grid (top 4) full-width below. Vertically stacked, never side-by-side — corrects the cramped two-column layout in the v1 preval where the asking tiles got pushed to ~40mm columns of italic addresses.
97
+ 7. **Recently with `<brand.name>` + sources** — agent's own listings as a clickable tile grid (`<a>` per card, status badge: Sold / Under offer / For sale), then the sources / methodology / accuracy / investment block. Closes with `<brand.name> · Generated <date> · <postcode>` in the footer.
74
98
 
75
99
  ## How to execute
76
100
 
77
101
  1. Match the postcode out of the address (`/[A-Z]{1,2}[0-9][A-Z0-9]?\s?[0-9][A-Z]{2}/i`). Stop if no match.
78
- 2. Run the 13 fan-out tools (12 PropertyData + 1 EPC) in parallel. Every failure is fail-loud — no mid-run paste prompts, no benchmark-only render, no degraded pack on disk:
102
+ 2. Run the 12 PropertyData fan-out tools in parallel. Every failure is fail-loud — no mid-run paste prompts, no benchmark-only render, no degraded pack on disk:
79
103
  - **PropertyData `key-not-registered`** → abort `reason=property-data-key-not-registered` with the `property-data-key-register` remediation hint.
80
104
  - **PropertyData `http-429`** → back off and retry the single throttled tool **once**. A second `http-429` aborts `reason=property-data-rate-limited`.
81
105
  - **PropertyData `http-5xx` / network failure** → abort `reason=property-data-unavailable`.
82
- - **EPC failure of any kind** `key-not-registered`, `http-404 (no record on file)`, `http-429`, `http-5xx`, network failure, or MCP not configured on the account — aborts the run. The operator's options before re-running are (a) run Task 155 to deploy / register the EPC MCP, or (b) paste `subject.sqft` (plus `subject.sqft_m2`) into the inputs as a deliberate operator override. There is no in-band prompt and no benchmark-only mode.
83
- 3. Compute valuation range:
84
- - `sold_psf_low` = `sold-prices-per-sqf` `70pc_range[0]`
85
- - `sold_psf_high` = `sold-prices-per-sqf` `70pc_range[1]`
86
- - `low = sqft × sold_psf_low`, `mid = sqft × sold_psf`, `high = sqft × sold_psf_high`
87
- - Apply `adjustments` linearly: `factor = 1 + Σ delta_pct / 100`. Final range = `[low × factor, high × factor]`, midpoint = `mid × factor`.
88
- 4. Assemble the `inputs.json` shape per `references/template-inputs.schema.json`.
89
- 5. `python3 references/render.py inputs.json`. Renderer fills the template, copies logos + hero into `img/`, drives Chrome `--print-to-pdf`, asserts page count == 5.
90
- 6. Return the PDF path.
106
+ - **Watchdog: any of the 12 PropertyData log lines missing** within 60 s of `[preval] start` `render.py` aborts `reason=observability-missing tool=<name>` naming the silent tool. A silent tool drop must never proceed to render.
107
+ 3. Derive `sqft` from `round(subject.total_floor_area_m2 × 10.7639)` for the page-2 KPI strip. The pack does not compute a £-valuation; the £/sqft band lives on page 3 (market context) and the comparables on page 4 — the human agent values from those in person.
108
+ 4. Compose `subject.narrative` and `market_summary` from the fan-out output per the rules in "Composed by the agent from the fan-out". No operator prompt for either.
109
+ 5. Assemble the `inputs.json` shape per `references/template-inputs.schema.json`.
110
+ 6. `python3 references/render.py inputs.json`. Renderer fills the template, copies logos + hero into `img/`, drives Chrome `--print-to-pdf`, asserts page count == 7.
111
+ 7. Return the PDF path.
91
112
 
92
- ## Adjustments — linear vs compound
113
+ ## Adjustments — label-only
93
114
 
94
- Deltas sum linearly (`-8 + 3 = -5%`, applied as 0.95`). Compound interpretation (`× 0.92 × 1.03`) would give a slightly different number (-5.24%) but the operator presents the figures verbally as a sum, so the displayed maths must match the verbal claim. If a future operator wants compound adjustments, this is a deliberate skill-level rewrite, not a config switch.
115
+ `subject.adjustments[]` survives in the schema as `{label, delta_pct}` but the renderer uses only the `label` field rendered as a "Notable features" bullet list on page 2. `delta_pct` is held for backward compat (it used to drive a numeric range that this skill no longer publishes). The human agent factors notable features into their valuation conversation; the pack just surfaces them as facts.
95
116
 
96
117
  ## Observability
97
118
 
98
119
  - `[preval] start address="<addr>" postcode=<pc>` at run start.
99
120
  - `[preval] done pdf=<path> pages=<n> ms=<n>` at run end.
100
121
  - `[preval] aborted reason=<cause> address="<addr>" postcode=<pc> ms=<n>` on any abort (one line, then exit 2; no `done`).
101
- - Each fan-out call emits its own `[property-data] tool=<name>` or `[epc] tool=<name>` line in `server.log` (inherited contracts; no new instrumentation here).
122
+ - Each fan-out call emits its own `[property-data] tool=<name>` line in `server.log` (inherited contract; no new instrumentation here). `render.py`'s observability watchdog tails these lines and aborts with `observability-missing tool=<name>` if any of the 12 expected names is absent 60 s after `[preval] start`.
102
123
 
103
124
  ## Hard breakpoints
104
125
 
@@ -106,26 +127,24 @@ Each row aborts the run with the named cause. No PDF or `index.html` is left on
106
127
 
107
128
  | Forbidden state | `reason=` cause |
108
129
  |---|---|
109
- | EPC MCP not configured / `key-not-registered` / `http-5xx` / network error | `epc-mcp-unavailable` (operator must run Task 155 or paste `subject.sqft` before invocation) |
110
- | `subject.sqft` null after EPC lookup | `subject-sqft-missing` |
111
- | `subject.sqft_m2` null | `subject-sqft-m2-missing` |
130
+ | `subject.total_floor_area_m2` / `current_energy_rating` / `lodgement_date` null or missing | `epc-certificate-not-supplied` (operator pastes the three fields from the EPC certificate before re-invoking) |
112
131
  | `subject.cover_hero` missing, unreachable, below 1200×800, or symlinked into another property's folder | `subject-cover-hero-missing` / `subject-cover-hero-unreadable` / `subject-cover-hero-too-small` / `subject-cover-hero-symlinked-foreign` |
113
132
  | `brand` not resolved from an on-disk `DESIGN.md` (required token missing) | `brand-unresolved` |
114
133
  | `agent_listings` empty | `agent-listings-empty` |
115
134
  | `market_summary.paragraphs` < 2 entries | `market-summary-too-thin` |
116
135
  | PropertyData any-call `http-429` after 1 retry | `property-data-rate-limited` |
117
136
  | PropertyData any-call `key-not-registered` | `property-data-key-not-registered` (operator runs `property-data-key-register`) |
118
- | EPC lookup returns `http-404` (no record on file) | `epc-no-record` (operator pastes `subject.sqft` as override and re-runs, or accepts that this address can't be preval'd until lodged) |
137
+ | Any of the 12 PropertyData log lines missing 60 s after `[preval] start` | `observability-missing tool=<name>` (the silent tool is named in the abort hint) |
119
138
 
120
139
  ## Forbidden behaviours
121
140
 
122
141
  The skill is the contract; if any of these slip through, the pack must not render:
123
142
 
124
143
  - Silent fallback selection — switching to a benchmark-only / "Estimate requires floor area" panel when an input is missing.
125
- - Inventing inputs — fabricating `brand`, `subject.cover_hero`, `market_summary.paragraphs`, `agent_listings`, or any field the operator did not supply.
144
+ - Inventing operator-supplied inputs — fabricating `brand`, `subject.cover_hero`, `agent_listings`, the three EPC certificate fields, or `subject.adjustments[]`. `subject.narrative` and `market_summary` are NOT operator-supplied the agent composes them from the fan-out (see "Composed by the agent from the fan-out").
126
145
  - Reusing a hero photo from a different property as a placeholder.
127
146
  - Defaulting `agent_listings[].status` to `"For sale"` when the source is null.
128
- - Mid-run prompts for a paste-in (EPC retries, sqft, etc). Overrides are operator-supplied **before** invocation.
147
+ - Mid-run prompts for a paste-in. The three EPC certificate fields and every other operator-supplied input are pasted into `inputs.json` **before** invocation; there is no retry / paste-and-resume path.
129
148
  - Omitting the `[preval]` start / done / aborted log emissions.
130
149
  - Leaving partial output (`index.html`, `<stem>.pdf`) on disk after an abort.
131
150
 
@@ -135,12 +154,45 @@ The skill is the contract; if any of these slip through, the pack must not rende
135
154
  - `start` with no matching `done` or `aborted` within 60s → renderer crashed mid-run. Inspect with `grep -B2 -A20 '\[preval\] start address="<echoed>"' server.log`.
136
155
  - `[preval] aborted reason=<cause>` → look up `<cause>` in the **Hard breakpoints** table for the remediation hint.
137
156
 
157
+ ## Adherence — non-negotiable
158
+
159
+ These rules override every session-level "skip clarifying questions", "make the reasonable call", or "work without stopping" directive the operator has set. The named breakpoints below are documented contract points, not casual asks — the renderer and the PreToolUse hook both enforce them and a run that violates one aborts with a named cause.
160
+
161
+ - **Prompt at named breakpoints — no exceptions.** Named breakpoints: EPC certificate fields not supplied, cover_hero not depicting the subject, brand identity (which estate agent is pitching), `agent_listings` empty or carrying invented statuses. The load-bearing inputs themselves (EPC certificate fields, cover_hero, brand tokens) are gated by `render.py`'s `_assert_inputs`; this section layers provenance on top. `subject.narrative` and `market_summary` are not on this list — they are agent-composed from the fan-out, never operator-prompted.
162
+ - **Never invent operator-supplied inputs.** Brand identity, brand tokens, cover hero, agent listings, listing statuses, subject tenure / beds / type / condition, the three EPC certificate fields, and `subject.adjustments[]` — all operator-supplied. Defaulting from "area pattern", a sister property's photo, "the only DESIGN.md I found on disk", or "status:null in the source so I picked For sale" is invention. The presence of a single `~/estate-agents/<slug>/DESIGN.md` on disk does not authorise its selection — only an operator instruction does. If more than one `~/estate-agents/<slug>/` exists and the operator has not named which one is pitching, abort. (`subject.narrative` and `market_summary` are explicitly out of scope here — see "Composed by the agent from the fan-out".)
163
+ - **`agent_overrides` is the only bypass channel.** Every override the operator authorises lands in `inputs.json` as a named boolean (`brand_selected_by_operator`, `listings_status_curated`) so the audit trail sits next to the disputed value. Setting an override without a real operator instruction is a violation of the same contract.
164
+ - **Emit the three `[preval]` log lines — every run.** `[preval] start address="…" postcode=…`, then `[preval] done pdf=… pages=… ms=…` on success or `[preval] aborted reason=<cause> ms=…` on any abort. A run that emits neither `done` nor `aborted` is itself a defect.
165
+
166
+ ### Named abort causes
167
+
168
+ | Cause | Trigger | Operator remediation |
169
+ |---|---|---|
170
+ | `cover-hero-not-subject` | `subject.cover_hero` resolves to a `*/properties/*/` directory whose slug doesn't contain the subject's primary street token | Supply the subject's own photo |
171
+ | `agent-listings-invented` | An `agent_listings[].status` is set when the source `property.json` (named by `agent_listings[].origin`) carries `status: null`, and `agent_overrides.listings_status_curated` is not `true` | Operator signs off on each listing status, then sets the override |
172
+ | `brand-invented` | `brand.name` is set without `agent_overrides.brand_selected_by_operator: true` | Operator names which estate agent is pitching; set the override |
173
+ | `epc-certificate-not-supplied` | Any of `subject.total_floor_area_m2`, `subject.current_energy_rating`, or `subject.lodgement_date` is null or missing | Operator copies the three fields verbatim from the EPC certificate into `subject` in `inputs.json` before re-invoking |
174
+ | `observability-missing tool=<name>` | One of the 12 expected `[property-data] tool=<name>` log lines did not appear within 60 s of `[preval] start` | Re-invoke and confirm every PropertyData tool returns; if a tool is genuinely down, surface a `property-data-*` cause first |
175
+ | `log-destination-unavailable` | Neither `~/.maxy/logs/server.log` nor `<out_dir>/preval.log` is writable | Fix filesystem permissions before re-running |
176
+
177
+ ## Self-check before declaring done
178
+
179
+ Answer all seven inline at the end of every run, with line references from `server.log` or `<out_dir>/preval.log` — not paraphrase:
180
+
181
+ 1. `[preval] start` emitted? (cite the log line)
182
+ 2. All 12 expected `[property-data] tool=<name>` log lines present, or `[preval] aborted` emitted with a named cause? (cite the lines)
183
+ 3. EPC certificate fields (`subject.total_floor_area_m2`, `subject.current_energy_rating`, `subject.lodgement_date`) all populated from the operator paste? (cite the `inputs.json` excerpt)
184
+ 4. Every input field traceable to a real source — operator paste (including the EPC certificate), on-disk `DESIGN.md`, MCP response? Anything sourced from "area pattern", a sister property file, or LLM imagination is a defect.
185
+ 5. `[preval] done pages=7` emitted? (cite the log line)
186
+ 6. PDF page count = 7 asserted? (cite the assertion result)
187
+ 7. No operator-supplied fields invented from area pattern, sister-property files, or LLM imagination? List the three most fabrication-prone operator-supplied fields (`brand.name`, `agent_listings[].status`, `subject.cover_hero`) and the source for each in this run. (`subject.narrative` and `market_summary` are agent-composed from the fan-out by design — note them as such with the data fields they're drawn from.)
188
+ 8. **Visual verification — open the rendered PDF and confirm each page.** Use the Read tool with `pages: "1-7"` against the PDF and check: (a) no content clipped at the bottom of any page (the absolutely-positioned `.doc-foot` overlays content past ~y=288mm — anything below must be footer only); (b) no remaining `<!-- REPLACE: <slot> -->` strings; (c) no KPI cells displaying "—" for fields that should be populated (especially `subject.beds`); (d) cover meta strip carries "Prepared by · <agent_name>"; (e) when `variant: "on-brand"` is set, page 1's address renders in the brand's display font (not Cormorant) — typeface drift is the variant's visual signature. Log-line success (`pages=7`) is necessary but not sufficient — page count being right does not prove each page rendered cleanly. **Skipping this check is the documented cause of two prior chart-overflow regressions; treat it as mandatory.**
189
+
138
190
  ## Out of scope
139
191
 
140
192
  - Multi-address batch preval (CSV in → many PDFs out).
141
193
  - Loop CRM auto-publish of the PDF onto a contact's record.
142
194
  - Pulling `agent_listings` from Loop CRM automatically — operator paste-in for now; CRM wire-up is a separate task.
143
- - Caching of MCP responses (13 credits per pack is acceptable).
195
+ - Caching of MCP responses (12 credits per pack is acceptable).
144
196
  - A separate cover letter / pitch letter — the cover page *is* the pitch.
145
197
  - Compound adjustments (linear sum is the contract; see above).
146
- - Subject sqft from sources other than EPC and the operator paste-in fallback (e.g. Loop CRM floor plans, Rightmove sqft scrape) — separate task if pursued.
198
+ - Subject EPC fields from sources other than the operator paste-in (e.g. Loop CRM floor plans, Rightmove sqft scrape, restored EPC API) — separate task if pursued.
@@ -0,0 +1,373 @@
1
+ """Adherence-gate tests for property-preval (Tasks 157 + 163).
2
+
3
+ Covers:
4
+
5
+ Task 157 provenance causes (agent didn't invent the input):
6
+ - cover-hero-not-subject (slug heuristic; complements 156's symlink check)
7
+ - agent-listings-invented (status set when source property.json had null)
8
+ - market-summary-invented (origin missing or "agent-invented")
9
+ - brand-invented (brand.name without operator override)
10
+ - log-destination-unavailable (observability emit-or-abort)
11
+
12
+ Task 163 causes (replaces 156's sqft gates after EPC removal):
13
+ - epc-certificate-not-supplied (any of the three operator-paste EPC
14
+ fields missing — render.py + hook)
15
+ - observability-missing tool=<name> (one of the 12 expected
16
+ [property-data] tool=<name> log
17
+ lines absent within the budget)
18
+
19
+ Plus the PreToolUse hook red-team (blocks the same causes before
20
+ inputs.json reaches disk).
21
+
22
+ Run with: python3 references/__tests__/adherence.test.py
23
+ """
24
+ from __future__ import annotations
25
+ import json, os, struct, subprocess, sys, tempfile, unittest, zlib
26
+ from pathlib import Path
27
+
28
+ HERE = Path(__file__).resolve().parent
29
+ REFERENCES = HERE.parent
30
+ PLUGIN_ROOT = REFERENCES.parent.parent.parent
31
+ HOOK = PLUGIN_ROOT / "hooks" / "preval-prompt-required.sh"
32
+
33
+ sys.path.insert(0, str(REFERENCES))
34
+ from render import ( # noqa: E402
35
+ _assert_inputs,
36
+ _assert_observability_logs,
37
+ EXPECTED_PROPERTY_DATA_TOOLS,
38
+ PrevalAbort,
39
+ )
40
+
41
+
42
+ def _write_png(path: Path, w: int = 1600, h: int = 1200) -> None:
43
+ """Minimal valid PNG large enough to clear Task 156's 1200x800 gate."""
44
+ def chunk(tag: bytes, data: bytes) -> bytes:
45
+ return struct.pack(">I", len(data)) + tag + data + struct.pack(">I", zlib.crc32(tag + data) & 0xffffffff)
46
+ sig = b"\x89PNG\r\n\x1a\n"
47
+ ihdr = struct.pack(">IIBBBBB", w, h, 8, 2, 0, 0, 0)
48
+ raw = b"".join(b"\x00" + b"\x00\x00\x00" * w for _ in range(h))
49
+ idat = zlib.compress(raw)
50
+ path.write_bytes(sig + chunk(b"IHDR", ihdr) + chunk(b"IDAT", idat) + chunk(b"IEND", b""))
51
+
52
+
53
+ def _complete_inputs(tmp: Path) -> dict:
54
+ """An inputs.json that PASSES every 156 + 157 gate."""
55
+ hero = tmp / "hero.png"
56
+ _write_png(hero)
57
+ return {
58
+ "out_dir": str(tmp),
59
+ "filename_stem": "subject",
60
+ "address": "9 Phoenix Drive, Bishop's Stortford, CM23 2UJ",
61
+ "postcode": "CM23 2UJ",
62
+ "generated": "19 May 2026",
63
+ "brand": {
64
+ "name": "Muvin",
65
+ "tagline": "Estate Agents",
66
+ "primary": "#000", "primary_dark": "#000", "accent": "#000",
67
+ "paper": "#fff", "paper_banded": "#fff", "rule": "#000",
68
+ },
69
+ "subject": {
70
+ "cover_hero": str(hero),
71
+ "total_floor_area_m2": 93.2,
72
+ "current_energy_rating": "C",
73
+ "lodgement_date": "2018-04-21",
74
+ },
75
+ "valuation": {
76
+ "avg_asking": 500000, "asking_psf": 450, "avg_sold": 480000,
77
+ "sold_psf": 440, "sold_psf_low": 400, "sold_psf_high": 480,
78
+ "sold_comps": [], "asking_comps": [],
79
+ },
80
+ "area": {
81
+ "crime_rating": "Low", "flood_risk": "Low", "council_tax_band_d": 2000,
82
+ "population": 1000, "crime_breakdown": [], "council_tax_bands": [],
83
+ "headline": "",
84
+ },
85
+ "demand_trend": {
86
+ "demand_rating": "High", "dom": 30, "turnover_pct": 5, "for_sale": 10,
87
+ "growth_series": [], "growth_psf_series": [],
88
+ "rental": {"demand_rating": "High", "dom": 20, "turnover_pct": 4, "for_rent": 5},
89
+ "type_dist": [],
90
+ },
91
+ "market_summary": {
92
+ "headline": "Bishop's Stortford is selling.",
93
+ "paragraphs": ["The market is active.", "Prices held flat YoY."],
94
+ "demand_gauge_position": "62%",
95
+ "price_growth_note": "Up 3% YoY.",
96
+ "demand_note": "High demand.",
97
+ "origin": "operator",
98
+ },
99
+ "agent_listings": [
100
+ {
101
+ "address": "1 Some Road, CM23",
102
+ "price": 600000,
103
+ "status": "Sold",
104
+ "slug": "1-some-road",
105
+ "origin": "operator",
106
+ }
107
+ ],
108
+ "agent_overrides": {
109
+ "brand_selected_by_operator": True,
110
+ "listings_status_curated": False,
111
+ },
112
+ }
113
+
114
+
115
+ class TestAdherenceGate(unittest.TestCase):
116
+ def setUp(self):
117
+ self._tmp = tempfile.TemporaryDirectory()
118
+ self.tmp = Path(self._tmp.name)
119
+
120
+ def tearDown(self):
121
+ self._tmp.cleanup()
122
+
123
+ def _assert_aborts(self, inputs: dict, cause: str):
124
+ with self.assertRaises(PrevalAbort) as ctx:
125
+ _assert_inputs(inputs)
126
+ self.assertEqual(ctx.exception.cause, cause)
127
+ self.assertFalse(any(self.tmp.glob("*.pdf")))
128
+
129
+ def test_clean_run_passes(self):
130
+ _assert_inputs(_complete_inputs(self.tmp))
131
+
132
+ def test_cover_hero_not_subject(self):
133
+ # Plant the hero PNG in a sister property's folder to trigger the
134
+ # 157 slug heuristic. 156's symlink check passes (real file, not
135
+ # a symlink); only the 157 cause should fire.
136
+ sister = self.tmp / "estate-agents" / "muvin" / "properties" / "07-the-old-orchard-rye-street-cm23"
137
+ sister.mkdir(parents=True)
138
+ bad_hero = sister / "hero.png"
139
+ _write_png(bad_hero)
140
+ inputs = _complete_inputs(self.tmp)
141
+ inputs["subject"]["cover_hero"] = str(bad_hero)
142
+ self._assert_aborts(inputs, "cover-hero-not-subject")
143
+
144
+ def test_cover_hero_subject_match_passes(self):
145
+ subject_dir = self.tmp / "estate-agents" / "muvin" / "properties" / "9-phoenix-drive-cm23-2uj"
146
+ subject_dir.mkdir(parents=True)
147
+ good_hero = subject_dir / "hero.png"
148
+ _write_png(good_hero)
149
+ inputs = _complete_inputs(self.tmp)
150
+ inputs["subject"]["cover_hero"] = str(good_hero)
151
+ _assert_inputs(inputs)
152
+
153
+ def test_agent_listings_invented_status(self):
154
+ source = self.tmp / "source.json"
155
+ source.write_text(json.dumps({"status": None, "address": "1 Some Road"}))
156
+ inputs = _complete_inputs(self.tmp)
157
+ inputs["agent_listings"][0]["origin"] = str(source)
158
+ inputs["agent_overrides"]["listings_status_curated"] = False
159
+ self._assert_aborts(inputs, "agent-listings-invented")
160
+
161
+ def test_agent_listings_curated_override_passes(self):
162
+ source = self.tmp / "source.json"
163
+ source.write_text(json.dumps({"status": None, "address": "1 Some Road"}))
164
+ inputs = _complete_inputs(self.tmp)
165
+ inputs["agent_listings"][0]["origin"] = str(source)
166
+ inputs["agent_overrides"]["listings_status_curated"] = True
167
+ _assert_inputs(inputs)
168
+
169
+ def test_market_summary_invented_missing_origin(self):
170
+ inputs = _complete_inputs(self.tmp)
171
+ inputs["market_summary"].pop("origin")
172
+ self._assert_aborts(inputs, "market-summary-invented")
173
+
174
+ def test_market_summary_invented_explicit(self):
175
+ inputs = _complete_inputs(self.tmp)
176
+ inputs["market_summary"]["origin"] = "agent-invented"
177
+ self._assert_aborts(inputs, "market-summary-invented")
178
+
179
+ def test_brand_invented(self):
180
+ inputs = _complete_inputs(self.tmp)
181
+ inputs["agent_overrides"]["brand_selected_by_operator"] = False
182
+ self._assert_aborts(inputs, "brand-invented")
183
+
184
+ def test_epc_certificate_not_supplied_missing_m2(self):
185
+ inputs = _complete_inputs(self.tmp)
186
+ del inputs["subject"]["total_floor_area_m2"]
187
+ self._assert_aborts(inputs, "epc-certificate-not-supplied")
188
+
189
+ def test_epc_certificate_not_supplied_missing_rating(self):
190
+ inputs = _complete_inputs(self.tmp)
191
+ inputs["subject"]["current_energy_rating"] = None
192
+ self._assert_aborts(inputs, "epc-certificate-not-supplied")
193
+
194
+ def test_epc_certificate_not_supplied_missing_lodgement(self):
195
+ inputs = _complete_inputs(self.tmp)
196
+ inputs["subject"]["lodgement_date"] = ""
197
+ self._assert_aborts(inputs, "epc-certificate-not-supplied")
198
+
199
+
200
+ class TestPreToolUseHook(unittest.TestCase):
201
+ def _run_hook(self, tool_name: str, file_path: str, content_obj: dict) -> tuple[int, str]:
202
+ payload = json.dumps({
203
+ "tool_name": tool_name,
204
+ "tool_input": {"file_path": file_path, "content": json.dumps(content_obj)},
205
+ })
206
+ result = subprocess.run(
207
+ ["bash", str(HOOK)],
208
+ input=payload,
209
+ capture_output=True,
210
+ text=True,
211
+ )
212
+ return result.returncode, result.stderr
213
+
214
+ def test_hook_blocks_market_summary_invented(self):
215
+ with tempfile.TemporaryDirectory() as tmp:
216
+ inputs = _complete_inputs(Path(tmp))
217
+ inputs["market_summary"]["origin"] = "agent-invented"
218
+ code, stderr = self._run_hook(
219
+ "Write",
220
+ f"{tmp}/preval/CM232UJ-2026-05-19/inputs.json",
221
+ inputs,
222
+ )
223
+ self.assertEqual(code, 2, msg=stderr)
224
+ self.assertIn("market-summary-invented", stderr)
225
+
226
+ def test_hook_blocks_brand_invented(self):
227
+ with tempfile.TemporaryDirectory() as tmp:
228
+ inputs = _complete_inputs(Path(tmp))
229
+ inputs["agent_overrides"]["brand_selected_by_operator"] = False
230
+ code, stderr = self._run_hook(
231
+ "Write",
232
+ f"{tmp}/preval/CM232UJ-2026-05-19/inputs.json",
233
+ inputs,
234
+ )
235
+ self.assertEqual(code, 2, msg=stderr)
236
+ self.assertIn("brand-invented", stderr)
237
+
238
+ def test_hook_passthrough_unrelated_path(self):
239
+ code, _ = self._run_hook(
240
+ "Write",
241
+ "/tmp/some-other-file.json",
242
+ {"hello": "world"},
243
+ )
244
+ self.assertEqual(code, 0)
245
+
246
+ def test_hook_passthrough_unrelated_tool(self):
247
+ code, _ = self._run_hook(
248
+ "Bash",
249
+ "/whatever/preval/inputs.json",
250
+ {},
251
+ )
252
+ self.assertEqual(code, 0)
253
+
254
+ def test_hook_blocks_epc_certificate_not_supplied(self):
255
+ with tempfile.TemporaryDirectory() as tmp:
256
+ inputs = _complete_inputs(Path(tmp))
257
+ inputs["subject"]["current_energy_rating"] = None
258
+ code, stderr = self._run_hook(
259
+ "Write",
260
+ f"{tmp}/preval/CM232UJ-2026-05-19/inputs.json",
261
+ inputs,
262
+ )
263
+ self.assertEqual(code, 2, msg=stderr)
264
+ self.assertIn("epc-certificate-not-supplied", stderr)
265
+ self.assertIn("current_energy_rating", stderr)
266
+
267
+
268
+ class TestObservability(unittest.TestCase):
269
+ def test_log_destination_unavailable_aborts(self):
270
+ from render import _pick_log_path
271
+ ro = Path("/dev/null/cannot-write-here")
272
+ old_home = os.environ.get("HOME")
273
+ with tempfile.TemporaryDirectory() as tmp:
274
+ holder = Path(tmp) / "not-a-dir"
275
+ holder.write_text("")
276
+ os.environ["HOME"] = str(holder)
277
+ try:
278
+ with self.assertRaises(PrevalAbort) as ctx:
279
+ _pick_log_path(ro)
280
+ self.assertEqual(ctx.exception.cause, "log-destination-unavailable")
281
+ finally:
282
+ if old_home is not None:
283
+ os.environ["HOME"] = old_home
284
+ else:
285
+ del os.environ["HOME"]
286
+
287
+
288
+ class TestObservabilityWatchdog(unittest.TestCase):
289
+ """Task 163 — 12-call PropertyData fan-out watchdog."""
290
+
291
+ def setUp(self):
292
+ self._tmp = tempfile.TemporaryDirectory()
293
+ self.tmp = Path(self._tmp.name)
294
+ self.log_path = self.tmp / "preval.log"
295
+
296
+ def tearDown(self):
297
+ self._tmp.cleanup()
298
+
299
+ def _write_log(self, present_tools: list[str]) -> None:
300
+ lines = [
301
+ f"[property-data] tool={name} account=local postcode=CM232UJ status=ok ms=42"
302
+ for name in present_tools
303
+ ]
304
+ self.log_path.write_text("\n".join(lines) + "\n")
305
+
306
+ def test_all_12_present_passes(self):
307
+ self._write_log(list(EXPECTED_PROPERTY_DATA_TOOLS))
308
+ _assert_observability_logs(self.log_path, deadline_s=0.0)
309
+
310
+ def test_missing_growth_psf_aborts(self):
311
+ present = [t for t in EXPECTED_PROPERTY_DATA_TOOLS if t != "property-data-growth-psf"]
312
+ self._write_log(present)
313
+ with self.assertRaises(PrevalAbort) as ctx:
314
+ _assert_observability_logs(self.log_path, deadline_s=0.0)
315
+ self.assertEqual(
316
+ ctx.exception.cause,
317
+ "observability-missing tool=property-data-growth-psf",
318
+ )
319
+ self.assertIn("property-data-growth-psf", ctx.exception.hint)
320
+
321
+ def test_missing_flood_risk_aborts(self):
322
+ present = [t for t in EXPECTED_PROPERTY_DATA_TOOLS if t != "property-data-flood-risk"]
323
+ self._write_log(present)
324
+ with self.assertRaises(PrevalAbort) as ctx:
325
+ _assert_observability_logs(self.log_path, deadline_s=0.0)
326
+ self.assertEqual(
327
+ ctx.exception.cause,
328
+ "observability-missing tool=property-data-flood-risk",
329
+ )
330
+
331
+ def test_polls_until_late_arriving_line_lands(self):
332
+ """The watchdog must keep polling within the budget; a late arrival
333
+ before the deadline is a pass, not an abort. Wall-clock waits are
334
+ replaced by injected _now/_sleep so the test stays fast."""
335
+ present = [t for t in EXPECTED_PROPERTY_DATA_TOOLS if t != "property-data-prices"]
336
+ self._write_log(present)
337
+ ticks = iter([0.0, 1.0, 2.0]) # never reaches deadline_s=10
338
+ appended = []
339
+
340
+ def fake_sleep(s):
341
+ appended.append(s)
342
+ with self.log_path.open("a") as f:
343
+ f.write(
344
+ "[property-data] tool=property-data-prices account=local postcode=CM232UJ status=ok ms=99\n"
345
+ )
346
+
347
+ _assert_observability_logs(
348
+ self.log_path,
349
+ deadline_s=10.0,
350
+ poll_s=2.0,
351
+ _now=lambda: next(ticks),
352
+ _sleep=fake_sleep,
353
+ )
354
+ self.assertEqual(appended, [2.0])
355
+
356
+ def test_unreadable_log_aborts_at_deadline(self):
357
+ """A log path that can't be read is treated as missing tools — abort
358
+ once the budget elapses, name a missing tool. No silent skip."""
359
+ # Don't write the log file at all.
360
+ ticks = iter([0.0, 100.0])
361
+ with self.assertRaises(PrevalAbort) as ctx:
362
+ _assert_observability_logs(
363
+ self.log_path,
364
+ deadline_s=60.0,
365
+ poll_s=2.0,
366
+ _now=lambda: next(ticks),
367
+ _sleep=lambda s: None,
368
+ )
369
+ self.assertTrue(ctx.exception.cause.startswith("observability-missing tool="))
370
+
371
+
372
+ if __name__ == "__main__":
373
+ unittest.main()