@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.
- package/.turbo/turbo-build.log +2 -3
- package/build.mjs +21 -5
- package/dist/agentic/claude-code/hooks/entity-migration-check.ts +32 -88
- package/dist/agentic/codex/enforcement-rules.md +2 -16
- package/dist/agentic/cursor/hooks/entity-migration-check.mjs +19 -50
- package/dist/agentic/cursor/rules/entity-guard.mdc +9 -21
- package/dist/agentic/cursor/rules/generated-guard.mdc +3 -5
- package/dist/agentic/cursor/rules/open-mercato.mdc +3 -29
- package/dist/agentic/guides/ai-workflows.md +76 -0
- package/dist/agentic/guides/architecture.md +107 -0
- package/dist/agentic/guides/backend-ui.md +80 -0
- package/dist/agentic/guides/contracts.md +92 -0
- package/dist/agentic/guides/extensions.md +104 -0
- package/dist/agentic/guides/integrations.md +81 -0
- package/dist/agentic/guides/module-facts.json +217 -81
- package/dist/agentic/guides/module-system.md +12 -127
- package/dist/agentic/guides/modules/ai_assistant.md +1 -1
- package/dist/agentic/guides/modules/api_docs.md +1 -1
- package/dist/agentic/guides/modules/api_keys.md +1 -1
- package/dist/agentic/guides/modules/attachments.md +2 -2
- package/dist/agentic/guides/modules/audit_logs.md +2 -2
- package/dist/agentic/guides/modules/auth.md +1 -1
- package/dist/agentic/guides/modules/business_rules.md +1 -1
- package/dist/agentic/guides/modules/catalog.md +5 -5
- package/dist/agentic/guides/modules/channel_gmail.md +1 -1
- package/dist/agentic/guides/modules/channel_imap.md +1 -1
- package/dist/agentic/guides/modules/checkout.md +1 -1
- package/dist/agentic/guides/modules/communication_channels.md +1 -1
- package/dist/agentic/guides/modules/configs.md +1 -1
- package/dist/agentic/guides/modules/content.md +1 -1
- package/dist/agentic/guides/modules/currencies.md +1 -1
- package/dist/agentic/guides/modules/customer_accounts.md +1 -1
- package/dist/agentic/guides/modules/customers.md +2 -2
- package/dist/agentic/guides/modules/dashboards.md +1 -1
- package/dist/agentic/guides/modules/data_sync.md +1 -1
- package/dist/agentic/guides/modules/dictionaries.md +1 -1
- package/dist/agentic/guides/modules/directory.md +1 -1
- package/dist/agentic/guides/modules/entities.md +2 -2
- package/dist/agentic/guides/modules/events.md +1 -1
- package/dist/agentic/guides/modules/feature_toggles.md +1 -1
- package/dist/agentic/guides/modules/gateway_stripe.md +1 -1
- package/dist/agentic/guides/modules/generators.md +1 -1
- package/dist/agentic/guides/modules/inbox_ops.md +1 -1
- package/dist/agentic/guides/modules/integrations.md +1 -1
- package/dist/agentic/guides/modules/messages.md +1 -1
- package/dist/agentic/guides/modules/notifications.md +1 -1
- package/dist/agentic/guides/modules/onboarding.md +1 -1
- package/dist/agentic/guides/modules/payment_gateways.md +1 -1
- package/dist/agentic/guides/modules/perspectives.md +1 -1
- package/dist/agentic/guides/modules/planner.md +1 -1
- package/dist/agentic/guides/modules/portal.md +1 -1
- package/dist/agentic/guides/modules/progress.md +1 -1
- package/dist/agentic/guides/modules/query_index.md +2 -2
- package/dist/agentic/guides/modules/record_locks.md +1 -1
- package/dist/agentic/guides/modules/resources.md +1 -1
- package/dist/agentic/guides/modules/sales.md +17 -17
- package/dist/agentic/guides/modules/scheduler.md +1 -1
- package/dist/agentic/guides/modules/search.md +1 -1
- package/dist/agentic/guides/modules/security.md +1 -1
- package/dist/agentic/guides/modules/shipping_carriers.md +1 -1
- package/dist/agentic/guides/modules/sso.md +1 -1
- package/dist/agentic/guides/modules/staff.md +2 -2
- package/dist/agentic/guides/modules/storage_s3.md +1 -1
- package/dist/agentic/guides/modules/sync_akeneo.md +1 -1
- package/dist/agentic/guides/modules/sync_excel.md +1 -1
- package/dist/agentic/guides/modules/system_status_overlays.md +1 -1
- package/dist/agentic/guides/modules/translations.md +1 -1
- package/dist/agentic/guides/modules/webhooks.md +2 -2
- package/dist/agentic/guides/modules/wms.md +2 -2
- package/dist/agentic/guides/modules/workflows.md +1 -1
- package/dist/agentic/guides/testing-debugging.md +74 -0
- package/dist/agentic/guides/upstream/AGENTS.md +297 -0
- package/dist/agentic/guides/upstream/BACKWARD_COMPATIBILITY.md +303 -0
- package/dist/agentic/guides/upstream/manifest.json +8 -0
- package/dist/agentic/shared/AGENTS.md.template +123 -311
- package/dist/agentic/shared/ai/agentic.config.json +1 -0
- package/dist/agentic/shared/ai/harness/README.md +48 -0
- package/dist/agentic/shared/ai/harness/RELEASE.md +57 -0
- package/dist/agentic/shared/ai/harness/cases.json +13487 -0
- package/dist/agentic/shared/ai/harness/cases.schema.json +132 -0
- package/dist/agentic/shared/ai/harness/fixtures/index.json +49 -0
- package/dist/agentic/shared/ai/harness/fixtures/seeds.json +162 -0
- package/dist/agentic/shared/ai/harness/generated-code-review-policy.md +20 -0
- package/dist/agentic/shared/ai/harness/generated-code-review-response.schema.json +43 -0
- package/dist/agentic/shared/ai/harness/generated-code-review-result.schema.json +110 -0
- package/dist/agentic/shared/ai/harness/release-matrix.json +133 -0
- package/dist/agentic/shared/ai/harness/release-result.schema.json +219 -0
- package/dist/agentic/shared/ai/harness/result.schema.json +76 -0
- package/dist/agentic/shared/ai/harness/routing-response.schema.json +12 -0
- package/dist/agentic/shared/ai/harness/target-validation-result.schema.json +73 -0
- package/dist/agentic/shared/ai/harness/validators.json +78 -0
- package/dist/agentic/shared/ai/harness/writable-ast-oracles.mjs +1768 -0
- package/dist/agentic/shared/ai/harness/writable-behavior-oracles.mjs +1096 -0
- package/dist/agentic/shared/ai/review-checklist.md +36 -0
- package/dist/agentic/shared/ai/skills/om-auto-review-pr/SKILL.md +4 -0
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/SKILL.md +20 -241
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/crud-surfaces.md +16 -0
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/frontend-and-design-system.md +53 -0
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/page-and-navigation.md +13 -0
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/quality-states.md +11 -0
- package/dist/agentic/shared/ai/skills/om-build-workflow/SKILL.md +30 -0
- package/dist/agentic/shared/ai/skills/om-build-workflow/references/activity-contracts.md +12 -0
- package/dist/agentic/shared/ai/skills/om-build-workflow/references/durability-and-progress.md +13 -0
- package/dist/agentic/shared/ai/skills/om-build-workflow/references/workflow-design.md +14 -0
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/SKILL.md +28 -0
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/attachments-and-overrides.md +12 -0
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/module-agents-and-tools.md +22 -0
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/orchestrator-agents.md +12 -0
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/surface-selector.md +19 -0
- package/dist/agentic/shared/ai/skills/om-data-model-design/SKILL.md +16 -601
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/integrity-and-concurrency.md +19 -0
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/migration-workflow.md +13 -0
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/schema-design.md +14 -0
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/sensitive-data.md +10 -0
- package/dist/agentic/shared/ai/skills/om-eject-and-customize/SKILL.md +14 -310
- package/dist/agentic/shared/ai/skills/om-eject-and-customize/references/decision-and-procedure.md +17 -0
- package/dist/agentic/shared/ai/skills/om-evolve-harness/SKILL.md +28 -0
- package/dist/agentic/shared/ai/skills/om-evolve-harness/references/case-template.md +89 -0
- package/dist/agentic/shared/ai/skills/om-evolve-harness/references/case-workflow.md +16 -0
- package/dist/agentic/shared/ai/skills/om-evolve-harness/references/owner-selection.md +17 -0
- package/dist/agentic/shared/ai/skills/om-framework-context/SKILL.md +25 -0
- package/dist/agentic/shared/ai/skills/om-framework-context/references/resolver-procedure.md +11 -0
- package/dist/agentic/shared/ai/skills/om-framework-context/references/skew-and-escalation.md +13 -0
- package/dist/agentic/shared/ai/skills/om-help/SKILL.md +15 -97
- package/dist/agentic/shared/ai/skills/om-help/references/delivery-workflows.md +17 -0
- package/dist/agentic/shared/ai/skills/om-help/references/task-families.md +20 -0
- package/dist/agentic/shared/ai/skills/om-implement-spec/SKILL.md +15 -156
- package/dist/agentic/shared/ai/skills/om-implement-spec/references/phases-and-gates.md +12 -0
- package/dist/agentic/shared/ai/skills/om-integration-builder/SKILL.md +24 -708
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/package-and-activation.md +16 -0
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/provider-families.md +14 -0
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/security-and-reliability.md +15 -0
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/sync-and-files.md +12 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/SKILL.md +20 -820
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/api-and-domain.md +19 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/business-one-shot-blueprints.md +107 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/data-and-migrations.md +12 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/discovery-surface-catalog.md +83 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/module-surfaces.md +21 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/planning.md +11 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/runtime-cache-and-queues.md +22 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/verification.md +13 -0
- package/dist/agentic/shared/ai/skills/om-system-extension/SKILL.md +19 -843
- package/dist/agentic/shared/ai/skills/om-system-extension/references/extension-branches.md +18 -0
- package/dist/agentic/shared/ai/skills/om-system-extension/references/mechanism-selector.md +25 -0
- package/dist/agentic/shared/ai/skills/om-system-extension/references/read-write-roundtrip.md +13 -0
- package/dist/agentic/shared/ai/skills/om-system-extension/references/unified-overrides.md +38 -0
- package/dist/agentic/shared/ai/skills/om-system-extension/references/verification.md +11 -0
- package/dist/agentic/shared/ai/skills/om-trim-unused-modules/SKILL.md +15 -63
- package/dist/agentic/shared/ai/skills/om-trim-unused-modules/references/dependency-and-redirect.md +15 -0
- package/dist/agentic/shared/ai/skills/om-troubleshooter/SKILL.md +16 -467
- package/dist/agentic/shared/ai/skills/om-troubleshooter/references/diagnosis-map.md +16 -0
- package/dist/agentic/shared/ai/skills/om-troubleshooter/references/regression-oracles.md +14 -0
- package/dist/agentic/shared/ai/skills/tiers.json +137 -20
- package/dist/agentic/shared/ai/skills/tiers.schema.json +52 -40
- package/dist/agentic/shared/scripts/agent-harness-tool-server.mjs +174 -0
- package/dist/agentic/shared/scripts/evaluate-agent-harness.mjs +2783 -0
- package/dist/agentic/shared/scripts/execution-sandbox.mjs +329 -0
- package/dist/agentic/shared/scripts/framework-context.mjs +894 -0
- package/dist/agentic/shared/scripts/install-skills.mjs +1029 -0
- package/dist/agentic/shared/scripts/install-skills.sh +4 -694
- package/dist/agentic/shared/scripts/prepare-agent-harness-fixture.mjs +222 -0
- package/dist/agentic/shared/scripts/run-agent-harness-release.mjs +1761 -0
- package/dist/lib/__integration__/TC-INT-008.spec.js +87 -8
- package/dist/lib/__integration__/TC-INT-008.spec.js.map +2 -2
- package/dist/lib/agentic-init.js +13 -3
- package/dist/lib/agentic-init.js.map +2 -2
- package/dist/lib/agentic-setup.js +418 -186
- package/dist/lib/agentic-setup.js.map +2 -2
- package/dist/lib/generators/extensions/injection-widgets.js +20 -0
- package/dist/lib/generators/extensions/injection-widgets.js.map +2 -2
- package/dist/lib/generators/module-facts-discovery.js +41 -7
- package/dist/lib/generators/module-facts-discovery.js.map +2 -2
- package/dist/lib/generators/module-facts.js +65 -17
- package/dist/lib/generators/module-facts.js.map +2 -2
- package/dist/lib/generators/module-registry.js +5 -4
- package/dist/lib/generators/module-registry.js.map +2 -2
- package/dist/lib/resolver.js +2 -0
- package/dist/lib/resolver.js.map +2 -2
- package/package.json +5 -5
- package/src/lib/__integration__/TC-INT-008.spec.ts +103 -8
- package/src/lib/__tests__/agentic-init.test.ts +41 -5
- package/src/lib/__tests__/agentic-setup.ownership.test.ts +380 -0
- package/src/lib/__tests__/injection-widget-id-validation.test.ts +184 -0
- package/src/lib/agentic-init.ts +15 -3
- package/src/lib/agentic-setup.ts +526 -224
- package/src/lib/generators/__tests__/module-facts.bc-guard.test.ts +6 -0
- package/src/lib/generators/__tests__/module-facts.customers.fixture.test.ts +1 -0
- package/src/lib/generators/__tests__/module-facts.discovery.test.ts +54 -10
- package/src/lib/generators/__tests__/module-facts.extension-hosts.test.ts +108 -0
- package/src/lib/generators/__tests__/module-subset.test.ts +18 -0
- package/src/lib/generators/extensions/injection-widgets.ts +51 -0
- package/src/lib/generators/module-facts-discovery.ts +58 -7
- package/src/lib/generators/module-facts.ts +84 -20
- package/src/lib/generators/module-registry.ts +8 -4
- package/src/lib/resolver.ts +3 -0
- package/dist/agentic/guides/cache.md +0 -45
- package/dist/agentic/guides/core.md +0 -453
- package/dist/agentic/guides/events.md +0 -117
- package/dist/agentic/guides/queue.md +0 -53
- package/dist/agentic/guides/search.md +0 -115
- package/dist/agentic/guides/shared.md +0 -108
- package/dist/agentic/guides/ui.md +0 -347
- package/dist/agentic/shared/ai/skills/om-auto-continue-pr-loop/SKILL.md +0 -27
- package/dist/agentic/shared/ai/skills/om-auto-create-pr-loop/SKILL.md +0 -27
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/ui-components.md +0 -260
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/mikro-orm-cheatsheet.md +0 -146
- package/dist/agentic/shared/ai/skills/om-help/references/skills-catalog.md +0 -84
- package/dist/agentic/shared/ai/skills/om-help/references/workflow-sequences.md +0 -193
- package/dist/agentic/shared/ai/skills/om-integration-builder/STANDALONE.md +0 -34
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/adapter-contracts.md +0 -762
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/naming-conventions.md +0 -50
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/navigation-patterns.md +0 -97
- package/dist/agentic/shared/ai/skills/om-system-extension/references/extension-contracts.md +0 -271
- package/dist/agentic/shared/ai/skills/om-troubleshooter/references/diagnostic-commands.md +0 -101
|
@@ -1,315 +1,127 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
|
53
|
-
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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.
|
|
@@ -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.
|