create-mercato-app 0.6.7-develop.6758.1.697eade236 → 0.6.7-develop.6768.1.9d2c4efc43
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/agentic/guides/extensions.md +20 -3
- package/agentic/shared/AGENTS.md.template +2 -2
- package/agentic/shared/ai/harness/README.md +2 -0
- package/agentic/shared/ai/harness/cases.json +80 -39
- package/agentic/shared/ai/skills/om-system-extension/references/mechanism-selector.md +3 -1
- package/agentic/shared/ai/skills/om-system-extension/references/unified-overrides.md +2 -1
- package/agentic/shared/scripts/framework-context.mjs +3 -9
- package/dist/agentic/guides/extensions.md +20 -3
- package/dist/agentic/guides/framework-extension-points.md +36 -0
- package/dist/agentic/guides/module-facts.json +39708 -230
- package/dist/agentic/guides/modules/ai_assistant.md +49 -9
- package/dist/agentic/guides/modules/api_docs.md +11 -1
- package/dist/agentic/guides/modules/api_keys.md +24 -1
- package/dist/agentic/guides/modules/attachments.md +22 -6
- package/dist/agentic/guides/modules/audit_logs.md +35 -1
- package/dist/agentic/guides/modules/auth.md +79 -15
- package/dist/agentic/guides/modules/business_rules.md +36 -3
- package/dist/agentic/guides/modules/catalog.md +160 -22
- package/dist/agentic/guides/modules/channel_gmail.md +14 -1
- package/dist/agentic/guides/modules/channel_imap.md +14 -1
- package/dist/agentic/guides/modules/checkout.md +134 -19
- package/dist/agentic/guides/modules/communication_channels.md +110 -20
- package/dist/agentic/guides/modules/configs.md +15 -1
- package/dist/agentic/guides/modules/content.md +11 -1
- package/dist/agentic/guides/modules/currencies.md +50 -9
- package/dist/agentic/guides/modules/customer_accounts.md +151 -28
- package/dist/agentic/guides/modules/customers.md +299 -52
- package/dist/agentic/guides/modules/dashboards.md +30 -1
- package/dist/agentic/guides/modules/data_sync.md +40 -7
- package/dist/agentic/guides/modules/dictionaries.md +24 -6
- package/dist/agentic/guides/modules/directory.md +52 -9
- package/dist/agentic/guides/modules/entities.md +41 -1
- package/dist/agentic/guides/modules/events.md +11 -1
- package/dist/agentic/guides/modules/feature_toggles.md +15 -1
- package/dist/agentic/guides/modules/gateway_stripe.md +14 -1
- package/dist/agentic/guides/modules/generators.md +11 -1
- package/dist/agentic/guides/modules/inbox_ops.md +58 -16
- package/dist/agentic/guides/modules/integrations.md +30 -7
- package/dist/agentic/guides/modules/messages.md +68 -13
- package/dist/agentic/guides/modules/notifications.md +13 -1
- package/dist/agentic/guides/modules/onboarding.md +13 -1
- package/dist/agentic/guides/modules/payment_gateways.md +51 -12
- package/dist/agentic/guides/modules/perspectives.md +16 -1
- package/dist/agentic/guides/modules/planner.md +33 -9
- package/dist/agentic/guides/modules/portal.md +24 -1
- package/dist/agentic/guides/modules/progress.md +34 -9
- package/dist/agentic/guides/modules/query_index.md +56 -3
- package/dist/agentic/guides/modules/record_locks.md +60 -13
- package/dist/agentic/guides/modules/resources.md +79 -18
- package/dist/agentic/guides/modules/sales.md +238 -48
- package/dist/agentic/guides/modules/scheduler.md +23 -7
- package/dist/agentic/guides/modules/search.md +28 -3
- package/dist/agentic/guides/modules/security.md +106 -23
- package/dist/agentic/guides/modules/shipping_carriers.md +38 -10
- package/dist/agentic/guides/modules/sso.md +47 -15
- package/dist/agentic/guides/modules/staff.md +117 -38
- package/dist/agentic/guides/modules/storage_s3.md +13 -1
- package/dist/agentic/guides/modules/sync_akeneo.md +13 -1
- package/dist/agentic/guides/modules/sync_excel.md +15 -1
- package/dist/agentic/guides/modules/system_status_overlays.md +14 -1
- package/dist/agentic/guides/modules/translations.md +25 -5
- package/dist/agentic/guides/modules/webhooks.md +85 -15
- package/dist/agentic/guides/modules/wms.md +234 -31
- package/dist/agentic/guides/modules/workflows.md +114 -30
- package/dist/agentic/guides/upstream/BACKWARD_COMPATIBILITY.md +7 -0
- package/dist/agentic/guides/upstream/manifest.json +2 -2
- package/dist/agentic/shared/AGENTS.md.template +2 -2
- package/dist/agentic/shared/ai/harness/README.md +2 -0
- package/dist/agentic/shared/ai/harness/cases.json +80 -39
- package/dist/agentic/shared/ai/skills/om-system-extension/references/mechanism-selector.md +3 -1
- package/dist/agentic/shared/ai/skills/om-system-extension/references/unified-overrides.md +2 -1
- package/dist/agentic/shared/scripts/framework-context.mjs +3 -9
- package/package.json +3 -3
- package/template/AGENTS.md +2 -2
- package/template/src/app/layout.tsx +14 -18
- package/template/src/components/DemoFeedbackWidget.tsx +1 -1
- package/template/src/modules.ts +5 -5
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
# Unified Module Extensions and Overrides
|
|
2
2
|
|
|
3
|
-
Use the smallest extension mechanism that preserves installed-module ownership. Resolve
|
|
3
|
+
Use the smallest extension mechanism that preserves installed-module ownership. Resolve mechanisms, targets, and round trips from generated facts before exact installed source; never invent spot, route, entity, event, registry, or override IDs.
|
|
4
|
+
|
|
5
|
+
## Fact-First Target Resolution
|
|
6
|
+
|
|
7
|
+
Resolve an installed extension in this order:
|
|
8
|
+
|
|
9
|
+
1. Choose the mechanism by intent below; the mechanism decides which contribution kind and host capability are required.
|
|
10
|
+
2. Open only the named target module sheet at `.ai/guides/modules/<module>.md`. Its `UMES hosts` rows prove mountable exact/pattern targets; its `UMES contributions` rows preserve activation, phases/operations, feature and scope contracts, specialist routes, correlation resolution, and read/write/UI `roundTripId` links.
|
|
11
|
+
3. For global shell, menu, dashboard, notification, or integration surfaces, use `.ai/guides/framework-extension-points.md`. Do not assign a framework-owned host to a business module or invent a `$framework` module.
|
|
12
|
+
4. Follow a contribution's `fact-ref` or `specialistRoute` to the existing event/entity/API/command/search/AI/provider facts and owning specialist route. A specialized registry is not evidence for a generic widget target.
|
|
13
|
+
5. Use `om-framework-context` for one named unresolved installed-version gap only. An `optional-external` target is explicit provenance and must degrade when its owner package is absent; an `unresolved` first-party target is a blocker, not permission to guess.
|
|
14
|
+
|
|
15
|
+
The legacy `Host extension points` token summary remains useful for compatibility, but it is not proof that a helper-built token is bound. Prefer the correlated host/contribution rows. A DataTable base token is a prefix, not a rendered mount; helper-only CrudForm/DataTable IDs marked `bound: false` are diagnostics and must never be selected.
|
|
4
16
|
|
|
5
17
|
## Route Selection
|
|
6
18
|
|
|
@@ -17,7 +29,7 @@ Add every other match too: `backend-ui` + `om-backend-ui-design` when authoring,
|
|
|
17
29
|
| Add pre/post command behavior without replacing the command | Command interceptor | `commands/interceptors.ts` |
|
|
18
30
|
| Block/rewrite a mutation with post-success work | Mutation guard contract | `data/guards.ts`; add widget injection only for a UI surface |
|
|
19
31
|
| Enrich query-engine reads | Query enricher | `data/enrichers.ts` with `queryEngine.enabled` |
|
|
20
|
-
| Add form fields/table columns/actions/filters/toolbar | Headless widget injection | `widgets/injection/**`, `widgets/injection-table.ts
|
|
32
|
+
| Add form fields/table columns/actions/filters/toolbar | Headless widget injection | `widgets/injection/**`, `widgets/injection-table.ts`; select an exact bound family row from target facts |
|
|
21
33
|
| Add/reorder menu items | Headless menu widget | same widget files, `menu:*` host |
|
|
22
34
|
| Render a card/tab/section in another page | UI widget injection | same widget files |
|
|
23
35
|
| Add app data linked to installed entity | Entity extension | `data/extensions.ts` |
|
|
@@ -66,7 +78,9 @@ Add every other match too: `backend-ui` + `om-backend-ui-design` when authoring,
|
|
|
66
78
|
- Gate display and execution separately. UI hiding never substitutes for backend authorization.
|
|
67
79
|
- Scope client handlers with `eventHandlers.filter.operations`; use `clientBroadcast`, `useAppEvent`, and `useOperationProgress` for typed real-time behavior instead of polling by default.
|
|
68
80
|
|
|
69
|
-
|
|
81
|
+
Bound CrudForm hosts are the base render/lifecycle host, `:header`, headless `:fields`, its component handle, and the declared transform/save/delete/field/navigation lifecycle handlers with create/update/delete operation filters. Bound DataTable hosts are rendered `:header`, `:footer`, `:toolbar`, conditional `:search-trailing`, headless `:columns`, `:row-actions`, `:bulk-actions`, `:filters`, and the `data-table:<tableId>` component handle. The DataTable base prefix, `emptyState`, and helper-only CrudForm before/after/footer/sidebar/group/field builders are not mountable unless a future bound-family fact explicitly says otherwise.
|
|
82
|
+
|
|
83
|
+
Menu hosts are framework-owned unless the named module facts prove otherwise. Use the framework catalog's exact menu surface/item IDs, label keys, feature gates, and relative placement; never derive `menu:sidebar:*` or `menu:topbar:*` from memory.
|
|
70
84
|
|
|
71
85
|
## Extensions and Optional Coupling
|
|
72
86
|
|
|
@@ -102,3 +116,6 @@ Common host families include `crud-form:<entityId>:fields`, `data-table:<tableId
|
|
|
102
116
|
2. Test authorized, unauthorized, and wildcard-feature callers.
|
|
103
117
|
3. Test list and detail, create/update/delete/action, cache hit/miss, and failure fallback where applicable.
|
|
104
118
|
4. Run `yarn generate`, inspect host registration, and verify no installed file changed.
|
|
119
|
+
5. Re-read the generated contribution row: its target must resolve as `exact`, `pattern`, `framework`, `fact-ref`, or intentional `optional-external`, and every shared `roundTripId` leg must remain present. Treat `unresolved` first-party provenance as a failed generation/coverage gate.
|
|
120
|
+
|
|
121
|
+
The repository umbrella specification may be available at `.ai/specs/implemented/SPEC-041-2026-02-24-universal-module-extension-system.md` in a source checkout. It is optional background only; the generated facts and this selector are sufficient offline in a standalone scaffold.
|
|
@@ -53,7 +53,7 @@ Existing installed form/table fields, filters, row/bulk actions without app pers
|
|
|
53
53
|
|---|---|---|
|
|
54
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
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` +
|
|
56
|
+
| `umes` | Extend/replace installed behavior | `.ai/guides/extensions.md` + named facts |
|
|
57
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
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
59
|
| `ai-workflow` | Agent/tool/MCP/orchestrator/durable workflow | `.ai/guides/ai-workflows.md` + facts; schedules/queues/workers/retries/progress alone are `module-data` |
|
|
@@ -85,7 +85,7 @@ Match every work-unit row; OPEN its skill before selection.
|
|
|
85
85
|
| `framework-context` | Exact installed contract still unknown | bounded `om-framework-context`, last |
|
|
86
86
|
| `debugging` + `testing` | Add/fix recurring harness case/test | `om-evolve-harness` |
|
|
87
87
|
|
|
88
|
-
`framework-context`:
|
|
88
|
+
`framework-context`: resolve one named module/framework fact first. Use bounded source only for an unresolved exact contract, current behavior, authorization, dependents, or safest customization seam; never for “installed contracts” alone.
|
|
89
89
|
|
|
90
90
|
### Axis 3 — SDLC and Delivery
|
|
91
91
|
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
`cases.json` is the 202-case standalone-app contract. Run `yarn harness:validate --all` for the deterministic gate. Live routing uses a fresh read-only process per case:
|
|
4
4
|
|
|
5
|
+
UMES routing is fact-first. The additive and unified-override audit evaluations, plus their targeted cases, resolve exact/pattern hosts, outgoing contributions, correlation provenance, round-trip groups, framework-owned targets, and override domain/key/mode from the generated module sheets and `.ai/guides/framework-extension-points.md` before bounded installed source. The repository UMES umbrella spec may appear as optional source-checkout provenance; it is never required in a standalone scaffold.
|
|
6
|
+
|
|
5
7
|
```text
|
|
6
8
|
yarn harness:validate --runner codex --all
|
|
7
9
|
yarn harness:validate --runner claude --case OMH-009
|
|
@@ -1970,7 +1970,7 @@
|
|
|
1970
1970
|
"mode": "one-shot",
|
|
1971
1971
|
"evaluationKind": "implementation",
|
|
1972
1972
|
"risk": "medium",
|
|
1973
|
-
"prompt": "In a freshly scaffolded standalone Open Mercato app, inject an editable
|
|
1973
|
+
"prompt": "In a freshly scaffolded standalone Open Mercato app, inject an editable installed CrudForm field across read, display, and save paths. Resolve the exact bound form host and its correlated read/write/UI round trip from the named module facts before using source context; reject helper-only or unbound IDs. Keep framework packages read-only, preserve tenant and organization boundaries, and identify the smallest relevant validation.",
|
|
1974
1974
|
"tags": [
|
|
1975
1975
|
"umes",
|
|
1976
1976
|
"backend-ui",
|
|
@@ -2022,6 +2022,9 @@
|
|
|
2022
2022
|
]
|
|
2023
2023
|
},
|
|
2024
2024
|
"requiredDecisions": [
|
|
2025
|
+
"facts-first-target",
|
|
2026
|
+
"bound-crud-form-host",
|
|
2027
|
+
"correlated-roundtrip",
|
|
2025
2028
|
"widget-read-write-roundtrip",
|
|
2026
2029
|
"stable-spot-id"
|
|
2027
2030
|
],
|
|
@@ -2078,7 +2081,7 @@
|
|
|
2078
2081
|
"mode": "one-shot",
|
|
2079
2082
|
"evaluationKind": "implementation",
|
|
2080
2083
|
"risk": "medium",
|
|
2081
|
-
"prompt": "In a freshly scaffolded standalone Open Mercato app, inject a DataTable column, filter, row action, bulk action, or toolbar item.
|
|
2084
|
+
"prompt": "In a freshly scaffolded standalone Open Mercato app, inject a DataTable column, filter, row action, bulk action, or toolbar item. Resolve the exact bound deep table host from the named module facts before using source context, distinguish it from the non-mountable base prefix and helper-only IDs, and preserve its correlated execution guard. Keep framework packages read-only, preserve tenant and organization boundaries, and identify the smallest relevant validation.",
|
|
2082
2085
|
"tags": [
|
|
2083
2086
|
"umes",
|
|
2084
2087
|
"backend-ui",
|
|
@@ -2119,6 +2122,9 @@
|
|
|
2119
2122
|
]
|
|
2120
2123
|
},
|
|
2121
2124
|
"requiredDecisions": [
|
|
2125
|
+
"facts-first-target",
|
|
2126
|
+
"bound-data-table-host",
|
|
2127
|
+
"base-prefix-not-mountable",
|
|
2122
2128
|
"stable-table-host",
|
|
2123
2129
|
"bulk-mutation-safety"
|
|
2124
2130
|
],
|
|
@@ -2173,7 +2179,7 @@
|
|
|
2173
2179
|
"mode": "one-shot",
|
|
2174
2180
|
"evaluationKind": "routing",
|
|
2175
2181
|
"risk": "medium",
|
|
2176
|
-
"prompt": "In a freshly scaffolded standalone Open Mercato app, add or reorder main, settings, profile, topbar, and profile-dropdown menus.
|
|
2182
|
+
"prompt": "In a freshly scaffolded standalone Open Mercato app, add or reorder main, settings, profile, topbar, and profile-dropdown menus. Resolve exact framework-owned menu surface and item IDs, label keys, feature gates, and relative placement from the framework extension catalog before using source context; do not attribute them to a business module or derive IDs from memory. Keep framework packages read-only, preserve tenant and organization boundaries, and identify the smallest relevant validation.",
|
|
2177
2183
|
"tags": [
|
|
2178
2184
|
"umes",
|
|
2179
2185
|
"backend-ui",
|
|
@@ -2214,7 +2220,8 @@
|
|
|
2214
2220
|
".ai/guides/extensions.md",
|
|
2215
2221
|
".ai/guides/backend-ui.md",
|
|
2216
2222
|
".ai/skills/om-backend-ui-design/SKILL.md",
|
|
2217
|
-
".ai/skills/om-system-extension/SKILL.md"
|
|
2223
|
+
".ai/skills/om-system-extension/SKILL.md",
|
|
2224
|
+
".ai/guides/framework-extension-points.md"
|
|
2218
2225
|
],
|
|
2219
2226
|
"allowedExtra": [
|
|
2220
2227
|
".ai/skills/om-framework-context/SKILL.md"
|
|
@@ -2225,6 +2232,8 @@
|
|
|
2225
2232
|
]
|
|
2226
2233
|
},
|
|
2227
2234
|
"requiredDecisions": [
|
|
2235
|
+
"framework-facts-first",
|
|
2236
|
+
"exact-framework-menu-host",
|
|
2228
2237
|
"menu-injection",
|
|
2229
2238
|
"stable-ordering"
|
|
2230
2239
|
],
|
|
@@ -2242,7 +2251,7 @@
|
|
|
2242
2251
|
"context.forbidden",
|
|
2243
2252
|
"patterns.forbidden"
|
|
2244
2253
|
],
|
|
2245
|
-
"maxContextFiles":
|
|
2254
|
+
"maxContextFiles": 7,
|
|
2246
2255
|
"maxInitialContextBytes": 49152,
|
|
2247
2256
|
"maxTotalContextBytes": 114688,
|
|
2248
2257
|
"relatedCases": [
|
|
@@ -2428,7 +2437,7 @@
|
|
|
2428
2437
|
"mode": "one-shot",
|
|
2429
2438
|
"evaluationKind": "implementation",
|
|
2430
2439
|
"risk": "high",
|
|
2431
|
-
"prompt": "In a freshly scaffolded standalone Open Mercato app, intercept an installed API request or response while preserving contracts.
|
|
2440
|
+
"prompt": "In a freshly scaffolded standalone Open Mercato app, intercept an installed API request or response while preserving contracts. Resolve the exact route, methods, before/after phases, host activation bridge, timeout, and failure posture from the named module facts before using source context. Keep framework packages read-only, preserve tenant and organization boundaries, and identify the smallest relevant validation.",
|
|
2432
2441
|
"tags": [
|
|
2433
2442
|
"umes",
|
|
2434
2443
|
"interceptor-contract"
|
|
@@ -2465,6 +2474,9 @@
|
|
|
2465
2474
|
]
|
|
2466
2475
|
},
|
|
2467
2476
|
"requiredDecisions": [
|
|
2477
|
+
"facts-first-target",
|
|
2478
|
+
"interceptor-activation",
|
|
2479
|
+
"interceptor-phases-and-failure-posture",
|
|
2468
2480
|
"interceptor-contract",
|
|
2469
2481
|
"scope-preservation"
|
|
2470
2482
|
],
|
|
@@ -2518,7 +2530,7 @@
|
|
|
2518
2530
|
"mode": "one-shot",
|
|
2519
2531
|
"evaluationKind": "routing",
|
|
2520
2532
|
"risk": "high",
|
|
2521
|
-
"prompt": "In a freshly scaffolded standalone Open Mercato app, add a mutation guard with safe payload rewrite and post-success callbacks.
|
|
2533
|
+
"prompt": "In a freshly scaffolded standalone Open Mercato app, add a mutation guard with safe payload rewrite and post-success callbacks. Resolve the exact entity, operations, block/rewrite/after-success capabilities, and locking-preservation contract from the named module facts before using source context. Keep framework packages read-only, preserve tenant and organization boundaries, and identify the smallest relevant validation.",
|
|
2522
2534
|
"tags": [
|
|
2523
2535
|
"umes",
|
|
2524
2536
|
"mutation-guard"
|
|
@@ -2555,6 +2567,9 @@
|
|
|
2555
2567
|
]
|
|
2556
2568
|
},
|
|
2557
2569
|
"requiredDecisions": [
|
|
2570
|
+
"facts-first-target",
|
|
2571
|
+
"guard-operations-and-capabilities",
|
|
2572
|
+
"locking-preserved",
|
|
2558
2573
|
"mutation-guard",
|
|
2559
2574
|
"safe-after-success"
|
|
2560
2575
|
],
|
|
@@ -2728,7 +2743,7 @@
|
|
|
2728
2743
|
"mode": "one-shot",
|
|
2729
2744
|
"evaluationKind": "routing",
|
|
2730
2745
|
"risk": "medium",
|
|
2731
|
-
"prompt": "In a freshly scaffolded standalone Open Mercato app, add DOM Event Bridge progress UI to a long-running operation supplied by an installed module. Extend
|
|
2746
|
+
"prompt": "In a freshly scaffolded standalone Open Mercato app, add DOM Event Bridge progress UI to a long-running operation supplied by an installed module. Resolve the event's client or portal broadcast fact, audience/scoping contract, and exact browser hook from the named module facts before using source context; a transport flag alone is not delivery. Extend through supported UMES surfaces, keep framework packages read-only, and identify the smallest relevant validation.",
|
|
2732
2747
|
"tags": [
|
|
2733
2748
|
"umes",
|
|
2734
2749
|
"backend-ui",
|
|
@@ -2762,7 +2777,8 @@
|
|
|
2762
2777
|
".ai/guides/extensions.md",
|
|
2763
2778
|
".ai/guides/backend-ui.md",
|
|
2764
2779
|
".ai/skills/om-system-extension/SKILL.md",
|
|
2765
|
-
".ai/guides/modules/progress.md"
|
|
2780
|
+
".ai/guides/modules/progress.md",
|
|
2781
|
+
".ai/guides/modules/events.md"
|
|
2766
2782
|
],
|
|
2767
2783
|
"warn": ["node_modules/@open-mercato/*/src/**"], "forbidden": [
|
|
2768
2784
|
".env*",
|
|
@@ -2770,6 +2786,9 @@
|
|
|
2770
2786
|
]
|
|
2771
2787
|
},
|
|
2772
2788
|
"requiredDecisions": [
|
|
2789
|
+
"facts-first-event",
|
|
2790
|
+
"broadcast-audience-scope",
|
|
2791
|
+
"exact-browser-hook",
|
|
2773
2792
|
"dom-event-bridge",
|
|
2774
2793
|
"operation-progress"
|
|
2775
2794
|
],
|
|
@@ -6177,7 +6196,7 @@
|
|
|
6177
6196
|
"mode": "analysis",
|
|
6178
6197
|
"evaluationKind": "routing",
|
|
6179
6198
|
"risk": "high",
|
|
6180
|
-
"prompt": "Audit how a standalone app can add behavior to installed modules without replacing them. Cover response and
|
|
6199
|
+
"prompt": "Audit how a standalone app can add behavior to installed modules without replacing them. Choose the mechanism first, then resolve each exact or pattern target from one named module fact sheet, the framework extension catalog for framework-owned hosts, or a contribution's fact-ref/specialistRoute; installed source is only a bounded fallback for one named unresolved version gap. Cover response and caller-opt-in query enrichers; API interceptors, mutation guards, and additive command interceptors with execute/undo phases; every actually bound CrudForm and DataTable render, headless, lifecycle, operation-filter, and component-handle family while rejecting base-prefix/helper-only IDs; framework menus; entity extensions; async, sync, and querying/queried lifecycle subscribers; reactive notification handlers plus client/portal browser bridges and audience scope; integration UI; specialized vector, AI, payment, shipping, currency, and workflow registries; and component wrappers. For each, preserve activation, phases/operations, features, scope, placement, timeout/fallback/cache or execution-guard details, target-resolution provenance, optional-external behavior, and correlated read/write/UI roundTripId legs. Treat unresolved first-party targets as blockers, never bypass command/locking/audit/undo, and prefer additive composition over unified replacement.",
|
|
6181
6200
|
"tags": ["umes", "extension-points", "additive", "audit"],
|
|
6182
6201
|
"owner": {
|
|
6183
6202
|
"kind": "skill",
|
|
@@ -6190,7 +6209,7 @@
|
|
|
6190
6209
|
"required": [
|
|
6191
6210
|
"AGENTS.md", ".ai/guides/extensions.md", ".ai/skills/om-system-extension/SKILL.md",
|
|
6192
6211
|
".ai/skills/om-system-extension/references/mechanism-selector.md", ".ai/skills/om-system-extension/references/extension-branches.md",
|
|
6193
|
-
".ai/guides/upstream/BACKWARD_COMPATIBILITY.md"
|
|
6212
|
+
".ai/guides/upstream/BACKWARD_COMPATIBILITY.md", ".ai/guides/framework-extension-points.md"
|
|
6194
6213
|
],
|
|
6195
6214
|
"allowedExtra": [
|
|
6196
6215
|
".ai/guides/modules/notifications.md",
|
|
@@ -6206,13 +6225,19 @@
|
|
|
6206
6225
|
],
|
|
6207
6226
|
"warn": ["node_modules/@open-mercato/*/src/**"], "forbidden": [".env*", ".git/**"]
|
|
6208
6227
|
},
|
|
6209
|
-
"requiredDecisions": ["additive-before-replacement", "exact-
|
|
6228
|
+
"requiredDecisions": ["additive-before-replacement", "facts-first-target-resolution", "framework-catalog-routing", "exact-pattern-fact-ref-resolution", "unresolved-first-party-blocker", "response-query-enricher-activation", "interceptor-guard-phases", "command-interceptor-execute-undo", "command-interceptor-acl-scope", "safe-command-block-rewrite", "querying-queried-caller-opt-in", "all-bound-crud-form-families", "all-bound-data-table-families", "reject-helper-only-hosts", "framework-menu-targets", "entity-extension-fact-ref", "subscriber-sync-persistent-priority", "dom-portal-audience-scope", "specialist-registry-routing", "component-wrapper-handle", "optional-external-provenance", "correlated-roundtrip-verification"],
|
|
6210
6229
|
"forbiddenPatterns": ["node_modules.{0,40}(?:write|edit|patch)", "direct ORM relationship", "(?:guess|invent).{0,30}(?:spot|handle|route|entity)"],
|
|
6211
6230
|
"validators": ["catalog.schema", "owner.reference", "skills.reference", "router.contract", "context.budget", "context.forbidden", "patterns.forbidden"],
|
|
6212
|
-
"maxContextFiles":
|
|
6213
|
-
"maxInitialContextBytes":
|
|
6214
|
-
"maxTotalContextBytes":
|
|
6215
|
-
"relatedCases": ["OMH-025", "OMH-026", "OMH-038", "OMH-089"]
|
|
6231
|
+
"maxContextFiles": 16,
|
|
6232
|
+
"maxInitialContextBytes": 98304,
|
|
6233
|
+
"maxTotalContextBytes": 262144,
|
|
6234
|
+
"relatedCases": ["OMH-025", "OMH-026", "OMH-038", "OMH-089"],
|
|
6235
|
+
"source": {
|
|
6236
|
+
"paths": [
|
|
6237
|
+
".ai/specs/2026-07-24-standalone-ai-development-harness.md",
|
|
6238
|
+
".ai/specs/implemented/SPEC-041-2026-02-24-universal-module-extension-system.md"
|
|
6239
|
+
]
|
|
6240
|
+
}
|
|
6216
6241
|
},
|
|
6217
6242
|
{
|
|
6218
6243
|
"id": "OMH-089",
|
|
@@ -6221,7 +6246,7 @@
|
|
|
6221
6246
|
"mode": "analysis",
|
|
6222
6247
|
"evaluationKind": "routing",
|
|
6223
6248
|
"risk": "high",
|
|
6224
|
-
"prompt": "Audit the canonical src/modules.ts entry.overrides surface for a standalone app and verify its stable IDs and replacement seams against the backward-compatibility policy.
|
|
6249
|
+
"prompt": "Audit the canonical src/modules.ts entry.overrides surface for a standalone app and verify its stable IDs and replacement seams against the backward-compatibility policy. Resolve every wired domain, exact key, and disable-replace/replace/additive mode from the named module facts and their fact-ref provenance before using bounded installed context; an unresolved or stale first-party correlation is a blocker. Account for AI agents/tools plus additive AI extensions; API and backend/frontend page routes; subscribers; workers; injection, component, and dashboard widgets; notification types/handlers; API and command interceptors; enrichers; page guards; CLI; entry-scoped setup; ACL; DI; and encryption maps. Preserve registry entry keys, worker metadata fallback, null-disable/typed replacement semantics, special AI-extension/setup shapes, global-map ownership, bootstrap/generation ordering, security, stale-key diagnostics, and rollback.",
|
|
6225
6250
|
"tags": ["umes", "unified-overrides", "all-domains", "audit"],
|
|
6226
6251
|
"owner": {
|
|
6227
6252
|
"kind": "skill",
|
|
@@ -6240,17 +6265,24 @@
|
|
|
6240
6265
|
".ai/guides/modules/ai_assistant.md",
|
|
6241
6266
|
".ai/guides/modules/dashboards.md",
|
|
6242
6267
|
".ai/guides/modules/events.md",
|
|
6243
|
-
".ai/guides/modules/notifications.md"
|
|
6268
|
+
".ai/guides/modules/notifications.md",
|
|
6269
|
+
".ai/guides/framework-extension-points.md"
|
|
6244
6270
|
],
|
|
6245
6271
|
"warn": ["node_modules/@open-mercato/*/src/**"], "forbidden": [".env*", ".git/**"]
|
|
6246
6272
|
},
|
|
6247
|
-
"requiredDecisions": ["all-eighteen-domains", "additive-ai-extensions", "stable-override-key", "resolved-widget-worker-keys", "entry-scoped-setup-shape", "null-disable", "typed-replacement", "security-preservation", "stale-key-diagnostic", "bootstrap-before-registry", "rollback-verification"],
|
|
6273
|
+
"requiredDecisions": ["all-eighteen-domains", "facts-first-override-resolution", "override-fact-ref-provenance", "override-mode-from-facts", "unresolved-first-party-blocker", "additive-ai-extensions", "stable-override-key", "resolved-widget-worker-keys", "entry-scoped-setup-shape", "null-disable", "typed-replacement", "security-preservation", "stale-key-diagnostic", "bootstrap-before-registry", "rollback-verification"],
|
|
6248
6274
|
"forbiddenPatterns": ["node_modules.{0,40}(?:write|edit|patch)", "load order.{0,30}(?:hope|accident)", "(?:weaken|remove).{0,30}(?:auth|scope|guard|lock)"],
|
|
6249
6275
|
"validators": ["catalog.schema", "owner.reference", "skills.reference", "router.contract", "context.budget", "context.forbidden", "patterns.forbidden"],
|
|
6250
|
-
"maxContextFiles":
|
|
6251
|
-
"maxInitialContextBytes":
|
|
6252
|
-
"maxTotalContextBytes":
|
|
6253
|
-
"relatedCases": ["OMH-029", "OMH-030", "OMH-056", "OMH-088"]
|
|
6276
|
+
"maxContextFiles": 10,
|
|
6277
|
+
"maxInitialContextBytes": 98304,
|
|
6278
|
+
"maxTotalContextBytes": 196608,
|
|
6279
|
+
"relatedCases": ["OMH-029", "OMH-030", "OMH-056", "OMH-088"],
|
|
6280
|
+
"source": {
|
|
6281
|
+
"paths": [
|
|
6282
|
+
".ai/specs/2026-07-24-standalone-ai-development-harness.md",
|
|
6283
|
+
".ai/specs/implemented/SPEC-041-2026-02-24-universal-module-extension-system.md"
|
|
6284
|
+
]
|
|
6285
|
+
}
|
|
6254
6286
|
},
|
|
6255
6287
|
{
|
|
6256
6288
|
"id": "OMH-090",
|
|
@@ -6290,7 +6322,7 @@
|
|
|
6290
6322
|
"mode": "one-shot",
|
|
6291
6323
|
"evaluationKind": "routing",
|
|
6292
6324
|
"risk": "high",
|
|
6293
|
-
"prompt": "Add an app-owned customer support cases page to the installed portal. Use frontend/[orgSlug]/portal/**/page.tsx with sibling metadata, customer auth/features for guarded pages while preserving public-page semantics, principal-derived scope, optional nav only for the list destination, frozen portal hooks/spots/handles, portal menu injection only for links without a backing page, DataTable for the list, shared responsive and accessible components, loading/empty/not-found/denial/error/conflict/success states, wildcard-aware authorization, direct-route protection, and portal integration tests.",
|
|
6325
|
+
"prompt": "Add an app-owned customer support cases page to the installed portal. Resolve exact or pattern portal hosts from the portal/customer_accounts module facts and framework-owned portal menu/chrome targets from the framework extension catalog before source context; preserve portalBroadcast audience scope and select the exact portal hook. Use frontend/[orgSlug]/portal/**/page.tsx with sibling metadata, customer auth/features for guarded pages while preserving public-page semantics, principal-derived scope, optional nav only for the list destination, frozen portal hooks/spots/handles, portal menu injection only for links without a backing page, DataTable for the list, shared responsive and accessible components, loading/empty/not-found/denial/error/conflict/success states, wildcard-aware authorization, direct-route protection, and portal integration tests.",
|
|
6294
6326
|
"tags": [
|
|
6295
6327
|
"frontend",
|
|
6296
6328
|
"portal",
|
|
@@ -6333,7 +6365,8 @@
|
|
|
6333
6365
|
".ai/skills/om-backend-ui-design/SKILL.md",
|
|
6334
6366
|
".ai/skills/om-backend-ui-design/references/frontend-and-design-system.md",
|
|
6335
6367
|
".ai/guides/modules/customer_accounts.md",
|
|
6336
|
-
".ai/guides/modules/portal.md"
|
|
6368
|
+
".ai/guides/modules/portal.md",
|
|
6369
|
+
".ai/guides/framework-extension-points.md"
|
|
6337
6370
|
],
|
|
6338
6371
|
"warn": ["node_modules/@open-mercato/*/src/**"], "forbidden": [
|
|
6339
6372
|
".env*",
|
|
@@ -6341,6 +6374,10 @@
|
|
|
6341
6374
|
]
|
|
6342
6375
|
},
|
|
6343
6376
|
"requiredDecisions": [
|
|
6377
|
+
"facts-first-portal-host",
|
|
6378
|
+
"framework-portal-menu-host",
|
|
6379
|
+
"portal-broadcast-audience-scope",
|
|
6380
|
+
"exact-portal-hook",
|
|
6344
6381
|
"portal-route-convention",
|
|
6345
6382
|
"portal-page-metadata",
|
|
6346
6383
|
"public-versus-guarded-portal-auth",
|
|
@@ -6498,7 +6535,7 @@
|
|
|
6498
6535
|
"oracle.business.command"
|
|
6499
6536
|
],
|
|
6500
6537
|
"maxContextFiles": 10,
|
|
6501
|
-
"maxInitialContextBytes":
|
|
6538
|
+
"maxInitialContextBytes": 61440,
|
|
6502
6539
|
"maxTotalContextBytes": 196608,
|
|
6503
6540
|
"relatedCases": [
|
|
6504
6541
|
"OMH-060",
|
|
@@ -10808,7 +10845,7 @@
|
|
|
10808
10845
|
"requiredDecisions":["durable-user-task","separation-of-duties","mutation-guards","status-invariant"],
|
|
10809
10846
|
"forbiddenPatterns":["node_modules.{0,40}(?:write|edit|patch)","(?:tenant|organization).{0,30}(?:unscoped|scope optional)","requireRoles"],
|
|
10810
10847
|
"validators":["catalog.schema","owner.reference","skills.reference","router.contract","context.budget","context.forbidden","patterns.forbidden"],
|
|
10811
|
-
"maxContextFiles":9,"maxInitialContextBytes":
|
|
10848
|
+
"maxContextFiles":9,"maxInitialContextBytes":53248,"maxTotalContextBytes":147456,"relatedCases":["OMH-053","OMH-074","OMH-077"]
|
|
10812
10849
|
},
|
|
10813
10850
|
{
|
|
10814
10851
|
"id": "OMH-140",
|
|
@@ -11736,7 +11773,7 @@
|
|
|
11736
11773
|
"requiredDecisions":["webhook-signature","typed-events","subscriber-idempotency","outbound-delivery-status"],
|
|
11737
11774
|
"forbiddenPatterns":["node_modules.{0,40}(?:write|edit|patch)","(?:tenant|organization).{0,30}(?:unscoped|scope optional)","(?:secret|token|credential).{0,20}(?:console|log|plain.?text)"],
|
|
11738
11775
|
"validators":["catalog.schema","owner.reference","skills.reference","router.contract","context.budget","context.forbidden","patterns.forbidden"],
|
|
11739
|
-
"maxContextFiles":12,"maxInitialContextBytes":
|
|
11776
|
+
"maxContextFiles":12,"maxInitialContextBytes":65536,"maxTotalContextBytes":147456,"relatedCases":["OMH-018","OMH-043"]
|
|
11740
11777
|
},
|
|
11741
11778
|
{
|
|
11742
11779
|
"id": "OMH-156",
|
|
@@ -12100,7 +12137,7 @@
|
|
|
12100
12137
|
"requiredDecisions":["public-scope-derived-server-side","idempotent-submission","deterministic-deduplication","optional-crm","delivery-route-preserves-task-routes","smallest-validation"],
|
|
12101
12138
|
"forbiddenPatterns":["node_modules.{0,40}(?:write|edit|patch)","(?:tenant|organization).{0,30}(?:unscoped|scope optional)","git (?:add|commit).{0,20}(?:--all|-a)","(?:skip|omit).{0,30}(?:validation|test)"],
|
|
12102
12139
|
"validators":["catalog.schema","owner.reference","skills.reference","router.contract","context.budget","context.forbidden","patterns.forbidden"],
|
|
12103
|
-
"maxContextFiles":11,"maxInitialContextBytes":
|
|
12140
|
+
"maxContextFiles":11,"maxInitialContextBytes":65536,"maxTotalContextBytes":196608,"relatedCases":["OMH-005","OMH-073"]
|
|
12104
12141
|
},
|
|
12105
12142
|
{
|
|
12106
12143
|
"id":"OMH-170","title":"Review a stock-reservation pull request for actionable problems only","family":"architecture","mode":"review","evaluationKind":"routing","risk":"medium",
|
|
@@ -12404,30 +12441,30 @@
|
|
|
12404
12441
|
},
|
|
12405
12442
|
{
|
|
12406
12443
|
"id":"OMH-179","title":"Show loyalty points in customer responses without copying customer records","family":"umes","mode":"one-shot","evaluationKind":"routing","risk":"medium",
|
|
12407
|
-
"prompt":"Show each customer's current loyalty-points balance in customer API results while keeping the existing customer data as the source of truth and
|
|
12444
|
+
"prompt":"Show each customer's current loyalty-points balance in customer list and detail API results while keeping the existing customer data as the source of truth. Resolve the dotted target entity, host-route opt-in, list/detail surfaces, timeout/fallback/cache posture, and correlation provenance from the customers module facts before source context; do not duplicate customer records or invent a target.",
|
|
12408
12445
|
"tags":["business-language","response-enrichment","loyalty"],
|
|
12409
12446
|
"owner":{"kind":"skill","path":".ai/skills/om-system-extension/SKILL.md","ruleIds":["BC-02","BC-03","BC-04"]},
|
|
12410
12447
|
"expectedRouter":{"required":["umes"],"allowedExtra":["module-data","framework-context"]},
|
|
12411
12448
|
"requiredSkills":["om-system-extension"],
|
|
12412
12449
|
"context":{"required":["AGENTS.md",".ai/guides/extensions.md",".ai/skills/om-system-extension/SKILL.md",".ai/guides/modules/customers.md"],"allowedExtra":[".ai/guides/contracts.md"],"warn": ["node_modules/@open-mercato/*/src/**"], "forbidden": [".env*",".git/**"]},
|
|
12413
|
-
"requiredDecisions":["scoped-enricher","batched-enrichment","exact-host-token","no-host-record-mutation"],
|
|
12450
|
+
"requiredDecisions":["facts-first-target","enricher-host-opt-in","enricher-list-detail-posture","scoped-enricher","batched-enrichment","exact-host-token","no-host-record-mutation"],
|
|
12414
12451
|
"forbiddenPatterns":["node_modules.{0,40}(?:write|edit|patch)","(?:tenant|organization).{0,30}(?:unscoped|scope optional)","(?:copy|duplicate).{0,20}customer (?:entity|record|table)"],
|
|
12415
12452
|
"validators":["catalog.schema","owner.reference","skills.reference","router.contract","context.budget","context.forbidden","patterns.forbidden"],
|
|
12416
12453
|
"maxContextFiles":6,"maxInitialContextBytes":40960,"maxTotalContextBytes":114688,"relatedCases":["OMH-025","OMH-088"]
|
|
12417
12454
|
},
|
|
12418
12455
|
{
|
|
12419
12456
|
"id":"OMH-180","title":"Add preferred contact time to the existing customer form with full round trip","family":"umes","mode":"one-shot","evaluationKind":"routing","risk":"high",
|
|
12420
|
-
"prompt":"Add preferred contact time to the existing customer form and make entering, displaying, changing, clearing, and reloading the value work correctly.",
|
|
12457
|
+
"prompt":"Add preferred contact time to the existing customer form and make entering, displaying, changing, clearing, and reloading the value work correctly. Resolve the exact bound CrudForm base/header/fields or lifecycle host and shared roundTripId from the customers module facts before source context; reject helper-only or unbound field builders.",
|
|
12421
12458
|
"tags":["business-language","form-extension","customer"],
|
|
12422
12459
|
"owner":{"kind":"skill","path":".ai/skills/om-system-extension/SKILL.md","ruleIds":["BC-02","BC-03","BC-06","BC-07","BC-08"]},
|
|
12423
12460
|
"expectedRouter":{"required":["module-data","backend-ui","umes"],"allowedExtra":["testing","framework-context"]},
|
|
12424
12461
|
"requiredSkills":["om-data-model-design","om-backend-ui-design","om-system-extension"],
|
|
12425
12462
|
"optionalSkills":[{"id":"om-framework-context","route":"framework-context"}],
|
|
12426
12463
|
"context":{"required":["AGENTS.md",".ai/guides/contracts.md",".ai/guides/extensions.md",".ai/guides/backend-ui.md",".ai/skills/om-data-model-design/SKILL.md",".ai/skills/om-system-extension/SKILL.md",".ai/skills/om-backend-ui-design/SKILL.md",".ai/guides/modules/customers.md"],"allowedExtra":[".ai/skills/om-framework-context/SKILL.md"],"warn": ["node_modules/@open-mercato/*/src/**"], "forbidden": [".env*",".git/**"]},
|
|
12427
|
-
"requiredDecisions":["widget-read-write-roundtrip","stable-spot-id","clear-null","optimistic-lock","translation-keys"],
|
|
12464
|
+
"requiredDecisions":["facts-first-target","bound-crud-form-host","correlated-roundtrip","reject-helper-only-host","widget-read-write-roundtrip","stable-spot-id","clear-null","optimistic-lock","translation-keys"],
|
|
12428
12465
|
"forbiddenPatterns":["node_modules.{0,40}(?:write|edit|patch)","raw (?:form|fetch)","hard-coded user-facing","direct ORM relationship"],
|
|
12429
12466
|
"validators":["catalog.schema","owner.reference","skills.reference","router.contract","context.budget","context.forbidden","patterns.forbidden"],
|
|
12430
|
-
"maxContextFiles":8,"maxInitialContextBytes":
|
|
12467
|
+
"maxContextFiles":8,"maxInitialContextBytes":53248,"maxTotalContextBytes":131072,"relatedCases":["OMH-024","OMH-026","OMH-061"]
|
|
12431
12468
|
},
|
|
12432
12469
|
{
|
|
12433
12470
|
"id": "OMH-181",
|
|
@@ -12436,7 +12473,7 @@
|
|
|
12436
12473
|
"mode": "one-shot",
|
|
12437
12474
|
"evaluationKind": "implementation",
|
|
12438
12475
|
"risk": "high",
|
|
12439
|
-
"prompt": "Add an order-risk filter and a bulk review action to the existing orders table, enforcing permission and version checks for every selected row.",
|
|
12476
|
+
"prompt": "Add an order-risk filter and a bulk review action to the existing orders table, enforcing permission and version checks for every selected row. Resolve the exact bound DataTable filter and bulk-action targets, deep table ID, execution guard, and correlation provenance from the sales module facts before source context; do not use the base prefix or helper-only IDs as mounts.",
|
|
12440
12477
|
"tags": [
|
|
12441
12478
|
"business-language",
|
|
12442
12479
|
"table-extension",
|
|
@@ -12493,6 +12530,10 @@
|
|
|
12493
12530
|
]
|
|
12494
12531
|
},
|
|
12495
12532
|
"requiredDecisions": [
|
|
12533
|
+
"facts-first-target",
|
|
12534
|
+
"bound-data-table-host",
|
|
12535
|
+
"base-prefix-not-mountable",
|
|
12536
|
+
"correlated-execution-guard",
|
|
12496
12537
|
"stable-table-host",
|
|
12497
12538
|
"bulk-mutation-safety",
|
|
12498
12539
|
"wildcard-acl",
|
|
@@ -12549,27 +12590,27 @@
|
|
|
12549
12590
|
},
|
|
12550
12591
|
{
|
|
12551
12592
|
"id":"OMH-182","title":"Block order cancellation after dispatch across every entry point","family":"umes","mode":"one-shot","evaluationKind":"routing","risk":"high",
|
|
12552
|
-
"prompt":"Block order cancellation after dispatch even when someone calls the API directly, while preserving the existing route, method, request, response, and error schemas.",
|
|
12593
|
+
"prompt":"Block order cancellation after dispatch even when someone calls the API directly, while preserving the existing route, method, request, response, and error schemas. Resolve the sales guard host entity, update operation, block capability, optimistic-lock preservation, and fact-ref provenance from the sales module facts before source context.",
|
|
12553
12594
|
"tags":["business-language","mutation-guard","orders"],
|
|
12554
12595
|
"owner":{"kind":"skill","path":".ai/skills/om-system-extension/SKILL.md","ruleIds":["BC-02","BC-03","BC-05","BC-08"]},
|
|
12555
12596
|
"expectedRouter":{"required":["umes"],"allowedExtra":["module-data","backend-ui","debugging","framework-context"]},
|
|
12556
12597
|
"requiredSkills":["om-system-extension"],
|
|
12557
12598
|
"optionalSkills":[{"id":"om-framework-context","route":"framework-context"}],
|
|
12558
12599
|
"context":{"required":["AGENTS.md",".ai/guides/extensions.md",".ai/skills/om-system-extension/SKILL.md",".ai/guides/modules/sales.md",".ai/guides/upstream/BACKWARD_COMPATIBILITY.md"],"allowedExtra":[".ai/skills/om-framework-context/SKILL.md"],"warn": ["node_modules/@open-mercato/*/src/**"], "forbidden": [".env*",".git/**"]},
|
|
12559
|
-
"requiredDecisions":["mutation-guard","backend-consistency","status-invariant"],
|
|
12600
|
+
"requiredDecisions":["facts-first-target","guard-operations-and-capabilities","locking-preserved","mutation-guard","backend-consistency","status-invariant"],
|
|
12560
12601
|
"forbiddenPatterns":["node_modules.{0,40}(?:write|edit|patch)","UI only","(?:skip|bypass).{0,30}(?:guard|permission|lock)","rewrite.{0,30}(?:all|entire).{0,20}(?:body|query)"],
|
|
12561
12602
|
"validators":["catalog.schema","owner.reference","skills.reference","router.contract","context.budget","context.forbidden","patterns.forbidden"],
|
|
12562
12603
|
"maxContextFiles":8,"maxInitialContextBytes":65536,"maxTotalContextBytes":114688,"relatedCases":["OMH-031","OMH-032","OMH-038"]
|
|
12563
12604
|
},
|
|
12564
12605
|
{
|
|
12565
12606
|
"id":"OMH-183","title":"Award loyalty points after payment while tolerating an absent sales feature","family":"umes","mode":"one-shot","evaluationKind":"routing","risk":"high",
|
|
12566
|
-
"prompt":"Award loyalty points after a payment completes, avoid awarding the same points twice, and keep the application working when sales is not installed.",
|
|
12607
|
+
"prompt":"Award loyalty points after a payment completes, avoid awarding the same points twice, and keep the application working when sales is not installed. Resolve the event/subscriber fact reference, sync/persistent/priority posture, and optional-external target provenance from the named payment and sales module facts before source context.",
|
|
12567
12608
|
"tags":["business-language","event-reaction","optional-feature"],
|
|
12568
12609
|
"owner":{"kind":"skill","path":".ai/skills/om-system-extension/SKILL.md","ruleIds":["BC-02","BC-03","BC-04","BC-05","BC-09"]},
|
|
12569
12610
|
"expectedRouter":{"required":["module-data","umes"],"allowedExtra":["integration","ai-workflow"]},
|
|
12570
12611
|
"requiredSkills":["om-module-scaffold","om-system-extension"],
|
|
12571
12612
|
"context":{"required":["AGENTS.md",".ai/guides/contracts.md",".ai/guides/extensions.md",".ai/skills/om-module-scaffold/SKILL.md",".ai/skills/om-system-extension/SKILL.md",".ai/guides/modules/sales.md"],"allowedExtra":[".ai/guides/modules/payment_gateways.md"],"warn": ["node_modules/@open-mercato/*/src/**"], "forbidden": [".env*",".git/**"]},
|
|
12572
|
-
"requiredDecisions":["typed-events","subscriber-idempotency","optional-host","safe-degradation","cross-module-id-link"],
|
|
12613
|
+
"requiredDecisions":["facts-first-event","subscriber-delivery-posture","optional-external-provenance","typed-events","subscriber-idempotency","optional-host","safe-degradation","cross-module-id-link"],
|
|
12573
12614
|
"forbiddenPatterns":["node_modules.{0,40}(?:write|edit|patch)","direct ORM relationship","(?:require|assume).{0,20}sales.{0,20}(?:installed|enabled)","(?:tenant|organization).{0,30}(?:unscoped|scope optional)"],
|
|
12574
12615
|
"validators":["catalog.schema","owner.reference","skills.reference","router.contract","context.budget","context.forbidden","patterns.forbidden"],
|
|
12575
12616
|
"maxContextFiles":7,"maxInitialContextBytes":49152,"maxTotalContextBytes":131072,"relatedCases":["OMH-018","OMH-034"]
|
|
@@ -20,6 +20,8 @@ Load this reference before choosing files.
|
|
|
20
20
|
| Hide/replace supported route/page/agent/tool/etc. | `src/modules.ts` unified override. |
|
|
21
21
|
| Change unsupported internals | Eject only after explicit approval. |
|
|
22
22
|
|
|
23
|
-
Resolve exact
|
|
23
|
+
Resolve exact targets from the named module sheet's `UMES hosts` and `UMES contributions` first. Use `.ai/guides/framework-extension-points.md` for framework-owned menus, dashboard, notification, integration, and shell targets. Follow `fact-ref` and `specialistRoute` provenance instead of inventing a generic target; use exact installed context only for one named fact gap. `optional-external` degrades when its package is absent, while an `unresolved` first-party target blocks implementation.
|
|
24
|
+
|
|
25
|
+
If multiple mechanisms are required (for example editable field = widget + enricher + interceptor), follow the shared `roundTripId`, name one owner for each read/write/UI leg, and test them as one round trip. Select only facts marked bound: DataTable's rendered header/footer/toolbar/search-trailing, headless columns/row-actions/bulk-actions/filters, and component handle; CrudForm's base/header/fields, component handle, and declared lifecycle/operation-filter pipeline. Base prefixes and helper-only/unbound IDs are not mountable. Reactive notifications, messages/inbox, query/vector, integrations, and AI/workflow work also select their owning task route; UMES does not replace that specialist context.
|
|
24
26
|
|
|
25
27
|
Prefer additive composition before replacement (`additive-before-replacement`). Ejection is the last resort after supported seams are proven insufficient and explicit approval is granted (`eject-last`).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Unified Override Domains
|
|
2
2
|
|
|
3
|
-
Load this reference when `src/modules.ts` must disable or replace an installed contribution. `entry.overrides` is the only canonical app-level override umbrella. Resolve every key from
|
|
3
|
+
Load this reference when `src/modules.ts` must disable or replace an installed contribution. `entry.overrides` is the only canonical app-level override umbrella. Resolve every domain/key from the named module sheet's `UMES contributions` override facts first, following `fact-ref` provenance to the existing route/page/event/worker/widget/agent/tool/setup/ACL/DI/encryption facts. Use exact installed context only for one named missing fact. For keyed override maps, `null` disables a supported contribution and a typed value replaces it; AI extensions and setup hooks have the special shapes below.
|
|
4
4
|
|
|
5
5
|
| Domain | Shape/key |
|
|
6
6
|
|---|---|
|
|
@@ -30,6 +30,7 @@ Load this reference when `src/modules.ts` must disable or replace an installed c
|
|
|
30
30
|
- API route methods are case-insensitive and paths normalize a leading/trailing slash; use the canonical displayed key. Disabling all methods removes the route entry.
|
|
31
31
|
- Page keys name generated frontend/backend URL paths, not filesystem paths. After hiding a landing page, provide a safe accessible redirect.
|
|
32
32
|
- Injection/dashboard keys are generated entry keys and may differ from widget metadata IDs. Worker keys are resolved descriptor IDs; inspect generated facts/source instead of constructing them from memory.
|
|
33
|
+
- Require the generated override fact's exact `domain`, `key`, and mode (`disable-replace`, `replace`, or `additive`). A stale or `unresolved` first-party correlation is a blocker; it is not a fallback to a guessed key.
|
|
33
34
|
- Keep AI extensions additive and ordered. Use agent/tool maps only for replacement or disable; do not encode an extension as a `null`-capable map entry.
|
|
34
35
|
- Preserve replacement type/signature, auth/features, scope, stable ID, and observable side effects. A replacement may strengthen safety but never silently narrow a public contract.
|
|
35
36
|
- Treat unknown/stale override diagnostics as failures. Run `yarn generate`, clear structural nav/module caches with the app's documented command, and verify the old contribution is absent in every bootstrap.
|
|
@@ -494,13 +494,6 @@ function fallbackInstalledPackageManifests(nodeModulesRoot) {
|
|
|
494
494
|
}
|
|
495
495
|
|
|
496
496
|
function fallbackBoundedSearch(query, sourceRoot) {
|
|
497
|
-
let pattern
|
|
498
|
-
try {
|
|
499
|
-
pattern = new RegExp(query)
|
|
500
|
-
} catch (error) {
|
|
501
|
-
throw new Error(`bounded search failed: ${error instanceof Error ? error.message : String(error)}`)
|
|
502
|
-
}
|
|
503
|
-
|
|
504
497
|
const matches = []
|
|
505
498
|
let bytesRead = 0
|
|
506
499
|
for (const file of fallbackRegularFiles(sourceRoot, 'bounded search failed')) {
|
|
@@ -515,7 +508,7 @@ function fallbackBoundedSearch(query, sourceRoot) {
|
|
|
515
508
|
const lines = content.toString('utf8').split(/\r?\n/)
|
|
516
509
|
for (let index = 0; index < lines.length; index += 1) {
|
|
517
510
|
const line = lines[index]
|
|
518
|
-
if (!
|
|
511
|
+
if (!line.includes(query)) continue
|
|
519
512
|
const preview = line.length > 500 ? `${line.slice(0, 500)}…` : line
|
|
520
513
|
matches.push(`${file}:${index + 1}:${preview}`)
|
|
521
514
|
if (matches.length > SEARCH_MATCH_LIMIT) break
|
|
@@ -640,7 +633,7 @@ function packageDiagnosticWarnings(diagnostics) {
|
|
|
640
633
|
|
|
641
634
|
function runBoundedSearch(query, sourceRoot) {
|
|
642
635
|
const fileSearch = runRg(
|
|
643
|
-
['--no-ignore', '--hidden', '--files-with-matches', '--null', '--sort', 'path', '--', query, sourceRoot],
|
|
636
|
+
['--no-ignore', '--hidden', '--fixed-strings', '--files-with-matches', '--null', '--sort', 'path', '--', query, sourceRoot],
|
|
644
637
|
'bounded search failed',
|
|
645
638
|
)
|
|
646
639
|
if (!fileSearch) return fallbackBoundedSearch(query, sourceRoot)
|
|
@@ -660,6 +653,7 @@ function runBoundedSearch(query, sourceRoot) {
|
|
|
660
653
|
[
|
|
661
654
|
'--no-ignore',
|
|
662
655
|
'--hidden',
|
|
656
|
+
'--fixed-strings',
|
|
663
657
|
'--line-number',
|
|
664
658
|
'--with-filename',
|
|
665
659
|
'--color',
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
# Unified Module Extensions and Overrides
|
|
2
2
|
|
|
3
|
-
Use the smallest extension mechanism that preserves installed-module ownership. Resolve
|
|
3
|
+
Use the smallest extension mechanism that preserves installed-module ownership. Resolve mechanisms, targets, and round trips from generated facts before exact installed source; never invent spot, route, entity, event, registry, or override IDs.
|
|
4
|
+
|
|
5
|
+
## Fact-First Target Resolution
|
|
6
|
+
|
|
7
|
+
Resolve an installed extension in this order:
|
|
8
|
+
|
|
9
|
+
1. Choose the mechanism by intent below; the mechanism decides which contribution kind and host capability are required.
|
|
10
|
+
2. Open only the named target module sheet at `.ai/guides/modules/<module>.md`. Its `UMES hosts` rows prove mountable exact/pattern targets; its `UMES contributions` rows preserve activation, phases/operations, feature and scope contracts, specialist routes, correlation resolution, and read/write/UI `roundTripId` links.
|
|
11
|
+
3. For global shell, menu, dashboard, notification, or integration surfaces, use `.ai/guides/framework-extension-points.md`. Do not assign a framework-owned host to a business module or invent a `$framework` module.
|
|
12
|
+
4. Follow a contribution's `fact-ref` or `specialistRoute` to the existing event/entity/API/command/search/AI/provider facts and owning specialist route. A specialized registry is not evidence for a generic widget target.
|
|
13
|
+
5. Use `om-framework-context` for one named unresolved installed-version gap only. An `optional-external` target is explicit provenance and must degrade when its owner package is absent; an `unresolved` first-party target is a blocker, not permission to guess.
|
|
14
|
+
|
|
15
|
+
The legacy `Host extension points` token summary remains useful for compatibility, but it is not proof that a helper-built token is bound. Prefer the correlated host/contribution rows. A DataTable base token is a prefix, not a rendered mount; helper-only CrudForm/DataTable IDs marked `bound: false` are diagnostics and must never be selected.
|
|
4
16
|
|
|
5
17
|
## Route Selection
|
|
6
18
|
|
|
@@ -17,7 +29,7 @@ Add every other match too: `backend-ui` + `om-backend-ui-design` when authoring,
|
|
|
17
29
|
| Add pre/post command behavior without replacing the command | Command interceptor | `commands/interceptors.ts` |
|
|
18
30
|
| Block/rewrite a mutation with post-success work | Mutation guard contract | `data/guards.ts`; add widget injection only for a UI surface |
|
|
19
31
|
| Enrich query-engine reads | Query enricher | `data/enrichers.ts` with `queryEngine.enabled` |
|
|
20
|
-
| Add form fields/table columns/actions/filters/toolbar | Headless widget injection | `widgets/injection/**`, `widgets/injection-table.ts
|
|
32
|
+
| Add form fields/table columns/actions/filters/toolbar | Headless widget injection | `widgets/injection/**`, `widgets/injection-table.ts`; select an exact bound family row from target facts |
|
|
21
33
|
| Add/reorder menu items | Headless menu widget | same widget files, `menu:*` host |
|
|
22
34
|
| Render a card/tab/section in another page | UI widget injection | same widget files |
|
|
23
35
|
| Add app data linked to installed entity | Entity extension | `data/extensions.ts` |
|
|
@@ -66,7 +78,9 @@ Add every other match too: `backend-ui` + `om-backend-ui-design` when authoring,
|
|
|
66
78
|
- Gate display and execution separately. UI hiding never substitutes for backend authorization.
|
|
67
79
|
- Scope client handlers with `eventHandlers.filter.operations`; use `clientBroadcast`, `useAppEvent`, and `useOperationProgress` for typed real-time behavior instead of polling by default.
|
|
68
80
|
|
|
69
|
-
|
|
81
|
+
Bound CrudForm hosts are the base render/lifecycle host, `:header`, headless `:fields`, its component handle, and the declared transform/save/delete/field/navigation lifecycle handlers with create/update/delete operation filters. Bound DataTable hosts are rendered `:header`, `:footer`, `:toolbar`, conditional `:search-trailing`, headless `:columns`, `:row-actions`, `:bulk-actions`, `:filters`, and the `data-table:<tableId>` component handle. The DataTable base prefix, `emptyState`, and helper-only CrudForm before/after/footer/sidebar/group/field builders are not mountable unless a future bound-family fact explicitly says otherwise.
|
|
82
|
+
|
|
83
|
+
Menu hosts are framework-owned unless the named module facts prove otherwise. Use the framework catalog's exact menu surface/item IDs, label keys, feature gates, and relative placement; never derive `menu:sidebar:*` or `menu:topbar:*` from memory.
|
|
70
84
|
|
|
71
85
|
## Extensions and Optional Coupling
|
|
72
86
|
|
|
@@ -102,3 +116,6 @@ Common host families include `crud-form:<entityId>:fields`, `data-table:<tableId
|
|
|
102
116
|
2. Test authorized, unauthorized, and wildcard-feature callers.
|
|
103
117
|
3. Test list and detail, create/update/delete/action, cache hit/miss, and failure fallback where applicable.
|
|
104
118
|
4. Run `yarn generate`, inspect host registration, and verify no installed file changed.
|
|
119
|
+
5. Re-read the generated contribution row: its target must resolve as `exact`, `pattern`, `framework`, `fact-ref`, or intentional `optional-external`, and every shared `roundTripId` leg must remain present. Treat `unresolved` first-party provenance as a failed generation/coverage gate.
|
|
120
|
+
|
|
121
|
+
The repository umbrella specification may be available at `.ai/specs/implemented/SPEC-041-2026-02-24-universal-module-extension-system.md` in a source checkout. It is optional background only; the generated facts and this selector are sufficient offline in a standalone scaffold.
|