@open-mercato/cli 0.6.7-develop.6685.1.77c0a5591b → 0.6.7-develop.6687.1.46a258e592

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 (215) hide show
  1. package/.turbo/turbo-build.log +2 -3
  2. package/build.mjs +21 -5
  3. package/dist/agentic/claude-code/hooks/entity-migration-check.ts +32 -88
  4. package/dist/agentic/codex/enforcement-rules.md +2 -16
  5. package/dist/agentic/cursor/hooks/entity-migration-check.mjs +19 -50
  6. package/dist/agentic/cursor/rules/entity-guard.mdc +9 -21
  7. package/dist/agentic/cursor/rules/generated-guard.mdc +3 -5
  8. package/dist/agentic/cursor/rules/open-mercato.mdc +3 -29
  9. package/dist/agentic/guides/ai-workflows.md +76 -0
  10. package/dist/agentic/guides/architecture.md +107 -0
  11. package/dist/agentic/guides/backend-ui.md +80 -0
  12. package/dist/agentic/guides/contracts.md +92 -0
  13. package/dist/agentic/guides/extensions.md +104 -0
  14. package/dist/agentic/guides/integrations.md +81 -0
  15. package/dist/agentic/guides/module-facts.json +217 -81
  16. package/dist/agentic/guides/module-system.md +12 -127
  17. package/dist/agentic/guides/modules/ai_assistant.md +1 -1
  18. package/dist/agentic/guides/modules/api_docs.md +1 -1
  19. package/dist/agentic/guides/modules/api_keys.md +1 -1
  20. package/dist/agentic/guides/modules/attachments.md +2 -2
  21. package/dist/agentic/guides/modules/audit_logs.md +2 -2
  22. package/dist/agentic/guides/modules/auth.md +1 -1
  23. package/dist/agentic/guides/modules/business_rules.md +1 -1
  24. package/dist/agentic/guides/modules/catalog.md +5 -5
  25. package/dist/agentic/guides/modules/channel_gmail.md +1 -1
  26. package/dist/agentic/guides/modules/channel_imap.md +1 -1
  27. package/dist/agentic/guides/modules/checkout.md +1 -1
  28. package/dist/agentic/guides/modules/communication_channels.md +1 -1
  29. package/dist/agentic/guides/modules/configs.md +1 -1
  30. package/dist/agentic/guides/modules/content.md +1 -1
  31. package/dist/agentic/guides/modules/currencies.md +1 -1
  32. package/dist/agentic/guides/modules/customer_accounts.md +1 -1
  33. package/dist/agentic/guides/modules/customers.md +2 -2
  34. package/dist/agentic/guides/modules/dashboards.md +1 -1
  35. package/dist/agentic/guides/modules/data_sync.md +1 -1
  36. package/dist/agentic/guides/modules/dictionaries.md +1 -1
  37. package/dist/agentic/guides/modules/directory.md +1 -1
  38. package/dist/agentic/guides/modules/entities.md +2 -2
  39. package/dist/agentic/guides/modules/events.md +1 -1
  40. package/dist/agentic/guides/modules/feature_toggles.md +1 -1
  41. package/dist/agentic/guides/modules/gateway_stripe.md +1 -1
  42. package/dist/agentic/guides/modules/generators.md +1 -1
  43. package/dist/agentic/guides/modules/inbox_ops.md +1 -1
  44. package/dist/agentic/guides/modules/integrations.md +1 -1
  45. package/dist/agentic/guides/modules/messages.md +1 -1
  46. package/dist/agentic/guides/modules/notifications.md +1 -1
  47. package/dist/agentic/guides/modules/onboarding.md +1 -1
  48. package/dist/agentic/guides/modules/payment_gateways.md +1 -1
  49. package/dist/agentic/guides/modules/perspectives.md +1 -1
  50. package/dist/agentic/guides/modules/planner.md +1 -1
  51. package/dist/agentic/guides/modules/portal.md +1 -1
  52. package/dist/agentic/guides/modules/progress.md +1 -1
  53. package/dist/agentic/guides/modules/query_index.md +2 -2
  54. package/dist/agentic/guides/modules/record_locks.md +1 -1
  55. package/dist/agentic/guides/modules/resources.md +1 -1
  56. package/dist/agentic/guides/modules/sales.md +17 -17
  57. package/dist/agentic/guides/modules/scheduler.md +1 -1
  58. package/dist/agentic/guides/modules/search.md +1 -1
  59. package/dist/agentic/guides/modules/security.md +1 -1
  60. package/dist/agentic/guides/modules/shipping_carriers.md +1 -1
  61. package/dist/agentic/guides/modules/sso.md +1 -1
  62. package/dist/agentic/guides/modules/staff.md +2 -2
  63. package/dist/agentic/guides/modules/storage_s3.md +1 -1
  64. package/dist/agentic/guides/modules/sync_akeneo.md +1 -1
  65. package/dist/agentic/guides/modules/sync_excel.md +1 -1
  66. package/dist/agentic/guides/modules/system_status_overlays.md +1 -1
  67. package/dist/agentic/guides/modules/translations.md +1 -1
  68. package/dist/agentic/guides/modules/webhooks.md +2 -2
  69. package/dist/agentic/guides/modules/wms.md +2 -2
  70. package/dist/agentic/guides/modules/workflows.md +1 -1
  71. package/dist/agentic/guides/testing-debugging.md +74 -0
  72. package/dist/agentic/guides/upstream/AGENTS.md +297 -0
  73. package/dist/agentic/guides/upstream/BACKWARD_COMPATIBILITY.md +303 -0
  74. package/dist/agentic/guides/upstream/manifest.json +8 -0
  75. package/dist/agentic/shared/AGENTS.md.template +123 -311
  76. package/dist/agentic/shared/ai/agentic.config.json +1 -0
  77. package/dist/agentic/shared/ai/harness/README.md +48 -0
  78. package/dist/agentic/shared/ai/harness/RELEASE.md +57 -0
  79. package/dist/agentic/shared/ai/harness/cases.json +13487 -0
  80. package/dist/agentic/shared/ai/harness/cases.schema.json +132 -0
  81. package/dist/agentic/shared/ai/harness/fixtures/index.json +49 -0
  82. package/dist/agentic/shared/ai/harness/fixtures/seeds.json +162 -0
  83. package/dist/agentic/shared/ai/harness/generated-code-review-policy.md +20 -0
  84. package/dist/agentic/shared/ai/harness/generated-code-review-response.schema.json +43 -0
  85. package/dist/agentic/shared/ai/harness/generated-code-review-result.schema.json +110 -0
  86. package/dist/agentic/shared/ai/harness/release-matrix.json +133 -0
  87. package/dist/agentic/shared/ai/harness/release-result.schema.json +219 -0
  88. package/dist/agentic/shared/ai/harness/result.schema.json +76 -0
  89. package/dist/agentic/shared/ai/harness/routing-response.schema.json +12 -0
  90. package/dist/agentic/shared/ai/harness/target-validation-result.schema.json +73 -0
  91. package/dist/agentic/shared/ai/harness/validators.json +78 -0
  92. package/dist/agentic/shared/ai/harness/writable-ast-oracles.mjs +1768 -0
  93. package/dist/agentic/shared/ai/harness/writable-behavior-oracles.mjs +1096 -0
  94. package/dist/agentic/shared/ai/review-checklist.md +36 -0
  95. package/dist/agentic/shared/ai/skills/om-auto-review-pr/SKILL.md +4 -0
  96. package/dist/agentic/shared/ai/skills/om-backend-ui-design/SKILL.md +20 -241
  97. package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/crud-surfaces.md +16 -0
  98. package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/frontend-and-design-system.md +53 -0
  99. package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/page-and-navigation.md +13 -0
  100. package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/quality-states.md +11 -0
  101. package/dist/agentic/shared/ai/skills/om-build-workflow/SKILL.md +30 -0
  102. package/dist/agentic/shared/ai/skills/om-build-workflow/references/activity-contracts.md +12 -0
  103. package/dist/agentic/shared/ai/skills/om-build-workflow/references/durability-and-progress.md +13 -0
  104. package/dist/agentic/shared/ai/skills/om-build-workflow/references/workflow-design.md +14 -0
  105. package/dist/agentic/shared/ai/skills/om-create-ai-agent/SKILL.md +28 -0
  106. package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/attachments-and-overrides.md +12 -0
  107. package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/module-agents-and-tools.md +22 -0
  108. package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/orchestrator-agents.md +12 -0
  109. package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/surface-selector.md +19 -0
  110. package/dist/agentic/shared/ai/skills/om-data-model-design/SKILL.md +16 -601
  111. package/dist/agentic/shared/ai/skills/om-data-model-design/references/integrity-and-concurrency.md +19 -0
  112. package/dist/agentic/shared/ai/skills/om-data-model-design/references/migration-workflow.md +13 -0
  113. package/dist/agentic/shared/ai/skills/om-data-model-design/references/schema-design.md +14 -0
  114. package/dist/agentic/shared/ai/skills/om-data-model-design/references/sensitive-data.md +10 -0
  115. package/dist/agentic/shared/ai/skills/om-eject-and-customize/SKILL.md +14 -310
  116. package/dist/agentic/shared/ai/skills/om-eject-and-customize/references/decision-and-procedure.md +17 -0
  117. package/dist/agentic/shared/ai/skills/om-evolve-harness/SKILL.md +28 -0
  118. package/dist/agentic/shared/ai/skills/om-evolve-harness/references/case-template.md +89 -0
  119. package/dist/agentic/shared/ai/skills/om-evolve-harness/references/case-workflow.md +16 -0
  120. package/dist/agentic/shared/ai/skills/om-evolve-harness/references/owner-selection.md +17 -0
  121. package/dist/agentic/shared/ai/skills/om-framework-context/SKILL.md +25 -0
  122. package/dist/agentic/shared/ai/skills/om-framework-context/references/resolver-procedure.md +11 -0
  123. package/dist/agentic/shared/ai/skills/om-framework-context/references/skew-and-escalation.md +13 -0
  124. package/dist/agentic/shared/ai/skills/om-help/SKILL.md +15 -97
  125. package/dist/agentic/shared/ai/skills/om-help/references/delivery-workflows.md +17 -0
  126. package/dist/agentic/shared/ai/skills/om-help/references/task-families.md +20 -0
  127. package/dist/agentic/shared/ai/skills/om-implement-spec/SKILL.md +15 -156
  128. package/dist/agentic/shared/ai/skills/om-implement-spec/references/phases-and-gates.md +12 -0
  129. package/dist/agentic/shared/ai/skills/om-integration-builder/SKILL.md +24 -708
  130. package/dist/agentic/shared/ai/skills/om-integration-builder/references/package-and-activation.md +16 -0
  131. package/dist/agentic/shared/ai/skills/om-integration-builder/references/provider-families.md +14 -0
  132. package/dist/agentic/shared/ai/skills/om-integration-builder/references/security-and-reliability.md +15 -0
  133. package/dist/agentic/shared/ai/skills/om-integration-builder/references/sync-and-files.md +12 -0
  134. package/dist/agentic/shared/ai/skills/om-module-scaffold/SKILL.md +20 -820
  135. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/api-and-domain.md +19 -0
  136. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/business-one-shot-blueprints.md +107 -0
  137. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/data-and-migrations.md +12 -0
  138. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/discovery-surface-catalog.md +83 -0
  139. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/module-surfaces.md +21 -0
  140. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/planning.md +11 -0
  141. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/runtime-cache-and-queues.md +22 -0
  142. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/verification.md +13 -0
  143. package/dist/agentic/shared/ai/skills/om-system-extension/SKILL.md +19 -843
  144. package/dist/agentic/shared/ai/skills/om-system-extension/references/extension-branches.md +18 -0
  145. package/dist/agentic/shared/ai/skills/om-system-extension/references/mechanism-selector.md +25 -0
  146. package/dist/agentic/shared/ai/skills/om-system-extension/references/read-write-roundtrip.md +13 -0
  147. package/dist/agentic/shared/ai/skills/om-system-extension/references/unified-overrides.md +38 -0
  148. package/dist/agentic/shared/ai/skills/om-system-extension/references/verification.md +11 -0
  149. package/dist/agentic/shared/ai/skills/om-trim-unused-modules/SKILL.md +15 -63
  150. package/dist/agentic/shared/ai/skills/om-trim-unused-modules/references/dependency-and-redirect.md +15 -0
  151. package/dist/agentic/shared/ai/skills/om-troubleshooter/SKILL.md +16 -467
  152. package/dist/agentic/shared/ai/skills/om-troubleshooter/references/diagnosis-map.md +16 -0
  153. package/dist/agentic/shared/ai/skills/om-troubleshooter/references/regression-oracles.md +14 -0
  154. package/dist/agentic/shared/ai/skills/tiers.json +137 -20
  155. package/dist/agentic/shared/ai/skills/tiers.schema.json +52 -40
  156. package/dist/agentic/shared/scripts/agent-harness-tool-server.mjs +174 -0
  157. package/dist/agentic/shared/scripts/evaluate-agent-harness.mjs +2783 -0
  158. package/dist/agentic/shared/scripts/execution-sandbox.mjs +329 -0
  159. package/dist/agentic/shared/scripts/framework-context.mjs +894 -0
  160. package/dist/agentic/shared/scripts/install-skills.mjs +1029 -0
  161. package/dist/agentic/shared/scripts/install-skills.sh +4 -694
  162. package/dist/agentic/shared/scripts/prepare-agent-harness-fixture.mjs +222 -0
  163. package/dist/agentic/shared/scripts/run-agent-harness-release.mjs +1761 -0
  164. package/dist/lib/__integration__/TC-INT-008.spec.js +87 -8
  165. package/dist/lib/__integration__/TC-INT-008.spec.js.map +2 -2
  166. package/dist/lib/agentic-init.js +13 -3
  167. package/dist/lib/agentic-init.js.map +2 -2
  168. package/dist/lib/agentic-setup.js +418 -186
  169. package/dist/lib/agentic-setup.js.map +2 -2
  170. package/dist/lib/generators/extensions/injection-widgets.js +20 -0
  171. package/dist/lib/generators/extensions/injection-widgets.js.map +2 -2
  172. package/dist/lib/generators/module-facts-discovery.js +41 -7
  173. package/dist/lib/generators/module-facts-discovery.js.map +2 -2
  174. package/dist/lib/generators/module-facts.js +65 -17
  175. package/dist/lib/generators/module-facts.js.map +2 -2
  176. package/dist/lib/generators/module-registry.js +5 -4
  177. package/dist/lib/generators/module-registry.js.map +2 -2
  178. package/dist/lib/resolver.js +2 -0
  179. package/dist/lib/resolver.js.map +2 -2
  180. package/package.json +5 -5
  181. package/src/lib/__integration__/TC-INT-008.spec.ts +103 -8
  182. package/src/lib/__tests__/agentic-init.test.ts +41 -5
  183. package/src/lib/__tests__/agentic-setup.ownership.test.ts +380 -0
  184. package/src/lib/__tests__/injection-widget-id-validation.test.ts +184 -0
  185. package/src/lib/agentic-init.ts +15 -3
  186. package/src/lib/agentic-setup.ts +526 -224
  187. package/src/lib/generators/__tests__/module-facts.bc-guard.test.ts +6 -0
  188. package/src/lib/generators/__tests__/module-facts.customers.fixture.test.ts +1 -0
  189. package/src/lib/generators/__tests__/module-facts.discovery.test.ts +54 -10
  190. package/src/lib/generators/__tests__/module-facts.extension-hosts.test.ts +108 -0
  191. package/src/lib/generators/__tests__/module-subset.test.ts +18 -0
  192. package/src/lib/generators/extensions/injection-widgets.ts +51 -0
  193. package/src/lib/generators/module-facts-discovery.ts +58 -7
  194. package/src/lib/generators/module-facts.ts +84 -20
  195. package/src/lib/generators/module-registry.ts +8 -4
  196. package/src/lib/resolver.ts +3 -0
  197. package/dist/agentic/guides/cache.md +0 -45
  198. package/dist/agentic/guides/core.md +0 -453
  199. package/dist/agentic/guides/events.md +0 -117
  200. package/dist/agentic/guides/queue.md +0 -53
  201. package/dist/agentic/guides/search.md +0 -115
  202. package/dist/agentic/guides/shared.md +0 -108
  203. package/dist/agentic/guides/ui.md +0 -347
  204. package/dist/agentic/shared/ai/skills/om-auto-continue-pr-loop/SKILL.md +0 -27
  205. package/dist/agentic/shared/ai/skills/om-auto-create-pr-loop/SKILL.md +0 -27
  206. package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/ui-components.md +0 -260
  207. package/dist/agentic/shared/ai/skills/om-data-model-design/references/mikro-orm-cheatsheet.md +0 -146
  208. package/dist/agentic/shared/ai/skills/om-help/references/skills-catalog.md +0 -84
  209. package/dist/agentic/shared/ai/skills/om-help/references/workflow-sequences.md +0 -193
  210. package/dist/agentic/shared/ai/skills/om-integration-builder/STANDALONE.md +0 -34
  211. package/dist/agentic/shared/ai/skills/om-integration-builder/references/adapter-contracts.md +0 -762
  212. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/naming-conventions.md +0 -50
  213. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/navigation-patterns.md +0 -97
  214. package/dist/agentic/shared/ai/skills/om-system-extension/references/extension-contracts.md +0 -271
  215. package/dist/agentic/shared/ai/skills/om-troubleshooter/references/diagnostic-commands.md +0 -101
@@ -1,315 +1,127 @@
1
- # Agent Context Routing — {{PROJECT_NAME}}
2
-
3
- **MANDATORY CONTEXT LOADING** — see the "BEFORE writing ANY code" Critical Rule below.
4
- Before writing code, find your task below and `Read` the listed files.
5
- Do NOT load the entire src/ tree — Open Mercato apps can have many modules.
6
-
7
- ## What This Project Is
8
-
9
- A standalone Open Mercato application built ON TOP of the framework.
10
- The framework lives in `node_modules/@open-mercato/*`. Never edit `node_modules` directly.
11
- Install official packages with `yarn mercato module add @open-mercato/<package>`.
12
- To customise a built-in module beyond extensions, eject with `yarn mercato eject <module>`.
13
-
14
- ## Task → Context Map
15
-
16
- Match your task below, then **STOP and Read the listed file(s)** before writing
17
- any code. A task may match multiple rows — load all of them. If you skip this
18
- step, you WILL produce incorrect imports and miss required patterns.
19
-
20
- ### Module Development
21
-
22
- | Task | Load |
23
- |---|---|
24
- | Understand the module system (anatomy, auto-discovery, naming, mandatory mechanisms, data integrity, migrations) | `.ai/guides/module-system.md` |
25
- | Scaffold a new module from scratch | `.ai/skills/om-module-scaffold/SKILL.md` |
26
- | Design entities and relationships | `.ai/skills/om-data-model-design/SKILL.md` |
27
- | Build backend UI (forms, tables, pages) | `.ai/skills/om-backend-ui-design/SKILL.md` |
28
- | Build an integration provider | `.ai/skills/om-integration-builder/SKILL.md` |
29
-
30
- ### Extending Core Modules (UMES)
31
-
32
- | Task | Load |
33
- |---|---|
34
- | Extend a core module (add fields, columns, menus, interceptors, enrichers) | `.ai/skills/om-system-extension/SKILL.md` |
35
- | Eject and customize a core module | `.ai/skills/om-eject-and-customize/SKILL.md` |
36
- | Add a response enricher to another module's API | `.ai/guides/core.md` → Response Enrichers |
37
- | Add an API interceptor (before/after hooks) | `.ai/guides/core.md` → API Interceptors |
38
- | Inject widgets into forms/tables/menus | `.ai/guides/core.md` → Widget Injection |
39
- | Replace or wrap a UI component | `.ai/guides/core.md` → Component Replacement |
40
-
41
- ### Framework Feature Usage
42
-
43
- | Task | Load |
44
- |---|---|
45
- | Add/modify an entity, create migration | `.ai/skills/om-data-model-design/SKILL.md`, `.ai/guides/core.md` → Module Files, then `yarn db:generate` |
46
- | Add a REST API endpoint | `.ai/guides/core.md` → API Routes |
47
- | Add a backend page | `.ai/guides/ui.md` → CrudForm / DataTable |
48
- | Configure sidebar navigation, page groups, settings pages | `.ai/skills/om-module-scaffold/references/navigation-patterns.md` |
49
- | Add event subscribers or emit events | `.ai/guides/events.md` |
50
- | Add real-time browser updates (SSE) | `.ai/guides/events.md` → DOM Event Bridge |
51
- | Add search to a module | `.ai/guides/search.md` |
52
- | Add caching | `.ai/guides/cache.md` |
53
- | Add background workers | `.ai/guides/queue.md` |
54
- | Use i18n (translations) | `.ai/guides/shared.md` → i18n |
55
- | Use encrypted queries (read sensitive columns that already have an encryption map; for authoring a NEW sensitive column see the row below first) | `.ai/guides/shared.md` → Encryption |
56
- | **Encrypt sensitive / GDPR-relevant fields** ("we need this column encrypted", "store this securely", "this is PII", "GDPR", "encryption at rest", addresses, contact info, free-text notes about people, integration credentials, secrets) — declare them in the framework's encryption-maps mechanism, never hand-rolled AES/KMS | `.ai/skills/om-data-model-design/SKILL.md` → Sensitive Data and Encryption Maps, then `.ai/skills/om-module-scaffold/SKILL.md` → Encryption maps. Reference: <https://docs.open-mercato.dev/user-guide/encryption> |
57
- | Use apiCall / UI components | `.ai/guides/ui.md` |
58
- | Add permissions (RBAC) | `.ai/guides/core.md` → Access Control |
59
- | Add notifications | `.ai/guides/core.md` → Notifications |
60
- | Add custom fields | `.ai/guides/core.md` → Custom Fields |
61
-
62
- ### Module-Specific Guides
63
-
64
- These per-module fact-sheets are **generated from source** and bundled for the modules enabled in this app. The list below is regenerated on scaffold from your enabled module set — do not edit between the markers.
1
+ # {{PROJECT_NAME}} — Standalone App Agent Rules
2
+
3
+ Extend this app. Route first; never probe unmatched context.
4
+
5
+ ## Always
6
+
7
+ - Route all axes; missing context: `yarn mercato agentic:init --update-harness`.
8
+ - App code: `src/modules/<id>/`; framework context only for a named version gap.
9
+ - Derive trusted `tenantId` + `organizationId` and fail closed. Only an installed contract may use system scope (`organizationId: null`).
10
+ - Use commands, `makeCrudRoute`, `CrudForm`/`DataTable`, DI, events, and UMES on canonical paths.
11
+ - Put entities in `src/modules/<id>/data/entities.ts`; API routes need per-method `metadata` + `openApi`.
12
+ - Editable records expose `updated_at`/`updatedAt`; custom update/delete clients send the version and surface 409s.
13
+ - Run `yarn db:generate`, review scoped SQL/snapshot, and ask before applying it.
14
+ - Run `yarn generate` after discovery files, `src/modules.ts`, routes, pages, events, widgets, agents, tools, or workflows change.
15
+ - Adding/changing/removing, preserving, or keeping stable a public route/schema/ID/export/seam/signature/event-payload/CLI MUST read `.ai/guides/upstream/BACKWARD_COMPATIBILITY.md`; tenant/org scope alone is not a contract surface.
16
+ - Localize strings; use shared UI/tokens and complete loading, empty, error, conflict, keyboard, and a11y states.
17
+
18
+ ## Ask First
19
+
20
+ - Ask before scope/architecture/public-contract/dependency/ejection/canonical-primitive changes; migrations/resets/DB targets; live credentials/providers; or weaker security, concurrency, retries, idempotency, audit, undo.
21
+
22
+ ## Never
23
+
24
+ - Never leak tenants, trust payload scope, or treat missing scope as unrestricted.
25
+ - Never edit `node_modules`, `.mercato/generated/**`, generated facts, or shipped migrations.
26
+ - Never use cross-module ORM relations; use IDs/snapshots, events, enrichers, extensions, or optional DI.
27
+ - Never use raw admin `fetch`/`<form>`, ad hoc crypto/cache/queues, role-name guards, or direct mutations when helpers exist.
28
+ - Never hard-code user strings/status colors; expose secrets/transcripts; or guess answerable contracts.
29
+
30
+ ## Validation
31
+
32
+ Use the smallest relevant set. Broad: `yarn generate && yarn typecheck && yarn lint && yarn test && yarn build`; integration: `yarn test:integration:ephemeral`. Report failures; never migrate to validate.
33
+
34
+ ## Three-Axis Context Assembler
35
+
36
+ Routes are additive: ownership says WHO; other axes say WHAT. Select every match.
37
+
38
+ `debugging` is additive. A scalar-ID/snapshot fix to persisted records or commands linked to an installed record MUST use `module-data` + `umes` and load `om-data-model-design` + `om-system-extension`.
39
+
40
+ `debugging` = reported bug/security/drift, not designed failure UI. Specs use `spec-pr`; implementation owns domain guides. Custom fields/entities = `umes` + `module-data` + `om-data-model-design`; editable round trips add `backend-ui`, requested coverage adds `testing`. Never infer work from specs/PRs.
41
+
42
+ Unified-override audits = `umes` only; add `architecture`/`framework-context` only for unresolved ownership or installed keys. Durable process/activity/user task = `module-data` + `ai-workflow`. Multi-stage waits/cancel/restart are durable; reminders and renewal/batch schedules are `module-data`.
43
+
44
+ `backend-ui`: replacing/wrapping, prop-transforming, menu-editing, or adding visible feedback adds `backend-ui`; merely hiding/toggling/rewiring installed UI does not.
45
+ Staff UI preview/report/bulk = `backend-ui`.
46
+ Existing installed form/table fields, filters, row/bulk actions without app persistence = `umes` + `backend-ui` only: read `crud-surfaces` + `quality-states`; do not load contracts, module-scaffold, or page/navigation.
47
+
48
+ `backend-ui`: UI skill `references/quality-states.md`; public/portal/responsive/a11y adds `frontend-and-design-system.md`.
49
+
50
+ ### Axis 1 — Area/Ownership
51
+
52
+ | Route | Match | Context |
53
+ |---|---|---|
54
+ | `architecture` | Capability/ownership/field-vs-history choice, boundary, upgrade, override, or registry failure; routine discovery stays in its area | `.ai/guides/architecture.md` + named facts |
55
+ | `module-data` | App-owned domain/data/API | `src/modules/<id>/` + `.ai/guides/contracts.md`; add architecture only when ownership is unresolved |
56
+ | `umes` | Extend/replace installed behavior | `.ai/guides/extensions.md` + target facts |
57
+ | `backend-ui` | Authored/restyled rendered surface or browser UI state/session bootstrap | `.ai/guides/backend-ui.md` + host facts; host-provided integration credentials/health UI alone does not match |
58
+ | `integration` | Provider, spreadsheet/CSV/file I/O, sync/webhook/storage | `.ai/guides/integrations.md`; imports = `integration`; AI consuming files = `ai-workflow`, NEVER `integration` unless transport/storage changes |
59
+ | `ai-workflow` | Agent/tool/MCP/orchestrator/durable workflow | `.ai/guides/ai-workflows.md` + facts; schedules/queues/workers/retries/progress alone are `module-data` |
60
+ | `debugging` | Bug/security/drift/runtime inconsistency | `.ai/guides/testing-debugging.md` + affected areas |
61
+
62
+ API/command/record/status/event/UI changes/guards = `umes`; app persistence = `module-data`; installed guard without app persistence = `umes` only, so do not load contracts; read-only behavior/auth/dependents/customization = `framework-context` (alone: no extensions guide; report `installed-version`). Facts do not. Providers are published, never `packages/*`.
63
+
64
+ ### Axis 2 — Work Units
65
+
66
+ Match every work-unit row; OPEN its skill before selection.
67
+
68
+ | Route | Work unit | Skill/context |
69
+ |---|---|---|
70
+ | `architecture` | Explain/choose module, UMES, package, eject | architecture; `om-help` for an unresolved or comparative choice across these mechanisms |
71
+ | `module-data` | Business slice or multi-seam domain/API/command fix | MUST load `om-module-scaffold` + its exact `.ai/skills/om-module-scaffold/references/business-one-shot-blueprints.md` key, which resolves units inside the slice, not ownership — an ownership/capability outline adds `architecture` |
72
+ | `spec-pr` | Spec/plan | Axis 3; phases+integration coverage (`integration-coverage`); no domain routes |
73
+ | `architecture` | Upgrade audit or disable built-in | troubleshooter + framework context, or trim skill + exact `src/modules.ts`/`package.json` |
74
+ | `architecture` + `integration` + `framework-context` | Provider superseded by installed capability | integration builder + exact framework context |
75
+ | `module-data` | Entity/link/validator/migration/encryption/lock/transaction | `om-data-model-design` + contracts |
76
+ | `module-data` | CRUD/API/command/OpenAPI/ACL/setup/mutation | `om-module-scaffold` + contracts |
77
+ | `backend-ui` | Form/table/page/renderer/middleware/nav/i18n/UI states | `om-backend-ui-design` + backend UI |
78
+ | `module-data` | Search/analytics/event/notification/message/worker/progress/cache/CLI | scaffold + contracts |
79
+ | `umes` | Fields/extension entities/links/enrichers/injection/interceptors/guards/subscribers/DOM/widgets/toggles/overrides | `om-system-extension` + extensions; choices load `mechanism-selector` + `extension-branches` |
80
+ | `integration` | Provider/credentials/health/webhook/files/client/reconciliation/package | `om-integration-builder` + integrations |
81
+ | `ai-workflow` | Agent/tool/MCP/OpenCode/Code Mode/orchestrator/AI file or content drafting/attachment/override | `om-create-ai-agent` + AI/workflows; MCP/OpenCode loads `surface-selector` + `ai_assistant` facts |
82
+ | `ai-workflow` | Workflow/activity/user task/idempotency/output/progress | `om-build-workflow` + AI/workflows |
83
+ | `testing` | REQUEST says test/coverage/prove, or verify by exercising API/browser/screen sizes/keyboard/screen-reader—not a fix's implicit regression duty or review/audit/config check | MUST read `.ai/guides/testing-debugging.md` + external `om-integration-tests` for integration/E2E/app tests |
84
+ | `debugging` | Reproduce/root-cause/minimal fix/regression oracle | `om-troubleshooter` + testing/debugging |
85
+ | `framework-context` | Exact installed contract still unknown | bounded `om-framework-context`, last |
86
+ | `debugging` + `testing` | Add/fix recurring harness case/test | `om-evolve-harness` |
87
+
88
+ `framework-context`: skip for “installed contracts” alone; require for exact contract/response/error identity or current behavior, authorization, dependents, and safest customization seam. Otherwise resolve one named unknown from facts.
89
+
90
+ ### Axis 3 — SDLC and Delivery
91
+
92
+ Pinned delivery skills: `yarn install-skills` (refresh: `--update`). Read BOTH `.agents/skills/<id>/SKILL.md` and a matching `.ai/skills/<id>/SKILL.md` override. Commit+ready PR MUST add `spec-pr`, read `.ai/skills/om-auto-create-pr/SKILL.md`, and keep task routes (`delivery-route-preserves-task-routes`).
93
+
94
+ | Route ID | Delivery need | Skill |
95
+ |---|---|---|
96
+ | `spec-pr` | Write/revise spec | `om-spec-writing` (OMH-005) + exact `.ai/agentic.config.json` for its specs-directory setting |
97
+ | `spec-pr` | Implement approved phases locally | `om-implement-spec` (OMH-006) |
98
+ | `spec-pr` | Whole-spec / commit+ready PR / issue / review | `om-auto-implement-spec` / `om-auto-create-pr` / `om-auto-fix-issue` / `om-auto-review-pr` |
99
+ | `testing` | Integration/E2E/UI QA | `om-integration-tests` / `om-auto-qa-pr` |
100
+ | — | No PR/spec workflow requested | Do not load delivery skills |
101
+
102
+ Absent skill: run `yarn install-skills` once; never substitute.
103
+
104
+ ### Token-Efficient Assembly Policy
105
+
106
+ - Load matched guides once, then only needed references/facts.
107
+ - Hard budgets: guide > skill > references; open a reference only for its named subject.
108
+ - Specs: list names; open one task match; skip README/template.
109
+ - Inspect app call sites before bounded `framework-context`.
110
+ - Additive page/form/table/conflict UI skips it.
111
+ - Never bulk-read guide, skill, fact, or source trees.
112
+
113
+ ## Module-Specific Facts
114
+
115
+ Load facts for every named/targeted module, not incidental use. Mechanisms: events/subscribers→events; long operation/progress→progress; provider settings/health/OAuth→integrations; sync/import→data_sync. Hosts: session/auth→auth; customer/contact/deal/pipeline→customers; product/price/stock/inventory→catalog; currency/money→currencies; cart/checkout/shopper→checkout; portal→portal + customer_accounts; quote/order/invoice/sales assistant→sales; notification→notifications; webhook/callback→webhooks; schedule/reminder→scheduler; workflow/activity/user task→workflows; assistant→ai_assistant; maintained query index/reindex→query_index; search convergence→search. staff/employee≠optional staff; audit/record-who≠audit_logs unless extended. App primitives skip api_docs/search/query_index unless changed.
65
116
 
66
117
  <!-- om:module-guides:start -->
67
118
  <!-- om:module-guides:end -->
68
119
 
69
- ### Skills: local + shared collection
70
-
71
- Skills come from two places. Repo-local skills (module scaffolding, UI design, troubleshooting, etc.) ship inside `.ai/skills/` and are installed by tier (see `.ai/skills/tiers.json`). The PR-automation and review skills below are maintained in the shared [open-mercato/skills](https://github.com/open-mercato/skills) collection — run **`yarn install-skills`** once to install the subset this app ships (`npx skills add`, then `npx skills update` on re-runs to refresh). Both sources install into the canonical cross-agent directory **`.agents/skills/`**; Codex and Cursor read it natively, while Claude Code — which cannot — additionally gets per-skill symlinks under `.claude/skills/`. The tables below therefore **reference external skills by name, not by a hard-coded harness path**: the directory depends on which agent you scaffolded, and pointing every reader at `.claude/skills/…` would mislead a Codex or Cursor scaffold. A folder under `.ai/skills/<name>/` matching an external skill is a repo-local **override** that the external skill reads on top of its built-in workflow (default-branch discovery, opt-in labels, `src/modules/…` layout). Repo-specific settings live in `.ai/agentic.config.json` and the tracker descriptor `.ai/trackers/github.md`.
72
-
73
- ### Quality & Process
74
-
75
- | Task | Load |
76
- |---|---|
77
- | Debug / fix errors | `.ai/skills/om-troubleshooter/SKILL.md` |
78
- | Review code changes | `om-code-review` (external — `yarn install-skills`) |
79
- | Write a spec | `om-spec-writing` (external — `yarn install-skills`), `.ai/specs/SPEC-000-template.md` |
80
- | Implement a spec (or selected phases) | `.ai/skills/om-implement-spec/SKILL.md` |
81
- | Create / run integration tests | `om-integration-tests` (external — `yarn install-skills`) |
82
- | Prepare / reuse a local test environment (shared descriptor for QA + integration tests) | `om-prepare-test-env` (external — invoked by `om-integration-tests` when no environment is running) |
83
- | Configure or re-configure the agent PR pipeline (`.ai/agentic.config.json`, tracker, labels, QA gate) | `om-setup-agent-pipeline` (external) |
84
- | Sync installed pipeline artifacts after `yarn install-skills` refreshed the collection | `om-apply-upgrade-notes` (external) |
85
- | Upgrade framework from 0.4.10 to 0.5.0 | `.ai/skills/om-auto-upgrade-0.4.10-to-0.5.0/SKILL.md` |
86
-
87
- ### Agent Automation / Auto-Skills
88
-
89
- These skills are installed from the shared collection by `yarn install-skills` (referenced by name — your harness loads them from its own skills directory); the matching `.ai/skills/<name>/` folder holds the standalone override they read on top of their workflow.
90
-
91
- | Task | Load |
92
- |---|---|
93
- | Delegate an arbitrary task end-to-end as a PR | `om-auto-create-pr` (external) |
94
- | Resume an in-progress agent PR | `om-auto-continue-pr` (external) |
95
- | Run a long multi-step spec implementation with resumable checkpoints | `om-auto-create-pr-loop` (external) |
96
- | Resume a checkpointed PR started by `om-auto-create-pr-loop` | `om-auto-continue-pr-loop` (external) |
97
- | Automated code review on a PR (with optional autofix) | `om-auto-review-pr` (external) |
98
- | Fix a GitHub issue by number and open a PR | `om-auto-fix-issue` (external — drives the chain `om-verify-in-repo` → `om-root-cause` → `om-fix` → `om-open-pr` → `om-auto-review-pr`, all installed alongside it) |
99
- | Propose disabling unused built-in modules after the user adds a new module (classic-mode slimdown) | `.ai/skills/om-trim-unused-modules/SKILL.md` |
100
-
101
- Invoke these as slash commands in your agent CLI (Claude Code, Codex, …), for example `/auto-create-pr add rate-limiting to the products API` or `/auto-fix-issue 42`. The skills read `.ai/agentic.config.json` (base branch `auto`, resolved via the tracker descriptor's **default-branch** operation; pipeline labels off by default; the standalone validation-gate command list) and perform every GitHub interaction through the tracker descriptor `.ai/trackers/github.md`. That config ships preconfigured, so the skills work without any setup step — run `/om-setup-agent-pipeline` when you want to tailor it: enable the full label pipeline (`labels.enabled: true` plus the tracker's **ensure-label-taxonomy** operation) and the QA gate, switch tracker, or change the validation commands. After `yarn install-skills` refreshes the external collection, run `/om-apply-upgrade-notes` to bring the installed artifacts (tracker descriptor, config) up to date with the new skill versions.
102
-
103
- ## Module Anatomy
104
-
105
- Each module in `src/modules/<id>/` is self-contained and auto-discovered:
106
-
107
- ```
108
- src/modules/<id>/
109
- ├── index.ts # Module metadata
110
- ├── data/
111
- │ ├── entities.ts # MikroORM entity classes
112
- │ ├── validators.ts # Zod validation schemas
113
- │ ├── extensions.ts # Cross-module entity links
114
- │ └── enrichers.ts # Response enrichers
115
- ├── api/
116
- │ ├── <resource>/route.ts # REST handlers (auto-discovered by method)
117
- │ └── interceptors.ts # API route interception hooks
118
- ├── backend/ # Admin UI pages (auto-discovered)
119
- │ └── page.tsx # → /backend/<module>
120
- ├── frontend/ # Public pages (auto-discovered)
121
- ├── subscribers/ # Event handlers (export metadata + default handler)
122
- ├── workers/ # Background jobs (export metadata + default handler)
123
- ├── widgets/
124
- │ ├── injection/ # UI widgets injected into other modules
125
- │ ├── injection-table.ts # Widget-to-slot mappings
126
- │ └── components.ts # Component replacement/wrapper definitions
127
- ├── di.ts # Awilix DI registrations
128
- ├── acl.ts # Permission features
129
- ├── setup.ts # Tenant init, role features, seed data
130
- ├── events.ts # Typed event declarations
131
- ├── search.ts # Search indexing configuration
132
- ├── ce.ts # Custom entities / custom field sets
133
- ├── translations.ts # Translatable fields per entity
134
- ├── notifications.ts # Notification type definitions
135
- ├── notifications.client.ts # Client-side notification renderers
136
- └── encryption.ts # Tenant data encryption maps (defaultEncryptionMaps) for sensitive / GDPR fields
137
- ```
138
-
139
- Register in `src/modules.ts`: `{ id: '<id>', from: '@app' }`
140
-
141
- ## Mandatory Module Mechanisms (every module MUST use these — no DIY substitutes)
142
-
143
- When the user asks to **create a new application** or a **new module**, do not invent your own routing, auth, persistence, forms, or caching. The framework provides one canonical primitive for each concern. If a feature is not on this list and not in the Task → Context Map, ask before adding it — do not roll your own.
144
-
145
- | Concern | Canonical mechanism | Where to learn it |
146
- |---|---|---|
147
- | Module structure & auto-discovery | `src/modules/<id>/{api,backend,frontend,data,subscribers,workers,widgets}` + `index.ts` + `src/modules.ts` (`from: '@app'`) — discovered by `yarn generate` | `.ai/skills/om-module-scaffold/SKILL.md`, `.ai/guides/core.md` → Module Files; <https://docs.open-mercato.dev/framework/modules/overview> |
148
- | **Backend admin pages** | Auto-discovered files under `src/modules/<id>/backend/**`, paired `page.meta.ts` with `requireAuth` + `requireFeatures` + `pageGroup`/`pageGroupKey`/`pageOrder` | `.ai/skills/om-backend-ui-design/SKILL.md`, `.ai/skills/om-module-scaffold/references/navigation-patterns.md`; <https://docs.open-mercato.dev/framework/modules/routes-and-pages> |
149
- | **Frontend public pages** | Auto-discovered files under `src/modules/<id>/frontend/**`. Customer portal pages live under `frontend/[orgSlug]/portal/<path>/page.tsx` with `requireCustomerAuth` / `requireCustomerFeatures` in `page.meta.ts` | `.ai/guides/ui.md` → Portal Extension; <https://docs.open-mercato.dev/framework/modules/routes-and-pages> |
150
- | **API routes** | Files under `src/modules/<id>/api/**/route.ts` exporting handlers + `metadata` (per-method `requireAuth` / `requireFeatures`) + `openApi`. NEVER write a top-level `export const requireAuth` — the registry no longer recognises it | `.ai/guides/core.md` → API Routes; <https://docs.open-mercato.dev/framework/api/api-development-guide> |
151
- | **CRUD APIs (factory)** | `makeCrudRoute({ metadata, orm, list, create, update, del, indexer })` from `@open-mercato/shared/lib/crud/factory` (`orm` is required; `list`/`create`/`update`/`del` are the per-operation configs). Always set `indexer` so query-index coverage stays correct. Custom (non-`makeCrudRoute`) write routes MUST use the mutation guard registry: map the route to `create`/`update`/`delete` (action endpoints usually `update`), collect registered guards, append `bridgeLegacyGuard(container)` when present, call `runMutationGuards(...)` with `{ userFeatures }` before the mutation, merge `modifiedPayload`, and run returned `afterSuccessCallbacks` after success while catching/logging callback failures | `.ai/skills/om-module-scaffold/SKILL.md` → Create API Routes; <https://docs.open-mercato.dev/framework/api/crud-factory> |
152
- | **CRUD forms in admin** | `<CrudForm entityId apiPath mode fields />` from `@open-mercato/ui/backend/CrudForm`; helpers `createCrud` / `updateCrud` / `deleteCrud` from `@open-mercato/ui/backend/utils/crud`; `createCrudFormError` from `@open-mercato/ui/backend/utils/serverErrors`. Never raw `<form>`, never raw `fetch` | `.ai/skills/om-backend-ui-design/SKILL.md`; <https://docs.open-mercato.dev/framework/admin-ui/crud-form> |
153
- | **DataTables in admin** | `<DataTable entityId apiPath title columns />` from `@open-mercato/ui/backend/DataTable`. Keep `entityId` and `extensionTableId` stable so widget injection (columns, row actions, bulk actions, filters, toolbar) keeps working | `.ai/skills/om-backend-ui-design/SKILL.md`; <https://docs.open-mercato.dev/framework/admin-ui/data-grids> |
154
- | **Authorization (RBAC)** | Declare features in `<module>/acl.ts`, grant them in `<module>/setup.ts` `defaultRoleFeatures`, gate pages and routes with `requireFeatures` in `metadata` / `page.meta.ts`. NEVER use `requireRoles` (role names mutate). Run `yarn mercato auth sync-role-acls` after adding new features | `.ai/guides/core.md` → Access Control; <https://docs.open-mercato.dev/framework/rbac/overview> |
155
- | **Multi-tenant scoping (default for every entity)** | Every tenant-scoped entity MUST include indexed `organization_id` and `tenant_id` columns and every read/write MUST filter by them. The CRUD factory injects scope automatically — do NOT bypass it. For ad-hoc queries use `withScopedPayload` from `@open-mercato/shared/lib/api/scoped` | `.ai/skills/om-data-model-design/SKILL.md`; <https://docs.open-mercato.dev/architecture/system-overview> |
156
- | **Encryption maps for sensitive data** | Declare a module-level `<module>/encryption.ts` exporting `defaultEncryptionMaps: ModuleEncryptionMap[]` from `@open-mercato/shared/modules/encryption`. Read encrypted columns via `findWithDecryption` / `findOneWithDecryption` from `@open-mercato/shared/lib/encryption/find`. NEVER hand-roll AES/KMS, NEVER use `em.find` on encrypted columns | `.ai/skills/om-data-model-design/SKILL.md` → Sensitive Data and Encryption Maps; <https://docs.open-mercato.dev/user-guide/encryption> |
157
- | **Cache** | Resolve the cache from DI (`container.resolve('cache')`) — never `new Redis(...)` or raw SQLite. Tag with `tenant:<id>` / `org:<id>` and the entity-type tag so invalidation stays tenant-scoped | `.ai/guides/cache.md`; <https://docs.open-mercato.dev/user-guide/cache-management> |
158
- | **Entity update safety** | Multi-phase scalar + relation mutations use `withAtomicFlush(em, phases, { transaction: true })` from `@open-mercato/shared/lib/commands/flush` — never interleave `em.find`/`em.findOne` between a scalar mutation and `em.flush()`. Keep `emitCrudSideEffects` + cache invalidation OUTSIDE it (they fire after commit) | See **Entity Update Safety** section below |
159
- | **Background workers** | `src/modules/<id>/workers/*.ts` exporting `metadata: { queue, id?, concurrency? }` + default handler. Never spin up custom queues | `.ai/guides/queue.md`; <https://docs.open-mercato.dev/framework/events/queue-workers> |
160
- | **Events between modules** | `<module>/events.ts` with `createModuleEvents({ moduleId, events } as const)`. Subscribers in `subscribers/*.ts`. Never call other modules' services directly across module boundaries | `.ai/guides/events.md`; <https://docs.open-mercato.dev/framework/events/overview> |
161
- | **i18n (every user-facing string)** | `useT()` client-side from `@open-mercato/shared/lib/i18n/context`, `resolveTranslations()` server-side from `@open-mercato/shared/lib/i18n/server`; keys in `src/i18n/<locale>.json`. Never hard-code labels in components | `.ai/guides/shared.md` → i18n |
162
-
163
- > Rule of thumb: if you find yourself reaching for raw `fetch`, raw `<form>`, ad-hoc `crypto`, ad-hoc `Redis`, or a manual `m2m` join across modules, stop and check the row above — there is a canonical helper.
164
-
165
- ## Entity Update Safety
166
-
167
- MikroORM v7 can silently discard pending scalar changes when a query (`em.find`, `em.findOne`, sync helper) runs on the same `EntityManager` between a scalar mutation and `em.flush()`. For any command in `{{PROJECT_NAME}}` that mutates entities across multiple phases:
168
-
169
- - MUST use `withAtomicFlush(em, phases, { transaction: true })` from `@open-mercato/shared/lib/commands/flush`.
170
- - NEVER interleave `em.find`/`em.findOne`/sync helpers between a scalar mutation and `em.flush()` on the same `EntityManager` without `withAtomicFlush` — the UPDATE is dropped.
171
- - Keep `emitCrudSideEffects` (and `emitCrudUndoSideEffects`) AND cache invalidation OUTSIDE the `withAtomicFlush` block — they fire only AFTER the DB write commits.
172
-
173
- ```typescript
174
- import { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'
175
-
176
- await withAtomicFlush(em, [
177
- () => { record.name = 'New Name'; record.status = 'active' },
178
- () => syncEntityTags(em, record, tags),
179
- ], { transaction: true, label: '<module>.<command>' })
180
-
181
- // Side effects + cache invalidation AFTER the atomic flush (post-commit)
182
- await emitCrudSideEffects({ /* ... */ })
183
- ```
184
-
185
- Because invalidation runs post-commit and the query-index read-projection tail (search tokens, vectors, fulltext, coverage) converges asynchronously, reads can briefly see a convergence window after a write. An opt-in env flag, `OM_CACHE_SAFETY_ALWAYS_CONSISTENT` (default OFF, backward compatible), is planned to make that tail converge synchronously on write at a write-latency cost — treat it as opt-in/forthcoming, not on by default.
186
-
187
- ## CRITICAL rules — always follow without exception
188
-
189
- 1. **Entity classes live in `src/modules/<module>/data/entities.ts` and MUST import decorators from `@mikro-orm/decorators/legacy`.** Start there for every schema change.
190
- 2. **After editing `src/modules.ts`** or any structural module file: run `yarn generate`
191
- 3. **Never edit `.mercato/generated/*`** — auto-generated. Never edit `node_modules/@open-mercato/*` — eject instead.
192
- 4. **After editing `src/modules/<module>/data/entities.ts`**: run `yarn db:generate` as a schema-diff probe. Default to the generated SQL, but if it emits unrelated churn, keep or write only the scoped SQL for your module and update `src/modules/<module>/migrations/.snapshot-open-mercato.json` in the same change.
193
- 5. **Confirm migrations with user** before running `yarn db:migrate`
194
- 6. **API route files MUST export `metadata`.** Every `src/modules/<module>/api/**/route.ts` that exports an HTTP handler (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`) MUST also export a `metadata` object describing per-method auth, otherwise the generator emits the warning `[generate] ⚠ Route file exports handlers but no metadata — auth will default to required` and every method silently falls back to "authentication required". Use the per-method shape:
195
- ```ts
196
- export const metadata = {
197
- GET: { requireAuth: true, requireFeatures: ['mymodule.view'] },
198
- POST: { requireAuth: true, requireFeatures: ['mymodule.manage'] },
199
- }
200
- ```
201
- For public endpoints, opt out explicitly with `{ requireAuth: false }`. Do not use the legacy top-level `export const requireAuth` / `export const requireFeatures` — they are no longer recognised.
202
- 7. **Write migrations in one shot.** `yarn dev` auto-applies pending migrations at startup by default (`OM_DEV_AUTO_MIGRATE=1`). Once a migration has been applied, editing the same file usually has no effect — the next migrate pass skips it as already-applied. If `yarn db:generate` shows unrelated churn, manual SQL for the intended module is allowed, but you MUST also update that module's `.snapshot-open-mercato.json`. Never hand-edit a historical migration that has already shipped; add a **new** migration instead.
203
- 8. **After the user adds a new module, offer to trim classic mode.** A fresh `create-mercato-app` scaffold enables every built-in module (classic mode). Once the user has added their own custom module, the defaults are usually dead weight. **Ask the user** (via a short `AskUserQuestion`) whether they want to disable built-in modules that are not needed for their project. If they say yes, invoke the `om-trim-unused-modules` skill — do NOT hand-craft the slimdown inside the AGENTS.md reading flow. If they say no, preserve classic mode silently.
204
-
205
- **Dashboards fallback rule.** When the user (or the `om-trim-unused-modules` skill) disables the `dashboards` module, you MUST update `src/app/(backend)/backend/page.tsx` so it no longer renders `<DashboardScreen />`. Replace the dashboard render with a `redirect(...)` to the first enabled backend page for the current user — preferring pages already registered in the main sidebar group and respecting the admin/superadmin role of the caller. Otherwise `/backend` will crash at build or request time because the removed module no longer ships `DashboardScreen`. Always fall back to `/backend/profile` only if no other backend page is available.
206
- 9. **New features MUST be visible to default roles immediately.** Every time you add a new feature ID (e.g. `my_module.view`, `my_module.manage`) to `src/modules/<module>/acl.ts`, you MUST also (a) add that feature to `defaultRoleFeatures` in the same module's `setup.ts` so the admin role and any other appropriate default roles get it on every tenant setup; and (b) run `yarn mercato auth sync-role-acls` so existing tenants pick up the new feature without a reinstall. Use `--tenant <tenantId>` only when the user asks to target one tenant. Do this automatically unless the user has explicitly said otherwise — the user should see the features you are building, not stare at a blank admin because their role is missing a grant. Feature IDs are FROZEN once shipped; if a rename is required, add the new ID alongside, grant it, and keep the old one as a deprecated alias.
207
- 10. **Strict Design System alignment for every UI change.** Any UI you add or edit MUST use the Open Mercato design system components and tokens. No hardcoded Tailwind status colors (`text-red-500`, `bg-green-100`, etc.) — use semantic tokens (`text-status-error-text`, `bg-status-success-bg`, …). No arbitrary text sizes (`text-[11px]`, `text-[13px]`) — use the Tailwind scale (`text-xs`, `text-sm`, `text-base`, `text-lg`, `text-xl`, `text-2xl`) or the `text-overline` token for 11px uppercase labels. In PAGE BODY UI, use `lucide-react` icons (never inline `<svg>`). Use `StatusBadge` for entity status, `Alert` for inline feedback, `FormField` for standalone form inputs, `SectionHeader` for detail-page section headings, `CollapsibleSection` for collapsible regions, `LoadingMessage`/`Spinner`/`DataLoader` for async states, and `EmptyState` (or DataTable's `emptyState` prop) for empty lists. For list pages, follow `.ai/skills/om-backend-ui-design/SKILL.md` and prefer the `DataTable` host pattern shown there (`entityId`, `apiPath`, stable `extensionTableId`, and explicit pagination props when you own the data source). Every dialog MUST support `Cmd/Ctrl+Enter` to submit and `Escape` to cancel. Every icon-only button MUST have an `aria-label`. These rules apply to `src/modules/<module>/backend/**` and `src/modules/<module>/frontend/**` alike.
208
- 11. **Sensitive / GDPR fields MUST go through the encryption-maps mechanism — never hand-rolled.** The framework provides per-tenant DEKs, KMS-backed key resolution, and a declarative field-level map. Whenever the user asks for "this field encrypted", "store this securely", "this is PII", "GDPR", "encryption at rest", or you are designing a column that will hold names, addresses, contacts, free-text notes about people, integration secrets/credentials, or any data subject to a data-processing agreement, you MUST:
209
- - Declare the entity + field list in `src/modules/<module>/encryption.ts` exporting `defaultEncryptionMaps: ModuleEncryptionMap[]` (type imported from `@open-mercato/shared/modules/encryption`).
210
- - Read those columns via `findWithDecryption` / `findOneWithDecryption` from `@open-mercato/shared/lib/encryption/find` (passing `tenantId` and `organizationId`). Never use raw `em.find` on encrypted columns.
211
- - For deterministic-lookup fields (e.g., login email), declare a sibling `hashField` in the map so equality lookups still work.
212
- - Run `yarn mercato entities seed-encryption --tenant <tenantId>` after adding maps so existing tenants pick them up; new tenants get them automatically during `auth:setup`.
213
- - Treat hand-rolled AES, raw `crypto.subtle`, custom KMS calls, or storing plaintext "for now" as broken — rewrite via the maps. See `.ai/skills/om-data-model-design/SKILL.md` → Sensitive Data and Encryption Maps and <https://docs.open-mercato.dev/user-guide/encryption>.
214
- 12. **BEFORE writing ANY code**, you MUST:
215
- - Match your task against the **Task → Context Map** above
216
- - `Read` every file listed in the "Load" column for your task type
217
- - Read the **Mandatory Module Mechanisms** section above to confirm which canonical primitives apply (CRUD factory, CrudForm, DataTable, RBAC, multi-tenant scoping, encryption maps, cache, events) — do not invent your own substitutes
218
- - Only then proceed to implementation
219
- - If your task matches multiple rows, load ALL listed files
220
- - **Do NOT skip this step.** The guides contain canonical import paths, required patterns, and conventions that CANNOT be reliably inferred from existing code alone. Skipping leads to wrong imports, missing conventions, and rework.
221
-
222
- ## Additional Conventions
223
-
224
- - Custom modules use `from: '@app'` in `src/modules.ts`
225
- - Entity classes belong in `src/modules/<module>/data/entities.ts` and use decorators from `@mikro-orm/decorators/legacy`
226
- - Standalone apps expose `yarn mercato configs cache ...` because the template enables the `configs` module from `@open-mercato/core`
227
- - `yarn generate` automatically runs a best-effort structural cache purge (`yarn mercato configs cache structural --all-tenants`) after successful generation; if the cache command is unavailable, generation still succeeds
228
- - Use `yarn dev:reset` only as the stale-Turbopack escape hatch; it clears `.mercato/next/dev` plus legacy `.next` caches.
229
- - Detail/read-model APIs that expose `customFields` MUST return bare field keys via `normalizeCustomFieldResponse()` (for example `{ priority: 3 }`). Keep `cf_` / `cf:` prefixes for request payloads, filters, and form field IDs only.
230
- - Sidebar icons MUST use `lucide-react` components — never inline SVG via `React.createElement`
231
- - `page.meta.ts` MUST include `pageGroup`, `pageGroupKey`, and `pageOrder` for sidebar grouping
232
- - Settings pages MUST use `pageContext: 'settings' as const` with `navHidden: true`
233
- - All related pages within a module MUST share the same `pageGroupKey`
234
- - DataTable hosts MUST keep `extensionTableId` stable; when you own pagination state, wire `page`, `pageSize`, `totalCount`, and `onPageChange`
235
-
236
- ## Naming Conventions
237
-
238
- - Module IDs: plural, snake_case (`order_items`)
239
- - Event IDs: `module.entity.action` (singular entity, past tense: `sales.order.created`)
240
- - DB tables: plural, snake_case with module prefix (`catalog_products`)
241
- - DB columns: snake_case (`created_at`, `organization_id`)
242
- - JS/TS identifiers: camelCase
243
- - Feature IDs: `<module>.<action>` (`my_module.view`, `my_module.create`)
244
- - UUID primary keys, explicit foreign keys, junction tables for M2M
245
-
246
- ## Key Imports Quick Reference
247
-
248
- ```typescript
249
- // Translations
250
- import { useT } from '@open-mercato/shared/lib/i18n/context'
251
- import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
252
-
253
- // API calls (MUST use — never raw fetch)
254
- import { apiCall, apiCallOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
255
-
256
- // CRUD forms
257
- import { CrudForm, type CrudField, type CrudFormGroup } from '@open-mercato/ui/backend/CrudForm'
258
- import { createCrud, updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'
259
- import { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'
260
-
261
- // UI components (MUST use — never raw <button>)
262
- import { Button } from '@open-mercato/ui/primitives/button'
263
- import { IconButton } from '@open-mercato/ui/primitives/icon-button'
264
- import { LoadingMessage, ErrorMessage } from '@open-mercato/ui/backend/detail'
265
- import { FormHeader, FormFooter } from '@open-mercato/ui/backend/forms'
266
- import { flash } from '@open-mercato/ui/backend/FlashMessages'
267
-
268
- // Encrypted queries (MUST use instead of em.find)
269
- import { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'
270
-
271
- // Events
272
- import { createModuleEvents } from '@open-mercato/shared/modules/events'
273
-
274
- // Widget injection
275
- import { InjectionPosition } from '@open-mercato/shared/modules/widgets/injection-position'
276
-
277
- // Types
278
- import type { ModuleSetupConfig } from '@open-mercato/shared/modules/setup'
279
- import type { ResponseEnricher } from '@open-mercato/shared/lib/crud/response-enricher'
280
- import type { ApiInterceptor } from '@open-mercato/shared/lib/crud/api-interceptor'
281
- ```
282
-
283
- ## Key Commands
284
-
285
- | Command | Purpose |
286
- |---|---|
287
- | `yarn dev` | Start compact dev runtime (`d` toggles raw logs) |
288
- | `yarn dev:verbose` | Start dev runtime with full raw passthrough logs |
289
- | `yarn generate` | Regenerate `.mercato/generated/` |
290
- | `yarn mercato configs cache structural --all-tenants` | Manually purge structural navigation/sidebar cache entries |
291
- | `yarn mercato module add <package>` | Install and enable an official module package |
292
- | `yarn db:generate` | Probe/create migration SQL for entity changes |
293
- | `yarn db:migrate` | Apply pending migrations after user confirmation |
294
- | `yarn initialize` | Bootstrap DB + first admin account |
295
- | `yarn build` | Build for production |
296
- | `yarn mercato eject <module>` | Copy a core module into `src/modules/` |
297
- | `yarn test:integration:ephemeral` | Run Playwright integration tests against a fresh ephemeral app + DB (reuses a healthy running env) — always prefer this over plain `yarn test:integration` |
298
- | `yarn test:integration:ephemeral:start` | Start the ephemeral app only (manual QA or iterative test loops; admin@acme.com / secret) — the `om-prepare-test-env` skill wraps this and shares the env via `.ai/qa/test-env.json` |
299
- | `yarn mercato test:integration <filter>` | Run small filtered test batches against the running ephemeral env (fast iteration) |
300
- | `npx playwright show-report .ai/qa/test-results/html` | Open the HTML integration test report |
301
-
302
- ## Architecture Rules
303
-
304
- - NO direct ORM relationships between modules — use foreign key IDs
305
- - Always filter by `organization_id` for tenant-scoped entities
306
- - Validate all inputs with Zod; derive types via `z.infer`
307
- - Use DI (Awilix) for services; avoid `new`-ing directly
308
- - No `any` types — use Zod schemas with `z.infer`, narrow with runtime checks
309
- - Every dialog: `Cmd/Ctrl+Enter` submit, `Escape` cancel
310
- - Keep `pageSize` at or below 100
311
- - Every API route MUST export `openApi`
312
-
313
- ## Stack
314
-
315
- Next.js App Router, TypeScript, MikroORM, Awilix DI, Zod
120
+ ## Working Sequence
121
+
122
+ 1. `spec-pr`: list `.ai/specs` once; open one match; plan-only skips specs.
123
+ 2. Route; load only matched guides/skills/facts.
124
+ 3. Implement the smallest complete slice through real call sites.
125
+ 4. Discovery change: run `yarn generate`; then the smallest gate/integration paths.
126
+
127
+ Precedence: root → BC → installed `AGENTS.md` → facts; stop on skew/conflict; never guess.
@@ -51,6 +51,7 @@
51
51
  ]
52
52
  },
53
53
  "qaGate": false,
54
+ "reviewChecklist": ".ai/review-checklist.md",
54
55
  "paths": {
55
56
  "runs": ".ai/runs",
56
57
  "analysis": ".ai/analysis",
@@ -0,0 +1,48 @@
1
+ # Agent harness evaluations
2
+
3
+ `cases.json` is the 192-case standalone-app contract. Run `yarn harness:validate --all` for the deterministic gate. Live routing uses a fresh read-only process per case:
4
+
5
+ ```text
6
+ yarn harness:validate --runner codex --all
7
+ yarn harness:validate --runner claude --case OMH-009
8
+ ```
9
+
10
+ For an explicitly requested Codex comparison outside the blocking release matrix, pin both dimensions so the sanitized result is reproducible, for example `--model gpt-5.4-mini --reasoning-effort high`. The effort override is Codex-only; supported values are `minimal`, `low`, `medium`, `high`, and `xhigh`, and omitting it preserves the existing runner default. Measured high-effort mini runs legitimately exceed ten minutes on broad context, so that exact model/effort pair uses a 15-minute per-attempt floor; measured Claude/Sonnet runs use a 10-minute floor. Passing `--timeout` remains authoritative, and other routing runs retain the five-minute default.
11
+
12
+ A blocking release selects one primary runner for every live lane. The optional portability runner must be different and receives only the exact 45-case representative read-only set:
13
+
14
+ ```text
15
+ yarn harness:release --runner codex --prepare-targets /absolute/empty-release-targets --acknowledge-writes
16
+ yarn harness:release --runner codex --portability-runner claude --prepare-targets /absolute/empty-release-targets --acknowledge-writes
17
+ ```
18
+
19
+ The primary runner owns all 192 routing cases, all 45 writable cases, and all generated-code reviews. No per-case fallback or mixed primary ownership is allowed. Omitting `--portability-runner` is valid and the sanitized report records `portabilityRunner: null`; explicitly requesting an unavailable or failing secondary runner fails that extended run.
20
+
21
+ Writable evaluation is intentionally opt-in. The expanded catalog has a 45-case writable release target, but only cases registered in `release-matrix.json` and backed by controller-owned fixtures and oracles are executable. Copy or create a fresh standalone app for one registered case, then seed only that case and mark the target disposable:
22
+
23
+ ```text
24
+ yarn harness:fixture --case OMH-009 --target /absolute/disposable/app --acknowledge-writes
25
+ yarn harness:validate --runner codex --case OMH-009 --writable-root /absolute/disposable/app --acknowledge-writes
26
+ ```
27
+
28
+ For a manually prepared writable target, run `yarn generate` in the target first and replace its `node_modules` directory with a link to the controller scaffold's dependency tree. The evaluator rejects copied or independently installed dependency trees because the controller must fingerprint and mount one protected dependency source. `--prepare-targets` performs both steps automatically for a full release run.
29
+
30
+ The preparer refuses the controller app, non-standalone targets, reused targets, and existing fixture files. The evaluator rejects writes outside each case's `allowedWrites`. Every writable case is checked by the fixed controller-owned TypeScript AST oracle, so imports, comments, and token stuffing cannot satisfy an implementation contract. Integration/workflow and seeded regression cases also run isolated mocked behavior probes; the after phase runs the target's fixed `yarn typecheck` gate. A case-local `timeoutMs` may only raise the operator timeout floor for an unusually broad writable one-shot; it never lowers an explicit operator timeout and is capped at 10 minutes. The target can never supply or replace executable oracle code. Regression oracles must fail before the change and pass afterward. Fixture preparation is not run evidence. Generated results live under ignored `.ai/harness/results/`; they contain hashes and sanitized summaries, never raw transcripts or environment values.
31
+
32
+ The four generated-test cases use direct controller-resolved Jest/Playwright CLIs, never target package scripts. The target and dependencies stay read-only; Jest has no network, Playwright has loopback only, and the browser lane exposes only the exact installed headless-shell runtime. JSON reporters must attest at least one passed test and zero skipped, todo, focused, flaky, or expected-failure tests before review evidence can be created.
33
+
34
+ Generated-code review is a separate post-oracle lane, never a nested second-model call. The individual command is opt-in while developing one case; the once-per-release suite requires it for every writable case:
35
+
36
+ ```text
37
+ yarn harness:validate --runner codex --review-writable-result /absolute/controller/.ai/harness/results/<writable-result>.json --writable-root /absolute/disposable/app
38
+ ```
39
+
40
+ The source must be a passing one-shot implementation result from the current harness and its final whole-target fingerprint must still match. The controller copies changed regular text files as line-numbered inert snapshots, plus its pinned installed `om-code-review` skill and bounded trusted evidence, into a temporary read-only bundle. Target package scripts, dependencies, Git data, tracker state, original source files, and the target's absolute path are not copied or supplied to the reviewer; trace-verified out-of-bundle, environment, or process inspection and any bundle or target mutation fail closed. A separate sanitized artifact records source-result, target, policy, and installed-skill hashes plus the strict verdict, findings, and report. This supplemental review uses prior controller oracle evidence and does not claim the full repository validation gate or CI passed.
41
+
42
+ ## Live-run security boundary
43
+
44
+ The trusted runner receives an explicit allowlist of runtime/authentication variables rather than the evaluator's complete environment. The model receives no general shell, process, environment, discovery, browser, or network tool. Codex and Claude are both restricted to one evaluator-owned MCP server launched through `env -i`; it exposes only exact-path `read` and, for writable cases, allowlisted atomic `write`. The server rejects absolute/traversal paths, symlink escapes, credentials, dependencies, Git state, build output, and harness internals. Every response-derived string is also recursively redacted before validation or persistence.
45
+
46
+ On macOS, Claude Code subscription credentials normally live in the login Keychain and cannot be copied into the isolated runner home. Run `claude setup-token`, export the resulting value as `CLAUDE_CODE_OAUTH_TOKEN`, and then start the Claude lane. Missing or exhausted provider authentication aborts the matrix as an environment failure instead of being counted as a case result.
47
+
48
+ The controller places routing and generated-code review inside a host filesystem sandbox: macOS uses `/usr/bin/sandbox-exec`; Linux uses Bubblewrap with user namespaces; native Windows is unsupported for live/review lanes. Only the trusted runner binary receives provider transport and isolated authentication state. Prompt-directed tools cannot open sockets or read runner state: the sole MCP subprocess has an empty environment, is rooted at the app or inert review bundle, and implements no process or network operation. The mandatory outer sandbox remains the filesystem authority; the narrow MCP contract is the model-tool authority. Tool-event traces are still mandatory release evidence: missing traces, out-of-root reads, `.env*`, `.git/**`, `.ai/harness/**`, and case-forbidden or arbitrary app-root reads fail closed. `actualContext` contains only traced MCP reads; `declaredContext` separately measures the model-reported selection. Writable runs additionally fingerprint normally ignored/protected roots before and after execution so writes under `.git`, `node_modules`, build output, or harness results cannot evade the allowlist check.